@@ -66,6 +66,8 @@ typedef struct {
6666
6767#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding)
6868
69+ // Skip local EP buffer if dedicated hw FIFO is supported
70+ #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0
6971typedef struct {
7072 TUD_EPBUF_DEF (epout , CFG_TUD_CDC_EP_BUFSIZE );
7173 TUD_EPBUF_DEF (epin , CFG_TUD_CDC_EP_BUFSIZE );
@@ -75,6 +77,9 @@ typedef struct {
7577 #endif
7678} cdcd_epbuf_t ;
7779
80+ CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf [CFG_TUD_CDC ];
81+ #endif
82+
7883//--------------------------------------------------------------------+
7984// Weak stubs: invoked if no strong implementation is available
8085//--------------------------------------------------------------------+
@@ -115,7 +120,6 @@ TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) {
115120// INTERNAL OBJECT & FUNCTION DECLARATION
116121//--------------------------------------------------------------------+
117122static cdcd_interface_t _cdcd_itf [CFG_TUD_CDC ];
118- CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf [CFG_TUD_CDC ];
119123static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT ();
120124
121125TU_ATTR_ALWAYS_INLINE static inline uint8_t find_cdc_itf (uint8_t ep_addr ) {
@@ -166,40 +170,22 @@ void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t *coding) {
166170}
167171
168172#if CFG_TUD_CDC_NOTIFY
169- bool tud_cdc_n_notify_uart_state (uint8_t itf , const cdc_notify_uart_state_t * state ) {
173+ bool tud_cdc_n_notify_msg (uint8_t itf , cdc_notify_msg_t * msg ) {
170174 TU_VERIFY (itf < CFG_TUD_CDC );
171- cdcd_interface_t * p_cdc = & _cdcd_itf [itf ];
172- cdcd_epbuf_t * p_epbuf = & _cdcd_epbuf [itf ];
175+ const cdcd_interface_t * p_cdc = & _cdcd_itf [itf ];
173176 TU_VERIFY (tud_ready () && p_cdc -> ep_notify != 0 );
174177 TU_VERIFY (usbd_edpt_claim (p_cdc -> rhport , p_cdc -> ep_notify ));
175178
176- cdc_notify_msg_t * notify_msg = & p_epbuf -> epnotify ;
177- notify_msg -> request .bmRequestType = CDC_REQ_TYPE_NOTIF ;
178- notify_msg -> request .bRequest = CDC_NOTIF_SERIAL_STATE ;
179- notify_msg -> request .wValue = 0 ;
180- notify_msg -> request .wIndex = p_cdc -> itf_num ;
181- notify_msg -> request .wLength = sizeof (cdc_notify_uart_state_t );
182- notify_msg -> serial_state = * state ;
183-
184- return usbd_edpt_xfer (p_cdc -> rhport , p_cdc -> ep_notify , (uint8_t * )notify_msg , 8 + sizeof (cdc_notify_uart_state_t ), false);
185- }
186-
187- bool tud_cdc_n_notify_conn_speed_change (uint8_t itf , const cdc_notify_conn_speed_change_t * conn_speed_change ) {
188- TU_VERIFY (itf < CFG_TUD_CDC );
189- cdcd_interface_t * p_cdc = & _cdcd_itf [itf ];
190- cdcd_epbuf_t * p_epbuf = & _cdcd_epbuf [itf ];
191- TU_VERIFY (tud_ready () && p_cdc -> ep_notify != 0 );
192- TU_VERIFY (usbd_edpt_claim (p_cdc -> rhport , p_cdc -> ep_notify ));
179+ #if CFG_TUD_EDPT_DEDICATED_HWFIFO
180+ cdc_notify_msg_t * msg_epbuf = msg ;
181+ #else
182+ cdc_notify_msg_t * msg_epbuf = & _cdcd_epbuf [itf ].epnotify ;
183+ * msg_epbuf = * msg ;
184+ #endif
193185
194- cdc_notify_msg_t * notify_msg = & p_epbuf -> epnotify ;
195- notify_msg -> request .bmRequestType = CDC_REQ_TYPE_NOTIF ;
196- notify_msg -> request .bRequest = CDC_NOTIF_CONNECTION_SPEED_CHANGE ;
197- notify_msg -> request .wValue = 0 ;
198- notify_msg -> request .wIndex = p_cdc -> itf_num ;
199- notify_msg -> request .wLength = sizeof (cdc_notify_conn_speed_change_t );
200- notify_msg -> conn_speed_change = * conn_speed_change ;
186+ msg_epbuf -> request .wIndex = p_cdc -> itf_num ;
201187
202- return usbd_edpt_xfer (p_cdc -> rhport , p_cdc -> ep_notify , (uint8_t * )notify_msg , 8 + sizeof ( cdc_notify_conn_speed_change_t ) , false);
188+ return usbd_edpt_xfer (p_cdc -> rhport , p_cdc -> ep_notify , (uint8_t * )msg_epbuf , 8 + msg_epbuf -> request . wLength , false);
203189}
204190#endif
205191
@@ -268,8 +254,6 @@ void cdcd_init(void) {
268254 tu_memclr (_cdcd_itf , sizeof (_cdcd_itf ));
269255 for (uint8_t i = 0 ; i < CFG_TUD_CDC ; i ++ ) {
270256 cdcd_interface_t * p_cdc = & _cdcd_itf [i ];
271- cdcd_epbuf_t * p_epbuf = & _cdcd_epbuf [i ];
272-
273257 p_cdc -> wanted_char = (char ) -1 ;
274258
275259 // default line coding is : stop bit = 1, parity = none, data bits = 8
@@ -278,14 +262,23 @@ void cdcd_init(void) {
278262 p_cdc -> line_coding .parity = 0 ;
279263 p_cdc -> line_coding .data_bits = 8 ;
280264
265+ #if CFG_TUD_EDPT_DEDICATED_HWFIFO
266+ uint8_t * epout_buf = NULL ;
267+ uint8_t * epin_buf = NULL ;
268+ #else
269+ cdcd_epbuf_t * p_epbuf = & _cdcd_epbuf [i ];
270+ uint8_t * epout_buf = p_epbuf -> epout ;
271+ uint8_t * epin_buf = p_epbuf -> epin ;
272+ #endif
273+
281274 tu_edpt_stream_init (& p_cdc -> stream .rx , false, false, false, p_cdc -> stream .rx_ff_buf , CFG_TUD_CDC_RX_BUFSIZE ,
282- p_epbuf -> epout , CFG_TUD_CDC_EP_BUFSIZE );
275+ epout_buf , CFG_TUD_CDC_EP_BUFSIZE );
283276
284277 // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not
285278 // know if data is actually polled by terminal. This way the most current data is prioritized.
286279 // Default: is overwritable
287280 tu_edpt_stream_init (& p_cdc -> stream .tx , false, true, _cdcd_cfg .tx_overwritabe_if_not_connected ,
288- p_cdc -> stream .tx_ff_buf , CFG_TUD_CDC_TX_BUFSIZE , p_epbuf -> epin , CFG_TUD_CDC_EP_BUFSIZE );
281+ p_cdc -> stream .tx_ff_buf , CFG_TUD_CDC_TX_BUFSIZE , epin_buf , CFG_TUD_CDC_EP_BUFSIZE );
289282 }
290283}
291284
@@ -481,11 +474,35 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
481474 if (ep_addr == stream_rx -> ep_addr ) {
482475 tu_edpt_stream_read_xfer_complete (stream_rx , xferred_bytes );
483476
484- // Check for wanted char and invoke wanted callback (multiple times if multiple wanted received)
477+ // Check for wanted char and invoke wanted callback
485478 if (((signed char )p_cdc -> wanted_char ) != -1 ) {
486- for (uint32_t i = 0 ; i < xferred_bytes ; i ++ ) {
487- if ((p_cdc -> wanted_char == (char )stream_rx -> ep_buf [i ]) && !tu_edpt_stream_empty (stream_rx )) {
488- tud_cdc_rx_wanted_cb (itf , p_cdc -> wanted_char );
479+ tu_fifo_buffer_info_t buf_info ;
480+ tu_fifo_get_read_info (& stream_rx -> ff , & buf_info );
481+
482+ // find backward
483+ uint8_t * ptr ;
484+ if (buf_info .wrapped .len > 0 ) {
485+ ptr = buf_info .wrapped .ptr + buf_info .wrapped .len - 1 ; // last byte of wrap buffer
486+ } else if (buf_info .linear .len > 0 ) {
487+ ptr = buf_info .linear .ptr + buf_info .linear .len - 1 ; // last byte of linear buffer
488+ } else {
489+ ptr = NULL ; // no data
490+ }
491+
492+ if (ptr != NULL ) {
493+ for (uint32_t i = 0 ; i < xferred_bytes ; i ++ ) {
494+ if (p_cdc -> wanted_char == (char )* ptr ) {
495+ tud_cdc_rx_wanted_cb (itf , p_cdc -> wanted_char );
496+ break ; // only invoke once per transfer, even if multiple wanted chars are present
497+ }
498+
499+ if (ptr == buf_info .wrapped .ptr ) {
500+ ptr = buf_info .linear .ptr + buf_info .linear .len - 1 ; // last byte of linear buffer
501+ } else if (ptr == buf_info .linear .ptr ) {
502+ break ; // reached the beginning
503+ } else {
504+ ptr -- ;
505+ }
489506 }
490507 }
491508 }
0 commit comments