edpt stream support xfer_fifo for device CFG_TUD_EDPT_DEDICATED_HWFIFO

cdc device omit ep buffer when hwfifo is supported
This commit is contained in:
hathach
2025-11-21 17:02:56 +07:00
parent d0d56a51a1
commit c9b623aa63
7 changed files with 58 additions and 21 deletions

View File

@ -5,7 +5,7 @@ Changelog
0.20.0
======
*November 19, 2024*
*November 19, 2025*
General
-------

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -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);

View File

@ -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)
//--------------------------------------------------------------------+