diff options
| author | hathach <[email protected]> | 2025-11-22 00:56:24 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2025-11-22 00:56:24 +0700 |
| commit | 7df6e7bd054e6b81af8e0b2549ee60571be8c1d4 (patch) | |
| tree | 1f39466127fa343445d3bf98bdf0bb7eb425bda2 /src | |
| parent | 793d3b5dd14ae4459ce7fbfdf9f4815973fea0e9 (diff) | |
implement wanted char for cdc device without ep_buf
Diffstat (limited to 'src')
| -rw-r--r-- | src/class/cdc/cdc_device.c | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index a11de2f91..aeaceb16c 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -66,8 +66,9 @@ typedef struct { #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) +#if CFG_TUD_EDPT_DEDICATED_HWFIFO || CFG_TUD_CDC_NOTIFY typedef struct { - // Don't use local EP buffer if dedicated FIFO is supported + // Don't use local EP buffer if dedicated hw 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); @@ -78,6 +79,9 @@ typedef struct { #endif } cdcd_epbuf_t; +CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC]; +#endif + //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ @@ -118,7 +122,6 @@ 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]; -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) { @@ -491,11 +494,35 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (ep_addr == stream_rx->ep_addr) { tu_edpt_stream_read_xfer_complete(stream_rx, xferred_bytes); - // Check for wanted char and invoke wanted callback (multiple times if multiple wanted received) + // Check for wanted char and invoke wanted callback if (((signed char)p_cdc->wanted_char) != -1) { - for (uint32_t i = 0; i < xferred_bytes; i++) { - 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); + tu_fifo_buffer_info_t buf_info; + tu_fifo_get_read_info(&stream_rx->ff, &buf_info); + + // find backward + uint8_t *ptr; + if (buf_info.len_wrap > 0) { + ptr = buf_info.ptr_wrap + buf_info.len_wrap - 1; // last byte of wrap buffer + } else if (buf_info.len_lin > 0) { + ptr = buf_info.ptr_lin + buf_info.len_lin - 1; // last byte of linear buffer + } else { + ptr = NULL; // no data + } + + if (ptr != NULL) { + for (uint32_t i = 0; i < xferred_bytes; i++) { + if (p_cdc->wanted_char == (char)*ptr) { + tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); + break; // only invoke once per transfer, even multiple wanted chars are present + } + + if (ptr == buf_info.ptr_wrap) { + ptr = buf_info.ptr_lin + buf_info.len_lin - 1; // last byte of linear buffer + } else if (ptr == buf_info.ptr_lin) { + break; // reached the beginning + } else { + ptr--; + } } } } |
