summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-11-21 17:02:56 +0700
committerhathach <[email protected]>2025-11-21 17:02:56 +0700
commitc9b623aa63d24d58a7a5e55dd296afd1261b2ab8 (patch)
treeb6f11dd1e945b2dac9b1841efa1aaca17a255134 /src
parentd0d56a51a15dbdb760f5607702cf4ceeb2451a9e (diff)
edpt stream support xfer_fifo for device CFG_TUD_EDPT_DEDICATED_HWFIFO
cdc device omit ep buffer when hwfifo is supported
Diffstat (limited to 'src')
-rw-r--r--src/class/cdc/cdc_device.c18
-rw-r--r--src/common/tusb_fifo.h4
-rw-r--r--src/common/tusb_private.h6
-rw-r--r--src/device/usbd.c11
-rw-r--r--src/tusb.c22
-rw-r--r--src/tusb_option.h16
6 files changed, 57 insertions, 20 deletions
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c
index 9e62c6509..a11de2f91 100644
--- a/src/class/cdc/cdc_device.c
+++ b/src/class/cdc/cdc_device.c
@@ -67,8 +67,11 @@ typedef struct {
#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding)
typedef struct {
+ // Don't use local EP buffer if dedicated FIFO is supported
+ #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0
TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE);
TUD_EPBUF_DEF(epin, CFG_TUD_CDC_EP_BUFSIZE);
+ #endif
#if CFG_TUD_CDC_NOTIFY
TUD_EPBUF_TYPE_DEF(cdc_notify_msg_t, epnotify);
@@ -268,8 +271,6 @@ 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_epbuf_t *p_epbuf = &_cdcd_epbuf[i];
-
p_cdc->wanted_char = (char) -1;
// default line coding is : stop bit = 1, parity = none, data bits = 8
@@ -278,14 +279,23 @@ void cdcd_init(void) {
p_cdc->line_coding.parity = 0;
p_cdc->line_coding.data_bits = 8;
+ #if CFG_TUD_EDPT_DEDICATED_HWFIFO
+ 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;
+ #endif
+
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);
+ epout_buf, CFG_TUD_CDC_EP_BUFSIZE);
// TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not
// know if data is actually polled by terminal. This way the most current data is prioritized.
// Default: is overwritable
tu_edpt_stream_init(&p_cdc->stream.tx, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected,
- p_cdc->stream.tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE);
+ p_cdc->stream.tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE);
}
}
diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h
index c16216606..0b8e83760 100644
--- a/src/common/tusb_fifo.h
+++ b/src/common/tusb_fifo.h
@@ -48,6 +48,10 @@ extern "C" {
// for OS None, we don't get preempted
#define CFG_FIFO_MUTEX OSAL_MUTEX_REQUIRED
+#if CFG_TUD_EDPT_DEDICATED_HWFIFO || CFG_TUH_EDPT_DEDICATED_HWFIFO
+ #define CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32
+#endif
+
/* Write/Read index is always in the range of:
* 0 .. 2*depth-1
* The extra window allow us to determine the fifo state of empty or full with only 2 indices
diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h
index be1264a71..48fd1d6d2 100644
--- a/src/common/tusb_private.h
+++ b/src/common/tusb_private.h
@@ -60,7 +60,7 @@ typedef struct {
uint8_t ep_addr;
uint16_t ep_bufsize;
- uint8_t* ep_buf; // TODO xfer_fifo can skip this buffer
+ uint8_t *ep_buf; // set to NULL to use xfer_fifo when CFG_TUD_EDPT_DEDICATED_HWFIFO = 1
tu_fifo_t ff;
// mutex: read if rx, otherwise write
@@ -98,7 +98,7 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove
// Deinit an endpoint stream
bool tu_edpt_stream_deinit(tu_edpt_stream_t* s);
-// Open an stream for an endpoint
+// Open an endpoint stream
TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) {
s->ep_addr = desc_ep->bEndpointAddress;
s->is_mps512 = tu_edpt_packet_size(desc_ep) == 512;
@@ -150,7 +150,7 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s);
// Complete read transfer by writing EP -> FIFO. Must be called in the transfer complete callback
TU_ATTR_ALWAYS_INLINE static inline
void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) {
- if (0u != tu_fifo_depth(&s->ff)) {
+ if (0u != tu_fifo_depth(&s->ff) && s->ep_buf != NULL) {
tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes);
}
}
diff --git a/src/device/usbd.c b/src/device/usbd.c
index a65d14daf..5e7d0ffa7 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -1474,6 +1474,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t t
// success message. If total_bytes is too big, the FIFO will copy only what is available
// into the USB buffer!
bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t total_bytes, bool is_isr) {
+ #if CFG_TUD_EDPT_DEDICATED_HWFIFO
rhport = _usbd_rhport;
uint8_t const epnum = tu_edpt_number(ep_addr);
@@ -1481,7 +1482,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_
TU_LOG_USBD(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes);
- // Attempt to transfer on a busy endpoint, sound like an race condition !
+ // Attempt to transfer on a busy endpoint, sound like a race condition !
TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
// Set busy first since the actual transfer can be complete before dcd_edpt_xfer() could return
@@ -1499,6 +1500,14 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_
TU_BREAKPOINT();
return false;
}
+ #else
+ (void)rhport;
+ (void)ep_addr;
+ (void)ff;
+ (void)total_bytes;
+ (void)is_isr;
+ return false;
+ #endif
}
bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr) {
diff --git a/src/tusb.c b/src/tusb.c
index 3852da76b..1b8fdc460 100644
--- a/src/tusb.c
+++ b/src/tusb.c
@@ -387,8 +387,12 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(uint8_t hwid, tu_edpt_strea
#endif
} else {
#if CFG_TUD_ENABLED
- return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false);
- #endif
+ if (s->ep_buf == NULL) {
+ return usbd_edpt_xfer_fifo(hwid, s->ep_addr, &s->ff, count, false);
+ } else {
+ return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false);
+ }
+ #endif
}
return false;
}
@@ -419,12 +423,17 @@ bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint3
}
uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) {
- // skip if no data
- TU_VERIFY(tu_fifo_count(&s->ff) > 0, 0);
+ const uint16_t ff_count = tu_fifo_count(&s->ff);
+ TU_VERIFY(ff_count > 0, 0); // skip if no data
TU_VERIFY(stream_claim(hwid, s), 0);
// Pull data from FIFO -> EP buf
- const uint16_t count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize);
+ uint16_t count;
+ if (s->ep_buf == NULL) {
+ count = ff_count;
+ } else {
+ count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize);
+ }
if (count > 0) {
TU_ASSERT(stream_xfer(hwid, s, count), 0);
@@ -441,7 +450,8 @@ 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)) {
- // no fifo for buffered
+ // no fifo for buffered, ep_buf must be valid
+ TU_VERIFY(s->ep_buf != NULL, 0);
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);
diff --git a/src/tusb_option.h b/src/tusb_option.h
index e2eaecd2d..d7b61d58d 100644
--- a/src/tusb_option.h
+++ b/src/tusb_option.h
@@ -306,18 +306,14 @@
#if defined(TUP_USBIP_DWC2)
#if CFG_TUD_DWC2_SLAVE_ENABLE
- #define CFG_TUD_EDPT_DEDICATED_FIFO
+ #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
#endif
#if CFG_TUD_DWC2_SLAVE_ENABLE
- #define CFG_TUH_EDPT_DEDICATED_FIFO
+ #define CFG_TUH_EDPT_DEDICATED_HWFIFO 1
#endif
#endif
-#if defined(CFG_TUD_EDPT_DEDICATED_FIFO) || defined(CFG_TUH_EDPT_DEDICATED_FIFO)
- #define CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32
-#endif
-
//------------- ChipIdea -------------//
// Enable CI_HS VBUS Charge. Set this to 1 if the USB_VBUS pin is not connected to 5V VBUS (note: 3.3V is
// insufficient).
@@ -590,6 +586,10 @@
#define CFG_TUD_NCM 0
#endif
+#ifndef CFG_TUD_EDPT_DEDICATED_HWFIFO
+ #define CFG_TUD_EDPT_DEDICATED_HWFIFO 0
+#endif
+
//--------------------------------------------------------------------
// Host Options (Default)
//--------------------------------------------------------------------
@@ -729,6 +729,10 @@
#define CFG_TUH_API_EDPT_XFER 0
#endif
+#ifndef CFG_TUH_EDPT_DEDICATED_HWFIFO
+ #define CFG_TUH_EDPT_DEDICATED_HWFIFO 0
+#endif
+
//--------------------------------------------------------------------+
// TypeC Options (Default)
//--------------------------------------------------------------------+