summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-11-27 18:41:57 +0700
committerhathach <[email protected]>2025-11-27 18:41:57 +0700
commit9a9bf0fd7b5a005fd4701ab6cb5b1728ecc0baa2 (patch)
tree4c67b1edfec639aac4f36b398da38ad267bd0dd7
parentf3dc2186aea9a472fe13ecab06464fbead50f0dd (diff)
change tud_vendor_rx_cb() behavior, buffer and bufsize only available when CFG_TUD_VENDOR_RX_BUFSIZE = 0
update vendor device to omit ep buf when dedicated hwfifo is supported
-rw-r--r--examples/device/webusb_serial/src/main.c15
-rw-r--r--src/class/cdc/cdc_device.c11
-rw-r--r--src/class/vendor/vendor_device.c45
-rw-r--r--src/class/vendor/vendor_device.h9
-rw-r--r--src/common/tusb_types.h5
-rw-r--r--src/tusb.c25
6 files changed, 73 insertions, 37 deletions
diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c
index 4fcddd724..50794bdba 100644
--- a/examples/device/webusb_serial/src/main.c
+++ b/examples/device/webusb_serial/src/main.c
@@ -211,15 +211,16 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
return false;
}
-void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint16_t bufsize) {
+void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint32_t bufsize) {
(void)idx;
+ (void)buffer;
+ (void)bufsize;
-// since we used data without pulling it from RX FIFO, we need to discard number of items used
-#if CFG_TUD_VENDOR_RX_BUFSIZE > 0
- tud_vendor_read_discard(bufsize);
-#endif
-
- echo_all(buffer, bufsize);
+ while (tud_vendor_available()) {
+ uint8_t buf[64];
+ const uint32_t count = tud_vendor_read(buf, sizeof(buf));
+ echo_all(buf, count);
+ }
}
//--------------------------------------------------------------------+
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c
index 7ef8aa738..d7792afe4 100644
--- a/src/class/cdc/cdc_device.c
+++ b/src/class/cdc/cdc_device.c
@@ -266,9 +266,8 @@ void cdcd_init(void) {
uint8_t *epout_buf = NULL;
uint8_t *epin_buf = NULL;
#else
- cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[i];
- uint8_t *epout_buf = p_epbuf->epout;
- uint8_t *epin_buf = p_epbuf->epin;
+ uint8_t *epout_buf = _cdcd_epbuf[i].epout;
+ uint8_t *epin_buf = _cdcd_epbuf[i].epin;
#endif
tu_edpt_stream_init(&p_cdc->stream.rx, false, false, false, p_cdc->stream.rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE,
@@ -516,11 +515,9 @@ 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) {
- // invoke transmit callback to possibly refill tx fifo
- tud_cdc_tx_complete_cb(itf);
+ tud_cdc_tx_complete_cb(itf); // invoke callback to possibly refill tx fifo
if (0 == tu_edpt_stream_write_xfer(rhport, stream_tx)) {
// If there is no data left, a ZLP should be sent if needed
diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c
index c2393c25d..bb736aba8 100644
--- a/src/class/vendor/vendor_device.c
+++ b/src/class/vendor/vendor_device.c
@@ -59,20 +59,30 @@ typedef struct {
static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR];
+#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || CFG_TUD_VENDOR_RX_BUFSIZE == 0
typedef struct {
+ // Skip local EP buffer if dedicated hw FIFO is supported
+ #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 || CFG_TUD_VENDOR_RX_BUFSIZE == 0
TUD_EPBUF_DEF(epout, CFG_TUD_VENDOR_EPSIZE);
+ #endif
+
+ // Skip local EP buffer if dedicated hw FIFO is supported
+ #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0
TUD_EPBUF_DEF(epin, CFG_TUD_VENDOR_EPSIZE);
+ #endif
} vendord_epbuf_t;
CFG_TUD_MEM_SECTION static vendord_epbuf_t _vendord_epbuf[CFG_TUD_VENDOR];
+ #endif
//--------------------------------------------------------------------+
// Weak stubs: invoked if no strong implementation is available
//--------------------------------------------------------------------+
-TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint16_t bufsize) {
+
+TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint32_t bufsize) {
(void)idx;
- (void) buffer;
- (void) bufsize;
+ (void)buffer;
+ (void)bufsize;
}
TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t idx, uint32_t sent_bytes) {
@@ -153,7 +163,19 @@ void vendord_init(void) {
for(uint8_t i=0; i<CFG_TUD_VENDOR; i++) {
vendord_interface_t* p_itf = &_vendord_itf[i];
- vendord_epbuf_t* p_epbuf = &_vendord_epbuf[i];
+
+ #if CFG_TUD_EDPT_DEDICATED_HWFIFO
+ #if CFG_TUD_VENDOR_RX_BUFSIZE == 0 // non-fifo rx still need ep buffer
+ uint8_t *epout_buf = _vendord_epbuf[i].epout;
+ #else
+ uint8_t *epout_buf = NULL;
+ #endif
+
+ uint8_t *epin_buf = NULL;
+ #else
+ uint8_t *epout_buf = _vendord_epbuf[i].epout;
+ uint8_t *epin_buf = _vendord_epbuf[i].epin;
+ #endif
#if CFG_TUD_VENDOR_RX_BUFSIZE > 0
uint8_t *rx_ff_buf = p_itf->stream.rx_ff_buf;
@@ -161,7 +183,7 @@ void vendord_init(void) {
uint8_t *rx_ff_buf = NULL;
#endif
- tu_edpt_stream_init(&p_itf->stream.rx, false, false, false, rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, p_epbuf->epout,
+ tu_edpt_stream_init(&p_itf->stream.rx, false, false, false, rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, epout_buf,
CFG_TUD_VENDOR_EPSIZE);
#if CFG_TUD_VENDOR_TX_BUFSIZE > 0
@@ -170,7 +192,7 @@ void vendord_init(void) {
uint8_t *tx_ff_buf = NULL;
#endif
- tu_edpt_stream_init(&p_itf->stream.tx, false, true, false, tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, p_epbuf->epin,
+ tu_edpt_stream_init(&p_itf->stream.tx, false, true, false, tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, epin_buf,
CFG_TUD_VENDOR_EPSIZE);
}
}
@@ -264,16 +286,19 @@ bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint
const uint8_t idx = find_vendor_itf(ep_addr);
TU_VERIFY(idx < CFG_TUD_VENDOR);
vendord_interface_t *p_vendor = &_vendord_itf[idx];
- vendord_epbuf_t *p_epbuf = &_vendord_epbuf[idx];
if (ep_addr == p_vendor->stream.rx.ep_addr) {
// Received new data: put into stream's fifo
tu_edpt_stream_read_xfer_complete(&p_vendor->stream.rx, xferred_bytes);
- // Invoked callback if any
- tud_vendor_rx_cb(idx, p_epbuf->epout, (uint16_t)xferred_bytes);
+ // invoke callback
+ #if CFG_TUD_VENDOR_RX_BUFSIZE == 0
+ tud_vendor_rx_cb(idx, p_vendor->stream.rx.ep_buf, xferred_bytes);
+ #else
+ tud_vendor_rx_cb(idx, NULL, 0);
+ #endif
- tu_edpt_stream_read_xfer(rhport, &p_vendor->stream.rx);
+ tu_edpt_stream_read_xfer(rhport, &p_vendor->stream.rx); // prepare next data
} else if (ep_addr == p_vendor->stream.tx.ep_addr) {
// Send complete
tud_vendor_tx_cb(idx, (uint16_t)xferred_bytes);
diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h
index e9dec788b..05de84f20 100644
--- a/src/class/vendor/vendor_device.h
+++ b/src/class/vendor/vendor_device.h
@@ -121,9 +121,12 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_available(void) {
// Application Callback API (weak is optional)
//--------------------------------------------------------------------+
-// Invoked when received new data
-void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint16_t bufsize);
-// Invoked when last rx transfer finished
+// Invoked when received new data.
+// - CFG_TUD_VENDOR_RX_BUFSIZE > 0; buffer and bufsize must not be used (both NULL,0) since data is in RX FIFO
+// - CFG_TUD_VENDOR_RX_BUFSIZE = 0: Buffer and bufsize are valid
+void tud_vendor_rx_cb(uint8_t idx, const uint8_t *buffer, uint32_t bufsize);
+
+// Invoked when tx transfer is finished
void tud_vendor_tx_cb(uint8_t idx, uint32_t sent_bytes);
//--------------------------------------------------------------------+
diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h
index 73c816e3e..d473e53e6 100644
--- a/src/common/tusb_types.h
+++ b/src/common/tusb_types.h
@@ -323,6 +323,11 @@ typedef struct {
tusb_speed_t speed;
} tusb_rhport_init_t;
+typedef struct {
+ uint16_t len;
+ uint8_t *buffer;
+} tusb_buffer_t;
+
//--------------------------------------------------------------------+
// USB Descriptors
//--------------------------------------------------------------------+
diff --git a/src/tusb.c b/src/tusb.c
index 2d122885b..94121b174 100644
--- a/src/tusb.c
+++ b/src/tusb.c
@@ -450,12 +450,19 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buf
TU_VERIFY(bufsize > 0); // TODO support ZLP
if (0 == tu_fifo_depth(&s->ff)) {
- // non-fifo mode, ep_buf must be valid
- TU_VERIFY(s->ep_buf != NULL, 0);
+ // non-fifo mode
TU_VERIFY(stream_claim(hwid, s), 0);
- const uint32_t xact_len = tu_min32(bufsize, s->ep_bufsize);
- memcpy(s->ep_buf, buffer, xact_len);
+ uint32_t xact_len;
+ if (s->ep_buf != NULL) {
+ // using ep buf
+ xact_len = tu_min32(bufsize, s->ep_bufsize);
+ memcpy(s->ep_buf, buffer, xact_len);
+ } else {
+ // using hwfifo
+ xact_len = bufsize;
+ }
TU_ASSERT(stream_xfer(hwid, s, (uint16_t) xact_len), 0);
+
return xact_len;
} else {
const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize);
@@ -494,7 +501,8 @@ uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s) {
//--------------------------------------------------------------------+
uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s) {
if (0 == tu_fifo_depth(&s->ff)) {
- // non-fifo mode
+ // non-fifo mode: RX need ep buffer
+ TU_VERIFY(s->ep_buf != NULL, 0);
TU_VERIFY(stream_claim(hwid, s), 0);
TU_ASSERT(stream_xfer(hwid, s, s->ep_bufsize), 0);
return s->ep_bufsize;
@@ -507,11 +515,8 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s) {
// and slowly move it to the FIFO when read().
// This pre-check reduces endpoint claiming
TU_VERIFY(available >= mps);
-
TU_VERIFY(stream_claim(hwid, s), 0);
-
- // get available again since fifo can be changed before endpoint is claimed
- available = tu_fifo_remaining(&s->ff);
+ available = tu_fifo_remaining(&s->ff); // re-get available since fifo can be changed
if (available >= mps) {
// multiple of packet size limit by ep bufsize
@@ -532,7 +537,7 @@ uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, ui
if (tu_fifo_depth(&s->ff) > 0) {
num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t)bufsize);
} else {
- // non-fifo mode
+ // non-fifo mode not support this
num_read = 0;
}