summaryrefslogtreecommitdiff
path: root/src/class/cdc
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-11-18 09:36:16 +0700
committerhathach <[email protected]>2025-11-18 09:36:16 +0700
commit98f7b0c7ba03fd770616195a6312e1bb65e5155f (patch)
tree6dce3fafc3794fd3cd1f13bd0cc04bfb84989e24 /src/class/cdc
parentbeea882c6bcee352b5ff69446aef9fc43237bab0 (diff)
parent66c84528f67c0eedc23d25221500d820e702d93f (diff)
Merge branch 'master' into fork/HiFiPhile/dwc2_iso_incomp
Diffstat (limited to 'src/class/cdc')
-rw-r--r--src/class/cdc/cdc.h22
-rw-r--r--src/class/cdc/cdc_device.c395
-rw-r--r--src/class/cdc/cdc_device.h15
-rw-r--r--src/class/cdc/cdc_host.c136
-rw-r--r--src/class/cdc/cdc_host.h6
-rw-r--r--src/class/cdc/cdc_rndis.h6
-rw-r--r--src/class/cdc/cdc_rndis_host.h6
-rw-r--r--src/class/cdc/serial/ftdi_sio.h13
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