summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/class/audio/audio_device.c115
-rw-r--r--src/class/cdc/cdc_device.c82
-rw-r--r--src/class/cdc/cdc_host.c283
-rw-r--r--src/class/cdc/cdc_host.h73
-rw-r--r--src/class/cdc/cdc_rndis_host.c289
-rw-r--r--src/class/cdc/cdc_rndis_host.h63
-rw-r--r--src/class/hid/hid_host.c64
-rw-r--r--src/class/hid/hid_host.h56
-rw-r--r--src/class/midi/midi_device.c38
-rw-r--r--src/class/midi/midi_host.c73
-rw-r--r--src/class/midi/midi_host.h62
-rw-r--r--src/class/msc/msc_host.c21
-rw-r--r--src/class/msc/msc_host.h48
-rw-r--r--src/class/mtp/mtp_device.c4
-rw-r--r--src/class/vendor/vendor_device.c37
-rw-r--r--src/class/vendor/vendor_device.h7
-rw-r--r--src/common/tusb_common.h5
-rw-r--r--src/common/tusb_compiler.h84
-rw-r--r--src/common/tusb_fifo.c13
-rw-r--r--src/common/tusb_fifo.h11
-rw-r--r--src/common/tusb_private.h94
-rw-r--r--src/device/usbd.c201
-rw-r--r--src/host/hub.c14
-rw-r--r--src/host/hub.h12
-rw-r--r--src/host/usbh.c101
-rw-r--r--src/host/usbh_pvt.h17
-rwxr-xr-xsrc/portable/synopsys/dwc2/dwc2_info.py1
-rw-r--r--src/portable/synopsys/dwc2/hcd_dwc2.c2
-rw-r--r--src/tusb.c216
-rw-r--r--src/tusb_option.h32
30 files changed, 810 insertions, 1308 deletions
diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c
index 19676234c..55eba81dd 100644
--- a/src/class/audio/audio_device.c
+++ b/src/class/audio/audio_device.c
@@ -65,40 +65,6 @@
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
-// Use ring buffer if it's available, some MCUs need extra RAM requirements
-// For DWC2 enable ring buffer will disable DMA (if available)
-#ifndef TUD_AUDIO_PREFER_RING_BUFFER
- #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX || \
- defined(TUP_USBIP_DWC2)
- #define TUD_AUDIO_PREFER_RING_BUFFER 0
- #else
- #define TUD_AUDIO_PREFER_RING_BUFFER 1
- #endif
-#endif
-
-// Linear buffer in case target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer
-// is available or driver is would need to be changed dramatically
-
-// Only STM32 and ChipIdea HS use non-linear buffer for now
-// Ring buffer is incompatible with dcache, since neither address nor size is aligned to cache line
-#if defined(TUP_USBIP_DWC2) || \
- defined(TUP_USBIP_FSDEV) || \
- CFG_TUSB_MCU == OPT_MCU_RX63X || \
- CFG_TUSB_MCU == OPT_MCU_RX65X || \
- CFG_TUSB_MCU == OPT_MCU_RX72N || \
- CFG_TUSB_MCU == OPT_MCU_LPC18XX || \
- CFG_TUSB_MCU == OPT_MCU_LPC43XX || \
- CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX || \
- CFG_TUSB_MCU == OPT_MCU_MSP432E4
- #if TUD_AUDIO_PREFER_RING_BUFFER && !CFG_TUD_MEM_DCACHE_ENABLE
- #define USE_LINEAR_BUFFER 0
- #else
- #define USE_LINEAR_BUFFER 1
- #endif
-#else
- #define USE_LINEAR_BUFFER 1
-#endif
-
// Declaration of buffers
// Check for maximum supported numbers
@@ -107,12 +73,12 @@
#endif
// Put swap buffer in USB section only if necessary
-#if USE_LINEAR_BUFFER
+#if !CFG_TUD_EDPT_DEDICATED_HWFIFO
#define IN_SW_BUF_MEM_ATTR TU_ATTR_ALIGNED(4)
#else
#define IN_SW_BUF_MEM_ATTR CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN
#endif
-#if USE_LINEAR_BUFFER
+#if !CFG_TUD_EDPT_DEDICATED_HWFIFO
#define OUT_SW_BUF_MEM_ATTR TU_ATTR_ALIGNED(4)
#else
#define OUT_SW_BUF_MEM_ATTR CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN
@@ -135,7 +101,7 @@ tu_static IN_SW_BUF_MEM_ATTR struct {
// Linear buffer TX in case:
// - target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically OR
-#if CFG_TUD_AUDIO_ENABLE_EP_IN && USE_LINEAR_BUFFER
+#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_EDPT_DEDICATED_HWFIFO
tu_static CFG_TUD_MEM_SECTION struct {
#if CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX > 0
TUD_EPBUF_DEF(buf_1, CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX);
@@ -147,7 +113,7 @@ tu_static CFG_TUD_MEM_SECTION struct {
TUD_EPBUF_DEF(buf_3, CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX);
#endif
} lin_buf_in;
-#endif// CFG_TUD_AUDIO_ENABLE_EP_IN && USE_LINEAR_BUFFER
+#endif// CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_EDPT_DEDICATED_HWFIFO
// EP OUT software buffers
#if CFG_TUD_AUDIO_ENABLE_EP_OUT
@@ -166,7 +132,7 @@ tu_static OUT_SW_BUF_MEM_ATTR struct {
// Linear buffer RX in case:
// - target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically OR
-#if CFG_TUD_AUDIO_ENABLE_EP_OUT && USE_LINEAR_BUFFER
+#if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_EDPT_DEDICATED_HWFIFO
tu_static CFG_TUD_MEM_SECTION struct {
#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0
TUD_EPBUF_DEF(buf_1, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX);
@@ -178,7 +144,7 @@ tu_static CFG_TUD_MEM_SECTION struct {
TUD_EPBUF_DEF(buf_3, CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX);
#endif
} lin_buf_out;
-#endif// CFG_TUD_AUDIO_ENABLE_EP_OUT && USE_LINEAR_BUFFER
+#endif// CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_EDPT_DEDICATED_HWFIFO
// Control buffer
CFG_TUD_MEM_ALIGN uint8_t ctrl_buf[CFG_TUD_AUDIO_CTRL_BUF_SZ];
@@ -287,14 +253,12 @@ typedef struct
#endif
// Linear buffer in case target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically
-#if CFG_TUD_AUDIO_ENABLE_EP_OUT && USE_LINEAR_BUFFER
+#if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_EDPT_DEDICATED_HWFIFO
uint8_t *lin_buf_out;
- #define USE_LINEAR_BUFFER_RX 1
#endif
-#if CFG_TUD_AUDIO_ENABLE_EP_IN && USE_LINEAR_BUFFER
+#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_EDPT_DEDICATED_HWFIFO
uint8_t *lin_buf_in;
- #define USE_LINEAR_BUFFER_TX 1
#endif
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
@@ -302,14 +266,6 @@ typedef struct
#endif
} audiod_function_t;
-#ifndef USE_LINEAR_BUFFER_TX
- #define USE_LINEAR_BUFFER_TX 0
-#endif
-
-#ifndef USE_LINEAR_BUFFER_RX
- #define USE_LINEAR_BUFFER_RX 0
-#endif
-
#if CFG_TUD_AUDIO_ENABLE_EP_OUT
#define ITF_MEM_RESET_SIZE offsetof(audiod_function_t, ep_out_ff)
#else
@@ -485,7 +441,8 @@ uint16_t tud_audio_n_read(uint8_t func_id, void *buffer, uint16_t bufsize) {
bool tud_audio_n_clear_ep_out_ff(uint8_t func_id) {
TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL);
- return tu_fifo_clear(&_audiod_fct[func_id].ep_out_ff);
+ tu_fifo_clear(&_audiod_fct[func_id].ep_out_ff);
+ return true;
}
tu_fifo_t *tud_audio_n_get_ep_out_ff(uint8_t func_id) {
@@ -498,7 +455,7 @@ tu_fifo_t *tud_audio_n_get_ep_out_ff(uint8_t func_id) {
static bool audiod_rx_xfer_isr(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received) {
uint8_t idx_audio_fct = audiod_get_audio_fct_idx(audio);
- #if USE_LINEAR_BUFFER_RX
+ #if !CFG_TUD_EDPT_DEDICATED_HWFIFO
// Data currently is in linear buffer, copy into EP OUT FIFO
TU_VERIFY(0 < tu_fifo_write_n(&audio->ep_out_ff, audio->lin_buf_out, n_bytes_received));
@@ -536,7 +493,8 @@ uint16_t tud_audio_n_write(uint8_t func_id, const void *data, uint16_t len) {
bool tud_audio_n_clear_ep_in_ff(uint8_t func_id) {
TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL);
- return tu_fifo_clear(&_audiod_fct[func_id].ep_in_ff);
+ tu_fifo_clear(&_audiod_fct[func_id].ep_in_ff);
+ return true;
}
tu_fifo_t *tud_audio_n_get_ep_in_ff(uint8_t func_id) {
@@ -572,7 +530,7 @@ static bool audiod_tx_xfer_isr(uint8_t rhport, audiod_function_t * audio, uint16
#else
n_bytes_tx = tu_min16(tu_fifo_count(&audio->ep_in_ff), audio->ep_in_sz);// Limit up to max packet size, more can not be done for ISO
#endif
- #if USE_LINEAR_BUFFER_TX
+ #if !CFG_TUD_EDPT_DEDICATED_HWFIFO
tu_fifo_read_n(&audio->ep_in_ff, audio->lin_buf_in, n_bytes_tx);
TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_in, audio->lin_buf_in, n_bytes_tx, true));
#else
@@ -730,32 +688,31 @@ void audiod_init(void) {
break;
#endif
}
-#endif// CFG_TUD_AUDIO_ENABLE_EP_IN
- // Initialize linear buffers
-#if USE_LINEAR_BUFFER_TX
+ // Initialize linear buffers
+ #if !CFG_TUD_EDPT_DEDICATED_HWFIFO
switch (i) {
- #if CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX > 0
+ #if CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX > 0
case 0:
audio->lin_buf_in = lin_buf_in.buf_1;
break;
- #endif
- #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX > 0
+ #endif
+ #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX > 0
case 1:
audio->lin_buf_in = lin_buf_in.buf_2;
break;
- #endif
- #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX > 0
+ #endif
+ #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX > 0
case 2:
audio->lin_buf_in = lin_buf_in.buf_3;
break;
- #endif
+ #endif
}
-#endif// USE_LINEAR_BUFFER_TX
+ #endif// !CFG_TUD_EDPT_DEDICATED_HWFIFO
+#endif// CFG_TUD_AUDIO_ENABLE_EP_IN
// Initialize OUT EP FIFO if required
#if CFG_TUD_AUDIO_ENABLE_EP_OUT
-
switch (i) {
#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0
case 0:
@@ -773,28 +730,28 @@ void audiod_init(void) {
break;
#endif
}
-#endif// CFG_TUD_AUDIO_ENABLE_EP_OUT
- // Initialize linear buffers
-#if USE_LINEAR_BUFFER_RX
+ #if !CFG_TUD_EDPT_DEDICATED_HWFIFO
+ // Initialize linear buffers
switch (i) {
- #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0
+ #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0
case 0:
audio->lin_buf_out = lin_buf_out.buf_1;
break;
- #endif
- #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX > 0
+ #endif
+ #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX > 0
case 1:
audio->lin_buf_out = lin_buf_out.buf_2;
break;
- #endif
- #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX > 0
+ #endif
+ #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX > 0
case 2:
audio->lin_buf_out = lin_buf_out.buf_3;
break;
- #endif
+ #endif
}
-#endif// USE_LINEAR_BUFFER_RX
+ #endif// !CFG_TUD_EDPT_DEDICATED_HWFIFO
+#endif// CFG_TUD_AUDIO_ENABLE_EP_OUT
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
switch (i) {
@@ -1231,7 +1188,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *p
audiod_parse_flow_control_params(audio, p_desc_parse_for_params);
#endif
// Schedule first transmit if alternate interface is not zero, as sample data is available a ZLP is loaded
- #if USE_LINEAR_BUFFER_TX
+ #if !CFG_TUD_EDPT_DEDICATED_HWFIFO
TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_in, audio->lin_buf_in, 0, false));
#else
// Send everything in ISO EP FIFO
@@ -1250,7 +1207,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *p
audio->ep_out_sz = tu_edpt_packet_size(desc_ep);
// Prepare for incoming data
- #if USE_LINEAR_BUFFER_RX
+ #if !CFG_TUD_EDPT_DEDICATED_HWFIFO
TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz, false));
#else
TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz, false));
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c
index d7792afe4..e2819ae4b 100644
--- a/src/class/cdc/cdc_device.c
+++ b/src/class/cdc/cdc_device.c
@@ -43,8 +43,6 @@
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
-#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
-
typedef struct {
uint8_t rhport;
uint8_t itf_num;
@@ -55,13 +53,11 @@ typedef struct {
TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding;
char wanted_char;
- struct {
- tu_edpt_stream_t tx;
- tu_edpt_stream_t rx;
+ tu_edpt_stream_t tx_stream;
+ tu_edpt_stream_t rx_stream;
- uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE];
- uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE];
- } stream;
+ uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE];
+ uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE];
} cdcd_interface_t;
#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding)
@@ -125,7 +121,7 @@ static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT();
TU_ATTR_ALWAYS_INLINE static inline uint8_t find_cdc_itf(uint8_t ep_addr) {
for (uint8_t idx = 0; idx < CFG_TUD_CDC; idx++) {
const cdcd_interface_t *p_cdc = &_cdcd_itf[idx];
- if (ep_addr == p_cdc->stream.rx.ep_addr || ep_addr == p_cdc->stream.tx.ep_addr ||
+ if (ep_addr == p_cdc->rx_stream.ep_addr || ep_addr == p_cdc->tx_stream.ep_addr ||
(ep_addr == p_cdc->ep_notify && ep_addr != 0)) {
return idx;
}
@@ -147,8 +143,8 @@ bool tud_cdc_n_ready(uint8_t itf) {
TU_VERIFY(tud_ready());
const cdcd_interface_t *p_cdc = &_cdcd_itf[itf];
- const bool in_opened = tu_edpt_stream_is_opened(&p_cdc->stream.tx);
- const bool out_opened = tu_edpt_stream_is_opened(&p_cdc->stream.rx);
+ const bool in_opened = tu_edpt_stream_is_opened(&p_cdc->tx_stream);
+ const bool out_opened = tu_edpt_stream_is_opened(&p_cdc->rx_stream);
return in_opened && out_opened;
}
@@ -199,25 +195,25 @@ void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) {
//--------------------------------------------------------------------+
uint32_t tud_cdc_n_available(uint8_t itf) {
TU_VERIFY(itf < CFG_TUD_CDC, 0);
- return tu_edpt_stream_read_available(&_cdcd_itf[itf].stream.rx);
+ return tu_edpt_stream_read_available(&_cdcd_itf[itf].rx_stream);
}
uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) {
TU_VERIFY(itf < CFG_TUD_CDC, 0);
cdcd_interface_t *p_cdc = &_cdcd_itf[itf];
- return tu_edpt_stream_read(p_cdc->rhport, &p_cdc->stream.rx, buffer, bufsize);
+ return tu_edpt_stream_read(&p_cdc->rx_stream, buffer, bufsize);
}
bool tud_cdc_n_peek(uint8_t itf, uint8_t *chr) {
TU_VERIFY(itf < CFG_TUD_CDC);
- return tu_edpt_stream_peek(&_cdcd_itf[itf].stream.rx, chr);
+ return tu_edpt_stream_peek(&_cdcd_itf[itf].rx_stream, chr);
}
void tud_cdc_n_read_flush(uint8_t itf) {
TU_VERIFY(itf < CFG_TUD_CDC, );
cdcd_interface_t *p_cdc = &_cdcd_itf[itf];
- tu_edpt_stream_clear(&p_cdc->stream.rx);
- tu_edpt_stream_read_xfer(p_cdc->rhport, &p_cdc->stream.rx);
+ tu_edpt_stream_clear(&p_cdc->rx_stream);
+ tu_edpt_stream_read_xfer(&p_cdc->rx_stream);
}
//--------------------------------------------------------------------+
@@ -226,25 +222,26 @@ void tud_cdc_n_read_flush(uint8_t itf) {
uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) {
TU_VERIFY(itf < CFG_TUD_CDC, 0);
cdcd_interface_t *p_cdc = &_cdcd_itf[itf];
- return tu_edpt_stream_write(p_cdc->rhport, &p_cdc->stream.tx, buffer, bufsize);
+ return tu_edpt_stream_write(&p_cdc->tx_stream, buffer, bufsize);
}
uint32_t tud_cdc_n_write_flush(uint8_t itf) {
TU_VERIFY(itf < CFG_TUD_CDC, 0);
cdcd_interface_t *p_cdc = &_cdcd_itf[itf];
- return tu_edpt_stream_write_xfer(p_cdc->rhport, &p_cdc->stream.tx);
+ return tu_edpt_stream_write_xfer(&p_cdc->tx_stream);
}
uint32_t tud_cdc_n_write_available(uint8_t itf) {
TU_VERIFY(itf < CFG_TUD_CDC, 0);
cdcd_interface_t *p_cdc = &_cdcd_itf[itf];
- return tu_edpt_stream_write_available(p_cdc->rhport, &p_cdc->stream.tx);
+ return tu_edpt_stream_write_available(&p_cdc->tx_stream);
}
bool tud_cdc_n_write_clear(uint8_t itf) {
TU_VERIFY(itf < CFG_TUD_CDC);
cdcd_interface_t *p_cdc = &_cdcd_itf[itf];
- return tu_edpt_stream_clear(&p_cdc->stream.tx);
+ tu_edpt_stream_clear(&p_cdc->tx_stream);
+ return true;
}
//--------------------------------------------------------------------+
@@ -270,22 +267,22 @@ void cdcd_init(void) {
uint8_t *epin_buf = _cdcd_epbuf[i].epin;
#endif
- tu_edpt_stream_init(&p_cdc->stream.rx, false, false, false, p_cdc->stream.rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE,
- epout_buf, CFG_TUD_CDC_EP_BUFSIZE);
+ tu_edpt_stream_init(&p_cdc->rx_stream, false, false, false, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, epout_buf,
+ CFG_TUD_CDC_EP_BUFSIZE);
// TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not
// know if data is actually polled by terminal. This way the most current data is prioritized.
// Default: is overwritable
- tu_edpt_stream_init(&p_cdc->stream.tx, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected,
- p_cdc->stream.tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE);
+ tu_edpt_stream_init(&p_cdc->tx_stream, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, p_cdc->tx_ff_buf,
+ CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE);
}
}
bool cdcd_deinit(void) {
for (uint8_t i = 0; i < CFG_TUD_CDC; i++) {
cdcd_interface_t* p_cdc = &_cdcd_itf[i];
- tu_edpt_stream_deinit(&p_cdc->stream.rx);
- tu_edpt_stream_deinit(&p_cdc->stream.tx);
+ tu_edpt_stream_deinit(&p_cdc->rx_stream);
+ tu_edpt_stream_deinit(&p_cdc->tx_stream);
}
return true;
}
@@ -297,9 +294,9 @@ void cdcd_reset(uint8_t rhport) {
cdcd_interface_t* p_cdc = &_cdcd_itf[i];
tu_memclr(p_cdc, ITF_MEM_RESET_SIZE);
- tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, _cdcd_cfg.tx_overwritabe_if_not_connected); // back to default
- tu_edpt_stream_close(&p_cdc->stream.rx);
- tu_edpt_stream_close(&p_cdc->stream.tx);
+ tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, _cdcd_cfg.tx_overwritabe_if_not_connected); // back to default
+ tu_edpt_stream_close(&p_cdc->rx_stream);
+ tu_edpt_stream_close(&p_cdc->tx_stream);
}
}
@@ -350,22 +347,22 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16
TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0);
if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
- tu_edpt_stream_t *stream_tx = &p_cdc->stream.tx;
+ tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream;
- tu_edpt_stream_open(stream_tx, desc_ep);
+ tu_edpt_stream_open(stream_tx, rhport, desc_ep);
if (_cdcd_cfg.tx_persistent) {
- tu_edpt_stream_write_xfer(rhport, stream_tx); // flush pending data
+ tu_edpt_stream_write_xfer(stream_tx); // flush pending data
} else {
tu_edpt_stream_clear(stream_tx);
}
} else {
- tu_edpt_stream_t *stream_rx = &p_cdc->stream.rx;
+ tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream;
- tu_edpt_stream_open(stream_rx, desc_ep);
+ tu_edpt_stream_open(stream_rx, rhport, desc_ep);
if (!_cdcd_cfg.rx_persistent) {
tu_edpt_stream_clear(stream_rx);
}
- TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare for incoming data
+ TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare for incoming data
}
}
@@ -430,9 +427,9 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ
// If enabled: fifo overwriting is disabled if DTR bit is set and vice versa
if (_cdcd_cfg.tx_overwritabe_if_not_connected) {
- tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, !dtr);
+ tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, !dtr);
} else {
- tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, false);
+ tu_fifo_set_overwritable(&p_cdc->tx_stream.ff, false);
}
TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts);
@@ -461,13 +458,14 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ
}
bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
+ (void)rhport;
(void)result;
uint8_t itf = find_cdc_itf(ep_addr);
TU_ASSERT(itf < CFG_TUD_CDC);
cdcd_interface_t *p_cdc = &_cdcd_itf[itf];
- tu_edpt_stream_t *stream_rx = &p_cdc->stream.rx;
- tu_edpt_stream_t *stream_tx = &p_cdc->stream.tx;
+ tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream;
+ tu_edpt_stream_t *stream_tx = &p_cdc->tx_stream;
// Received new data, move to fifo
if (ep_addr == stream_rx->ep_addr) {
@@ -511,7 +509,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
tud_cdc_rx_cb(itf);
}
- tu_edpt_stream_read_xfer(rhport, stream_rx); // prepare for more data
+ tu_edpt_stream_read_xfer(stream_rx); // prepare for more data
}
// Data sent to host, we continue to fetch from tx fifo to send.
@@ -519,9 +517,9 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
if (ep_addr == stream_tx->ep_addr) {
tud_cdc_tx_complete_cb(itf); // invoke callback to possibly refill tx fifo
- if (0 == tu_edpt_stream_write_xfer(rhport, stream_tx)) {
+ if (0 == tu_edpt_stream_write_xfer(stream_tx)) {
// If there is no data left, a ZLP should be sent if needed
- tu_edpt_stream_write_zlp_if_needed(rhport, stream_tx, xferred_bytes);
+ tu_edpt_stream_write_zlp_if_needed(stream_tx, xferred_bytes);
}
}
diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c
index 35717ddf6..32f6827b0 100644
--- a/src/class/cdc/cdc_host.c
+++ b/src/class/cdc/cdc_host.c
@@ -29,6 +29,8 @@
#include "tusb_option.h"
+#include <stdint.h>
+
#if (CFG_TUH_ENABLED && CFG_TUH_CDC)
#include "host/usbh.h"
@@ -41,13 +43,14 @@
#include "serial/pl2303.h"
// Level where CFG_TUSB_DEBUG must be at least for this driver is logged
-#ifndef CFG_TUH_CDC_LOG_LEVEL
- #define CFG_TUH_CDC_LOG_LEVEL 2
-#endif
+ #ifndef CFG_TUH_CDC_LOG_LEVEL
+ #define CFG_TUH_CDC_LOG_LEVEL 2
+ #endif
-#define TU_LOG_DRV(...) TU_LOG(CFG_TUH_CDC_LOG_LEVEL, __VA_ARGS__)
-#define TU_LOG_CDC(_cdc, _format, ...) TU_LOG_DRV("[:%u:%u] CDCh %s " _format "\r\n", _cdc->daddr, _cdc->bInterfaceNumber, \
- serial_drivers[_cdc->serial_drid].name, ##__VA_ARGS__)
+ #define TU_LOG_DRV(...) TU_LOG(CFG_TUH_CDC_LOG_LEVEL, __VA_ARGS__)
+ #define TU_LOG_CDC(_cdc, _format, ...) \
+ TU_LOG_DRV("[:%u:%u] CDCh %s " _format "\r\n", _cdc->daddr, _cdc->bInterfaceNumber, \
+ serial_drivers[_cdc->serial_drid].name, ##__VA_ARGS__)
//--------------------------------------------------------------------+
// Host CDC Interface
@@ -113,63 +116,59 @@ static void cdch_set_line_coding_stage1_baudrate_complete(tuh_xfer_t *xfer);
static void cdch_set_line_coding_stage2_data_format_complete(tuh_xfer_t *xfer);
//------------- ACM prototypes -------------//
-static bool acm_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
-static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
-static void acm_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
-
-static bool acm_set_line_coding(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-static bool acm_set_control_line_state(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+static uint16_t acm_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len);
+static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
+static void acm_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
+static bool acm_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+static bool acm_set_control_line_state(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-//------------- FTDI prototypes -------------//
-#if CFG_TUH_CDC_FTDI
+ //------------- FTDI prototypes -------------//
+ #if CFG_TUH_CDC_FTDI
static uint16_t const ftdi_vid_pid_list[][2] = {CFG_TUH_CDC_FTDI_VID_PID_LIST};
-static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t * itf_desc, uint16_t max_len);
-static bool ftdi_proccess_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
-static void ftdi_internal_control_complete(cdch_interface_t* p_cdc, tuh_xfer_t *xfer);
-static bool ftdi_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-static bool ftdi_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-static bool ftdi_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-#endif
+static uint16_t ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len);
+static bool ftdi_proccess_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
+static void ftdi_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
+static bool ftdi_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+static bool ftdi_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+static bool ftdi_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+ #endif
-//------------- CP210X prototypes -------------//
-#if CFG_TUH_CDC_CP210X
+ //------------- CP210X prototypes -------------//
+ #if CFG_TUH_CDC_CP210X
static uint16_t const cp210x_vid_pid_list[][2] = {CFG_TUH_CDC_CP210X_VID_PID_LIST};
-static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
-static bool cp210x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
-static void cp210x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
-
-static bool cp210x_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-static bool cp210x_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-static bool cp210x_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-#endif
+static uint16_t cp210x_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len);
+static bool cp210x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
+static void cp210x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
+static bool cp210x_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+static bool cp210x_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+static bool cp210x_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+ #endif
-//------------- CH34x prototypes -------------//
-#if CFG_TUH_CDC_CH34X
+ //------------- CH34x prototypes -------------//
+ #if CFG_TUH_CDC_CH34X
static uint16_t const ch34x_vid_pid_list[][2] = {CFG_TUH_CDC_CH34X_VID_PID_LIST};
-static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
-static bool ch34x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
-static void ch34x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
-
-static bool ch34x_set_baudrate(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-static bool ch34x_set_data_format(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-static bool ch34x_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-#endif
+static uint16_t ch34x_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len);
+static bool ch34x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
+static void ch34x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
+static bool ch34x_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+static bool ch34x_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+static bool ch34x_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+ #endif
-//------------- PL2303 prototypes -------------//
-#if CFG_TUH_CDC_PL2303
+ //------------- PL2303 prototypes -------------//
+ #if CFG_TUH_CDC_PL2303
static uint16_t const pl2303_vid_pid_list[][2] = {CFG_TUH_CDC_PL2303_VID_PID_LIST};
static const pl2303_type_data_t pl2303_type_data[PL2303_TYPE_COUNT] = {PL2303_TYPE_DATA};
-static bool pl2303_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
-static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
-static void pl2303_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
-
-static bool pl2303_set_line_coding(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-static bool pl2303_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
-#endif
+static uint16_t pl2303_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len);
+static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
+static void pl2303_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
+static bool pl2303_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+static bool pl2303_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+ #endif
//------------- Common -------------//
enum {
@@ -197,11 +196,12 @@ enum {
typedef bool (*serial_driver_func_t)(cdch_interface_t * p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
typedef struct {
- uint16_t const (*vid_pid_list)[2];
- uint16_t const vid_pid_count;
- bool (*const open)(uint8_t daddr, const tusb_desc_interface_t * itf_desc, uint16_t max_len);
- bool (*const process_set_config)(cdch_interface_t * p_cdc, tuh_xfer_t * xfer);
- void (*const request_complete)(cdch_interface_t * p_cdc, tuh_xfer_t * xfer); // internal request complete handler to update line state
+ const uint16_t (*vid_pid_list)[2];
+ const uint16_t vid_pid_count;
+ uint16_t (*const open)(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len);
+ bool (*const process_set_config)(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
+ // internal request complete handler to update line state
+ void (*const request_complete)(cdch_interface_t *p_cdc, tuh_xfer_t *xfer);
serial_driver_func_t set_control_line_state, set_baudrate, set_data_format, set_line_coding;
@@ -470,25 +470,26 @@ bool tuh_cdc_get_line_coding_local(uint8_t idx, cdc_line_coding_t * line_coding)
uint32_t tuh_cdc_write(uint8_t idx, void const * buffer, uint32_t bufsize) {
cdch_interface_t * p_cdc = get_itf(idx);
TU_VERIFY(p_cdc);
- return tu_edpt_stream_write(p_cdc->daddr, &p_cdc->stream.tx, buffer, bufsize);
+ return tu_edpt_stream_write(&p_cdc->stream.tx, buffer, bufsize);
}
uint32_t tuh_cdc_write_flush(uint8_t idx) {
cdch_interface_t * p_cdc = get_itf(idx);
TU_VERIFY(p_cdc);
- return tu_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx);
+ return tu_edpt_stream_write_xfer(&p_cdc->stream.tx);
}
bool tuh_cdc_write_clear(uint8_t idx) {
cdch_interface_t * p_cdc = get_itf(idx);
TU_VERIFY(p_cdc);
- return tu_edpt_stream_clear(&p_cdc->stream.tx);
+ tu_edpt_stream_clear(&p_cdc->stream.tx);
+ return true;
}
uint32_t tuh_cdc_write_available(uint8_t idx) {
cdch_interface_t * p_cdc = get_itf(idx);
TU_VERIFY(p_cdc);
- return tu_edpt_stream_write_available(p_cdc->daddr, &p_cdc->stream.tx);
+ return tu_edpt_stream_write_available(&p_cdc->stream.tx);
}
//--------------------------------------------------------------------+
@@ -498,7 +499,7 @@ uint32_t tuh_cdc_write_available(uint8_t idx) {
uint32_t tuh_cdc_read (uint8_t idx, void * buffer, uint32_t bufsize) {
cdch_interface_t * p_cdc = get_itf(idx);
TU_VERIFY(p_cdc);
- return tu_edpt_stream_read(p_cdc->daddr, &p_cdc->stream.rx, buffer, bufsize);
+ return tu_edpt_stream_read(&p_cdc->stream.rx, buffer, bufsize);
}
uint32_t tuh_cdc_read_available(uint8_t idx) {
@@ -517,9 +518,9 @@ bool tuh_cdc_read_clear (uint8_t idx) {
cdch_interface_t * p_cdc = get_itf(idx);
TU_VERIFY(p_cdc);
- bool ret = tu_edpt_stream_clear(&p_cdc->stream.rx);
- (void)tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx);
- return ret;
+ tu_edpt_stream_clear(&p_cdc->stream.rx);
+ (void)tu_edpt_stream_read_xfer(&p_cdc->stream.rx);
+ return true;
}
//--------------------------------------------------------------------+
@@ -692,10 +693,10 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t
if (ep_addr == p_cdc->stream.tx.ep_addr) {
tuh_cdc_tx_complete_cb(idx); // invoke transmit complete callback
- if (0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx)) {
+ if (0 == tu_edpt_stream_write_xfer(&p_cdc->stream.tx)) {
// If there is no data left, a ZLP should be sent if:
// - xferred_bytes is multiple of EP Packet size and not zero
- (void)tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes);
+ (void)tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes);
}
} else if (ep_addr == p_cdc->stream.rx.ep_addr) {
#if CFG_TUH_CDC_FTDI
@@ -715,7 +716,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t
}
// prepare for next transfer if needed
- tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx);
+ tu_edpt_stream_read_xfer(&p_cdc->stream.rx);
} else if (ep_addr == p_cdc->ep_notif) {
// TODO handle notification endpoint
} else {
@@ -730,12 +731,11 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t
//--------------------------------------------------------------------+
static bool open_ep_stream_pair(cdch_interface_t *p_cdc, tusb_desc_endpoint_t const *desc_ep) {
for (size_t i = 0; i < 2; i++) {
- TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType &&
- TUSB_XFER_BULK == desc_ep->bmAttributes.xfer);
+ TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer, 0);
TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep));
- tu_edpt_stream_t *stream =
- (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) ? &p_cdc->stream.rx : &p_cdc->stream.tx;
- tu_edpt_stream_open(stream, desc_ep);
+ const uint8_t ep_dir = tu_edpt_dir(desc_ep->bEndpointAddress);
+ tu_edpt_stream_t *stream = (ep_dir == TUSB_DIR_IN) ? &p_cdc->stream.rx : &p_cdc->stream.tx;
+ tu_edpt_stream_open(stream, p_cdc->daddr, desc_ep);
tu_edpt_stream_clear(stream);
desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_ep);
@@ -744,8 +744,8 @@ static bool open_ep_stream_pair(cdch_interface_t *p_cdc, tusb_desc_endpoint_t co
return true;
}
-bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) {
- (void) rhport;
+uint16_t cdch_open(uint8_t rhport, uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) {
+ (void)rhport;
// For CDC: only support ACM subclass
// Note: Protocol 0xFF can be RNDIS device
if (TUSB_CLASS_CDC == itf_desc->bInterfaceClass &&
@@ -754,15 +754,15 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d
} else if (SERIAL_DRIVER_COUNT > 1 &&
TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass) {
uint16_t vid, pid;
- TU_VERIFY(tuh_vid_pid_get(daddr, &vid, &pid));
+ TU_VERIFY(tuh_vid_pid_get(daddr, &vid, &pid), 0);
- for (size_t dr = 1; dr < SERIAL_DRIVER_COUNT; dr++) {
- const cdch_serial_driver_t *driver = &serial_drivers[dr];
+ for (size_t drv = 1; drv < SERIAL_DRIVER_COUNT; drv++) {
+ const cdch_serial_driver_t *driver = &serial_drivers[drv];
for (size_t i = 0; i < driver->vid_pid_count; i++) {
if (driver->vid_pid_list[i][0] == vid && driver->vid_pid_list[i][1] == pid) {
- const bool ret = driver->open(daddr, itf_desc, max_len);
- TU_LOG_DRV("[:%u:%u] CDCh %s open %s\r\n", daddr, itf_desc->bInterfaceNumber, driver->name, ret ? "OK" : "FAILED");
- return ret;
+ const uint16_t drv_len = driver->open(daddr, itf_desc, max_len);
+ TU_LOG_DRV("[:%u:%u] CDCh %s open %s\r\n", daddr, itf_desc->bInterfaceNumber, driver->name, drv_len > 0 ? "OK" : "FAILED");
+ return drv_len;
}
}
}
@@ -770,7 +770,7 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d
// not supported class
}
- return false;
+ return 0;
}
bool cdch_set_config(uint8_t daddr, uint8_t itf_num) {
@@ -798,7 +798,7 @@ static void set_config_complete(cdch_interface_t *p_cdc, bool success) {
p_cdc->mounted = true;
tuh_cdc_mount_cb(idx);
// Prepare for incoming data
- tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx);
+ tu_edpt_stream_read_xfer(&p_cdc->stream.rx);
} else {
// clear the interface entry
p_cdc->daddr = 0;
@@ -1011,19 +1011,19 @@ enum {
CONFIG_ACM_COMPLETE = 0
};
-static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) {
- uint8_t const *p_desc_end = ((uint8_t const *) itf_desc) + max_len;
+static uint16_t acm_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) {
+ const uint8_t *p_desc = (const uint8_t *)itf_desc;
+ const uint8_t *desc_end = p_desc + max_len;
cdch_interface_t *p_cdc = make_new_itf(daddr, itf_desc);
- TU_VERIFY(p_cdc);
-
+ TU_VERIFY(p_cdc, 0);
p_cdc->serial_drid = SERIAL_DRIVER_ACM;
//------------- Control Interface -------------//
- uint8_t const *p_desc = tu_desc_next(itf_desc);
+ p_desc = tu_desc_next(p_desc);
// Communication Functional Descriptors
- while ((p_desc < p_desc_end) && (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc))) {
+ while ((p_desc < desc_end) && (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc))) {
if (CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc)) {
// save ACM bmCapabilities
p_cdc->acm.capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities;
@@ -1034,26 +1034,27 @@ static bool acm_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint1
// Open notification endpoint of control interface if any
if (itf_desc->bNumEndpoints == 1) {
- TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc));
- tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc;
-
- TU_ASSERT(tuh_edpt_open(daddr, desc_ep));
+ TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(p_desc), 0);
+ const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc;
+ TU_ASSERT(tuh_edpt_open(daddr, desc_ep), 0);
p_cdc->ep_notif = desc_ep->bEndpointAddress;
p_desc = tu_desc_next(p_desc);
}
//------------- Data Interface (if any) -------------//
- if ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) &&
- (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass)) {
- // next to endpoint descriptor
- p_desc = tu_desc_next(p_desc);
+ if (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) {
+ const tusb_desc_interface_t *data_itf = (const tusb_desc_interface_t *)p_desc;
+ if (data_itf->bInterfaceClass == TUSB_CLASS_CDC_DATA) {
+ p_desc = tu_desc_next(p_desc); // next to endpoint descriptor
- // data endpoints expected to be in pairs
- TU_ASSERT(open_ep_stream_pair(p_cdc, (tusb_desc_endpoint_t const *) p_desc));
+ // data endpoints expected to be in pairs
+ TU_ASSERT(open_ep_stream_pair(p_cdc, (const tusb_desc_endpoint_t *)p_desc), 0);
+ p_desc += data_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t);
+ }
}
- return true;
+ return (uint16_t)((uintptr_t)p_desc - (uintptr_t)itf_desc);
}
static bool acm_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) {
@@ -1186,28 +1187,30 @@ enum {
CONFIG_FTDI_COMPLETE
};
-static bool ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) {
+static uint16_t ftdi_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) {
// FTDI Interface includes 1 vendor interface + 2 bulk endpoints
TU_VERIFY(itf_desc->bInterfaceSubClass == 0xff && itf_desc->bInterfaceProtocol == 0xff &&
- itf_desc->bNumEndpoints == 2);
- TU_VERIFY(sizeof(tusb_desc_interface_t) + 2 * sizeof(tusb_desc_endpoint_t) <= max_len);
+ itf_desc->bNumEndpoints == 2,
+ 0);
+ const uint16_t drv_len =
+ (uint16_t)(sizeof(tusb_desc_interface_t) + itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
+ TU_VERIFY(drv_len <= max_len, 0);
cdch_interface_t *p_cdc = make_new_itf(daddr, itf_desc);
- TU_VERIFY(p_cdc);
+ TU_VERIFY(p_cdc, 0);
p_cdc->serial_drid = SERIAL_DRIVER_FTDI;
// endpoint pair
- tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc);
+ const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(itf_desc);
- /*
- * NOTE: Some customers have programmed FT232R/FT245R devices
- * with an endpoint size of 0 - not good.
- */
- TU_ASSERT(desc_ep->wMaxPacketSize != 0);
+ /* NOTE: Some users have programmed FT232R/FT245R devices
+ * with an endpoint size of 0 !!! */
+ TU_ASSERT(desc_ep->wMaxPacketSize != 0, 0);
- // data endpoints expected to be in pairs
- return open_ep_stream_pair(p_cdc, desc_ep);
+ TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep), 0);
+
+ return drv_len;
}
static bool ftdi_proccess_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) {
@@ -1578,21 +1581,23 @@ enum {
CONFIG_CP210X_COMPLETE
};
-static bool cp210x_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) {
+static uint16_t cp210x_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) {
// CP210x Interface includes 1 vendor interface + 2 bulk endpoints
- TU_VERIFY(itf_desc->bInterfaceSubClass == 0 && itf_desc->bInterfaceProtocol == 0 && itf_desc->bNumEndpoints == 2);
- TU_VERIFY(sizeof(tusb_desc_interface_t) + 2 * sizeof(tusb_desc_endpoint_t) <= max_len);
+ TU_VERIFY(itf_desc->bInterfaceSubClass == 0 && itf_desc->bInterfaceProtocol == 0 && itf_desc->bNumEndpoints == 2, 0);
+ const uint16_t drv_len =
+ (uint16_t)(sizeof(tusb_desc_interface_t) + itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
+ TU_VERIFY(drv_len <= max_len, 0);
cdch_interface_t *p_cdc = make_new_itf(daddr, itf_desc);
- TU_VERIFY(p_cdc);
+ TU_VERIFY(p_cdc, 0);
p_cdc->serial_drid = SERIAL_DRIVER_CP210X;
- // endpoint pair
- tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc);
-
// data endpoints expected to be in pairs
- return open_ep_stream_pair(p_cdc, desc_ep);
+ const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(itf_desc);
+ TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep));
+
+ return drv_len;
}
static bool cp210x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) {
@@ -1752,29 +1757,30 @@ enum {
CONFIG_CH34X_COMPLETE
};
-static bool ch34x_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len) {
+static uint16_t ch34x_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) {
// CH34x Interface includes 1 vendor interface + 2 bulk + 1 interrupt endpoints
- TU_VERIFY(itf_desc->bNumEndpoints == 3);
- TU_VERIFY(sizeof(tusb_desc_interface_t) + 3 * sizeof(tusb_desc_endpoint_t) <= max_len);
+ TU_VERIFY(itf_desc->bNumEndpoints == 3, 0);
+ const uint16_t drv_len =
+ (uint16_t)(sizeof(tusb_desc_interface_t) + itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
+ TU_VERIFY(drv_len <= max_len, 0);
cdch_interface_t * p_cdc = make_new_itf(daddr, itf_desc);
- TU_VERIFY(p_cdc);
+ TU_VERIFY(p_cdc, 0);
p_cdc->serial_drid = SERIAL_DRIVER_CH34X;
- tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc);
+ const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(itf_desc);
// data endpoints expected to be in pairs
- TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep));
- desc_ep += 2;
+ TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep), 0);
+ desc_ep = (const tusb_desc_endpoint_t *)((uintptr_t)desc_ep + 2 * sizeof(tusb_desc_endpoint_t));
// Interrupt endpoint: not used for now
- TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) &&
- TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer);
- TU_ASSERT(tuh_edpt_open(daddr, desc_ep));
+ TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0);
+ TU_ASSERT(tuh_edpt_open(daddr, desc_ep), 0);
p_cdc->ep_notif = desc_ep->bEndpointAddress;
- return true;
+ return drv_len;
}
static bool ch34x_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) {
@@ -2088,13 +2094,15 @@ enum {
CONFIG_PL2303_COMPLETE
};
-static bool pl2303_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) {
+static uint16_t pl2303_open(uint8_t daddr, const tusb_desc_interface_t *itf_desc, uint16_t max_len) {
// PL2303 Interface includes 1 vendor interface + 1 interrupt endpoints + 2 bulk
- TU_VERIFY(itf_desc->bNumEndpoints == 3);
- TU_VERIFY(sizeof(tusb_desc_interface_t) + 3 * sizeof(tusb_desc_endpoint_t) <= max_len);
+ TU_VERIFY(itf_desc->bNumEndpoints == 3, 0);
+ const uint16_t drv_len =
+ (uint16_t)(sizeof(tusb_desc_interface_t) + itf_desc->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
+ TU_VERIFY(drv_len <= max_len, 0);
cdch_interface_t *p_cdc = make_new_itf(daddr, itf_desc);
- TU_VERIFY(p_cdc);
+ TU_VERIFY(p_cdc, 0);
p_cdc->serial_drid = SERIAL_DRIVER_PL2303;
p_cdc->pl2303.quirks = 0;
@@ -2103,16 +2111,15 @@ static bool pl2303_open(uint8_t daddr, tusb_desc_interface_t const *itf_desc, ui
tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc);
// Interrupt endpoint: not used for now
- TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) &&
- TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer);
- TU_ASSERT(tuh_edpt_open(daddr, desc_ep));
+ TU_ASSERT(TUSB_DESC_ENDPOINT == tu_desc_type(desc_ep) && TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0);
+ TU_ASSERT(tuh_edpt_open(daddr, desc_ep), 0);
p_cdc->ep_notif = desc_ep->bEndpointAddress;
desc_ep += 1;
// data endpoints expected to be in pairs
- TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep));
+ TU_ASSERT(open_ep_stream_pair(p_cdc, desc_ep), 0);
- return true;
+ return drv_len;
}
static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) {
diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h
index e8637beac..57919c7ff 100644
--- a/src/class/cdc/cdc_host.h
+++ b/src/class/cdc/cdc_host.h
@@ -30,7 +30,7 @@
#include "cdc.h"
#ifdef __cplusplus
- extern "C" {
+extern "C" {
#endif
//--------------------------------------------------------------------+
@@ -39,22 +39,22 @@
// RX FIFO size
#ifndef CFG_TUH_CDC_RX_BUFSIZE
-#define CFG_TUH_CDC_RX_BUFSIZE TUH_EPSIZE_BULK_MPS
+ #define CFG_TUH_CDC_RX_BUFSIZE TUH_EPSIZE_BULK_MPS
#endif
// RX Endpoint size
#ifndef CFG_TUH_CDC_RX_EPSIZE
-#define CFG_TUH_CDC_RX_EPSIZE TUH_EPSIZE_BULK_MPS
+ #define CFG_TUH_CDC_RX_EPSIZE TUH_EPSIZE_BULK_MPS
#endif
// TX FIFO size
#ifndef CFG_TUH_CDC_TX_BUFSIZE
-#define CFG_TUH_CDC_TX_BUFSIZE TUH_EPSIZE_BULK_MPS
+ #define CFG_TUH_CDC_TX_BUFSIZE TUH_EPSIZE_BULK_MPS
#endif
// TX Endpoint size
#ifndef CFG_TUH_CDC_TX_EPSIZE
-#define CFG_TUH_CDC_TX_EPSIZE TUH_EPSIZE_BULK_MPS
+ #define CFG_TUH_CDC_TX_EPSIZE TUH_EPSIZE_BULK_MPS
#endif
//--------------------------------------------------------------------+
@@ -67,7 +67,7 @@ uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num);
// Get Interface information
// return true if index is correct and interface is currently mounted
-bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t* info);
+bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t *info);
// Check if an interface is mounted
bool tuh_cdc_mounted(uint8_t idx);
@@ -75,7 +75,7 @@ bool tuh_cdc_mounted(uint8_t idx);
// Get local (cached) line state
// This function should return correct values if tuh_cdc_set_control_line_state() / tuh_cdc_get_control_line_state()
// are invoked previously or CFG_TUH_CDC_LINE_STATE_ON_ENUM is defined.
-bool tuh_cdc_get_control_line_state_local(uint8_t idx, uint16_t* line_state);
+bool tuh_cdc_get_control_line_state_local(uint8_t idx, uint16_t *line_state);
// Get current DTR status
TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_get_dtr(uint8_t idx) {
@@ -100,7 +100,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connected(uint8_t idx) {
// This function should return correct values if tuh_cdc_set_line_coding() / tuh_cdc_get_line_coding()
// are invoked previously or CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined.
// NOTE: This function does not make any USB transfer request to device.
-bool tuh_cdc_get_line_coding_local(uint8_t idx, cdc_line_coding_t* line_coding);
+bool tuh_cdc_get_line_coding_local(uint8_t idx, cdc_line_coding_t *line_coding);
#define tuh_cdc_get_local_line_coding tuh_cdc_get_line_coding_local // backward compatibility
@@ -112,7 +112,7 @@ bool tuh_cdc_get_line_coding_local(uint8_t idx, cdc_line_coding_t* line_coding);
uint32_t tuh_cdc_write_available(uint8_t idx);
// Write to cdc interface
-uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize);
+uint32_t tuh_cdc_write(uint8_t idx, const void *buffer, uint32_t bufsize);
// Force sending data if possible, return number of forced bytes
uint32_t tuh_cdc_write_flush(uint8_t idx);
@@ -128,13 +128,13 @@ bool tuh_cdc_write_clear(uint8_t idx);
uint32_t tuh_cdc_read_available(uint8_t idx);
// Read from cdc interface
-uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize);
+uint32_t tuh_cdc_read(uint8_t idx, void *buffer, uint32_t bufsize);
// Get a byte from RX FIFO without removing it
-bool tuh_cdc_peek(uint8_t idx, uint8_t* ch);
+bool tuh_cdc_peek(uint8_t idx, uint8_t *ch);
// Clear the received FIFO
-bool tuh_cdc_read_clear (uint8_t idx);
+bool tuh_cdc_read_clear(uint8_t idx);
//--------------------------------------------------------------------+
// Control Request API
@@ -149,16 +149,18 @@ bool tuh_cdc_read_clear (uint8_t idx);
bool tuh_cdc_set_control_line_state(uint8_t idx, uint16_t line_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
// Request to Set DTR
-TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_set_dtr(uint8_t idx, bool dtr_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
- cdc_line_control_state_t line_state = { .dtr = dtr_state };
- line_state.rts = tuh_cdc_get_rts(idx);
+TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_set_dtr(uint8_t idx, bool dtr_state, tuh_xfer_cb_t complete_cb,
+ uintptr_t user_data) {
+ cdc_line_control_state_t line_state = {.dtr = dtr_state};
+ line_state.rts = tuh_cdc_get_rts(idx);
return tuh_cdc_set_control_line_state(idx, line_state.value, complete_cb, user_data);
}
// Request to Set RTS
-TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_set_rts(uint8_t idx, bool rts_state, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
- cdc_line_control_state_t line_state = { .rts = rts_state };
- line_state.dtr = tuh_cdc_get_dtr(idx);
+TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_set_rts(uint8_t idx, bool rts_state, tuh_xfer_cb_t complete_cb,
+ uintptr_t user_data) {
+ cdc_line_control_state_t line_state = {.rts = rts_state};
+ line_state.dtr = tuh_cdc_get_dtr(idx);
return tuh_cdc_set_control_line_state(idx, line_state.value, complete_cb, user_data);
}
@@ -166,11 +168,13 @@ TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_set_rts(uint8_t idx, bool rts_s
bool tuh_cdc_set_baudrate(uint8_t idx, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
// Request to set data format
-bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+bool tuh_cdc_set_data_format(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits,
+ tuh_xfer_cb_t complete_cb, uintptr_t user_data);
// Request to Set Line Coding = baudrate + data format
// Note: only implemented by ACM and CH34x, not supported by FTDI and CP210x yet
-bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+bool tuh_cdc_set_line_coding(uint8_t idx, const cdc_line_coding_t *line_coding, tuh_xfer_cb_t complete_cb,
+ uintptr_t user_data);
// Request to Get Line Coding (ACM only)
// Should only use if tuh_cdc_set_line_coding() / tuh_cdc_get_line_coding() never got invoked and
@@ -179,11 +183,13 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding,
// Connect by set both DTR, RTS
TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_connect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
- return tuh_cdc_set_control_line_state(idx, CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS, complete_cb, user_data);
+ return tuh_cdc_set_control_line_state(idx, CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS, complete_cb,
+ user_data);
}
// Disconnect by clear both DTR, RTS
-TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
+TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_disconnect(uint8_t idx, tuh_xfer_cb_t complete_cb,
+ uintptr_t user_data) {
return tuh_cdc_set_control_line_state(idx, 0x00, complete_cb, user_data);
}
@@ -192,7 +198,8 @@ TU_ATTR_ALWAYS_INLINE static inline bool tuh_cdc_disconnect(uint8_t idx, tuh_xfe
// Each Function will make a USB control transfer request to/from device the function will block until request is
// complete. The function will return the transfer request result
//--------------------------------------------------------------------+
-TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_control_line_state_sync(uint8_t idx, uint16_t line_state) {
+TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_control_line_state_sync(uint8_t idx,
+ uint16_t line_state) {
TU_API_SYNC(tuh_cdc_set_control_line_state, idx, line_state);
}
@@ -208,11 +215,13 @@ TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_baudrate_sync
TU_API_SYNC(tuh_cdc_set_baudrate, idx, baudrate);
}
-TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_data_format_sync(uint8_t idx, uint8_t stop_bits, uint8_t parity, uint8_t data_bits) {
+TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_data_format_sync(uint8_t idx, uint8_t stop_bits,
+ uint8_t parity, uint8_t data_bits) {
TU_API_SYNC(tuh_cdc_set_data_format, idx, stop_bits, parity, data_bits);
}
-TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_cdc_set_line_coding_sync(uint8_t idx, cdc_line_coding_t const* line_coding) {
+TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t
+tuh_cdc_set_line_coding_sync(uint8_t idx, const cdc_line_coding_t *line_coding) {
TU_API_SYNC(tuh_cdc_set_line_coding, idx, line_coding);
}
@@ -244,15 +253,15 @@ extern void tuh_cdc_tx_complete_cb(uint8_t idx);
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
-bool cdch_init (void);
-bool cdch_deinit (void);
-bool cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len);
-bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num);
-bool cdch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
-void cdch_close (uint8_t dev_addr);
+bool cdch_init(void);
+bool cdch_deinit(void);
+uint16_t cdch_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *itf_desc, uint16_t max_len);
+bool cdch_set_config(uint8_t dev_addr, uint8_t itf_num);
+bool cdch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
+void cdch_close(uint8_t dev_addr);
#ifdef __cplusplus
- }
+}
#endif
#endif /* TUSB_CDC_HOST_H_ */
diff --git a/src/class/cdc/cdc_rndis_host.c b/src/class/cdc/cdc_rndis_host.c
deleted file mode 100644
index e975ea440..000000000
--- a/src/class/cdc/cdc_rndis_host.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Ha Thach (tinyusb.org)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * This file is part of the TinyUSB stack.
- */
-
-#include "tusb_option.h"
-
-#if (CFG_TUH_ENABLED && CFG_TUH_CDC && CFG_TUH_CDC_RNDIS)
-
-//--------------------------------------------------------------------+
-// INCLUDE
-//--------------------------------------------------------------------+
-#include "common/tusb_common.h"
-#include "cdc_host.h"
-#include "cdc_rndis_host.h"
-
-#if 0 // TODO remove subtask related macros later
-// Sub Task
-#define OSAL_SUBTASK_BEGIN
-#define OSAL_SUBTASK_END return TUSB_ERROR_NONE;
-
-#define STASK_RETURN(_error) return _error;
-#define STASK_INVOKE(_subtask, _status) (_status) = _subtask
-#define STASK_ASSERT(_cond) TU_VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED)
-#endif
-
-//--------------------------------------------------------------------+
-// MACRO CONSTANT TYPEDEF
-//--------------------------------------------------------------------+
-#define RNDIS_MSG_PAYLOAD_MAX (1024*4)
-
-CFG_TUH_MEM_SECTION static uint8_t msg_notification[CFG_TUH_DEVICE_MAX][8];
-CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN static uint8_t msg_payload[RNDIS_MSG_PAYLOAD_MAX];
-
-static rndish_data_t rndish_data[CFG_TUH_DEVICE_MAX];
-
-// TODO Microsoft requires message length for any get command must be at least 4096 bytes
-
-//--------------------------------------------------------------------+
-// INTERNAL OBJECT & FUNCTION DECLARATION
-//--------------------------------------------------------------------+
-static tusb_error_t rndis_body_subtask(void);
-static tusb_error_t send_message_get_response_subtask( uint8_t dev_addr, cdch_data_t *p_cdc,
- uint8_t * p_mess, uint32_t mess_length,
- uint8_t *p_response );
-
-//--------------------------------------------------------------------+
-// APPLICATION API
-//--------------------------------------------------------------------+
-tusb_error_t tusbh_cdc_rndis_get_mac_addr(uint8_t dev_addr, uint8_t mac_address[6])
-{
- TU_ASSERT( tusbh_cdc_rndis_is_mounted(dev_addr), TUSB_ERROR_CDCH_DEVICE_NOT_MOUNTED);
- TU_VERIFY( mac_address, TUSB_ERROR_INVALID_PARA);
-
- memcpy(mac_address, rndish_data[dev_addr-1].mac_address, 6);
-
- return TUSB_ERROR_NONE;
-}
-
-//--------------------------------------------------------------------+
-// IMPLEMENTATION
-//--------------------------------------------------------------------+
-
-// To enable the TASK_ASSERT style (quick return on false condition) in a real RTOS, a task must act as a wrapper
-// and is used mainly to call subtasks. Within a subtask return statement can be called freely, the task with
-// forever loop cannot have any return at all.
-OSAL_TASK_FUNCTION(cdch_rndis_task) (void* param;)
-{
- OSAL_TASK_BEGIN
- rndis_body_subtask();
- OSAL_TASK_END
-}
-
-static tusb_error_t rndis_body_subtask(void)
-{
- static uint8_t relative_addr;
-
- OSAL_SUBTASK_BEGIN
-
- for (relative_addr = 0; relative_addr < CFG_TUH_DEVICE_MAX; relative_addr++)
- {
-
- }
-
- tusb_time_delay_ms_api(100);
-
- OSAL_SUBTASK_END
-}
-
-//--------------------------------------------------------------------+
-// RNDIS-CDC Driver API
-//--------------------------------------------------------------------+
-void rndish_init(void)
-{
- tu_memclr(rndish_data, sizeof(rndish_data_t)*CFG_TUH_DEVICE_MAX);
-
- //------------- Task creation -------------//
-
- //------------- semaphore creation for notification pipe -------------//
- for(uint8_t i=0; i<CFG_TUH_DEVICE_MAX; i++)
- {
- rndish_data[i].sem_notification_hdl = osal_semaphore_create( OSAL_SEM_REF(rndish_data[i].semaphore_notification) );
- }
-}
-
-void rndish_close(uint8_t dev_addr)
-{
- osal_semaphore_reset( rndish_data[dev_addr-1].sem_notification_hdl );
-// tu_memclr(&rndish_data[dev_addr-1], sizeof(rndish_data_t)); TODO need to move semaphore & its handle out before memclr
-}
-
-
-static rndis_msg_initialize_t const msg_init =
-{
- .type = RNDIS_MSG_INITIALIZE,
- .length = sizeof(rndis_msg_initialize_t),
- .request_id = 1, // TODO should use some magic number
- .major_version = 1,
- .minor_version = 0,
- .max_xfer_size = 0x4000 // TODO mimic windows
-};
-
-static rndis_msg_query_t const msg_query_permanent_addr =
-{
- .type = RNDIS_MSG_QUERY,
- .length = sizeof(rndis_msg_query_t)+6,
- .request_id = 1,
- .oid = RNDIS_OID_802_3_PERMANENT_ADDRESS,
- .buffer_length = 6,
- .buffer_offset = 20,
-};
-
-static rndis_msg_set_t const msg_set_packet_filter =
-{
- .type = RNDIS_MSG_SET,
- .length = sizeof(rndis_msg_set_t)+4,
- .request_id = 1,
- .oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER,
- .buffer_length = 4,
- .buffer_offset = 20,
-};
-
-tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc)
-{
- tusb_error_t error;
-
- OSAL_SUBTASK_BEGIN
-
- //------------- Message Initialize -------------//
- memcpy(msg_payload, &msg_init, sizeof(rndis_msg_initialize_t));
- STASK_INVOKE(
- send_message_get_response_subtask( dev_addr, p_cdc,
- msg_payload, sizeof(rndis_msg_initialize_t),
- msg_payload),
- error
- );
- if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error);
-
- // TODO currently not support multiple data packets per xfer
- rndis_msg_initialize_cmplt_t * const p_init_cmpt = (rndis_msg_initialize_cmplt_t *) msg_payload;
- STASK_ASSERT(p_init_cmpt->type == RNDIS_MSG_INITIALIZE_CMPLT && p_init_cmpt->status == RNDIS_STATUS_SUCCESS &&
- p_init_cmpt->max_packet_per_xfer == 1 && p_init_cmpt->max_xfer_size <= RNDIS_MSG_PAYLOAD_MAX);
- rndish_data[dev_addr-1].max_xfer_size = p_init_cmpt->max_xfer_size;
-
- //------------- Message Query 802.3 Permanent Address -------------//
- memcpy(msg_payload, &msg_query_permanent_addr, sizeof(rndis_msg_query_t));
- tu_memclr(msg_payload + sizeof(rndis_msg_query_t), 6); // 6 bytes for MAC address
-
- STASK_INVOKE(
- send_message_get_response_subtask( dev_addr, p_cdc,
- msg_payload, sizeof(rndis_msg_query_t) + 6,
- msg_payload),
- error
- );
- if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error);
-
- rndis_msg_query_cmplt_t * const p_query_cmpt = (rndis_msg_query_cmplt_t *) msg_payload;
- STASK_ASSERT(p_query_cmpt->type == RNDIS_MSG_QUERY_CMPLT && p_query_cmpt->status == RNDIS_STATUS_SUCCESS);
- memcpy(rndish_data[dev_addr-1].mac_address, msg_payload + 8 + p_query_cmpt->buffer_offset, 6);
-
- //------------- Set OID_GEN_CURRENT_PACKET_FILTER to (DIRECTED | MULTICAST | BROADCAST) -------------//
- memcpy(msg_payload, &msg_set_packet_filter, sizeof(rndis_msg_set_t));
- tu_memclr(msg_payload + sizeof(rndis_msg_set_t), 4); // 4 bytes for filter flags
- ((rndis_msg_set_t*) msg_payload)->oid_buffer[0] = (RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_MULTICAST | RNDIS_PACKET_TYPE_BROADCAST);
-
- STASK_INVOKE(
- send_message_get_response_subtask( dev_addr, p_cdc,
- msg_payload, sizeof(rndis_msg_set_t) + 4,
- msg_payload),
- error
- );
- if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error);
-
- rndis_msg_set_cmplt_t * const p_set_cmpt = (rndis_msg_set_cmplt_t *) msg_payload;
- STASK_ASSERT(p_set_cmpt->type == RNDIS_MSG_SET_CMPLT && p_set_cmpt->status == RNDIS_STATUS_SUCCESS);
-
- tusbh_cdc_rndis_mounted_cb(dev_addr);
-
- OSAL_SUBTASK_END
-}
-
-void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes)
-{
- if ( pipehandle_is_equal(pipe_hdl, p_cdc->pipe_notification) )
- {
- osal_semaphore_post( rndish_data[pipe_hdl.dev_addr-1].sem_notification_hdl );
- }
-}
-
-//--------------------------------------------------------------------+
-// INTERNAL & HELPER
-//--------------------------------------------------------------------+
-static tusb_error_t send_message_get_response_subtask( uint8_t dev_addr, cdch_data_t *p_cdc,
- uint8_t * p_mess, uint32_t mess_length,
- uint8_t *p_response)
-{
- tusb_error_t error;
-
- OSAL_SUBTASK_BEGIN
-
- //------------- Send RNDIS Control Message -------------//
- STASK_INVOKE(
- usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_OUT, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_INTERFACE),
- CDC_REQUEST_SEND_ENCAPSULATED_COMMAND, 0, p_cdc->interface_number,
- mess_length, p_mess),
- error
- );
- if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error);
-
- //------------- waiting for Response Available notification -------------//
- (void) usbh_edpt_xfer(p_cdc->pipe_notification, msg_notification[dev_addr-1], 8);
- osal_semaphore_wait(rndish_data[dev_addr-1].sem_notification_hdl, OSAL_TIMEOUT_NORMAL, &error);
- if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error);
- STASK_ASSERT(msg_notification[dev_addr-1][0] == 1);
-
- //------------- Get RNDIS Message Initialize Complete -------------//
- STASK_INVOKE(
- usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_INTERFACE),
- CDC_REQUEST_GET_ENCAPSULATED_RESPONSE, 0, p_cdc->interface_number,
- RNDIS_MSG_PAYLOAD_MAX, p_response),
- error
- );
- if ( TUSB_ERROR_NONE != error ) STASK_RETURN(error);
-
- OSAL_SUBTASK_END
-}
-
-//static tusb_error_t send_process_msg_initialize_subtask(uint8_t dev_addr, cdch_data_t *p_cdc)
-//{
-// tusb_error_t error;
-//
-// OSAL_SUBTASK_BEGIN
-//
-// *((rndis_msg_initialize_t*) msg_payload) = (rndis_msg_initialize_t)
-// {
-// .type = RNDIS_MSG_INITIALIZE,
-// .length = sizeof(rndis_msg_initialize_t),
-// .request_id = 1, // TODO should use some magic number
-// .major_version = 1,
-// .minor_version = 0,
-// .max_xfer_size = 0x4000 // TODO mimic windows
-// };
-//
-//
-//
-// OSAL_SUBTASK_END
-//}
-#endif
diff --git a/src/class/cdc/cdc_rndis_host.h b/src/class/cdc/cdc_rndis_host.h
deleted file mode 100644
index e70d27f79..000000000
--- a/src/class/cdc/cdc_rndis_host.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Ha Thach (tinyusb.org)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * This file is part of the TinyUSB stack.
- */
-
-/** \ingroup CDC_RNDIS
- * \defgroup CDC_RNSID_Host Host
- * @{ */
-
-#ifndef TUSB_CDC_RNDIS_HOST_H_
-#define TUSB_CDC_RNDIS_HOST_H_
-
-#include "common/tusb_common.h"
-#include "host/usbh.h"
-#include "cdc_rndis.h"
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-//--------------------------------------------------------------------+
-// INTERNAL RNDIS-CDC Driver API
-//--------------------------------------------------------------------+
-typedef struct {
- OSAL_SEM_DEF(semaphore_notification);
- osal_semaphore_handle_t sem_notification_hdl; // used to wait on notification pipe
- uint32_t max_xfer_size; // got from device's msg initialize complete
- uint8_t mac_address[6];
-}rndish_data_t;
-
-void rndish_init(void);
-bool rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc);
-void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes);
-void rndish_close(uint8_t dev_addr);
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* TUSB_CDC_RNDIS_HOST_H_ */
-
-/** @} */
diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c
index da776d04c..98f9bf80b 100644
--- a/src/class/hid/hid_host.c
+++ b/src/class/hid/hid_host.c
@@ -141,7 +141,9 @@ static uint8_t get_idx_by_epaddr(uint8_t daddr, uint8_t ep_addr) {
static hidh_interface_t* find_new_itf(void) {
for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
- if (_hidh_itf[i].daddr == 0) return &_hidh_itf[i];
+ if (_hidh_itf[i].daddr == 0) {
+ return &_hidh_itf[i];
+ }
}
return NULL;
}
@@ -152,7 +154,9 @@ static hidh_interface_t* find_new_itf(void) {
uint8_t tuh_hid_itf_get_count(uint8_t daddr) {
uint8_t count = 0;
for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
- if (_hidh_itf[i].daddr == daddr) count++;
+ if (_hidh_itf[i].daddr == daddr) {
+ count++;
+ }
}
return count;
}
@@ -160,7 +164,9 @@ uint8_t tuh_hid_itf_get_count(uint8_t daddr) {
uint8_t tuh_hid_itf_get_total_count(void) {
uint8_t count = 0;
for (uint8_t i = 0; i < CFG_TUH_HID; i++) {
- if (_hidh_itf[i].daddr != 0) count++;
+ if (_hidh_itf[i].daddr != 0) {
+ count++;
+ }
}
return count;
}
@@ -506,36 +512,43 @@ void hidh_close(uint8_t daddr) {
//--------------------------------------------------------------------+
// Enumeration
//--------------------------------------------------------------------+
-
-bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_itf, uint16_t max_len) {
+uint16_t hidh_open(uint8_t rhport, uint8_t daddr, const tusb_desc_interface_t *desc_itf, uint16_t max_len) {
(void) rhport;
(void) max_len;
- TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass);
+ TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0);
TU_LOG_DRV("[%u] HID opening Interface %u\r\n", daddr, desc_itf->bInterfaceNumber);
// len = interface + hid + n*endpoints
- uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) +
- desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
- TU_ASSERT(max_len >= drv_len);
- uint8_t const* p_desc = (uint8_t const*) desc_itf;
+ const uint16_t drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) +
+ desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
+ TU_ASSERT(drv_len <= max_len, 0);
+ const uint8_t *p_desc = (const uint8_t *)desc_itf;
- //------------- HID descriptor -------------//
+ // HID descriptor: mostly right after interface descriptor, in some rare case it might be after endpoint descriptors
p_desc = tu_desc_next(p_desc);
- tusb_hid_descriptor_hid_t const* desc_hid = (tusb_hid_descriptor_hid_t const*) p_desc;
- TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType);
-
- hidh_interface_t* p_hid = find_new_itf();
- TU_ASSERT(p_hid); // not enough interface, try to increase CFG_TUH_HID
- p_hid->daddr = daddr;
+ const tusb_hid_descriptor_hid_t *desc_hid;
+ if (tu_desc_type(p_desc) == HID_DESC_TYPE_HID) {
+ // HID after interface
+ desc_hid = (const tusb_hid_descriptor_hid_t *)p_desc;
+ p_desc = tu_desc_next(p_desc);
+ } else {
+ // HID after endpoint
+ desc_hid = (const tusb_hid_descriptor_hid_t *)(p_desc + sizeof(tusb_desc_endpoint_t) * desc_itf->bNumEndpoints);
+ TU_ASSERT(tu_desc_type(desc_hid) == HID_DESC_TYPE_HID, 0);
+ }
- //------------- Endpoint Descriptors -------------//
- p_desc = tu_desc_next(p_desc);
- tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) p_desc;
+ // Allocate new interface
+ hidh_interface_t *p_hid = find_new_itf();
+ TU_ASSERT(p_hid, 0); // not enough interface, try to increase CFG_TUH_HID
+ p_hid->daddr = daddr;
+ p_hid->itf_num = desc_itf->bInterfaceNumber;
- for (int i = 0; i < desc_itf->bNumEndpoints; i++) {
- TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType);
- TU_ASSERT(tuh_edpt_open(daddr, desc_ep));
+ // Endpoint Descriptors
+ for (uint8_t i = 0; i < desc_itf->bNumEndpoints; i++) {
+ const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc;
+ TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType, 0);
+ TU_ASSERT(tuh_edpt_open(daddr, desc_ep), 0);
if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
p_hid->ep_in = desc_ep->bEndpointAddress;
@@ -546,11 +559,8 @@ bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_
}
p_desc = tu_desc_next(p_desc);
- desc_ep = (tusb_desc_endpoint_t const*) p_desc;
}
- p_hid->itf_num = desc_itf->bInterfaceNumber;
-
// Assume bNumDescriptors = 1
p_hid->report_desc_type = desc_hid->bReportType;
// Use offsetof to avoid pointer to the odd/misaligned address
@@ -562,7 +572,7 @@ bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_
p_hid->itf_protocol = desc_itf->bInterfaceProtocol;
}
- return true;
+ return drv_len;
}
//--------------------------------------------------------------------+
diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h
index 87f0e7dc9..d7a415485 100644
--- a/src/class/hid/hid_host.h
+++ b/src/class/hid/hid_host.h
@@ -39,22 +39,22 @@ extern "C" {
// TODO Highspeed interrupt can be up to 512 bytes
#ifndef CFG_TUH_HID_EPIN_BUFSIZE
-#define CFG_TUH_HID_EPIN_BUFSIZE 64
+ #define CFG_TUH_HID_EPIN_BUFSIZE 64
#endif
#ifndef CFG_TUH_HID_EPOUT_BUFSIZE
-#define CFG_TUH_HID_EPOUT_BUFSIZE 64
+ #define CFG_TUH_HID_EPOUT_BUFSIZE 64
#endif
typedef struct {
- uint8_t report_id;
- uint8_t usage;
+ uint8_t report_id;
+ uint8_t usage;
uint16_t usage_page;
// TODO still use the endpoint size for now
-// uint8_t in_len; // length of IN report
-// uint8_t out_len; // length of OUT report
+ // uint8_t in_len; // length of IN report
+ // uint8_t out_len; // length of OUT report
} tuh_hid_report_info_t;
//--------------------------------------------------------------------+
@@ -68,10 +68,10 @@ uint8_t tuh_hid_itf_get_count(uint8_t dev_addr);
uint8_t tuh_hid_itf_get_total_count(void);
// backward compatible rename
-#define tuh_hid_instance_count tuh_hid_itf_get_count
+#define tuh_hid_instance_count tuh_hid_itf_get_count
// Get Interface information
-bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t* itf_info);
+bool tuh_hid_itf_get_info(uint8_t daddr, uint8_t idx, tuh_itf_info_t *itf_info);
// Get Interface index from device address + interface number
// return TUSB_INDEX_INVALID_8 (0xFF) if not found
@@ -85,8 +85,8 @@ bool tuh_hid_mounted(uint8_t dev_addr, uint8_t idx);
// Parse report descriptor into array of report_info struct and return number of reports.
// For complicated report, application should write its own parser.
-TU_ATTR_UNUSED uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, uint8_t arr_count,
- uint8_t const* desc_report, uint16_t desc_len);
+TU_ATTR_UNUSED uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t *reports_info_arr, uint8_t arr_count,
+ const uint8_t *desc_report, uint16_t desc_len);
//--------------------------------------------------------------------+
// Control Endpoint API
@@ -107,12 +107,13 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t idx, uint8_t protocol);
// Get Report using control endpoint
// report_type is either Input, Output or Feature, (value from hid_report_type_t)
-bool tuh_hid_get_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void* report, uint16_t len);
+bool tuh_hid_get_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void *report,
+ uint16_t len);
// Set Report using control endpoint
// report_type is either Input, Output or Feature, (value from hid_report_type_t)
-bool tuh_hid_set_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type,
- void* report, uint16_t len);
+bool tuh_hid_set_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, void *report,
+ uint16_t len);
//--------------------------------------------------------------------+
// Interrupt Endpoint API
@@ -133,8 +134,9 @@ bool tuh_hid_receive_abort(uint8_t dev_addr, uint8_t idx);
bool tuh_hid_send_ready(uint8_t dev_addr, uint8_t idx);
// Send report using interrupt endpoint
-// If report_id > 0 (composite), it will be sent as 1st byte, then report contents. Otherwise only report content is sent.
-bool tuh_hid_send_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, const void* report, uint16_t len);
+// If report_id > 0 (composite), it will be sent as 1st byte, then report contents. Otherwise only report content is
+// sent.
+bool tuh_hid_send_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, const void *report, uint16_t len);
//--------------------------------------------------------------------+
// Callbacks (Weak is optional)
@@ -145,25 +147,27 @@ bool tuh_hid_send_report(uint8_t dev_addr, uint8_t idx, uint8_t report_id, const
// can be used to parse common/simple enough descriptor.
// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped
// therefore report_desc = NULL, desc_len = 0
-void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report_desc, uint16_t desc_len);
+void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t idx, const uint8_t *report_desc, uint16_t desc_len);
// Invoked when device with hid interface is un-mounted
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t idx);
// Invoked when received report from device via interrupt endpoint
// Note: if there is report ID (composite), it is 1st byte of report
-void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report, uint16_t len);
+void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t idx, const uint8_t *report, uint16_t len);
// Invoked when sent report to device successfully via interrupt endpoint
-void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t idx, uint8_t const* report, uint16_t len);
+void tuh_hid_report_sent_cb(uint8_t dev_addr, uint8_t idx, const uint8_t *report, uint16_t len);
// Invoked when Get Report to device via either control endpoint
// len = 0 indicate there is error in the transfer e.g stalled response
-void tuh_hid_get_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len);
+void tuh_hid_get_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type,
+ uint16_t len);
// Invoked when Sent Report to device via either control endpoint
// len = 0 indicate there is error in the transfer e.g stalled response
-void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type, uint16_t len);
+void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t report_id, uint8_t report_type,
+ uint16_t len);
// Invoked when Set Protocol request is complete
void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t protocol);
@@ -171,12 +175,12 @@ void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx, uint8_t pro
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
-bool hidh_init(void);
-bool hidh_deinit(void);
-bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len);
-bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num);
-bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
-void hidh_close(uint8_t dev_addr);
+bool hidh_init(void);
+bool hidh_deinit(void);
+uint16_t hidh_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len);
+bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num);
+bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
+void hidh_close(uint8_t dev_addr);
#ifdef __cplusplus
}
diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c
index 8d1dc7d4a..023a81595 100644
--- a/src/class/midi/midi_device.c
+++ b/src/class/midi/midi_device.c
@@ -171,16 +171,13 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, ui
bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]) {
midid_interface_t *p_midi = &_midid_itf[itf];
tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx;
- TU_VERIFY(tu_edpt_stream_is_opened(ep_str));
- return 4 == tu_edpt_stream_read(p_midi->rhport, ep_str, packet, 4);
+ return 4 == tu_edpt_stream_read(ep_str, packet, 4);
}
uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_packets) {
midid_interface_t *p_midi = &_midid_itf[itf];
tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx;
- TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0);
-
- const uint32_t num_read = tu_edpt_stream_read(p_midi->rhport, ep_str, packets, 4u * max_packets);
+ const uint32_t num_read = tu_edpt_stream_read(ep_str, packets, 4u * max_packets);
return num_read >> 2u;
}
@@ -195,7 +192,7 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t *
uint32_t i = 0;
while (i < bufsize) {
- if (tu_edpt_stream_write_available(p_midi->rhport, ep_str) < 4) {
+ if (tu_edpt_stream_write_available(ep_str) < 4) {
break;
}
@@ -268,7 +265,7 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t *
stream->buffer[idx] = 0;
}
- const uint32_t count = tu_edpt_stream_write(p_midi->rhport, ep_str, stream->buffer, 4);
+ const uint32_t count = tu_edpt_stream_write(ep_str, stream->buffer, 4);
// complete current event packet, reset stream
stream->index = stream->total = 0;
@@ -278,7 +275,7 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t *
}
}
- (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str);
+ (void)tu_edpt_stream_write_xfer(ep_str);
return i;
}
@@ -288,9 +285,9 @@ bool tud_midi_n_packet_write (uint8_t itf, const uint8_t packet[4]) {
tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx;
TU_VERIFY(tu_edpt_stream_is_opened(ep_str));
- TU_VERIFY(tu_edpt_stream_write_available(p_midi->rhport, ep_str) >= 4);
- TU_VERIFY(tu_edpt_stream_write(p_midi->rhport, ep_str, packet, 4) > 0);
- (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str);
+ TU_VERIFY(tu_edpt_stream_write_available(ep_str) >= 4);
+ TU_VERIFY(tu_edpt_stream_write(ep_str, packet, 4) > 0);
+ (void)tu_edpt_stream_write_xfer(ep_str);
return true;
}
@@ -300,11 +297,11 @@ uint32_t tud_midi_n_packet_write_n(uint8_t itf, const uint8_t packets[], uint32_
tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx;
TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0);
- uint32_t n_bytes = tu_edpt_stream_write_available(p_midi->rhport, ep_str);
+ uint32_t n_bytes = tu_edpt_stream_write_available(ep_str);
n_bytes = tu_min32(tu_align4(n_bytes), n_packets << 2u);
- const uint32_t n_write = tu_edpt_stream_write(p_midi->rhport, ep_str, packets, n_bytes);
- (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str);
+ const uint32_t n_write = tu_edpt_stream_write(ep_str, packets, n_bytes);
+ (void)tu_edpt_stream_write_xfer(ep_str);
return n_write >> 2u;
}
@@ -411,13 +408,13 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint1
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
tu_edpt_stream_t *stream_tx = &p_midi->ep_stream.tx;
- tu_edpt_stream_open(stream_tx, desc_ep);
+ tu_edpt_stream_open(stream_tx, rhport, desc_ep);
tu_edpt_stream_clear(stream_tx);
} else {
tu_edpt_stream_t *stream_rx = &p_midi->ep_stream.rx;
- tu_edpt_stream_open(stream_rx, desc_ep);
+ tu_edpt_stream_open(stream_rx, rhport, desc_ep);
tu_edpt_stream_clear(stream_rx);
- TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare to receive data
+ TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare to receive data
}
p_desc = tu_desc_next(p_desc); // skip CS Endpoint descriptor
@@ -439,6 +436,7 @@ bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_req
}
bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
+ (void)rhport;
(void)result;
uint8_t idx = find_midi_itf(ep_addr);
@@ -454,12 +452,12 @@ bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32
tu_edpt_stream_read_xfer_complete(ep_st_rx, xferred_bytes);
tud_midi_rx_cb(idx); // invoke callback
}
- tu_edpt_stream_read_xfer(rhport, ep_st_rx); // prepare for next data
+ tu_edpt_stream_read_xfer(ep_st_rx); // prepare for next data
} else if (ep_addr == ep_st_tx->ep_addr && result == XFER_RESULT_SUCCESS) {
// sent complete: try to send more if possible
- if (0 == tu_edpt_stream_write_xfer(rhport, ep_st_tx)) {
+ if (0 == tu_edpt_stream_write_xfer(ep_st_tx)) {
// If there is no data left, a ZLP should be sent if needed
- (void)tu_edpt_stream_write_zlp_if_needed(rhport, ep_st_tx, xferred_bytes);
+ (void)tu_edpt_stream_write_zlp_if_needed(ep_st_tx, xferred_bytes);
}
} else {
return false;
diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c
index 07062875c..5548a0ba8 100644
--- a/src/class/midi/midi_host.c
+++ b/src/class/midi/midi_host.c
@@ -175,14 +175,14 @@ bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint
tuh_midi_rx_cb(idx, xferred_bytes);
}
- tu_edpt_stream_read_xfer(dev_addr, ep_str_rx); // prepare for next transfer
+ tu_edpt_stream_read_xfer(ep_str_rx); // prepare for next transfer
} else if (ep_addr == ep_str_tx->ep_addr) {
tuh_midi_tx_cb(idx, xferred_bytes);
- if (0 == tu_edpt_stream_write_xfer(dev_addr, ep_str_tx)) {
+ if (0 == tu_edpt_stream_write_xfer(ep_str_tx)) {
// If there is no data left, a ZLP should be sent if
// xferred_bytes is multiple of EP size and not zero
- tu_edpt_stream_write_zlp_if_needed(dev_addr, ep_str_tx, xferred_bytes);
+ tu_edpt_stream_write_zlp_if_needed(ep_str_tx, xferred_bytes);
}
}
@@ -192,15 +192,16 @@ bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint
//--------------------------------------------------------------------+
// Enumeration
//--------------------------------------------------------------------+
-bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) {
+uint16_t midih_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len) {
(void) rhport;
- TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass);
- const uint8_t *p_end = ((const uint8_t *) desc_itf) + max_len;
- const uint8_t *p_desc = (const uint8_t *) desc_itf;
+ TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass, 0);
+ const uint8_t *desc_start = (const uint8_t *)desc_itf;
+ const uint8_t *p_desc = desc_start;
+ const uint8_t *desc_end = desc_start + max_len;
const uint8_t idx = find_new_midi_index();
- TU_VERIFY(idx < CFG_TUH_MIDI);
+ TU_VERIFY(idx < CFG_TUH_MIDI, 0);
midih_interface_t *p_midi = &_midi_host[idx];
p_midi->itf_count = 0;
@@ -217,29 +218,30 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
// driver after parsing the audio control interface and then resume parsing
// the streaming audio interface.
if (AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass) {
- TU_VERIFY(max_len > 2*sizeof(tusb_desc_interface_t) + sizeof(midi10_desc_cs_ac_interface_t));
-
+ TU_VERIFY(max_len > 2 * sizeof(tusb_desc_interface_t) + sizeof(midi10_desc_cs_ac_interface_t), 0);
p_desc = tu_desc_next(p_desc);
TU_VERIFY(tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE &&
- tu_desc_subtype(p_desc) == AUDIO10_CS_AC_INTERFACE_HEADER);
+ tu_desc_subtype(p_desc) == AUDIO10_CS_AC_INTERFACE_HEADER,
+ 0);
desc_cb.desc_audio_control = desc_itf;
p_desc = tu_desc_next(p_desc);
desc_itf = (const tusb_desc_interface_t *)p_desc;
p_midi->itf_count = 1;
// skip non-interface and non-midi streaming descriptors
- while (tu_desc_in_bounds(p_desc, p_end) &&
- (desc_itf->bDescriptorType != TUSB_DESC_INTERFACE || (desc_itf->bInterfaceClass == TUSB_CLASS_AUDIO && desc_itf->bInterfaceSubClass != AUDIO_SUBCLASS_MIDI_STREAMING))) {
+ while (tu_desc_in_bounds(p_desc, desc_end) && (desc_itf->bDescriptorType != TUSB_DESC_INTERFACE ||
+ (desc_itf->bInterfaceClass == TUSB_CLASS_AUDIO &&
+ desc_itf->bInterfaceSubClass != AUDIO_SUBCLASS_MIDI_STREAMING))) {
if (desc_itf->bDescriptorType == TUSB_DESC_INTERFACE && desc_itf->bAlternateSetting == 0) {
p_midi->itf_count++;
}
p_desc = tu_desc_next(p_desc);
- desc_itf = (tusb_desc_interface_t const *)p_desc;
+ desc_itf = (const tusb_desc_interface_t *)p_desc;
}
- TU_VERIFY(p_desc < p_end); // TODO: If MIDI interface comes after Audio Streaming, then max_len did not include the MIDI interface descriptor
- TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass);
+ TU_VERIFY(p_desc < desc_end, 0);
+ TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass, 0);
}
- TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass);
+ TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass, 0);
TU_LOG_DRV("MIDI opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr);
p_midi->bInterfaceNumber = desc_itf->bInterfaceNumber;
@@ -250,7 +252,7 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
p_desc = tu_desc_next(p_desc); // next to CS Header
bool found_new_interface = false;
- while (tu_desc_in_bounds(p_desc, p_end) && !found_new_interface) {
+ while (tu_desc_in_bounds(p_desc, desc_end) && !found_new_interface) {
switch (tu_desc_type(p_desc)) {
case TUSB_DESC_INTERFACE:
found_new_interface = true;
@@ -287,8 +289,9 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
case TUSB_DESC_ENDPOINT: {
const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc;
+
p_desc = tu_desc_next(p_desc); // next to CS endpoint
- TU_VERIFY(p_desc < p_end && tu_desc_next(p_desc) <= p_end);
+ TU_VERIFY(tu_desc_in_bounds(p_desc, desc_end), 0);
const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc;
TU_LOG_DRV(" Endpoint and CS_Endpoint descriptor %02x\r\n", p_ep->bEndpointAddress);
@@ -302,8 +305,8 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
desc_cb.desc_epin = p_ep;
ep_stream = &p_midi->ep_stream.rx;
}
- TU_ASSERT(tuh_edpt_open(dev_addr, p_ep));
- tu_edpt_stream_open(ep_stream, p_ep);
+ TU_ASSERT(tuh_edpt_open(dev_addr, p_ep), 0);
+ tu_edpt_stream_open(ep_stream, dev_addr, p_ep);
tu_edpt_stream_clear(ep_stream);
break;
@@ -313,12 +316,12 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
}
p_desc = tu_desc_next(p_desc);
}
- desc_cb.desc_midi_total_len = (uint16_t) ((uintptr_t)p_desc - (uintptr_t) desc_itf);
+ desc_cb.desc_midi_total_len = (uint16_t)((uintptr_t)p_desc - (uintptr_t)desc_start);
p_midi->daddr = dev_addr;
tuh_midi_descriptor_cb(idx, &desc_cb);
- return true;
+ return desc_cb.desc_midi_total_len;
}
bool midih_set_config(uint8_t dev_addr, uint8_t itf_num) {
@@ -335,7 +338,7 @@ bool midih_set_config(uint8_t dev_addr, uint8_t itf_num) {
};
tuh_midi_mount_cb(idx, &mount_cb_data);
- tu_edpt_stream_read_xfer(dev_addr, &p_midi->ep_stream.rx); // prepare for incoming data
+ tu_edpt_stream_read_xfer(&p_midi->ep_stream.rx); // prepare for incoming data
// No special config things to do for MIDI
usbh_driver_set_config_complete(dev_addr, p_midi->bInterfaceNumber);
@@ -414,7 +417,7 @@ uint32_t tuh_midi_read_available(uint8_t idx) {
uint32_t tuh_midi_write_flush(uint8_t idx) {
TU_VERIFY(idx < CFG_TUH_MIDI);
midih_interface_t *p_midi = &_midi_host[idx];
- return tu_edpt_stream_write_xfer(p_midi->daddr, &p_midi->ep_stream.tx);
+ return tu_edpt_stream_write_xfer(&p_midi->ep_stream.tx);
}
//--------------------------------------------------------------------+
@@ -427,7 +430,7 @@ uint32_t tuh_midi_packet_read_n(uint8_t idx, uint8_t* buffer, uint32_t bufsize)
uint32_t count4 = tu_min32(bufsize, tu_edpt_stream_read_available(&p_midi->ep_stream.rx));
count4 = tu_align4(count4); // round down to multiple of 4
TU_VERIFY(count4 > 0, 0);
- return tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, buffer, count4);
+ return tu_edpt_stream_read(&p_midi->ep_stream.rx, buffer, count4);
}
uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t* buffer, uint32_t bufsize) {
@@ -436,7 +439,7 @@ uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t* buffer, uint32_t bu
const uint32_t bufsize4 = tu_align4(bufsize);
TU_VERIFY(bufsize4 > 0, 0);
- return tu_edpt_stream_write(p_midi->daddr, &p_midi->ep_stream.tx, buffer, bufsize4);
+ return tu_edpt_stream_write(&p_midi->ep_stream.tx, buffer, bufsize4);
}
//--------------------------------------------------------------------+
@@ -450,8 +453,8 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu
midi_driver_stream_t *stream = &p_midi->stream_write;
uint32_t byte_count = 0;
- while ((byte_count < bufsize) && (tu_edpt_stream_write_available(p_midi->daddr, &p_midi->ep_stream.tx) >= 4)) {
- uint8_t const data = buffer[byte_count];
+ while ((byte_count < bufsize) && (tu_edpt_stream_write_available(&p_midi->ep_stream.tx) >= 4)) {
+ const uint8_t data = buffer[byte_count];
byte_count++;
if (data >= MIDI_STATUS_SYSREAL_TIMING_CLOCK) {
// real-time messages need to be sent right away
@@ -460,7 +463,7 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu
streamrt.buffer[1] = data;
streamrt.index = 2;
streamrt.total = 2;
- uint32_t const count = tu_edpt_stream_write(p_midi->daddr, &p_midi->ep_stream.tx, streamrt.buffer, 4);
+ const uint32_t count = tu_edpt_stream_write(&p_midi->ep_stream.tx, streamrt.buffer, 4);
TU_ASSERT(count == 4, byte_count); // Check FIFO overflown, since we already check fifo remaining. It is probably race condition
} else if (stream->index == 0) {
//------------- New event packet -------------//
@@ -529,7 +532,7 @@ uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *bu
}
TU_LOG3_MEM(stream->buffer, 4, 2);
- const uint32_t count = tu_edpt_stream_write(p_midi->daddr, &p_midi->ep_stream.tx, stream->buffer, 4);
+ const uint32_t count = tu_edpt_stream_write(&p_midi->ep_stream.tx, stream->buffer, 4);
// complete current event packet, reset stream
stream->index = 0;
@@ -551,7 +554,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff
return 0;
}
*p_cable_num = (one_byte >> 4) & 0xf;
- uint32_t nread = tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4);
+ uint32_t nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4);
static uint16_t cable_sysex_in_progress;// bit i is set if received MIDI_STATUS_SYSEX_START but not MIDI_STATUS_SYSEX_END
while (nread == 4 && bytes_buffered < bufsize) {
*p_cable_num = (p_midi->stream_read.buffer[0] >> 4) & 0x0f;
@@ -579,7 +582,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff
}
else {
// bad packet discard
- nread = tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4);
+ nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4);
continue;
}
} else if (status < MIDI_STATUS_SYSEX_START) {
@@ -626,7 +629,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff
}
else {
// bad packet discard
- nread = tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4);
+ nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4);
continue;
}
@@ -639,7 +642,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff
uint8_t new_cable = (one_byte >> 4) & 0xf;
if (new_cable == *p_cable_num) {
// still on the same cable. Continue reading the stream
- nread = tu_edpt_stream_read(p_midi->daddr, &p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4);
+ nread = tu_edpt_stream_read(&p_midi->ep_stream.rx, p_midi->stream_read.buffer, 4);
}
}
}
diff --git a/src/class/midi/midi_host.h b/src/class/midi/midi_host.h
index 06554a03d..8a8dccab4 100644
--- a/src/class/midi/midi_host.h
+++ b/src/class/midi/midi_host.h
@@ -31,45 +31,45 @@
#include "midi.h"
#ifdef __cplusplus
- extern "C" {
+extern "C" {
#endif
//--------------------------------------------------------------------+
// Class Driver Configuration
//--------------------------------------------------------------------+
#ifndef CFG_TUH_MIDI_RX_BUFSIZE
-#define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MPS
+ #define CFG_TUH_MIDI_RX_BUFSIZE TUH_EPSIZE_BULK_MPS
#endif
#ifndef CFG_TUH_MIDI_TX_BUFSIZE
-#define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MPS
+ #define CFG_TUH_MIDI_TX_BUFSIZE TUH_EPSIZE_BULK_MPS
#endif
#ifndef CFG_TUH_MIDI_EP_BUFSIZE
-#define CFG_TUH_MIDI_EP_BUFSIZE TUH_EPSIZE_BULK_MPS
+ #define CFG_TUH_MIDI_EP_BUFSIZE TUH_EPSIZE_BULK_MPS
#endif
// Enable the MIDI stream read/write API. Some library can work with raw USB MIDI packet
// Disable this can save driver footprint.
#ifndef CFG_TUH_MIDI_STREAM_API
-#define CFG_TUH_MIDI_STREAM_API 1
+ #define CFG_TUH_MIDI_STREAM_API 1
#endif
//--------------------------------------------------------------------+
// Application Types
//--------------------------------------------------------------------+
typedef struct {
- const tusb_desc_interface_t* desc_audio_control;
- const tusb_desc_interface_t* desc_midi; // start of whole midi interface descriptor
- uint16_t desc_midi_total_len;
+ const tusb_desc_interface_t *desc_audio_control;
+ const tusb_desc_interface_t *desc_midi; // start of whole midi interface descriptor
+ uint16_t desc_midi_total_len;
- const uint8_t* desc_header;
- const uint8_t* desc_element;
- const tusb_desc_endpoint_t* desc_epin; // endpoint IN descriptor, CS_ENDPOINT is right after
- const tusb_desc_endpoint_t* desc_epout; // endpoint OUT descriptor, CS_ENDPOINT is right after
+ const uint8_t *desc_header;
+ const uint8_t *desc_element;
+ const tusb_desc_endpoint_t *desc_epin; // endpoint IN descriptor, CS_ENDPOINT is right after
+ const tusb_desc_endpoint_t *desc_epout; // endpoint OUT descriptor, CS_ENDPOINT is right after
- uint8_t jack_num;
- const uint8_t* desc_jack[32]; // list of jack descriptors (embedded + external)
+ uint8_t jack_num;
+ const uint8_t *desc_jack[32]; // list of jack descriptors (embedded + external)
} tuh_midi_descriptor_cb_t;
typedef struct {
@@ -92,7 +92,7 @@ uint8_t tuh_midi_itf_get_index(uint8_t daddr, uint8_t itf_num);
// Get Interface information
// return true if index is correct and interface is currently mounted
-bool tuh_midi_itf_get_info(uint8_t idx, tuh_itf_info_t* info);
+bool tuh_midi_itf_get_info(uint8_t idx, tuh_itf_info_t *info);
// return the number of virtual midi cables on the device's IN endpoint
uint8_t tuh_midi_get_rx_cable_count(uint8_t idx);
@@ -115,24 +115,22 @@ uint32_t tuh_midi_write_flush(uint8_t idx);
// Read all available MIDI packets from the connected device
// Return number of bytes read (always multiple of 4)
-uint32_t tuh_midi_packet_read_n(uint8_t idx, uint8_t* buffer, uint32_t bufsize);
+uint32_t tuh_midi_packet_read_n(uint8_t idx, uint8_t *buffer, uint32_t bufsize);
// Read a raw MIDI packet from the connected device
// Return true if a packet was returned
-TU_ATTR_ALWAYS_INLINE static inline
-bool tuh_midi_packet_read (uint8_t idx, uint8_t packet[4]) {
- return 4 == tuh_midi_packet_read_n(idx, packet, 4);
+TU_ATTR_ALWAYS_INLINE static inline bool tuh_midi_packet_read(uint8_t idx, uint8_t packet[4]) {
+ return 4 == tuh_midi_packet_read_n(idx, packet, 4);
}
// Write all 4-byte packets, data is locally buffered and only transferred when buffered bytes
// reach the endpoint packet size or tuh_midi_write_flush() is called
-uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t* buffer, uint32_t bufsize);
+uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t *buffer, uint32_t bufsize);
// Write a 4-bytes packet to the device.
// Returns true if the packet was successfully queued.
-TU_ATTR_ALWAYS_INLINE static inline
-bool tuh_midi_packet_write (uint8_t idx, uint8_t const packet[4]) {
- return 4 == tuh_midi_packet_write_n(idx, packet, 4);
+TU_ATTR_ALWAYS_INLINE static inline bool tuh_midi_packet_write(uint8_t idx, const uint8_t packet[4]) {
+ return 4 == tuh_midi_packet_write_n(idx, packet, 4);
}
//--------------------------------------------------------------------+
@@ -143,7 +141,7 @@ bool tuh_midi_packet_write (uint8_t idx, uint8_t const packet[4]) {
// Queue a message to the device using stream API. data is locally buffered and only transferred when buffered bytes
// reach the endpoint packet size or tuh_midi_write_flush() is called
// Returns number of bytes was successfully queued.
-uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *p_buffer, uint32_t bufsize);
+uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, const uint8_t *p_buffer, uint32_t bufsize);
// Get the MIDI stream from the device. Set the value pointed
// to by p_cable_num to the MIDI cable number intended to receive it.
@@ -162,10 +160,10 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff
// Invoked when MIDI interface is detected in enumeration. Application can copy/parse descriptor if needed.
// Note: may be fired before tuh_midi_mount_cb(), therefore midi interface is not mounted/ready.
-void tuh_midi_descriptor_cb(uint8_t idx, const tuh_midi_descriptor_cb_t * desc_cb_data);
+void tuh_midi_descriptor_cb(uint8_t idx, const tuh_midi_descriptor_cb_t *desc_cb_data);
// Invoked when device with MIDI interface is mounted.
-void tuh_midi_mount_cb(uint8_t idx, const tuh_midi_mount_cb_t* mount_cb_data);
+void tuh_midi_mount_cb(uint8_t idx, const tuh_midi_mount_cb_t *mount_cb_data);
// Invoked when device with MIDI interface is un-mounted
void tuh_midi_umount_cb(uint8_t idx);
@@ -179,12 +177,12 @@ void tuh_midi_tx_cb(uint8_t idx, uint32_t xferred_bytes);
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
-bool midih_init (void);
-bool midih_deinit (void);
-bool midih_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len);
-bool midih_set_config (uint8_t dev_addr, uint8_t itf_num);
-bool midih_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
-void midih_close (uint8_t daddr);
+bool midih_init(void);
+bool midih_deinit(void);
+uint16_t midih_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len);
+bool midih_set_config(uint8_t dev_addr, uint8_t itf_num);
+bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
+void midih_close(uint8_t daddr);
#ifdef __cplusplus
}
diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c
index daff345c5..6a36c2820 100644
--- a/src/class/msc/msc_host.c
+++ b/src/class/msc/msc_host.c
@@ -379,22 +379,21 @@ static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_d
static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data);
static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data);
-bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len) {
+uint16_t msch_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len) {
(void) rhport;
- TU_VERIFY (MSC_SUBCLASS_SCSI == desc_itf->bInterfaceSubClass &&
- MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol);
+ TU_VERIFY(MSC_SUBCLASS_SCSI == desc_itf->bInterfaceSubClass && MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol, 0);
// msc driver length is fixed
- uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) +
- desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
- TU_ASSERT(drv_len <= max_len);
+ const uint16_t drv_len =
+ (uint16_t)(sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
+ TU_ASSERT(drv_len <= max_len, 0);
- msch_interface_t* p_msc = get_itf(dev_addr);
- tusb_desc_endpoint_t const* ep_desc = (tusb_desc_endpoint_t const*) tu_desc_next(desc_itf);
+ msch_interface_t *p_msc = get_itf(dev_addr);
+ const tusb_desc_endpoint_t *ep_desc = (const tusb_desc_endpoint_t *)tu_desc_next(desc_itf);
for (uint32_t i = 0; i < 2; i++) {
- TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer);
- TU_ASSERT(tuh_edpt_open(dev_addr, ep_desc));
+ TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer, 0);
+ TU_ASSERT(tuh_edpt_open(dev_addr, ep_desc), 0);
if (TUSB_DIR_IN == tu_edpt_dir(ep_desc->bEndpointAddress)) {
p_msc->ep_in = ep_desc->bEndpointAddress;
@@ -407,7 +406,7 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* de
p_msc->itf_num = desc_itf->bInterfaceNumber;
- return true;
+ return drv_len;
}
bool msch_set_config(uint8_t daddr, uint8_t itf_num) {
diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h
index b5fd55547..5dc7c0b94 100644
--- a/src/class/msc/msc_host.h
+++ b/src/class/msc/msc_host.h
@@ -30,7 +30,7 @@
#include "msc.h"
#ifdef __cplusplus
- extern "C" {
+extern "C" {
#endif
//--------------------------------------------------------------------+
@@ -38,17 +38,17 @@
//--------------------------------------------------------------------+
#ifndef CFG_TUH_MSC_MAXLUN
-#define CFG_TUH_MSC_MAXLUN 4
+ #define CFG_TUH_MSC_MAXLUN 4
#endif
typedef struct {
- msc_cbw_t const* cbw; // SCSI command
- msc_csw_t const* csw; // SCSI status
- void* scsi_data; // SCSI Data
- uintptr_t user_arg; // user argument
-}tuh_msc_complete_data_t;
+ const msc_cbw_t *cbw; // SCSI command
+ const msc_csw_t *csw; // SCSI status
+ void *scsi_data; // SCSI Data
+ uintptr_t user_arg; // user argument
+} tuh_msc_complete_data_t;
-typedef bool (*tuh_msc_complete_cb_t)(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data);
+typedef bool (*tuh_msc_complete_cb_t)(uint8_t dev_addr, const tuh_msc_complete_data_t *cb_data);
//--------------------------------------------------------------------+
// Application API
@@ -74,12 +74,14 @@ uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun);
// Complete callback is invoked when SCSI op is complete.
// return true if success, false if there is already pending operation.
// NOTE: buffer must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled
-bool tuh_msc_scsi_command(uint8_t daddr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
+bool tuh_msc_scsi_command(uint8_t daddr, const msc_cbw_t *cbw, void *data, tuh_msc_complete_cb_t complete_cb,
+ uintptr_t arg);
// Perform SCSI Inquiry command
// Complete callback is invoked when SCSI op is complete.
// NOTE: response must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled
-bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
+bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t *response, tuh_msc_complete_cb_t complete_cb,
+ uintptr_t arg);
// Perform SCSI Test Unit Ready command
// Complete callback is invoked when SCSI op is complete.
@@ -88,23 +90,27 @@ bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_
// Perform SCSI Request Sense 10 command
// Complete callback is invoked when SCSI op is complete.
// NOTE: response must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled
-bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
+bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_msc_complete_cb_t complete_cb,
+ uintptr_t arg);
// Perform SCSI Read 10 command. Read n blocks starting from LBA to buffer
// Complete callback is invoked when SCSI op is complete.
// NOTE: buffer must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled
-bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
+bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void *buffer, uint32_t lba, uint16_t block_count,
+ tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
// Perform SCSI Write 10 command. Write n blocks starting from LBA to device
// Complete callback is invoked when SCSI op is complete.
// NOTE: buffer must be accessible by USB/DMA controller, aligned correctly and multiple of cache line if enabled
-bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
+bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, const void *buffer, uint32_t lba, uint16_t block_count,
+ tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
// Perform SCSI Read Capacity 10 command
// Complete callback is invoked when SCSI op is complete.
// Note: during enumeration, host stack already carried out this request. Application can retrieve capacity by
// simply call tuh_msc_get_block_count() and tuh_msc_get_block_size()
-bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
+bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t *response,
+ tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
//------------- Application Callback -------------//
@@ -118,15 +124,15 @@ void tuh_msc_umount_cb(uint8_t dev_addr);
// Internal Class Driver API
//--------------------------------------------------------------------+
-bool msch_init (void);
-bool msch_deinit (void);
-bool msch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len);
-bool msch_set_config (uint8_t daddr, uint8_t itf_num);
-void msch_close (uint8_t dev_addr);
-bool msch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
+bool msch_init(void);
+bool msch_deinit(void);
+uint16_t msch_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *desc_itf, uint16_t max_len);
+bool msch_set_config(uint8_t daddr, uint8_t itf_num);
+void msch_close(uint8_t dev_addr);
+bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
#ifdef __cplusplus
- }
+}
#endif
#endif
diff --git a/src/class/mtp/mtp_device.c b/src/class/mtp/mtp_device.c
index 764019e42..4942a105a 100644
--- a/src/class/mtp/mtp_device.c
+++ b/src/class/mtp/mtp_device.c
@@ -422,10 +422,10 @@ bool mtpd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
cb_data.total_xferred_bytes = p_mtp->xferred_len;
bool is_complete = false;
- // complete if ZLP or short packet or overflow
+ // complete if ZLP or short packet or total length reached
if (xferred_bytes == 0 || // ZLP
(xferred_bytes & (bulk_mps - 1)) || // short packet
- p_mtp->xferred_len > p_mtp->total_len) {
+ p_mtp->xferred_len >= p_mtp->total_len) { // total length reached
is_complete = true;
}
diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c
index 62e183465..9972911e0 100644
--- a/src/class/vendor/vendor_device.c
+++ b/src/class/vendor/vendor_device.c
@@ -119,20 +119,14 @@ bool tud_vendor_n_peek(uint8_t idx, uint8_t *u8) {
uint32_t tud_vendor_n_read(uint8_t idx, void *buffer, uint32_t bufsize) {
TU_VERIFY(idx < CFG_TUD_VENDOR, 0);
vendord_interface_t *p_itf = &_vendord_itf[idx];
- return tu_edpt_stream_read(p_itf->rhport, &p_itf->stream.rx, buffer, bufsize);
-}
-
-uint32_t tud_vendor_n_read_discard(uint8_t idx, uint32_t count) {
- TU_VERIFY(idx < CFG_TUD_VENDOR, 0);
- vendord_interface_t *p_itf = &_vendord_itf[idx];
- return tu_edpt_stream_discard(&p_itf->stream.rx, count);
+ return tu_edpt_stream_read(&p_itf->stream.rx, buffer, bufsize);
}
void tud_vendor_n_read_flush(uint8_t idx) {
TU_VERIFY(idx < CFG_TUD_VENDOR, );
vendord_interface_t *p_itf = &_vendord_itf[idx];
tu_edpt_stream_clear(&p_itf->stream.rx);
- tu_edpt_stream_read_xfer(p_itf->rhport, &p_itf->stream.rx);
+ tu_edpt_stream_read_xfer(&p_itf->stream.rx);
}
#endif
@@ -140,7 +134,7 @@ void tud_vendor_n_read_flush(uint8_t idx) {
bool tud_vendor_n_read_xfer(uint8_t idx) {
TU_VERIFY(idx < CFG_TUD_VENDOR);
vendord_interface_t *p_itf = &_vendord_itf[idx];
- return tu_edpt_stream_read_xfer(p_itf->rhport, &p_itf->stream.rx);
+ return tu_edpt_stream_read_xfer(&p_itf->stream.rx);
}
#endif
@@ -151,20 +145,20 @@ bool tud_vendor_n_read_xfer(uint8_t idx) {
uint32_t tud_vendor_n_write(uint8_t idx, const void *buffer, uint32_t bufsize) {
TU_VERIFY(idx < CFG_TUD_VENDOR, 0);
vendord_interface_t *p_itf = &_vendord_itf[idx];
- return tu_edpt_stream_write(p_itf->rhport, &p_itf->stream.tx, buffer, (uint16_t)bufsize);
+ return tu_edpt_stream_write(&p_itf->stream.tx, buffer, (uint16_t)bufsize);
}
#if CFG_TUD_VENDOR_TX_BUFSIZE > 0
uint32_t tud_vendor_n_write_flush(uint8_t idx) {
TU_VERIFY(idx < CFG_TUD_VENDOR, 0);
vendord_interface_t *p_itf = &_vendord_itf[idx];
- return tu_edpt_stream_write_xfer(p_itf->rhport, &p_itf->stream.tx);
+ return tu_edpt_stream_write_xfer(&p_itf->stream.tx);
}
uint32_t tud_vendor_n_write_available(uint8_t idx) {
TU_VERIFY(idx < CFG_TUD_VENDOR, 0);
vendord_interface_t *p_itf = &_vendord_itf[idx];
- return tu_edpt_stream_write_available(p_itf->rhport, &p_itf->stream.tx);
+ return tu_edpt_stream_write_available(&p_itf->stream.tx);
}
#endif
@@ -276,15 +270,15 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uin
if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
tu_edpt_stream_t *stream_tx = &p_vendor->stream.tx;
if (stream_tx->ep_addr == 0) {
- tu_edpt_stream_open(stream_tx, desc_ep);
- tu_edpt_stream_write_xfer(rhport, stream_tx); // flush pending data
+ tu_edpt_stream_open(stream_tx, rhport, desc_ep);
+ tu_edpt_stream_write_xfer(stream_tx); // flush pending data
}
} else {
tu_edpt_stream_t *stream_rx = &p_vendor->stream.rx;
if (stream_rx->ep_addr == 0) {
- tu_edpt_stream_open(stream_rx, desc_ep);
+ tu_edpt_stream_open(stream_rx, rhport, desc_ep);
#if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0
- TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare for incoming data
+ TU_ASSERT(tu_edpt_stream_read_xfer(stream_rx) > 0, 0); // prepare for incoming data
#endif
}
}
@@ -297,14 +291,17 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uin
}
bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
- (void) result;
+ (void)rhport;
+ (void)result;
const uint8_t idx = find_vendor_itf(ep_addr);
TU_VERIFY(idx < CFG_TUD_VENDOR);
vendord_interface_t *p_vendor = &_vendord_itf[idx];
if (ep_addr == p_vendor->stream.rx.ep_addr) {
+ #if CFG_TUD_VENDOR_RX_BUFSIZE
// Received new data: put into stream's fifo
tu_edpt_stream_read_xfer_complete(&p_vendor->stream.rx, xferred_bytes);
+ #endif
// invoke callback
#if CFG_TUD_VENDOR_RX_BUFSIZE == 0
@@ -314,7 +311,7 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint
#endif
#if CFG_TUD_VENDOR_RX_MANUAL_XFER == 0
- tu_edpt_stream_read_xfer(rhport, &p_vendor->stream.rx); // prepare next data
+ tu_edpt_stream_read_xfer(&p_vendor->stream.rx); // prepare next data
#endif
} else if (ep_addr == p_vendor->stream.tx.ep_addr) {
// Send complete
@@ -322,9 +319,9 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint
#if CFG_TUD_VENDOR_TX_BUFSIZE > 0
// try to send more if possible
- if (0 == tu_edpt_stream_write_xfer(rhport, &p_vendor->stream.tx)) {
+ if (0 == tu_edpt_stream_write_xfer(&p_vendor->stream.tx)) {
// If there is no data left, a ZLP should be sent if xferred_bytes is multiple of EP Packet size and not zero
- tu_edpt_stream_write_zlp_if_needed(rhport, &p_vendor->stream.tx, xferred_bytes);
+ tu_edpt_stream_write_zlp_if_needed(&p_vendor->stream.tx, xferred_bytes);
}
#endif
}
diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h
index 764d99070..d59c885d2 100644
--- a/src/class/vendor/vendor_device.h
+++ b/src/class/vendor/vendor_device.h
@@ -73,9 +73,6 @@ bool tud_vendor_n_peek(uint8_t idx, uint8_t *ui8);
// Read from RX FIFO
uint32_t tud_vendor_n_read(uint8_t idx, void *buffer, uint32_t bufsize);
-// Discard count bytes in RX FIFO
-uint32_t tud_vendor_n_read_discard(uint8_t idx, uint32_t count);
-
// Flush (clear) RX FIFO
void tud_vendor_n_read_flush(uint8_t idx);
#endif
@@ -124,10 +121,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_read(void *buffer, uint3
return tud_vendor_n_read(0, buffer, bufsize);
}
-TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_read_discard(uint32_t count) {
- return tud_vendor_n_read_discard(0, count);
-}
-
TU_ATTR_ALWAYS_INLINE static inline void tud_vendor_read_flush(void) {
tud_vendor_n_read_flush(0);
}
diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h
index b53fa5c02..d74760608 100644
--- a/src/common/tusb_common.h
+++ b/src/common/tusb_common.h
@@ -388,10 +388,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_subtype(void const* desc) {
}
TU_ATTR_ALWAYS_INLINE static inline bool tu_desc_in_bounds(const uint8_t *p_desc, const uint8_t *desc_end) {
- if (p_desc >= desc_end) {
- return false;
- }
- return tu_desc_next(p_desc) <= desc_end;
+ return p_desc < desc_end && tu_desc_next(p_desc) <= desc_end;
}
// find descriptor that match byte1 (type)
diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h
index 7719790d1..f20834cea 100644
--- a/src/common/tusb_compiler.h
+++ b/src/common/tusb_compiler.h
@@ -24,21 +24,13 @@
* This file is part of the TinyUSB stack.
*/
-/** \ingroup Group_Common
- * \defgroup Group_Compiler Compiler
- * \brief Group_Compiler brief
- * @{ */
-
-#ifndef TUSB_COMPILER_H_
-#define TUSB_COMPILER_H_
+#pragma once
#define TU_TOKEN(x) x
#define TU_STRING(x) #x ///< stringify without expand
#define TU_XSTRING(x) TU_STRING(x) ///< expand then stringify
-
#define TU_STRCAT(a, b) a##b ///< concat without expand
#define TU_STRCAT3(a, b, c) a##b##c ///< concat without expand
-
#define TU_XSTRCAT(a, b) TU_STRCAT(a, b) ///< expand then concat
#define TU_XSTRCAT3(a, b, c) TU_STRCAT3(a, b, c) ///< expand then concat 3 tokens
@@ -139,18 +131,20 @@
#define TU_FUNC_OPTIONAL_ARG(func, ...) TU_XSTRCAT(func##_arg, TU_ARGS_NUM(__VA_ARGS__))(__VA_ARGS__)
//--------------------------------------------------------------------+
-// Compiler porting with Attribute and Endian
+// Compiler Attribute Abstraction
//--------------------------------------------------------------------+
+#if defined(__GNUC__) || defined(__ICCARM__) || defined(__TI_COMPILER_VERSION__)
+ #if defined(__ICCARM__)
+ #include <intrinsics.h> // for builtin functions
+ #endif
-// TODO refactor since __attribute__ is supported across many compiler
-#if defined(__GNUC__)
- #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
- #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
- #define TU_ATTR_PACKED __attribute__ ((packed))
- #define TU_ATTR_WEAK __attribute__ ((weak))
- // #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)))
- #ifndef TU_ATTR_ALWAYS_INLINE // allow to override for debug
- #define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
+ #define TU_ATTR_ALIGNED(Bytes) __attribute__((aligned(Bytes)))
+ #define TU_ATTR_SECTION(sec_name) __attribute__((section(#sec_name)))
+ #define TU_ATTR_PACKED __attribute__((packed))
+ #define TU_ATTR_WEAK __attribute__((weak))
+// #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)))
+ #ifndef TU_ATTR_ALWAYS_INLINE // allow to override for debug
+ #define TU_ATTR_ALWAYS_INLINE __attribute__((always_inline))
#endif
#define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used
#define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
@@ -161,18 +155,17 @@
#define TU_ATTR_BIT_FIELD_ORDER_BEGIN
#define TU_ATTR_BIT_FIELD_ORDER_END
- #if __GNUC__ < 5
- #define TU_ATTR_FALLTHROUGH do {} while (0) /* fallthrough */
+ #if (defined(__has_attribute) && __has_attribute(__fallthrough__)) || defined(__TI_COMPILER_VERSION__)
+ #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough))
#else
- #if __has_attribute(__fallthrough__)
- #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough))
- #else
- #define TU_ATTR_FALLTHROUGH do {} while (0) /* fallthrough */
- #endif
+ #define TU_ATTR_FALLTHROUGH \
+ do { \
+ } while (0) /* fallthrough */
#endif
- // Endian conversion use well-known host to network (big endian) naming
- #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+// Endian conversion use well-known host to network (big endian) naming
+// For TI ARM compiler, __BYTE_ORDER__ is not defined for MSP430 but still LE
+ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || defined(__MSP430__)
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
#else
#define TU_BYTE_ORDER TU_BIG_ENDIAN
@@ -190,39 +183,12 @@
#define TU_BSWAP32(u32) (__builtin_bswap32(u32))
#endif
- #ifndef __ARMCC_VERSION
// List of obsolete callback function that is renamed and should not be defined.
// Put it here since only gcc support this pragma
- #pragma GCC poison tud_vendor_control_request_cb
- #endif
-
-#elif defined(__TI_COMPILER_VERSION__)
- #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
- #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
- #define TU_ATTR_PACKED __attribute__ ((packed))
- #define TU_ATTR_WEAK __attribute__ ((weak))
- // #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)))
- #define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
- #define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used
- #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
- #define TU_ATTR_USED __attribute__ ((used))
- #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough))
-
- #define TU_ATTR_PACKED_BEGIN
- #define TU_ATTR_PACKED_END
- #define TU_ATTR_BIT_FIELD_ORDER_BEGIN
- #define TU_ATTR_BIT_FIELD_ORDER_END
-
- // __BYTE_ORDER is defined in the TI ARM compiler, but not MSP430 (which is little endian)
- #if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__)) || defined(__MSP430__)
- #define TU_BYTE_ORDER TU_LITTLE_ENDIAN
- #else
- #define TU_BYTE_ORDER TU_BIG_ENDIAN
+ #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__)
+ #pragma GCC poison tud_vendor_control_request_cb
#endif
- #define TU_BSWAP16(u16) (__builtin_bswap16(u16))
- #define TU_BSWAP32(u32) (__builtin_bswap32(u32))
-
#elif defined(__ICCARM__)
#include <intrinsics.h>
#define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
@@ -316,7 +282,3 @@
#else
#error Byte order is undefined
#endif
-
-#endif /* TUSB_COMPILER_H_ */
-
-/// @}
diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c
index 06b0d6a58..e97b6ccce 100644
--- a/src/common/tusb_fifo.c
+++ b/src/common/tusb_fifo.c
@@ -84,7 +84,7 @@ bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_si
}
// clear fifo by resetting read and write indices
-bool tu_fifo_clear(tu_fifo_t *f) {
+void tu_fifo_clear(tu_fifo_t *f) {
ff_lock(f->mutex_wr);
ff_lock(f->mutex_rd);
@@ -93,13 +93,12 @@ bool tu_fifo_clear(tu_fifo_t *f) {
ff_unlock(f->mutex_wr);
ff_unlock(f->mutex_rd);
- return true;
}
// Change the fifo overwritable mode
-bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) {
+void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) {
if (f->overwritable == overwritable) {
- return true;
+ return;
}
ff_lock(f->mutex_wr);
@@ -109,8 +108,6 @@ bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) {
ff_unlock(f->mutex_wr);
ff_unlock(f->mutex_rd);
-
- return true;
}
//--------------------------------------------------------------------+
@@ -292,7 +289,7 @@ static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd
// Advance an absolute index
// "absolute" index is only in the range of [0..2*depth)
-TU_ATTR_ALWAYS_INLINE static inline uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) {
+static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) {
// We limit the index space of p such that a correct wrap around happens
// Check for a wrap around or if we are in unused index space - This has to be checked first!!
// We are exploiting the wrap around to the correct index
@@ -316,7 +313,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t idx2ptr(uint16_t depth, uint16_t id
// Works on local copies of w
// When an overwritable fifo is overflowed, rd_idx will be re-index so that it forms a full fifo
-TU_ATTR_ALWAYS_INLINE static inline uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) {
+static uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) {
uint16_t rd_idx;
if (wr_idx >= f->depth) {
rd_idx = wr_idx - f->depth;
diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h
index 42f154bca..2e2a0db6f 100644
--- a/src/common/tusb_fifo.h
+++ b/src/common/tusb_fifo.h
@@ -157,8 +157,8 @@ typedef enum {
// Setup API
//--------------------------------------------------------------------+
bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_size, bool overwritable);
-bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable);
-bool tu_fifo_clear(tu_fifo_t *f);
+void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable);
+void tu_fifo_clear(tu_fifo_t *f);
#if OSAL_MUTEX_REQUIRED
TU_ATTR_ALWAYS_INLINE static inline
@@ -224,10 +224,11 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_write_n(tu_fifo_t *f, const
//--------------------------------------------------------------------+
// return overflowable count (index difference), which can be used to determine both fifo count and an overflow state
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_ff_overflow_count(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) {
- if (wr_idx >= rd_idx) {
- return (uint16_t)(wr_idx - rd_idx);
+ const int32_t diff = (int32_t)wr_idx - (int32_t)rd_idx;
+ if (diff >= 0) {
+ return (uint16_t)diff;
} else {
- return (uint16_t)(2 * depth - (rd_idx - wr_idx));
+ return (uint16_t)(2 * depth + diff);
}
}
diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h
index 8643bb020..10e12c2af 100644
--- a/src/common/tusb_private.h
+++ b/src/common/tusb_private.h
@@ -33,6 +33,18 @@
extern "C" {
#endif
+//--------------------------------------------------------------------+
+// Configuration
+//--------------------------------------------------------------------+
+
+#if CFG_TUD_ENABLED && CFG_TUD_VENDOR && (CFG_TUD_VENDOR_TX_BUFSIZE == 0 || CFG_TUD_VENDOR_RX_BUFSIZE == 0)
+ #define CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED 1
+#endif
+
+#ifndef CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED
+ #define CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED 0
+#endif
+
#define TUP_USBIP_CONTROLLER_NUM 2
extern tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM];
@@ -50,36 +62,40 @@ typedef struct TU_ATTR_PACKED {
volatile uint8_t busy : 1;
volatile uint8_t stalled : 1;
volatile uint8_t claimed : 1;
-}tu_edpt_state_t;
+} tu_edpt_state_t;
typedef struct {
- struct TU_ATTR_PACKED {
- bool is_host : 1; // 1: host, 0: device
- bool is_mps512 : 1; // 1: 512, 0: 64 since stream is used for Bulk only
- };
+ uint8_t hwid; // device: rhport, host: daddr
+ bool is_host; // 1: host, 0: device
uint8_t ep_addr;
- uint16_t ep_bufsize;
+ uint16_t mps;
+ uint16_t ep_bufsize;
uint8_t *ep_buf; // set to NULL to use xfer_fifo when CFG_TUD_EDPT_DEDICATED_HWFIFO = 1
tu_fifo_t ff;
// mutex: read if rx, otherwise write
OSAL_MUTEX_DEF(ff_mutexdef);
-
}tu_edpt_stream_t;
//--------------------------------------------------------------------+
// Endpoint
//--------------------------------------------------------------------+
-// Check if endpoint descriptor is valid per USB specs
-bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed, bool is_host);
-
-// Bind all endpoint of a interface descriptor to class driver
-void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* p_desc, uint16_t desc_len, uint8_t driver_id);
+// Check if endpoint descriptor is valid per USB specs if debug is enabled
+#if CFG_TUSB_DEBUG
+bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed);
+#else
+TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) {
+ (void)desc_ep;
+ (void)speed;
+ return true;
+}
+#endif
-// Calculate total length of n interfaces (depending on IAD)
-uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len);
+// Bind drivers to all interfaces and endpoints in the provided configuration descriptor
+bool tu_bind_driver_to_ep_itf(uint8_t driver_id, uint8_t ep2drv[][2], uint8_t itf2drv[], uint8_t itf_max,
+ const uint8_t *p_desc, uint16_t desc_len);
// Claim an endpoint with provided mutex
bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex);
@@ -92,16 +108,28 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex);
//--------------------------------------------------------------------+
// Init an endpoint stream
-bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable,
- void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize);
+bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf,
+ uint16_t ff_bufsize, uint8_t *ep_buf, uint16_t ep_bufsize);
// Deinit an endpoint stream
-bool tu_edpt_stream_deinit(tu_edpt_stream_t* s);
+TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_deinit(tu_edpt_stream_t *s) {
+ (void)s;
+#if OSAL_MUTEX_REQUIRED
+ if (s->ff.mutex_wr) {
+ osal_mutex_delete(s->ff.mutex_wr);
+ }
+ if (s->ff.mutex_rd) {
+ osal_mutex_delete(s->ff.mutex_rd);
+ }
+#endif
+}
// Open an endpoint stream
-TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) {
+TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t *s, uint8_t hwid,
+ const tusb_desc_endpoint_t *desc_ep) {
+ s->hwid = hwid;
s->ep_addr = desc_ep->bEndpointAddress;
- s->is_mps512 = tu_edpt_packet_size(desc_ep) == 512;
+ s->mps = tu_edpt_packet_size(desc_ep);
}
TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_is_opened(const tu_edpt_stream_t *s) {
@@ -112,8 +140,8 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_close(tu_edpt_stream_t*
s->ep_addr = 0;
}
-TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_clear(tu_edpt_stream_t* s) {
- return tu_fifo_clear(&s->ff);
+TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_clear(tu_edpt_stream_t *s) {
+ tu_fifo_clear(&s->ff);
}
TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_empty(tu_edpt_stream_t *s) {
@@ -125,42 +153,40 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_empty(tu_edpt_stream_t *
//--------------------------------------------------------------------+
// Write to stream
-uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize);
+uint32_t tu_edpt_stream_write(tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize);
// Start an usb transfer if endpoint is not busy. Return number of queued bytes
-uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s);
+uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s);
// Start an zero-length packet if needed
-bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes);
+bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t *s, uint32_t last_xferred_bytes);
// Get the number of bytes available for writing to FIFO
// Note: if no fifo, return endpoint size if not busy, 0 otherwise
-uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s);
+uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t *s);
//--------------------------------------------------------------------+
// Stream Read
//--------------------------------------------------------------------+
// Read from stream
-uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize);
+uint32_t tu_edpt_stream_read(tu_edpt_stream_t *s, void *buffer, uint32_t bufsize);
// Start an usb transfer if endpoint is not busy
-uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s);
+uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s);
// Complete read transfer by writing EP -> FIFO. Must be called in the transfer complete callback
TU_ATTR_ALWAYS_INLINE static inline
void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) {
- if (0u != tu_fifo_depth(&s->ff) && s->ep_buf != NULL) {
- tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes);
+ if (s->ep_buf != NULL) {
+ tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t)xferred_bytes);
}
}
// Complete read transfer with provided buffer
TU_ATTR_ALWAYS_INLINE static inline
void tu_edpt_stream_read_xfer_complete_with_buf(tu_edpt_stream_t *s, const void *buf, uint32_t xferred_bytes) {
- if (0u != tu_fifo_depth(&s->ff)) {
- tu_fifo_write_n(&s->ff, buf, (uint16_t) xferred_bytes);
- }
+ tu_fifo_write_n(&s->ff, buf, (uint16_t)xferred_bytes);
}
// Get the number of bytes available for reading
@@ -172,10 +198,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_peek(tu_edpt_stream_t *s
return tu_fifo_peek(&s->ff, ch);
}
-TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_edpt_stream_discard(tu_edpt_stream_t *s, uint32_t len) {
- return (uint32_t)tu_fifo_discard_n(&s->ff, (uint16_t)len);
-}
-
#ifdef __cplusplus
}
#endif
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 5e7d0ffa7..6c2ff2f62 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -115,30 +115,29 @@ TU_ATTR_WEAK bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_si
//--------------------------------------------------------------------+
// Device Data
//--------------------------------------------------------------------+
-
-// Invalid driver ID in itf2drv[] ep2drv[][] mapping
-enum { DRVID_INVALID = 0xFFu };
-
typedef struct {
- struct TU_ATTR_PACKED {
- volatile uint8_t connected : 1;
- volatile uint8_t addressed : 1;
- volatile uint8_t suspended : 1;
+ // Note: these may share an enum state
+ volatile uint8_t connected;
+ volatile uint8_t addressed;
+ volatile uint8_t suspended;
- uint8_t remote_wakeup_en : 1; // enable/disable by host
- uint8_t remote_wakeup_support : 1; // configuration descriptor's attribute
- uint8_t self_powered : 1; // configuration descriptor's attribute
+ union {
+ struct TU_ATTR_PACKED {
+ uint8_t self_powered : 1; // configuration descriptor's attribute;
+ uint8_t remote_wakeup_en : 1; // enable/disable by host
+ };
+ uint8_t dev_state_bm;
};
- volatile uint8_t cfg_num; // current active configuration (0x00 is not configured)
- uint8_t speed;
+
+ uint8_t cfg_num; // current active configuration (0x00 is not configured)
+ uint8_t speed;
volatile uint8_t sof_consumer;
uint8_t itf2drv[CFG_TUD_INTERFACE_MAX]; // map interface number to driver (0xff is invalid)
uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each
tu_edpt_state_t ep_status[CFG_TUD_ENDPPOINT_MAX][2];
-
-}usbd_device_t;
+} usbd_device_t;
static usbd_device_t _usbd_dev;
static volatile uint8_t _usbd_queued_setup;
@@ -146,11 +145,11 @@ static volatile uint8_t _usbd_queued_setup;
//--------------------------------------------------------------------+
// Class Driver
//--------------------------------------------------------------------+
-#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
- #define DRIVER_NAME(_name) _name
-#else
- #define DRIVER_NAME(_name) NULL
-#endif
+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
+ #define DRIVER_NAME(_name) _name
+ #else
+ #define DRIVER_NAME(_name) NULL
+ #endif
// Built-in class drivers
static const usbd_class_driver_t _usbd_driver[] = {
@@ -343,7 +342,7 @@ enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) };
static const usbd_class_driver_t *_app_driver = NULL;
static uint8_t _app_driver_count = 0;
- #define TOTAL_DRIVER_COUNT ((uint8_t) (_app_driver_count + BUILTIN_DRIVER_COUNT))
+#define TOTAL_DRIVER_COUNT ((uint8_t) (_app_driver_count + BUILTIN_DRIVER_COUNT))
// virtually joins built-in and application drivers together.
// Application is positioned first to allow overwriting built-in ones.
@@ -475,8 +474,8 @@ bool tud_suspended(void) {
}
bool tud_remote_wakeup(void) {
- // only wake up host if this feature is supported and enabled and we are suspended
- TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en);
+ // only wake up host if this feature is enabled and we are suspended
+ TU_VERIFY(_usbd_dev.suspended && _usbd_dev.remote_wakeup_en);
dcd_remote_wakeup(_usbd_rhport);
return true;
}
@@ -507,9 +506,9 @@ bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
return true; // skip if already initialized
}
TU_ASSERT(rh_init);
-#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
char const* speed_str = 0;
- switch (rh_init->speed) {
+ switch (rh_init->speed) {
case TUSB_SPEED_HIGH:
speed_str = "High";
break;
@@ -611,8 +610,8 @@ static void configuration_reset(uint8_t rhport) {
}
tu_varclr(&_usbd_dev);
- (void) memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping
- (void) memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping
+ (void)memset(_usbd_dev.itf2drv, TUSB_INDEX_INVALID_8, sizeof(_usbd_dev.itf2drv)); // invalid mapping
+ (void)memset(_usbd_dev.ep2drv, TUSB_INDEX_INVALID_8, sizeof(_usbd_dev.ep2drv)); // invalid mapping
}
static void usbd_reset(uint8_t rhport) {
@@ -655,7 +654,9 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) {
}
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
- if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG_USBD("\r\n"); // extra line for setup
+ if (event.event_id == DCD_EVENT_SETUP_RECEIVED) {
+ TU_LOG_USBD("\r\n"); // extra line for setup
+ }
TU_LOG_USBD("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED");
#endif
@@ -883,7 +884,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
case TUSB_REQ_FEATURE_REMOTE_WAKEUP:
TU_LOG_USBD(" Enable Remote Wakeup\r\n");
// Host may enable remote wake up before suspending especially HID device
- _usbd_dev.remote_wakeup_en = true;
+ _usbd_dev.remote_wakeup_en = 1;
tud_control_status(rhport, p_request);
break;
@@ -912,15 +913,15 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
TU_LOG_USBD(" Disable Remote Wakeup\r\n");
// Host may disable remote wake up after resuming
- _usbd_dev.remote_wakeup_en = false;
+ _usbd_dev.remote_wakeup_en = 0;
tud_control_status(rhport, p_request);
break;
case TUSB_REQ_GET_STATUS: {
// Device status bit mask
- // - Bit 0: Self Powered
+ // - Bit 0: Self Powered TODO must invoke callback to get actual status
// - Bit 1: Remote Wakeup enabled
- uint16_t status = (uint16_t) ((_usbd_dev.self_powered ? 1u : 0u) | (_usbd_dev.remote_wakeup_en ? 2u : 0u));
+ uint16_t status = (uint16_t)_usbd_dev.dev_state_bm;
tud_control_xfer(rhport, p_request, &status, 2);
break;
}
@@ -1034,117 +1035,46 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// Process Set Configure Request
// This function parse configuration descriptor & open drivers accordingly
-static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
-{
+static bool process_set_config(uint8_t rhport, uint8_t cfg_num) {
// index is cfg_num-1
- tusb_desc_configuration_t const * desc_cfg = (tusb_desc_configuration_t const *) tud_descriptor_configuration_cb(cfg_num-1);
+ const tusb_desc_configuration_t *desc_cfg =
+ (const tusb_desc_configuration_t *)tud_descriptor_configuration_cb(cfg_num - 1);
TU_ASSERT(desc_cfg != NULL && desc_cfg->bDescriptorType == TUSB_DESC_CONFIGURATION);
// Parse configuration descriptor
- _usbd_dev.remote_wakeup_support = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP) ? 1u : 0u;
- _usbd_dev.self_powered = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_SELF_POWERED ) ? 1u : 0u;
+ _usbd_dev.self_powered = (desc_cfg->bmAttributes & TUSB_DESC_CONFIG_ATT_SELF_POWERED) ? 1u : 0u;
// Parse interface descriptor
- uint8_t const * p_desc = ((uint8_t const*) desc_cfg) + sizeof(tusb_desc_configuration_t);
- uint8_t const * desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength);
-
- while( p_desc < desc_end )
- {
- uint8_t assoc_itf_count = 1;
-
- // Class will always starts with Interface Association (if any) and then Interface descriptor
- if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) )
- {
- tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const *) p_desc;
- assoc_itf_count = desc_iad->bInterfaceCount;
+ const uint8_t *p_desc = ((const uint8_t *)desc_cfg) + sizeof(tusb_desc_configuration_t);
+ const uint8_t *desc_end = ((const uint8_t *)desc_cfg) + tu_le16toh(desc_cfg->wTotalLength);
+ while (tu_desc_in_bounds(p_desc, desc_end)) {
+ // Class will always start with Interface Association (if any) and then Interface descriptor
+ if (TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc)) {
p_desc = tu_desc_next(p_desc); // next to Interface
-
- // IAD's first interface number and class should match with opened interface
- //TU_ASSERT(desc_iad->bFirstInterface == desc_itf->bInterfaceNumber &&
- // desc_iad->bFunctionClass == desc_itf->bInterfaceClass);
+ continue;
}
- TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) );
- tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const*) p_desc;
+ TU_ASSERT(TUSB_DESC_INTERFACE == tu_desc_type(p_desc));
+ const tusb_desc_interface_t *desc_itf = (const tusb_desc_interface_t *)p_desc;
// Find driver for this interface
- uint16_t const remaining_len = (uint16_t) (desc_end-p_desc);
- uint8_t drv_id;
- for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++)
- {
- usbd_class_driver_t const *driver = get_driver(drv_id);
+ const uint16_t remaining_len = (uint16_t)(desc_end - p_desc);
+ uint8_t drv_id;
+ for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
+ const usbd_class_driver_t *driver = get_driver(drv_id);
TU_ASSERT(driver);
- uint16_t const drv_len = driver->open(rhport, desc_itf, remaining_len);
+ const uint16_t drv_len = driver->open(rhport, desc_itf, remaining_len);
- if ( (sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len) )
- {
+ if ((sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len)) {
// Open successfully
TU_LOG_USBD(" %s opened\r\n", driver->name);
- // Some drivers use 2 or more interfaces but may not have IAD e.g MIDI (always) or
- // BTH (even CDC) with class in device descriptor (single interface)
- if (assoc_itf_count == 1) {
- #if CFG_TUD_CDC
- if ( driver->open == cdcd_open ) {
- assoc_itf_count = 2;
- }
- #endif
-
- #if CFG_TUD_MIDI
- if (driver->open == midid_open) {
- // If there is a class-compliant Audio Control Class, then 2 interfaces. Otherwise, only one
- if (TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass &&
- AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass &&
- AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) {
- assoc_itf_count = 2;
- }
- }
- #endif
-
- #if CFG_TUD_BTH && CFG_TUD_BTH_ISO_ALT_COUNT
- if ( driver->open == btd_open ) assoc_itf_count = 2;
- #endif
-
- #if CFG_TUD_AUDIO
- if (driver->open == audiod_open) {
- // UAC1 device doesn't have IAD, needs to read AS interface count from CS AC descriptor
- if (TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass &&
- AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass &&
- AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) {
- uint8_t const* p = tu_desc_next(p_desc);
- uint8_t const* const itf_end = p_desc + remaining_len;
- while (p < itf_end) {
- if (TUSB_DESC_CS_INTERFACE == tu_desc_type(p) &&
- AUDIO10_CS_AC_INTERFACE_HEADER == ((audio10_desc_cs_ac_interface_1_t const *) p)->bDescriptorSubType) {
- audio10_desc_cs_ac_interface_1_t const * p_header = (audio10_desc_cs_ac_interface_1_t const *) p;
- // AC + AS interfaces
- assoc_itf_count = p_header->bInCollection + 1;
- break;
- }
- p = tu_desc_next(p);
- }
- }
- }
- #endif
- }
-
- // bind (associated) interfaces to found driver
- for(uint8_t i=0; i<assoc_itf_count; i++)
- {
- uint8_t const itf_num = desc_itf->bInterfaceNumber+i;
-
- // Interface number must not be used already
- TU_ASSERT(DRVID_INVALID == _usbd_dev.itf2drv[itf_num]);
- _usbd_dev.itf2drv[itf_num] = drv_id;
- }
-
- // bind all endpoints to found driver
- tu_edpt_bind_driver(_usbd_dev.ep2drv, desc_itf, drv_len, drv_id);
-
- // next Interface
- p_desc += drv_len;
+ // bind found driver to all interfaces and endpoint within drv_len
+ TU_ASSERT(tu_bind_driver_to_ep_itf(drv_id, _usbd_dev.ep2drv, _usbd_dev.itf2drv, CFG_TUD_INTERFACE_MAX, p_desc,
+ drv_len));
+ p_desc += drv_len; // next Interface
break; // exit driver find loop
}
}
@@ -1363,20 +1293,17 @@ void usbd_spin_unlock(bool in_isr) {
}
// Parse consecutive endpoint descriptors (IN & OUT)
-bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in)
-{
- for(int i=0; i<ep_count; i++)
- {
- tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc;
+bool usbd_open_edpt_pair(uint8_t rhport, const uint8_t *p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t *ep_out,
+ uint8_t *ep_in) {
+ for (int i = 0; i < ep_count; i++) {
+ const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc;
TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && xfer_type == desc_ep->bmAttributes.xfer);
TU_ASSERT(usbd_edpt_open(rhport, desc_ep));
- if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN )
- {
+ if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
(*ep_in) = desc_ep->bEndpointAddress;
- }else
- {
+ } else {
(*ep_out) = desc_ep->bEndpointAddress;
}
@@ -1406,7 +1333,7 @@ bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) {
rhport = _usbd_rhport;
TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < CFG_TUD_ENDPPOINT_MAX);
- TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed, false));
+ TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t)_usbd_dev.speed));
return dcd_edpt_open(rhport, desc_ep);
}
@@ -1480,7 +1407,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
- TU_LOG_USBD(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes);
+ TU_LOG_USBD(" Queue FIFO EP %02X with %u bytes ... ", ep_addr, total_bytes);
// Attempt to transfer on a busy endpoint, sound like a race condition !
TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
@@ -1616,7 +1543,7 @@ bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep)
uint8_t const dir = tu_edpt_dir(desc_ep->bEndpointAddress);
TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX);
- TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed, false));
+ TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t)_usbd_dev.speed));
_usbd_dev.ep_status[epnum][dir].stalled = 0;
_usbd_dev.ep_status[epnum][dir].busy = 0;
diff --git a/src/host/hub.c b/src/host/hub.c
index 0b172a596..3baaff30f 100644
--- a/src/host/hub.c
+++ b/src/host/hub.c
@@ -218,27 +218,27 @@ bool hub_deinit(void) {
return true;
}
-bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) {
+uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) {
(void) rhport;
TU_VERIFY(TUSB_CLASS_HUB == itf_desc->bInterfaceClass &&
- 0 == itf_desc->bInterfaceSubClass);
- TU_VERIFY(itf_desc->bInterfaceProtocol <= 1); // not support multiple TT yet
+ 0 == itf_desc->bInterfaceSubClass, 0);
+ TU_VERIFY(itf_desc->bInterfaceProtocol <= 1, 0); // not support multiple TT yet
- uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t);
- TU_ASSERT(drv_len <= max_len);
+ const uint16_t drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t);
+ TU_ASSERT(drv_len <= max_len, 0);
// Interrupt Status endpoint
tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc);
TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType &&
TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0);
- TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep));
+ TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep), 0);
hub_interface_t* p_hub = get_hub_itf(dev_addr);
p_hub->itf_num = itf_desc->bInterfaceNumber;
p_hub->ep_in = desc_ep->bEndpointAddress;
- return true;
+ return drv_len;
}
void hub_close(uint8_t dev_addr) {
diff --git a/src/host/hub.h b/src/host/hub.h
index 3587f0ee3..d9750f8a5 100644
--- a/src/host/hub.h
+++ b/src/host/hub.h
@@ -206,12 +206,12 @@ bool hub_clear_feature(uint8_t hub_addr, uint8_t feature, tuh_xfer_cb_t complete
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
-bool hub_init (void);
-bool hub_deinit (void);
-bool hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len);
-bool hub_set_config (uint8_t daddr, uint8_t itf_num);
-bool hub_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
-void hub_close (uint8_t dev_addr);
+bool hub_init(void);
+bool hub_deinit(void);
+uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *itf_desc, uint16_t max_len);
+bool hub_set_config(uint8_t daddr, uint8_t itf_num);
+bool hub_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
+void hub_close(uint8_t dev_addr);
#ifdef __cplusplus
}
diff --git a/src/host/usbh.c b/src/host/usbh.c
index 734024771..5b14a15cb 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -1066,7 +1066,14 @@ static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) {
}
bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const* desc_ep) {
- TU_ASSERT(tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr), true));
+ // HACK: some device incorrectly always report 512 bulk regardless of link speed, overwrite descriptor to force 64
+ if (desc_ep->bmAttributes.xfer == TUSB_XFER_BULK && tu_edpt_packet_size(desc_ep) > 64 &&
+ tuh_speed_get(dev_addr) == TUSB_SPEED_FULL) {
+ TU_LOG1(" WARN: EP max packet size is 512 in fullspeed, force to 64\r\n");
+ tusb_desc_endpoint_t *hacked_ep = (tusb_desc_endpoint_t *)(uintptr_t)desc_ep;
+ hacked_ep->wMaxPacketSize = tu_htole16(64);
+ }
+ TU_ASSERT(tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr)));
return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, desc_ep);
}
@@ -1815,85 +1822,51 @@ static bool enum_parse_configuration_desc(uint8_t dev_addr, tusb_desc_configurat
TU_LOG_USBH("Parsing Configuration descriptor (wTotalLength = %u)\r\n", total_len);
// parse each interfaces
- while( p_desc < desc_end ) {
- if ( 0 == tu_desc_len(p_desc) ) {
+ while (tu_desc_in_bounds(p_desc, desc_end)) {
+ if (0 == tu_desc_len(p_desc)) {
// A zero length descriptor indicates that the device is off spec (e.g. wrong wTotalLength).
// Parsed interfaces should still be usable
TU_LOG_USBH("Encountered a zero-length descriptor after %" PRIu32 " bytes\r\n", (uint32_t)p_desc - (uint32_t)desc_cfg);
break;
}
- uint8_t assoc_itf_count = 1;
-
- // Class will always starts with Interface Association (if any) and then Interface descriptor
- if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) ) {
- tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const *) p_desc;
- assoc_itf_count = desc_iad->bInterfaceCount;
-
- p_desc = tu_desc_next(p_desc); // next to Interface
-
- // IAD's first interface number and class should match with opened interface
- //TU_ASSERT(desc_iad->bFirstInterface == desc_itf->bInterfaceNumber &&
- // desc_iad->bFunctionClass == desc_itf->bInterfaceClass);
+ // skip if not interface
+ if (TUSB_DESC_INTERFACE != tu_desc_type(p_desc)) {
+ p_desc = tu_desc_next(p_desc);
+ continue;
}
+ const tusb_desc_interface_t *desc_itf = (const tusb_desc_interface_t *)p_desc;
- TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) );
- tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc;
-
-#if CFG_TUH_MIDI
- // MIDI has 2 interfaces (Audio Control v1 + MIDIStreaming) but does not have IAD
- // manually force associated count = 2
- if (1 == assoc_itf_count &&
- TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass &&
- AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass &&
- AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) {
- assoc_itf_count = 2;
- }
-#endif
-
-#if CFG_TUH_CDC
- // Some legacy CDC device does not use IAD but rather use device class as hint to combine 2 interfaces
- // manually force associated count = 2
- if (1 == assoc_itf_count &&
- TUSB_CLASS_CDC == desc_itf->bInterfaceClass &&
- CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == desc_itf->bInterfaceSubClass) {
- assoc_itf_count = 2;
- }
-#endif
-
- uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, (uint16_t) (desc_end-p_desc));
- TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t));
+ // uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, (uint16_t)
+ // (desc_end-p_desc)); TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t));
// Find driver for this interface
- for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
- usbh_class_driver_t const * driver = get_driver(drv_id);
- if (driver && driver->open(dev->bus_info.rhport, dev_addr, desc_itf, drv_len) ) {
- // open successfully
- TU_LOG_USBH(" %s opened\r\n", driver->name);
+ const uint16_t remaining_len = (uint16_t)(desc_end - p_desc);
+ uint8_t drv_id;
+ for (drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
+ const usbh_class_driver_t *driver = get_driver(drv_id);
+ if (driver) {
+ const uint16_t drv_len = driver->open(dev->bus_info.rhport, dev_addr, desc_itf, remaining_len);
+ if ((sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len)) {
+ // open successfully
+ TU_LOG_USBH(" %s opened\r\n", driver->name);
- // bind (associated) interfaces to found driver
- for(uint8_t i=0; i<assoc_itf_count; i++) {
- uint8_t const itf_num = desc_itf->bInterfaceNumber+i;
+ // bind found driver to all interfaces and endpoint within drv_len
+ tu_bind_driver_to_ep_itf(drv_id, dev->ep2drv, dev->itf2drv, CFG_TUH_INTERFACE_MAX, p_desc, drv_len);
- // Interface number must not be used already
- TU_ASSERT( TUSB_INDEX_INVALID_8 == dev->itf2drv[itf_num] );
- dev->itf2drv[itf_num] = drv_id;
+ p_desc += drv_len; // next Interface
+ break; // exit driver find loop
}
-
- // bind all endpoints to found driver
- tu_edpt_bind_driver(dev->ep2drv, desc_itf, drv_len, drv_id);
-
- break; // exit driver find loop
- }
-
- if (drv_id == TOTAL_DRIVER_COUNT - 1) {
- TU_LOG_USBH("[%u:%u] Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n",
- dev->bus_info.rhport, dev_addr, desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol);
}
}
- // next Interface or IAD descriptor
- p_desc += drv_len;
+ // no driver found
+ if (drv_id == TOTAL_DRIVER_COUNT) {
+ p_desc = tu_desc_next(p_desc); // skip this interface
+ TU_LOG_USBH("[%u:%u] Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n",
+ dev->bus_info.rhport, dev_addr, desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass,
+ desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol);
+ }
}
return true;
diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h
index d722bb7e8..57428e3c5 100644
--- a/src/host/usbh_pvt.h
+++ b/src/host/usbh_pvt.h
@@ -44,16 +44,15 @@
//--------------------------------------------------------------------+
// Class Driver API
//--------------------------------------------------------------------+
-
typedef struct {
- char const* name;
- bool (* const init )(void);
- bool (* const deinit )(void);
- bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
- bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num);
- bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
- void (* const close )(uint8_t dev_addr);
-} usbh_class_driver_t;
+ const char *name;
+ bool (*const init)(void);
+ bool (*const deinit)(void);
+ uint16_t (*const open)(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *itf_desc, uint16_t max_len);
+ bool (*const set_config)(uint8_t dev_addr, uint8_t itf_num);
+ bool (*const xfer_cb)(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
+ void (*const close)(uint8_t dev_addr);
+ } usbh_class_driver_t;
// Invoked when initializing host stack to get additional class drivers.
// Can be implemented by application to extend/overwrite class driver support.
diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py
index f6bd2785a..8fbbc00a0 100755
--- a/src/portable/synopsys/dwc2/dwc2_info.py
+++ b/src/portable/synopsys/dwc2/dwc2_info.py
@@ -2,7 +2,6 @@
import ctypes
import argparse
-import click
import pandas as pd
# hex value for register: guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4
diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c
index b92448685..fc748c85f 100644
--- a/src/portable/synopsys/dwc2/hcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/hcd_dwc2.c
@@ -821,7 +821,7 @@ static void channel_xfer_in_retry(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t hci
}
}
-#if CFG_TUSB_DEBUG
+#if CFG_TUSB_DEBUG && 0
TU_ATTR_ALWAYS_INLINE static inline void print_hcint(uint32_t hcint) {
const char* str[] = {
"XFRC", "HALTED", "AHBERR", "STALL",
diff --git a/src/tusb.c b/src/tusb.c
index b6cfd1260..8ba9f0fff 100644
--- a/src/tusb.c
+++ b/src/tusb.c
@@ -241,13 +241,14 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) {
return ret;
}
-bool tu_edpt_validate(tusb_desc_endpoint_t const* desc_ep, tusb_speed_t speed, bool is_host) {
- uint16_t const max_packet_size = tu_edpt_packet_size(desc_ep);
+#if CFG_TUSB_DEBUG
+bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) {
+ const uint16_t max_packet_size = tu_edpt_packet_size(desc_ep);
TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size);
switch (desc_ep->bmAttributes.xfer) {
case TUSB_XFER_ISOCHRONOUS: {
- uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 1023);
+ const uint16_t spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 1023);
TU_ASSERT(max_packet_size <= spec_size);
break;
}
@@ -258,16 +259,7 @@ bool tu_edpt_validate(tusb_desc_endpoint_t const* desc_ep, tusb_speed_t speed, b
TU_ASSERT(max_packet_size == 512);
} else {
// Bulk fullspeed can only be 8, 16, 32, 64
- if (is_host && max_packet_size == 512) {
- // HACK: while in host mode, some device incorrectly always report 512 regardless of link speed
- // overwrite descriptor to force 64
- TU_LOG1(" WARN: EP max packet size is 512 in fullspeed, force to 64\r\n");
- tusb_desc_endpoint_t* hacked_ep = (tusb_desc_endpoint_t*) (uintptr_t) desc_ep;
- hacked_ep->wMaxPacketSize = tu_htole16(64);
- } else {
- TU_ASSERT(max_packet_size == 8 || max_packet_size == 16 ||
- max_packet_size == 32 || max_packet_size == 64);
- }
+ TU_ASSERT(max_packet_size == 8 || max_packet_size == 16 || max_packet_size == 32 || max_packet_size == 64);
}
break;
@@ -283,61 +275,46 @@ bool tu_edpt_validate(tusb_desc_endpoint_t const* desc_ep, tusb_speed_t speed, b
return true;
}
+#endif
-void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len,
- uint8_t driver_id) {
- uint8_t const* p_desc = (uint8_t const*) desc_itf;
- uint8_t const* desc_end = p_desc + desc_len;
+bool tu_bind_driver_to_ep_itf(uint8_t driver_id, uint8_t ep2drv[][2], uint8_t itf2drv[], uint8_t itf_max,
+ const uint8_t *p_desc, uint16_t desc_len) {
+ const uint8_t *desc_end = p_desc + desc_len;
+ while (tu_desc_in_bounds(p_desc, desc_end)) {
+ const uint8_t desc_type = tu_desc_type(p_desc);
- while (p_desc < desc_end) {
- if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) {
- uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress;
- TU_LOG(2, " Bind EP %02x to driver id %u\r\n", ep_addr, driver_id);
- ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = driver_id;
+ if (desc_type == TUSB_DESC_ENDPOINT) {
+ const uint8_t ep_addr = ((const tusb_desc_endpoint_t *)p_desc)->bEndpointAddress;
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const uint8_t ep_dir = tu_edpt_dir(ep_addr);
+ ep2drv[ep_num][ep_dir] = driver_id;
+ } else if (desc_type == TUSB_DESC_INTERFACE) {
+ const tusb_desc_interface_t *desc_itf = (const tusb_desc_interface_t *)p_desc;
+ if (desc_itf->bAlternateSetting == 0) {
+ TU_ASSERT(desc_itf->bInterfaceNumber < itf_max);
+ itf2drv[desc_itf->bInterfaceNumber] = driver_id;
+ }
}
- p_desc = tu_desc_next(p_desc);
- }
-}
-uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len) {
- uint8_t const* p_desc = (uint8_t const*) desc_itf;
- uint16_t len = 0;
-
- while ((itf_count--) > 0) {
- // Next on interface desc
- len += tu_desc_len(desc_itf);
p_desc = tu_desc_next(p_desc);
-
- while (len < max_len) {
- if (tu_desc_len(p_desc) == 0) {
- // Escape infinite loop
- break;
- }
- // return on IAD regardless of itf count
- if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION) {
- return len;
- }
- if ((tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) &&
- ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0) {
- break;
- }
-
- len += tu_desc_len(p_desc);
- p_desc = tu_desc_next(p_desc);
- }
}
-
- return len;
+ return true;
}
//--------------------------------------------------------------------+
// Endpoint Stream Helper for both Host and Device stack
//--------------------------------------------------------------------+
-bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable,
- void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize) {
+bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf,
+ uint16_t ff_bufsize, uint8_t *ep_buf, uint16_t ep_bufsize) {
(void) is_tx;
+ #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED == 0 // FIFO is required
+ if (ff_buf == NULL || ff_bufsize == 0) {
+ return false;
+ }
+ #endif
+
s->is_host = is_host;
tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable);
@@ -354,58 +331,46 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove
return true;
}
-bool tu_edpt_stream_deinit(tu_edpt_stream_t *s) {
- (void)s;
- #if OSAL_MUTEX_REQUIRED
- if (s->ff.mutex_wr) {
- osal_mutex_delete(s->ff.mutex_wr);
- }
- if (s->ff.mutex_rd) {
- osal_mutex_delete(s->ff.mutex_rd);
- }
- #endif
- return true;
-}
-
-TU_ATTR_ALWAYS_INLINE static inline bool stream_claim(uint8_t hwid, tu_edpt_stream_t* s) {
+static bool stream_claim(tu_edpt_stream_t *s) {
+ TU_VERIFY(s->ep_addr != 0); // must be opened
if (s->is_host) {
#if CFG_TUH_ENABLED
- return usbh_edpt_claim(hwid, s->ep_addr);
- #endif
+ return usbh_edpt_claim(s->hwid, s->ep_addr);
+ #endif
} else {
#if CFG_TUD_ENABLED
- return usbd_edpt_claim(hwid, s->ep_addr);
- #endif
+ return usbd_edpt_claim(s->hwid, s->ep_addr);
+ #endif
}
return false;
}
-TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(uint8_t hwid, tu_edpt_stream_t* s, uint16_t count) {
+static bool stream_xfer(tu_edpt_stream_t *s, uint16_t count) {
if (s->is_host) {
#if CFG_TUH_ENABLED
- return usbh_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count);
- #endif
+ return usbh_edpt_xfer(s->hwid, s->ep_addr, count ? s->ep_buf : NULL, count);
+ #endif
} else {
#if CFG_TUD_ENABLED
if (s->ep_buf == NULL) {
- return usbd_edpt_xfer_fifo(hwid, s->ep_addr, &s->ff, count, false);
+ return usbd_edpt_xfer_fifo(s->hwid, s->ep_addr, &s->ff, count, false);
} else {
- return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false);
+ return usbd_edpt_xfer(s->hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false);
}
#endif
}
return false;
}
-TU_ATTR_ALWAYS_INLINE static inline bool stream_release(uint8_t hwid, tu_edpt_stream_t* s) {
+static bool stream_release(tu_edpt_stream_t *s) {
if (s->is_host) {
#if CFG_TUH_ENABLED
- return usbh_edpt_release(hwid, s->ep_addr);
- #endif
+ return usbh_edpt_release(s->hwid, s->ep_addr);
+ #endif
} else {
#if CFG_TUD_ENABLED
- return usbd_edpt_release(hwid, s->ep_addr);
- #endif
+ return usbd_edpt_release(s->hwid, s->ep_addr);
+ #endif
}
return false;
}
@@ -413,19 +378,18 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_release(uint8_t hwid, tu_edpt_st
//--------------------------------------------------------------------+
// Stream Write
//--------------------------------------------------------------------+
-bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes) {
+bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t *s, uint32_t last_xferred_bytes) {
// ZLP condition: no pending data, last transferred bytes is multiple of packet size
- const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS;
- TU_VERIFY(tu_fifo_empty(&s->ff) && last_xferred_bytes > 0 && (0 == (last_xferred_bytes & (mps - 1))));
- TU_VERIFY(stream_claim(hwid, s));
- TU_ASSERT(stream_xfer(hwid, s, 0));
+ TU_VERIFY(tu_fifo_empty(&s->ff) && last_xferred_bytes > 0 && (0 == (last_xferred_bytes & (s->mps - 1))));
+ TU_VERIFY(stream_claim(s));
+ TU_ASSERT(stream_xfer(s, 0));
return true;
}
-uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) {
+uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s) {
const uint16_t ff_count = tu_fifo_count(&s->ff);
TU_VERIFY(ff_count > 0, 0); // skip if no data
- TU_VERIFY(stream_claim(hwid, s), 0);
+ TU_VERIFY(stream_claim(s), 0);
// Pull data from FIFO -> EP buf
uint16_t count;
@@ -436,22 +400,23 @@ uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) {
}
if (count > 0) {
- TU_ASSERT(stream_xfer(hwid, s, count), 0);
+ TU_ASSERT(stream_xfer(s, count), 0);
return count;
} else {
// Release endpoint since we don't make any transfer
// Note: data is dropped if terminal is not connected
- stream_release(hwid, s);
+ stream_release(s);
return 0;
}
}
-uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize) {
- TU_VERIFY(bufsize > 0); // TODO support ZLP
+uint32_t tu_edpt_stream_write(tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize) {
+ TU_VERIFY(bufsize > 0);
+ #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED
if (0 == tu_fifo_depth(&s->ff)) {
// non-fifo mode
- TU_VERIFY(stream_claim(hwid, s), 0);
+ TU_VERIFY(stream_claim(s), 0);
uint32_t xact_len;
if (s->ep_buf != NULL) {
// using ep buf
@@ -461,80 +426,89 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buf
// using hwfifo
xact_len = bufsize;
}
- TU_ASSERT(stream_xfer(hwid, s, (uint16_t) xact_len), 0);
+ TU_ASSERT(stream_xfer(s, (uint16_t)xact_len), 0);
return xact_len;
- } else {
+ } else
+ #endif
+ {
const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize);
// flush if fifo has more than packet size or
// in rare case: fifo depth is configured too small (which never reach packet size)
- const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS;
- if ((tu_fifo_count(&s->ff) >= mps) || (tu_fifo_depth(&s->ff) < mps)) {
- tu_edpt_stream_write_xfer(hwid, s);
+ if ((tu_fifo_count(&s->ff) >= s->mps) || (tu_fifo_depth(&s->ff) < s->mps)) {
+ tu_edpt_stream_write_xfer(s);
}
return ret;
}
}
-uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s) {
- if (tu_fifo_depth(&s->ff) > 0) {
- return (uint32_t) tu_fifo_remaining(&s->ff);
- } else {
+uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t *s) {
+ #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED
+ if (0 == tu_fifo_depth(&s->ff)) {
// non-fifo mode
+ TU_VERIFY(s->ep_addr > 0); // must be opened
bool is_busy = true;
if (s->is_host) {
#if CFG_TUH_ENABLED
- is_busy = usbh_edpt_busy(hwid, s->ep_addr);
- #endif
+ is_busy = usbh_edpt_busy(s->hwid, s->ep_addr);
+ #endif
} else {
#if CFG_TUD_ENABLED
- is_busy = usbd_edpt_busy(hwid, s->ep_addr);
- #endif
+ is_busy = usbd_edpt_busy(s->hwid, s->ep_addr);
+ #endif
}
return is_busy ? 0 : s->ep_bufsize;
+ } else
+ #endif
+ {
+ return (uint32_t)tu_fifo_remaining(&s->ff);
}
}
//--------------------------------------------------------------------+
// Stream Read
//--------------------------------------------------------------------+
-uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s) {
+uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s) {
+ #if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED
if (0 == tu_fifo_depth(&s->ff)) {
// non-fifo mode: RX need ep buffer
TU_VERIFY(s->ep_buf != NULL, 0);
- TU_VERIFY(stream_claim(hwid, s), 0);
- TU_ASSERT(stream_xfer(hwid, s, s->ep_bufsize), 0);
+ TU_VERIFY(stream_claim(s), 0);
+ TU_ASSERT(stream_xfer(s, s->ep_bufsize), 0);
return s->ep_bufsize;
- } else {
- const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS;
+ } else
+ #endif
+ {
uint16_t available = tu_fifo_remaining(&s->ff);
// Prepare for incoming data but only allow what we can store in the ring buffer.
// TODO Actually we can still carry out the transfer, keeping count of received bytes
// and slowly move it to the FIFO when read().
// This pre-check reduces endpoint claiming
- TU_VERIFY(available >= mps);
- TU_VERIFY(stream_claim(hwid, s), 0);
+ TU_VERIFY(available >= s->mps);
+ TU_VERIFY(stream_claim(s), 0);
available = tu_fifo_remaining(&s->ff); // re-get available since fifo can be changed
- if (available >= mps) {
+ if (available >= s->mps) {
// multiple of packet size limit by ep bufsize
- uint16_t count = (uint16_t) (available & ~(mps - 1));
- count = tu_min16(count, s->ep_bufsize);
- TU_ASSERT(stream_xfer(hwid, s, count), 0);
+ uint16_t count = (uint16_t) (available & ~(s->mps - 1));
+ if (s->ep_buf != NULL) {
+ count = tu_min16(count, s->ep_bufsize);
+ }
+ TU_ASSERT(stream_xfer(s, count), 0);
return count;
} else {
// Release endpoint since we don't make any transfer
- stream_release(hwid, s);
+ stream_release(s);
return 0;
}
}
}
-uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) {
+uint32_t tu_edpt_stream_read(tu_edpt_stream_t *s, void *buffer, uint32_t bufsize) {
const uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t)bufsize);
- tu_edpt_stream_read_xfer(hwid, s);
+ tu_edpt_stream_read_xfer(s);
return num_read;
}
diff --git a/src/tusb_option.h b/src/tusb_option.h
index eb072faab..a70d7a97e 100644
--- a/src/tusb_option.h
+++ b/src/tusb_option.h
@@ -31,7 +31,7 @@
// Version is release as major.minor.revision eg 1.0.0
#define TUSB_VERSION_MAJOR 0
#define TUSB_VERSION_MINOR 20
-#define TUSB_VERSION_REVISION 0
+#define TUSB_VERSION_REVISION 1
#define TUSB_VERSION_NUMBER (TUSB_VERSION_MAJOR * 10000 + TUSB_VERSION_MINOR * 100 + TUSB_VERSION_REVISION)
#define TUSB_VERSION_STRING TU_XSTRING(TUSB_VERSION_MAJOR) "." TU_XSTRING(TUSB_VERSION_MINOR) "." TU_XSTRING(TUSB_VERSION_REVISION)
@@ -309,7 +309,7 @@
#define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
#endif
- #if CFG_TUD_DWC2_SLAVE_ENABLE && !CFG_TUH_DWC2_DMA_ENABLE
+ #if CFG_TUH_DWC2_SLAVE_ENABLE && !CFG_TUH_DWC2_DMA_ENABLE
#define CFG_TUH_EDPT_DEDICATED_HWFIFO 1
#endif
#endif
@@ -321,10 +321,18 @@
#ifndef CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT
#define CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT 0
#endif
-
#define CFG_TUD_CI_HS_VBUS_CHARGE CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT
#endif
+// CI_HS support FIFO transfer if endpoint buffer is 4k aligned and size is multiple of 4k, also DCACHE is disabled
+#ifndef CFG_TUD_CI_HS_EPBUF_4K_ALIGNED
+ #define CFG_TUD_CI_HS_EPBUF_4K_ALIGNED 0
+#endif
+
+#if CFG_TUD_CI_HS_EPBUF_4K_ALIGNED && !CFG_TUD_MEM_DCACHE_ENABLE
+ #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
+#endif
+
//------------- pio-usb -------------//
// Enable PIO-USB software host controller
#ifndef CFG_TUH_RPI_PIO_USB
@@ -335,11 +343,27 @@
#define CFG_TUD_RPI_PIO_USB 0
#endif
-// MAX3421 Host controller option
+//------------ MAX3421 -------------//
+// Enable MAX3421 USB host controller
#ifndef CFG_TUH_MAX3421
#define CFG_TUH_MAX3421 0
#endif
+//------------ FSDEV --------------//
+#if defined(TUP_USBIP_FSDEV)
+ #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
+#endif
+
+//------------ MUSB --------------//
+#if defined(TUP_USBIP_MUSB)
+ #define CFG_TUD_EDPT_DEDICATED_HWFIFO 0 // need testing to enable
+#endif
+
+//------------ RUSB2 --------------//
+#if defined(TUP_USBIP_RUSB2)
+ #define CFG_TUD_EDPT_DEDICATED_HWFIFO 0 // need testing to enable
+#endif
+
//--------------------------------------------------------------------
// RootHub Mode detection
//--------------------------------------------------------------------