summaryrefslogtreecommitdiff
path: root/src/class/cdc
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2026-03-12 14:57:29 +0700
committerGitHub <[email protected]>2026-03-12 14:57:29 +0700
commitac61a5b176b44db503d8bcc287a622463b65e48e (patch)
treeffae5c864f88a540b1689763dbd7494b4ad29c8e /src/class/cdc
parentf2450788b13f8424b2f75e33240ed21329a875ad (diff)
parent9e5345e70228153ab4efff6f6666c4e54471a4aa (diff)
Merge pull request #3487 from hathach/zlp-hs-on-fs
fix transfer length when high speed capable device/host working at full speed
Diffstat (limited to 'src/class/cdc')
-rw-r--r--src/class/cdc/cdc_device.c22
-rw-r--r--src/class/cdc/cdc_device.h64
-rw-r--r--src/class/cdc/cdc_host.c8
-rw-r--r--src/class/cdc/cdc_host.h8
4 files changed, 57 insertions, 45 deletions
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c
index e2819ae4b..c7547c92b 100644
--- a/src/class/cdc/cdc_device.c
+++ b/src/class/cdc/cdc_device.c
@@ -63,10 +63,10 @@ typedef struct {
#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding)
// Skip local EP buffer if dedicated hw FIFO is supported
- #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0
+#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0
typedef struct {
- TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE);
- TUD_EPBUF_DEF(epin, CFG_TUD_CDC_EP_BUFSIZE);
+ TUD_EPBUF_DEF(epout, CFG_TUD_CDC_RX_EPSIZE);
+ TUD_EPBUF_DEF(epin, CFG_TUD_CDC_TX_EPSIZE);
#if CFG_TUD_CDC_NOTIFY
TUD_EPBUF_TYPE_DEF(cdc_notify_msg_t, epnotify);
@@ -116,7 +116,7 @@ TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) {
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
-static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT();
+static tud_cdc_configure_t _cdcd_cfg = 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++) {
@@ -267,14 +267,13 @@ void cdcd_init(void) {
uint8_t *epin_buf = _cdcd_epbuf[i].epin;
#endif
- 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);
+ tu_edpt_stream_init(&p_cdc->rx_stream, false, false, false, p_cdc->rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, epout_buf);
// 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->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);
+ CFG_TUD_CDC_TX_BUFSIZE, epin_buf);
}
}
@@ -348,8 +347,7 @@ 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->tx_stream;
-
- tu_edpt_stream_open(stream_tx, rhport, desc_ep);
+ tu_edpt_stream_open(stream_tx, rhport, desc_ep, CFG_TUD_CDC_TX_EPSIZE);
if (_cdcd_cfg.tx_persistent) {
tu_edpt_stream_write_xfer(stream_tx); // flush pending data
} else {
@@ -357,8 +355,8 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16
}
} else {
tu_edpt_stream_t *stream_rx = &p_cdc->rx_stream;
-
- tu_edpt_stream_open(stream_rx, rhport, desc_ep);
+ tu_edpt_stream_open(stream_rx, rhport, desc_ep,
+ CFG_TUD_CDC_RX_NEED_ZLP ? CFG_TUD_CDC_RX_EPSIZE : tu_edpt_packet_size(desc_ep));
if (!_cdcd_cfg.rx_persistent) {
tu_edpt_stream_clear(stream_rx);
}
@@ -513,7 +511,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
}
// 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 !
+ // Note: This will cause incorrect baudrate set in line coding. Though maybe the baudrate is not really important!
if (ep_addr == stream_tx->ep_addr) {
tud_cdc_tx_complete_cb(itf); // invoke callback to possibly refill tx fifo
diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h
index 0809b578f..0348bd2ec 100644
--- a/src/class/cdc/cdc_device.h
+++ b/src/class/cdc/cdc_device.h
@@ -29,6 +29,10 @@
#include "cdc.h"
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
//--------------------------------------------------------------------+
// Class Driver Configuration
//--------------------------------------------------------------------+
@@ -37,41 +41,52 @@
#endif
#ifndef CFG_TUD_CDC_TX_BUFSIZE
- #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
+ #define CFG_TUD_CDC_TX_BUFSIZE TUD_EPSIZE_BULK_MAX
#endif
#ifndef CFG_TUD_CDC_RX_BUFSIZE
- #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
+ #define CFG_TUD_CDC_RX_BUFSIZE TUD_EPSIZE_BULK_MAX
#endif
-#if !defined(CFG_TUD_CDC_EP_BUFSIZE) && defined(CFG_TUD_CDC_EPSIZE)
- #warning CFG_TUD_CDC_EPSIZE is renamed to CFG_TUD_CDC_EP_BUFSIZE, please update to use the new name
- #define CFG_TUD_CDC_EP_BUFSIZE CFG_TUD_CDC_EPSIZE
+// EP_BUFSIZE is separated to RX_EPSIZE and TX_EPSIZE
+#ifndef CFG_TUD_CDC_RX_EPSIZE
+ #ifdef CFG_TUD_CDC_EP_BUFSIZE
+ #define CFG_TUD_CDC_RX_EPSIZE CFG_TUD_CDC_EP_BUFSIZE
+ #else
+ #define CFG_TUD_CDC_RX_EPSIZE TUD_EPSIZE_BULK_MAX
+ #endif
#endif
-#ifndef CFG_TUD_CDC_EP_BUFSIZE
- #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
+#ifndef CFG_TUD_CDC_TX_EPSIZE
+ #ifdef CFG_TUD_CDC_EP_BUFSIZE
+ #define CFG_TUD_CDC_TX_EPSIZE CFG_TUD_CDC_EP_BUFSIZE
+ #else
+ #define CFG_TUD_CDC_TX_EPSIZE TUD_EPSIZE_BULK_MAX
+ #endif
#endif
-#ifdef __cplusplus
- extern "C" {
+// Enable multi-packet RX transfer with ZLP termination for better throughput. Requires host support for ZLP.
+#ifndef CFG_TUD_CDC_RX_NEED_ZLP
+ #define CFG_TUD_CDC_RX_NEED_ZLP 0
+#endif
+
+#ifndef CFG_TUD_CDC_CONFIGURE_DEFAULT
+ #define CFG_TUD_CDC_CONFIGURE_DEFAULT() \
+ { \
+ .rx_persistent = false, \
+ .tx_persistent = false, \
+ .tx_overwritabe_if_not_connected = true, \
+ }
#endif
//--------------------------------------------------------------------+
// Driver Configuration
//--------------------------------------------------------------------+
-typedef struct TU_ATTR_PACKED {
- 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
+typedef struct {
+ bool rx_persistent; // keep rx fifo data even with bus reset or disconnect
+ bool tx_persistent; // keep tx fifo data even with reset or disconnect
+ bool tx_overwritabe_if_not_connected; // 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 = false, \
- .tx_persistent = false, \
- .tx_overwritabe_if_not_connected = true, \
-}
// Configure CDC driver behavior
bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg);
@@ -84,13 +99,13 @@ bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg);
// Application API (Multiple Ports) i.e. CFG_TUD_CDC > 1
//--------------------------------------------------------------------+
-// Check if interface is ready
+// Check if the interface is ready
bool tud_cdc_n_ready(uint8_t itf);
-// Check if terminal is connected to this port
+// Check if the terminal is connected to this port
bool tud_cdc_n_connected(uint8_t itf);
-// Get current line state. Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send)
+// Get the current line state. Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send)
uint8_t tud_cdc_n_get_line_state(uint8_t itf);
// Get current line encoding: bit rate, stop bits parity etc ..
@@ -136,10 +151,9 @@ uint32_t tud_cdc_n_write_flush(uint8_t itf);
// Return the number of bytes (characters) available for writing to TX FIFO buffer in a single n_write operation.
uint32_t tud_cdc_n_write_available(uint8_t itf);
-// Clear the transmit FIFO
+// Clear the TX FIFO
bool tud_cdc_n_write_clear(uint8_t itf);
-
#if CFG_TUD_CDC_NOTIFY
bool tud_cdc_n_notify_msg(uint8_t itf, cdc_notify_msg_t *msg);
diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c
index 8f6dd7200..62c313b83 100644
--- a/src/class/cdc/cdc_host.c
+++ b/src/class/cdc/cdc_host.c
@@ -650,10 +650,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_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.tx, true, true, false, p_cdc->stream.tx_ff_buf,
+ CFG_TUH_CDC_TX_BUFSIZE, epbuf->tx));
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));
+ CFG_TUH_CDC_RX_BUFSIZE, epbuf->rx));
}
return true;
@@ -737,7 +737,7 @@ static bool open_ep_stream_pair(cdch_interface_t *p_cdc, tusb_desc_endpoint_t co
TU_ASSERT(tuh_edpt_open(p_cdc->daddr, 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_open(stream, p_cdc->daddr, desc_ep, tu_edpt_packet_size(desc_ep));
tu_edpt_stream_clear(stream);
desc_ep = (const tusb_desc_endpoint_t *)tu_desc_next(desc_ep);
diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h
index 57919c7ff..1b1709b18 100644
--- a/src/class/cdc/cdc_host.h
+++ b/src/class/cdc/cdc_host.h
@@ -39,22 +39,22 @@ extern "C" {
// 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_MAX
#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_MAX
#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_MAX
#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_MAX
#endif
//--------------------------------------------------------------------+