diff options
| author | hathach <[email protected]> | 2025-11-18 09:36:16 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2025-11-18 09:36:16 +0700 |
| commit | 98f7b0c7ba03fd770616195a6312e1bb65e5155f (patch) | |
| tree | 6dce3fafc3794fd3cd1f13bd0cc04bfb84989e24 /src/class/cdc | |
| parent | beea882c6bcee352b5ff69446aef9fc43237bab0 (diff) | |
| parent | 66c84528f67c0eedc23d25221500d820e702d93f (diff) | |
Merge branch 'master' into fork/HiFiPhile/dwc2_iso_incomp
Diffstat (limited to 'src/class/cdc')
| -rw-r--r-- | src/class/cdc/cdc.h | 22 | ||||
| -rw-r--r-- | src/class/cdc/cdc_device.c | 395 | ||||
| -rw-r--r-- | src/class/cdc/cdc_device.h | 15 | ||||
| -rw-r--r-- | src/class/cdc/cdc_host.c | 136 | ||||
| -rw-r--r-- | src/class/cdc/cdc_host.h | 6 | ||||
| -rw-r--r-- | src/class/cdc/cdc_rndis.h | 6 | ||||
| -rw-r--r-- | src/class/cdc/cdc_rndis_host.h | 6 | ||||
| -rw-r--r-- | src/class/cdc/serial/ftdi_sio.h | 13 |
8 files changed, 267 insertions, 332 deletions
diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index 10ba16a7c..679723ba6 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -29,8 +29,8 @@ * Currently only Abstract Control Model subclass is supported * @{ */ -#ifndef _TUSB_CDC_H__ -#define _TUSB_CDC_H__ +#ifndef TUSB_CDC_H__ +#define TUSB_CDC_H__ #include "common/tusb_common.h" @@ -192,10 +192,10 @@ typedef enum { CDC_LINE_CODING_STOP_BITS_2 = 2, // 2 bits } cdc_line_coding_stopbits_t; -#define CDC_LINE_CODING_STOP_BITS_TEXT(STOP_BITS) ( \ - STOP_BITS == CDC_LINE_CODING_STOP_BITS_1 ? "1" : \ - STOP_BITS == CDC_LINE_CODING_STOP_BITS_1_5 ? "1.5" : \ - STOP_BITS == CDC_LINE_CODING_STOP_BITS_2 ? "2" : "?" ) +#define CDC_LINE_CODING_STOP_BITS_TEXT(STOP_BITS) ( \ + (STOP_BITS) == CDC_LINE_CODING_STOP_BITS_1 ? "1" : \ + (STOP_BITS) == CDC_LINE_CODING_STOP_BITS_1_5 ? "1.5" : \ + (STOP_BITS) == CDC_LINE_CODING_STOP_BITS_2 ? "2" : "?" ) // TODO Backward compatible for typos. Maybe removed in the future release #define CDC_LINE_CONDING_STOP_BITS_1 CDC_LINE_CODING_STOP_BITS_1 @@ -211,11 +211,11 @@ typedef enum { } cdc_line_coding_parity_t; #define CDC_LINE_CODING_PARITY_CHAR(PARITY) ( \ - PARITY == CDC_LINE_CODING_PARITY_NONE ? 'N' : \ - PARITY == CDC_LINE_CODING_PARITY_ODD ? 'O' : \ - PARITY == CDC_LINE_CODING_PARITY_EVEN ? 'E' : \ - PARITY == CDC_LINE_CODING_PARITY_MARK ? 'M' : \ - PARITY == CDC_LINE_CODING_PARITY_SPACE ? 'S' : '?' ) + (PARITY) == CDC_LINE_CODING_PARITY_NONE ? 'N' : \ + (PARITY) == CDC_LINE_CODING_PARITY_ODD ? 'O' : \ + (PARITY) == CDC_LINE_CODING_PARITY_EVEN ? 'E' : \ + (PARITY) == CDC_LINE_CODING_PARITY_MARK ? 'M' : \ + (PARITY) == CDC_LINE_CODING_PARITY_SPACE ? 'S' : '?' ) //--------------------------------------------------------------------+ // Management Element Notification (Notification Endpoint) diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index f1c4a3bbf..babb89952 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -48,28 +48,23 @@ typedef struct { uint8_t rhport; uint8_t itf_num; - uint8_t ep_in; - uint8_t ep_out; - uint8_t ep_notify; uint8_t line_state; // Bit 0: DTR, Bit 1: RTS /*------------- From this point, data is not cleared by bus reset -------------*/ - char wanted_char; TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; + char wanted_char; - // FIFO - tu_fifo_t rx_ff; - tu_fifo_t tx_ff; - - uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE]; - uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE]; + struct { + tu_edpt_stream_t tx; + tu_edpt_stream_t rx; - OSAL_MUTEX_DEF(rx_ff_mutex); - OSAL_MUTEX_DEF(tx_ff_mutex); + uint8_t tx_ff_buf[CFG_TUD_CDC_TX_BUFSIZE]; + uint8_t rx_ff_buf[CFG_TUD_CDC_RX_BUFSIZE]; + } stream; } cdcd_interface_t; -#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char) +#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) typedef struct { TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE); @@ -81,110 +76,100 @@ typedef struct { } cdcd_epbuf_t; //--------------------------------------------------------------------+ -// INTERNAL OBJECT & FUNCTION DECLARATION -//--------------------------------------------------------------------+ -static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; -CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; - -static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT(); - -static bool _prep_out_transaction(uint8_t itf) { - const uint8_t rhport = 0; - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; - - // Skip if usb is not ready yet - TU_VERIFY(tud_ready() && p_cdc->ep_out); - - uint16_t available = tu_fifo_remaining(&p_cdc->rx_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 >= CFG_TUD_CDC_EP_BUFSIZE); - - // claim endpoint - TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_out)); - - // fifo can be changed before endpoint is claimed - available = tu_fifo_remaining(&p_cdc->rx_ff); - - if (available >= CFG_TUD_CDC_EP_BUFSIZE) { - return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_epbuf->epout, CFG_TUD_CDC_EP_BUFSIZE); - } else { - // Release endpoint since we don't make any transfer - usbd_edpt_release(p_cdc->rhport, p_cdc->ep_out); - return false; - } -} - -//--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf) { - (void) itf; + (void)itf; } TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { - (void) itf; - (void) wanted_char; + (void)itf; + (void)wanted_char; } TU_ATTR_WEAK void tud_cdc_tx_complete_cb(uint8_t itf) { - (void) itf; + (void)itf; } TU_ATTR_WEAK void tud_cdc_notify_complete_cb(uint8_t itf) { - (void) itf; + (void)itf; } TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { - (void) itf; - (void) dtr; - (void) rts; + (void)itf; + (void)dtr; + (void)rts; } -TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding) { - (void) itf; - (void) p_line_coding; +TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, const cdc_line_coding_t *p_line_coding) { + (void)itf; + (void)p_line_coding; } TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) { - (void) itf; - (void) duration_ms; + (void)itf; + (void)duration_ms; +} + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; +CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; +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 || + (ep_addr == p_cdc->ep_notify && ep_addr != 0)) { + return idx; + } + } + return TUSB_INDEX_INVALID_8; } //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg) { - TU_VERIFY(driver_cfg); + TU_VERIFY(driver_cfg != NULL); _cdcd_cfg = *driver_cfg; return true; } bool tud_cdc_n_ready(uint8_t itf) { - return tud_ready() && _cdcd_itf[itf].ep_in != 0 && _cdcd_itf[itf].ep_out != 0; + TU_VERIFY(itf < CFG_TUD_CDC); + 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); + return in_opened && out_opened; } bool tud_cdc_n_connected(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_CDC); + TU_VERIFY(tud_ready()); // DTR (bit 0) active is considered as connected - return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0); + return tu_bit_test(_cdcd_itf[itf].line_state, 0); } uint8_t tud_cdc_n_get_line_state(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_CDC, 0); return _cdcd_itf[itf].line_state; } -void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding) { +void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t *coding) { + TU_VERIFY(itf < CFG_TUD_CDC, ); (*coding) = _cdcd_itf[itf].line_coding; } #if CFG_TUD_CDC_NOTIFY bool tud_cdc_n_notify_uart_state (uint8_t itf, const cdc_notify_uart_state_t *state) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; + TU_VERIFY(itf < CFG_TUD_CDC); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[itf]; TU_VERIFY(tud_ready() && p_cdc->ep_notify != 0); TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_notify)); @@ -200,8 +185,9 @@ bool tud_cdc_n_notify_uart_state (uint8_t itf, const cdc_notify_uart_state_t *st } bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed_change_t* conn_speed_change) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; + TU_VERIFY(itf < CFG_TUD_CDC); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[itf]; TU_VERIFY(tud_ready() && p_cdc->ep_notify != 0); TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_notify)); @@ -218,6 +204,7 @@ bool tud_cdc_n_notify_conn_speed_change(uint8_t itf, const cdc_notify_conn_speed #endif void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { + TU_VERIFY(itf < CFG_TUD_CDC, ); _cdcd_itf[itf].wanted_char = wanted; } @@ -225,77 +212,53 @@ void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { // READ API //--------------------------------------------------------------------+ uint32_t tud_cdc_n_available(uint8_t itf) { - return tu_fifo_count(&_cdcd_itf[itf].rx_ff); + TU_VERIFY(itf < CFG_TUD_CDC, 0); + return tu_edpt_stream_read_available(&_cdcd_itf[itf].stream.rx); } uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(itf); - return num_read; + 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); } -bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { - return tu_fifo_peek(&_cdcd_itf[itf].rx_ff, chr); +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); } void tud_cdc_n_read_flush(uint8_t itf) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - tu_fifo_clear(&p_cdc->rx_ff); - _prep_out_transaction(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); } //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - uint16_t wr_count = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - - // flush if queue more than packet size - if (tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE - #if CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE - || tu_fifo_full(&p_cdc->tx_ff) // check full if fifo size is less than packet size - #endif - ) { - tud_cdc_n_write_flush(itf); - } - - return wr_count; + 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); } uint32_t tud_cdc_n_write_flush(uint8_t itf) { - cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; - TU_VERIFY(tud_ready(), 0); // Skip if usb is not ready yet - - // No data to send - if (!tu_fifo_count(&p_cdc->tx_ff)) { - return 0; - } - - TU_VERIFY(usbd_edpt_claim(p_cdc->rhport, p_cdc->ep_in), 0); // Claim the endpoint - - // Pull data from FIFO - const uint16_t count = tu_fifo_read_n(&p_cdc->tx_ff, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE); - - if (count) { - TU_ASSERT(usbd_edpt_xfer(p_cdc->rhport, p_cdc->ep_in, p_epbuf->epin, count), 0); - return count; - } else { - // Release endpoint since we don't make any transfer - // Note: data is dropped if terminal is not connected - usbd_edpt_release(p_cdc->rhport, p_cdc->ep_in); - return 0; - } + 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); } uint32_t tud_cdc_n_write_available(uint8_t itf) { - return tu_fifo_remaining(&_cdcd_itf[itf].tx_ff); + 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); } bool tud_cdc_n_write_clear(uint8_t itf) { - return tu_fifo_clear(&_cdcd_itf[itf].tx_ff); + TU_VERIFY(itf < CFG_TUD_CDC); + cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; + return tu_edpt_stream_clear(&p_cdc->stream.tx); } //--------------------------------------------------------------------+ @@ -304,7 +267,8 @@ bool tud_cdc_n_write_clear(uint8_t itf) { void cdcd_init(void) { tu_memclr(_cdcd_itf, sizeof(_cdcd_itf)); for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { - cdcd_interface_t* p_cdc = &_cdcd_itf[i]; + cdcd_interface_t *p_cdc = &_cdcd_itf[i]; + cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[i]; p_cdc->wanted_char = (char) -1; @@ -314,44 +278,23 @@ void cdcd_init(void) { p_cdc->line_coding.parity = 0; p_cdc->line_coding.data_bits = 8; - // Config RX fifo - tu_fifo_config(&p_cdc->rx_ff, p_cdc->rx_ff_buf, TU_ARRAY_SIZE(p_cdc->rx_ff_buf), 1, false); + tu_edpt_stream_init(&p_cdc->stream.rx, false, false, false, p_cdc->stream.rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, + p_epbuf->epout, 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_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, _cdcd_cfg.tx_overwritabe_if_not_connected); - - #if OSAL_MUTEX_REQUIRED - osal_mutex_t mutex_rd = osal_mutex_create(&p_cdc->rx_ff_mutex); - osal_mutex_t mutex_wr = osal_mutex_create(&p_cdc->tx_ff_mutex); - TU_ASSERT(mutex_rd != NULL && mutex_wr != NULL, ); - - tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, mutex_rd); - tu_fifo_config_mutex(&p_cdc->tx_ff, mutex_wr, NULL); - #endif + 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, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE); } } bool cdcd_deinit(void) { - #if OSAL_MUTEX_REQUIRED - for(uint8_t i=0; i<CFG_TUD_CDC; i++) { + for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { cdcd_interface_t* p_cdc = &_cdcd_itf[i]; - osal_mutex_t mutex_rd = p_cdc->rx_ff.mutex_rd; - osal_mutex_t mutex_wr = p_cdc->tx_ff.mutex_wr; - - if (mutex_rd) { - osal_mutex_delete(mutex_rd); - tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, NULL); - } - - if (mutex_wr) { - osal_mutex_delete(mutex_wr); - tu_fifo_config_mutex(&p_cdc->tx_ff, NULL, NULL); - } + tu_edpt_stream_deinit(&p_cdc->stream.rx); + tu_edpt_stream_deinit(&p_cdc->stream.tx); } - #endif - return true; } @@ -360,74 +303,85 @@ void cdcd_reset(uint8_t rhport) { for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { cdcd_interface_t* p_cdc = &_cdcd_itf[i]; - tu_memclr(p_cdc, ITF_MEM_RESET_SIZE); - if (!_cdcd_cfg.rx_persistent) { - tu_fifo_clear(&p_cdc->rx_ff); - } - if (!_cdcd_cfg.tx_persistent) { - tu_fifo_clear(&p_cdc->tx_ff); - } - tu_fifo_set_overwritable(&p_cdc->tx_ff, _cdcd_cfg.tx_overwritabe_if_not_connected); + + 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); } } uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16_t max_len) { // Only support ACM subclass - TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && - CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0); + TU_VERIFY(TUSB_CLASS_CDC == itf_desc->bInterfaceClass && + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, + 0); - // Find available interface - cdcd_interface_t* p_cdc; - uint8_t cdc_id; - for (cdc_id = 0; cdc_id < CFG_TUD_CDC; cdc_id++) { - p_cdc = &_cdcd_itf[cdc_id]; - if (p_cdc->ep_in == 0) { - break; - } - } + const uint8_t cdc_id = find_cdc_itf(0); // Find available interface TU_ASSERT(cdc_id < CFG_TUD_CDC, 0); + cdcd_interface_t *p_cdc = &_cdcd_itf[cdc_id]; //------------- Control Interface -------------// p_cdc->rhport = rhport; p_cdc->itf_num = itf_desc->bInterfaceNumber; - uint16_t drv_len = sizeof(tusb_desc_interface_t); - const uint8_t* p_desc = tu_desc_next(itf_desc); + const uint8_t *p_desc = (const uint8_t *)itf_desc; + const uint8_t *desc_end = p_desc + max_len; - // Communication Functional Descriptors - while (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len) { - drv_len += tu_desc_len(p_desc); + // Skip all class-specific descriptor + p_desc = tu_desc_next(itf_desc); + while (tu_desc_in_bounds(p_desc, desc_end) && TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) { p_desc = tu_desc_next(p_desc); } + // notification endpoint (optional) if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { - // notification endpoint const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); p_cdc->ep_notify = desc_ep->bEndpointAddress; - drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } - //------------- Data Interface (if any) -------------// - if ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && - (TUSB_CLASS_CDC_DATA == ((const tusb_desc_interface_t*) p_desc)->bInterfaceClass)) { - // next to endpoint descriptor - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + //------------- Data Interface (optional) -------------// + if (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) { + const tusb_desc_interface_t *data_itf_desc = (const tusb_desc_interface_t *)p_desc; + if (TUSB_CLASS_CDC_DATA == data_itf_desc->bInterfaceClass) { + for (uint8_t e = 0; e < data_itf_desc->bNumEndpoints; e++) { + if (!tu_desc_in_bounds(p_desc, desc_end)) { + break; + } + p_desc = tu_desc_next(p_desc); - // Open endpoint pair - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in), 0); + const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc; + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer, 0); - drv_len += 2 * sizeof(tusb_desc_endpoint_t); - } + 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; - // Prepare for incoming data - _prep_out_transaction(cdc_id); + tu_edpt_stream_open(stream_tx, desc_ep); + if (_cdcd_cfg.tx_persistent) { + tu_edpt_stream_write_xfer(rhport, stream_tx); // flush pending data + } else { + tu_edpt_stream_clear(stream_tx); + } + } else { + tu_edpt_stream_t *stream_rx = &p_cdc->stream.rx; - return drv_len; + tu_edpt_stream_open(stream_rx, 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 + } + } + + p_desc = tu_desc_next(p_desc); + } + } + + return (uint16_t)(p_desc - (const uint8_t *)itf_desc); } // Invoked when a control transfer occurred on an interface of this class @@ -456,6 +410,8 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); } else if (stage == CONTROL_STAGE_ACK) { tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); + } else { + // nothing to do } break; @@ -482,15 +438,15 @@ 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->tx_ff, !dtr); + tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, !dtr); } else { - tu_fifo_set_overwritable(&p_cdc->tx_ff, false); + tu_fifo_set_overwritable(&p_cdc->stream.tx.ff, false); } TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); - - // Invoke callback - tud_cdc_line_state_cb(itf, dtr, rts); + tud_cdc_line_state_cb(itf, dtr, rts); // invoke callback + } else { + // nothing to do } break; @@ -500,6 +456,8 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ } else if (stage == CONTROL_STAGE_ACK) { TU_LOG_DRV(" Send Break\r\n"); tud_cdc_send_break_cb(itf, request->wValue); + } else { + // nothing to do } break; @@ -511,58 +469,45 @@ 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) result; + (void)result; - uint8_t itf; - cdcd_interface_t* p_cdc; - - // Identify which interface to use - for (itf = 0; itf < CFG_TUD_CDC; itf++) { - p_cdc = &_cdcd_itf[itf]; - if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in) || (ep_addr == p_cdc->ep_notify)) { - break; - } - } + uint8_t itf = find_cdc_itf(ep_addr); TU_ASSERT(itf < CFG_TUD_CDC); - cdcd_epbuf_t* p_epbuf = &_cdcd_epbuf[itf]; + 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; - // Received new data - if (ep_addr == p_cdc->ep_out) { - tu_fifo_write_n(&p_cdc->rx_ff, p_epbuf->epout, (uint16_t) xferred_bytes); + // Received new data, move to fifo + if (ep_addr == stream_rx->ep_addr) { + tu_edpt_stream_read_xfer_complete(stream_rx, xferred_bytes); - // Check for wanted char and invoke callback if needed - if (((signed char) p_cdc->wanted_char) != -1) { + // Check for wanted char and invoke wanted callback (multiple times if multiple wanted received) + if (((signed char)p_cdc->wanted_char) != -1) { for (uint32_t i = 0; i < xferred_bytes; i++) { - if ((p_cdc->wanted_char == p_epbuf->epout[i]) && !tu_fifo_empty(&p_cdc->rx_ff)) { + if ((p_cdc->wanted_char == (char)stream_rx->ep_buf[i]) && !tu_edpt_stream_empty(stream_rx)) { tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); } } } - // invoke receive callback (if there is still data) - if (!tu_fifo_empty(&p_cdc->rx_ff)) { + // invoke receive callback if there is still data + if (!tu_edpt_stream_empty(stream_rx)) { tud_cdc_rx_cb(itf); } - // prepare for OUT transaction - _prep_out_transaction(itf); + tu_edpt_stream_read_xfer(rhport, stream_rx); // prepare for more data } // Data sent to host, we continue to fetch from tx fifo to send. // Note: This will cause incorrect baudrate set in line coding. // Though maybe the baudrate is not really important !!! - if (ep_addr == p_cdc->ep_in) { + if (ep_addr == stream_tx->ep_addr) { // invoke transmit callback to possibly refill tx fifo tud_cdc_tx_complete_cb(itf); - if (0 == tud_cdc_n_write_flush(itf)) { - // If there is no data left, a ZLP should be sent if - // xferred_bytes is multiple of EP Packet size and not zero - if (!tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE - 1)))) { - if (usbd_edpt_claim(rhport, p_cdc->ep_in)) { - TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0)); - } - } + if (0 == tu_edpt_stream_write_xfer(rhport, 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); } } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 9673b9807..6f21af4f3 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -53,15 +53,16 @@ // Driver Configuration //--------------------------------------------------------------------+ typedef struct TU_ATTR_PACKED { - uint8_t rx_persistent : 1; // keep rx fifo data even with bus reset or disconnect - uint8_t tx_persistent : 1; // keep tx fifo data even with reset or disconnect - uint8_t tx_overwritabe_if_not_connected : 1; // if not connected, tx fifo can be overwritten + bool rx_persistent : 1; // keep rx fifo data even with bus reset or disconnect + bool tx_persistent : 1; // keep tx fifo data even with reset or disconnect + bool tx_overwritabe_if_not_connected : 1; // if not connected, tx fifo can be overwritten } tud_cdc_configure_t; +TU_VERIFY_STATIC(sizeof(tud_cdc_configure_t) == 1, "size is not correct"); #define TUD_CDC_CONFIGURE_DEFAULT() { \ - .rx_persistent = 0, \ - .tx_persistent = 0, \ - .tx_overwritabe_if_not_connected = 1, \ + .rx_persistent = false, \ + .tx_persistent = false, \ + .tx_overwritabe_if_not_connected = true, \ } // Configure CDC driver behavior @@ -257,4 +258,4 @@ bool cdcd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t re } #endif -#endif /* _TUSB_CDC_DEVICE_H_ */ +#endif /* TUSB_CDC_DEVICE_H_ */ diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index beef03eff..35717ddf6 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -298,6 +298,7 @@ TU_VERIFY_STATIC(TU_ARRAY_SIZE(serial_drivers) == SERIAL_DRIVER_COUNT, "Serial d //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ +static bool open_ep_stream_pair(cdch_interface_t *p_cdc, const tusb_desc_endpoint_t *desc_ep); TU_ATTR_ALWAYS_INLINE static inline cdch_interface_t * get_itf(uint8_t idx) { TU_ASSERT(idx < CFG_TUH_CDC, NULL); @@ -364,7 +365,7 @@ static cdch_interface_t* get_itf_by_xfer(const tuh_xfer_t * xfer) { #endif default: - break; + break; // unknown driver } } } @@ -389,8 +390,6 @@ static cdch_interface_t * make_new_itf(uint8_t daddr, tusb_desc_interface_t cons return NULL; } -static bool open_ep_stream_pair(cdch_interface_t * p_cdc , tusb_desc_endpoint_t const *desc_ep); - //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ @@ -519,7 +518,7 @@ bool tuh_cdc_read_clear (uint8_t idx) { TU_VERIFY(p_cdc); bool ret = tu_edpt_stream_clear(&p_cdc->stream.rx); - tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); + (void)tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); return ret; } @@ -602,7 +601,7 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const *line_coding, p_cdc->requested_line.coding = *line_coding; p_cdc->user_complete_cb = complete_cb; - if (driver->set_line_coding) { + if (driver->set_line_coding != NULL) { // driver support set_line_coding request TU_VERIFY(driver->set_line_coding(p_cdc, complete_cb ? cdch_internal_control_complete : NULL, user_data)); @@ -611,7 +610,7 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const *line_coding, } } else { // driver does not support set_line_coding and need 2 stage to set baudrate and data format separately - if (complete_cb) { + if (complete_cb != NULL) { // non-blocking TU_VERIFY(driver->set_baudrate(p_cdc, cdch_set_line_coding_stage1_baudrate_complete, user_data)); } else { @@ -619,7 +618,7 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const *line_coding, xfer_result_t result = XFER_RESULT_INVALID; TU_VERIFY(driver->set_baudrate(p_cdc, NULL, (uintptr_t) &result)); - if (user_data) { + if (user_data != 0) { *((xfer_result_t *) user_data) = result; } TU_VERIFY(result == XFER_RESULT_SUCCESS); @@ -627,7 +626,7 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const *line_coding, result = XFER_RESULT_INVALID; TU_VERIFY(driver->set_data_format(p_cdc, NULL, (uintptr_t) &result)); - if (user_data) { + if (user_data != 0) { *((xfer_result_t *) user_data) = result; } TU_VERIFY(result == XFER_RESULT_SUCCESS); @@ -648,13 +647,10 @@ bool cdch_init(void) { for (size_t i = 0; i < CFG_TUH_CDC; i++) { cdch_interface_t *p_cdc = &cdch_data[i]; cdch_epbuf_t *epbuf = &cdch_epbuf[i]; - tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, - p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, - epbuf->tx, CFG_TUH_CDC_TX_EPSIZE); - - tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, - p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, - epbuf->rx, CFG_TUH_CDC_RX_EPSIZE); + TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, + epbuf->tx, CFG_TUH_CDC_TX_EPSIZE)); + TU_ASSERT(tu_edpt_stream_init(&p_cdc->stream.rx, true, false, false, p_cdc->stream.rx_ff_buf, + CFG_TUH_CDC_RX_BUFSIZE, epbuf->rx, CFG_TUH_CDC_RX_EPSIZE)); } return true; @@ -663,8 +659,8 @@ bool cdch_init(void) { bool cdch_deinit(void) { for (size_t i = 0; i < CFG_TUH_CDC; i++) { cdch_interface_t *p_cdc = &cdch_data[i]; - tu_edpt_stream_deinit(&p_cdc->stream.tx); - tu_edpt_stream_deinit(&p_cdc->stream.rx); + (void)tu_edpt_stream_deinit(&p_cdc->stream.tx); + (void)tu_edpt_stream_deinit(&p_cdc->stream.rx); } return true; } @@ -674,11 +670,9 @@ void cdch_close(uint8_t daddr) { cdch_interface_t *p_cdc = &cdch_data[idx]; if (p_cdc->daddr == daddr) { TU_LOG_CDC(p_cdc, "close"); + tuh_cdc_umount_cb(idx); // invoke callback - // Invoke application callback - tuh_cdc_umount_cb(idx); - - p_cdc->daddr = 0; + p_cdc->daddr = 0; p_cdc->bInterfaceNumber = 0; p_cdc->mounted = false; tu_edpt_stream_close(&p_cdc->stream.tx); @@ -696,13 +690,12 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t TU_ASSERT(p_cdc); if (ep_addr == p_cdc->stream.tx.ep_addr) { - // invoke tx complete callback to possibly refill tx fifo - tuh_cdc_tx_complete_cb(idx); + tuh_cdc_tx_complete_cb(idx); // invoke transmit complete callback if (0 == tu_edpt_stream_write_xfer(daddr, &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 - tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes); + (void)tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes); } } else if (ep_addr == p_cdc->stream.rx.ep_addr) { #if CFG_TUH_CDC_FTDI @@ -718,7 +711,6 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t #endif { tu_edpt_stream_read_xfer_complete(&p_cdc->stream.rx, xferred_bytes); - tuh_cdc_rx_cb(idx); // invoke receive callback } @@ -727,7 +719,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t } else if (ep_addr == p_cdc->ep_notif) { // TODO handle notification endpoint } else { - TU_ASSERT(false); + return false; } return true; @@ -736,20 +728,17 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t //--------------------------------------------------------------------+ // Enumeration //--------------------------------------------------------------------+ - 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(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); + tu_edpt_stream_clear(stream); - if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_cdc->stream.rx, desc_ep); - } else { - tu_edpt_stream_open(&p_cdc->stream.tx, desc_ep); - } - - desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(desc_ep); + desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_ep); } return true; @@ -777,6 +766,8 @@ bool cdch_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const *itf_d } } } + } else { + // not supported class } return false; @@ -830,6 +821,7 @@ static void cdch_process_set_config(tuh_xfer_t *xfer) { } } +// return false if there is no active transfer static bool set_line_state_on_enum(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) { enum { ENUM_SET_LINE_CODING = 0, @@ -894,7 +886,7 @@ static void cdch_internal_control_complete(tuh_xfer_t *xfer) { // Invoke application callback xfer->complete_cb = p_cdc->user_complete_cb; - if (xfer->complete_cb) { + if (xfer->complete_cb != NULL) { xfer->complete_cb(xfer); } } @@ -910,7 +902,7 @@ static void cdch_set_line_coding_stage1_baudrate_complete(tuh_xfer_t *xfer) { TU_ASSERT(driver->set_data_format(p_cdc, cdch_set_line_coding_stage2_data_format_complete, xfer->user_data),); } else { xfer->complete_cb = p_cdc->user_complete_cb; - if (xfer->complete_cb) { + if (xfer->complete_cb != NULL) { xfer->complete_cb(xfer); } } @@ -926,7 +918,7 @@ static void cdch_set_line_coding_stage2_data_format_complete(tuh_xfer_t *xfer) { } xfer->complete_cb = p_cdc->user_complete_cb; - if (xfer->complete_cb) { + if (xfer->complete_cb != NULL) { xfer->complete_cb(xfer); } } @@ -950,12 +942,12 @@ static void acm_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t *x break; default: - break; + break; // unknown request } } static bool acm_set_control_line_state(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - TU_VERIFY(p_cdc->acm.capability.support_line_request); + TU_VERIFY(p_cdc->acm.capability.support_line_request != 0); const tusb_control_request_t request = { .bmRequestType_bit = { @@ -982,7 +974,7 @@ static bool acm_set_control_line_state(cdch_interface_t *p_cdc, tuh_xfer_cb_t co } static bool acm_set_line_coding(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - TU_VERIFY(p_cdc->acm.capability.support_line_request); + TU_VERIFY(p_cdc->acm.capability.support_line_request != 0); TU_VERIFY((p_cdc->requested_line.coding.data_bits >= 5 && p_cdc->requested_line.coding.data_bits <= 8) || p_cdc->requested_line.coding.data_bits == 16); @@ -1136,7 +1128,6 @@ static inline bool ftdi_sio_reset(cdch_interface_t *p_cdc, tuh_xfer_cb_t complet // internal control complete to update state such as line state, line_coding static void ftdi_internal_control_complete(cdch_interface_t* p_cdc, tuh_xfer_t *xfer) { - TU_VERIFY(xfer->result == XFER_RESULT_SUCCESS,); const tusb_control_request_t * setup = xfer->setup; if (xfer->result == XFER_RESULT_SUCCESS) { if (setup->bRequest == FTDI_SIO_SET_MODEM_CTRL_REQUEST && @@ -1168,10 +1159,10 @@ static bool ftdi_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete static bool ftdi_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint32_t index_value = ftdi_get_divisor(p_cdc); - TU_VERIFY(index_value); + TU_VERIFY(index_value != 0); uint16_t value = (uint16_t) index_value; uint16_t index = (uint16_t) (index_value >> 16); - if (p_cdc->ftdi.channel) { + if (p_cdc->ftdi.channel != 0) { index = (uint16_t) ((index << 8) | p_cdc->ftdi.channel); } @@ -1365,7 +1356,7 @@ static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) { uint8_t divfrac[8] = {0, 3, 2, 4, 1, 5, 6, 7}; uint32_t divisor; /* divisor shifted 3 bits to the left */ - uint32_t divisor3 = DIV_ROUND_CLOSEST(base, 2 * baud); + uint32_t divisor3 = tu_div_round_nearest(base, 2 * baud); divisor = divisor3 >> 3; divisor |= (uint32_t) divfrac[divisor3 & 0x7] << 14; /* Deal with special cases for highest baud rates. */ @@ -1373,6 +1364,8 @@ static uint32_t ftdi_232bm_baud_base_to_divisor(uint32_t baud, uint32_t base) { divisor = 0; } else if (divisor == 0x4001) /* 1.5 */ { divisor = 1; + } else { + // nothing to do } return divisor; } @@ -1387,7 +1380,7 @@ static uint32_t ftdi_2232h_baud_base_to_divisor(uint32_t baud, uint32_t base) { uint32_t divisor3; /* hi-speed baud rate is 10-bit sampling instead of 16-bit */ - divisor3 = DIV_ROUND_CLOSEST(8 * base, 10 * baud); + divisor3 = tu_div_round_nearest(8 * base, 10 * baud); divisor = divisor3 >> 3; divisor |= (uint32_t) divfrac[divisor3 & 0x7] << 14; @@ -1396,12 +1389,13 @@ static uint32_t ftdi_2232h_baud_base_to_divisor(uint32_t baud, uint32_t base) { divisor = 0; } else if (divisor == 0x4001) /* 1.5 */ { divisor = 1; + } else { + // nothing to do } - /* - * Set this bit to turn off a divide by 2.5 on baud rate generator + + /* Set this bit to turn off a divide by 2.5 on baud rate generator * This enables baud rates up to 12Mbaud but cannot reach below 1200 - * baud with this bit set - */ + * baud with this bit set */ divisor |= 0x00020000; return divisor; } @@ -1413,7 +1407,7 @@ static inline uint32_t ftdi_2232h_baud_to_divisor(uint32_t baud) { static inline uint32_t ftdi_get_divisor(cdch_interface_t *p_cdc) { uint32_t baud = p_cdc->requested_line.coding.bit_rate; uint32_t div_value = 0; - TU_VERIFY(baud); + TU_VERIFY(baud != 0); switch (p_cdc->ftdi.chip_type) { case FTDI_UNKNOWN: @@ -1553,7 +1547,8 @@ static void cp210x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t p_cdc->line.coding.bit_rate = p_cdc->requested_line.coding.bit_rate; break; - default: break; + default: + break; // unsupported request } } @@ -1714,7 +1709,8 @@ static void ch34x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t p_cdc->line.coding.data_bits = p_cdc->requested_line.coding.data_bits; break; - default: break; + default: + break; // unsupported } break; @@ -1722,19 +1718,20 @@ static void ch34x_internal_control_complete(cdch_interface_t *p_cdc, tuh_xfer_t p_cdc->line.control_state = p_cdc->requested_line.control_state; break; - default: break; + default: + break; // unsupported request } } static bool ch34x_set_data_format(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { const uint8_t lcr = ch34x_get_lcr(p_cdc); - TU_VERIFY(lcr); + TU_VERIFY(lcr > 0); return ch34x_write_reg(p_cdc, CH32X_REG16_LCR2_LCR, lcr, complete_cb, user_data); } static bool ch34x_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { const uint16_t div_ps = ch34x_get_divisor_prescaler(p_cdc); - TU_VERIFY(div_ps); + TU_VERIFY(div_ps > 0); return ch34x_write_reg(p_cdc, CH34X_REG16_DIVISOR_PRESCALER, div_ps, complete_cb, user_data); } @@ -1917,7 +1914,8 @@ static uint8_t ch34x_get_lcr(cdch_interface_t *p_cdc) { lcr |= CH34X_LCR_ENABLE_PAR | CH34X_LCR_MARK_SPACE | CH34X_LCR_PAR_EVEN; break; - default: break; + default: + break; // invalid parity } // 1.5 stop bits not supported @@ -2000,13 +1998,15 @@ static inline bool pl2303_supports_hx_status(cdch_interface_t *p_cdc, tuh_xfer_c // return pl2303_set_request(p_cdc, PL2303_BREAK_REQUEST, PL2303_BREAK_REQUEST_TYPE, state, 0, NULL, 0); //} -static inline int pl2303_clear_halt(cdch_interface_t *p_cdc, uint8_t endp, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { +static inline bool +pl2303_clear_halt(cdch_interface_t *p_cdc, uint8_t endp, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { /* we don't care if it wasn't halted first. in fact some devices * (like some ibmcam model 1 units) seem to expect hosts to make * this request for iso endpoints, which can't halt! */ - return pl2303_set_request(p_cdc, TUSB_REQ_CLEAR_FEATURE, PL2303_CLEAR_HALT_REQUEST_TYPE, TUSB_REQ_FEATURE_EDPT_HALT, endp, - NULL, 0, complete_cb, user_data); + return pl2303_set_request( + p_cdc, TUSB_REQ_CLEAR_FEATURE, PL2303_CLEAR_HALT_REQUEST_TYPE, TUSB_REQ_FEATURE_EDPT_HALT, endp, NULL, 0, + complete_cb, user_data); } //------------- Driver API -------------// @@ -2131,10 +2131,9 @@ static bool pl2303_process_set_config(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) if (type == PL2303_TYPE_NEED_SUPPORTS_HX_STATUS) { TU_ASSERT(pl2303_supports_hx_status(p_cdc, cdch_process_set_config, CONFIG_PL2303_READ1)); break; - } else { - // no transfer triggered and continue with CONFIG_PL2303_READ1 - TU_ATTR_FALLTHROUGH; } + // no transfer triggered and continue with CONFIG_PL2303_READ1 + TU_ATTR_FALLTHROUGH; case CONFIG_PL2303_READ1: // get supports_hx_status, type and quirks (step 2), do special read @@ -2379,10 +2378,12 @@ static pl2303_type_t pl2303_detect_type(cdch_interface_t *p_cdc, uint8_t step) { return PL2303_TYPE_HXN; default: - break; + break; // unknown device } break; - default: break; + + default: + break; // unknown device } TU_LOG_CDC(p_cdc, "unknown device type bcdUSB = 0x%04x", desc_dev.bcdUSB); @@ -2444,8 +2445,9 @@ static uint32_t pl2303_encode_baud_rate_divisor(uint8_t buf[PL2303_LINE_CODING_B */ baseline = 12000000 * 32; mantissa = baseline / baud; - if (mantissa == 0) + if (mantissa == 0) { mantissa = 1; /* Avoid dividing by zero if baud > 32 * 12M. */ + } exponent = 0; while (mantissa >= 512) { if (exponent < 7) { @@ -2517,7 +2519,7 @@ static bool pl2303_encode_baud_rate(cdch_interface_t *p_cdc, uint8_t buf[PL2303_ * Use direct method for supported baud rates, otherwise use divisors. * Newer chip types do not support divisor encoding. */ - if (type_data->no_divisors) { + if (type_data->no_divisors != 0) { baud_sup = baud; } else { baud_sup = pl2303_get_supported_baud_rate(baud); @@ -2525,7 +2527,7 @@ static bool pl2303_encode_baud_rate(cdch_interface_t *p_cdc, uint8_t buf[PL2303_ if (baud == baud_sup) { baud = pl2303_encode_baud_rate_direct(buf, baud); - } else if (type_data->alt_divisors) { + } else if (type_data->alt_divisors != 0) { baud = pl2303_encode_baud_rate_divisor_alt(buf, baud); } else { baud = pl2303_encode_baud_rate_divisor(buf, baud); diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index bf6711d7e..e8637beac 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_CDC_HOST_H_ -#define _TUSB_CDC_HOST_H_ +#ifndef TUSB_CDC_HOST_H_ +#define TUSB_CDC_HOST_H_ #include "cdc.h" @@ -255,4 +255,4 @@ void cdch_close (uint8_t dev_addr); } #endif -#endif /* _TUSB_CDC_HOST_H_ */ +#endif /* TUSB_CDC_HOST_H_ */ diff --git a/src/class/cdc/cdc_rndis.h b/src/class/cdc/cdc_rndis.h index ad153e0ac..fbbd43206 100644 --- a/src/class/cdc/cdc_rndis.h +++ b/src/class/cdc/cdc_rndis.h @@ -30,8 +30,8 @@ * \defgroup CDC_RNDIS_Common Common Definitions * @{ */ -#ifndef _TUSB_CDC_RNDIS_H_ -#define _TUSB_CDC_RNDIS_H_ +#ifndef TUSB_CDC_RNDIS_H_ +#define TUSB_CDC_RNDIS_H_ #include "cdc.h" @@ -295,7 +295,7 @@ typedef enum } #endif -#endif /* _TUSB_CDC_RNDIS_H_ */ +#endif /* TUSB_CDC_RNDIS_H_ */ /** @} */ /** @} */ diff --git a/src/class/cdc/cdc_rndis_host.h b/src/class/cdc/cdc_rndis_host.h index bb431ec1f..e70d27f79 100644 --- a/src/class/cdc/cdc_rndis_host.h +++ b/src/class/cdc/cdc_rndis_host.h @@ -28,8 +28,8 @@ * \defgroup CDC_RNSID_Host Host * @{ */ -#ifndef _TUSB_CDC_RNDIS_HOST_H_ -#define _TUSB_CDC_RNDIS_HOST_H_ +#ifndef TUSB_CDC_RNDIS_HOST_H_ +#define TUSB_CDC_RNDIS_HOST_H_ #include "common/tusb_common.h" #include "host/usbh.h" @@ -58,6 +58,6 @@ void rndish_close(uint8_t dev_addr); } #endif -#endif /* _TUSB_CDC_RNDIS_HOST_H_ */ +#endif /* TUSB_CDC_RNDIS_HOST_H_ */ /** @} */ diff --git a/src/class/cdc/serial/ftdi_sio.h b/src/class/cdc/serial/ftdi_sio.h index 8abf74f11..9bd56cef4 100644 --- a/src/class/cdc/serial/ftdi_sio.h +++ b/src/class/cdc/serial/ftdi_sio.h @@ -215,17 +215,4 @@ typedef struct ftdi_private { #define FTDI_NOT_POSSIBLE -1 #define FTDI_REQUESTED -2 -// division and round function overtaken from math.h -#define DIV_ROUND_CLOSEST(x, divisor)( \ -{ \ - typeof(x) __x = x; \ - typeof(divisor) __d = divisor; \ - (((typeof(x))-1) > 0 || \ - ((typeof(divisor))-1) > 0 || \ - (((__x) > 0) == ((__d) > 0))) ? \ - (((__x) + ((__d) / 2)) / (__d)) : \ - (((__x) - ((__d) / 2)) / (__d)); \ -} \ -) - #endif //TUSB_FTDI_SIO_H |
