@@ -72,22 +72,27 @@ typedef struct {
72
72
73
73
OSAL_MUTEX_DEF (rx_ff_mutex );
74
74
OSAL_MUTEX_DEF (tx_ff_mutex );
75
-
76
- // Endpoint Transfer buffer
77
- CFG_TUSB_MEM_ALIGN uint8_t epout_buf [CFG_TUD_CDC_EP_BUFSIZE ];
78
- CFG_TUSB_MEM_ALIGN uint8_t epin_buf [CFG_TUD_CDC_EP_BUFSIZE ];
79
75
} cdcd_interface_t ;
80
76
81
77
#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char)
82
78
79
+ typedef struct {
80
+ TUD_EPBUF_DEF (epout , CFG_TUD_CDC_EP_BUFSIZE );
81
+ TUD_EPBUF_DEF (epin , CFG_TUD_CDC_EP_BUFSIZE );
82
+ } cdcd_epbuf_t ;
83
+
83
84
//--------------------------------------------------------------------+
84
85
// INTERNAL OBJECT & FUNCTION DECLARATION
85
86
//--------------------------------------------------------------------+
86
- CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf [CFG_TUD_CDC ];
87
+ static cdcd_interface_t _cdcd_itf [CFG_TUD_CDC ];
88
+ CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf [CFG_TUD_CDC ];
89
+
87
90
static tud_cdc_configure_fifo_t _cdcd_fifo_cfg ;
88
91
89
- static bool _prep_out_transaction (cdcd_interface_t * p_cdc ) {
90
- uint8_t const rhport = 0 ;
92
+ static bool _prep_out_transaction (uint8_t itf ) {
93
+ const uint8_t rhport = 0 ;
94
+ cdcd_interface_t * p_cdc = & _cdcd_itf [itf ];
95
+ cdcd_epbuf_t * p_epbuf = & _cdcd_epbuf [itf ];
91
96
92
97
// Skip if usb is not ready yet
93
98
TU_VERIFY (tud_ready () && p_cdc -> ep_out );
@@ -98,17 +103,17 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) {
98
103
// TODO Actually we can still carry out the transfer, keeping count of received bytes
99
104
// and slowly move it to the FIFO when read().
100
105
// This pre-check reduces endpoint claiming
101
- TU_VERIFY (available >= sizeof ( p_cdc -> epout_buf ) );
106
+ TU_VERIFY (available >= CFG_TUD_CDC_EP_BUFSIZE );
102
107
103
108
// claim endpoint
104
109
TU_VERIFY (usbd_edpt_claim (rhport , p_cdc -> ep_out ));
105
110
106
111
// fifo can be changed before endpoint is claimed
107
112
available = tu_fifo_remaining (& p_cdc -> rx_ff );
108
113
109
- if ( available >= sizeof ( p_cdc -> epout_buf ) ) {
110
- return usbd_edpt_xfer (rhport , p_cdc -> ep_out , p_cdc -> epout_buf , sizeof ( p_cdc -> epout_buf ) );
111
- }else {
114
+ if (available >= CFG_TUD_CDC_EP_BUFSIZE ) {
115
+ return usbd_edpt_xfer (rhport , p_cdc -> ep_out , p_epbuf -> epout , CFG_TUD_CDC_EP_BUFSIZE );
116
+ } else {
112
117
// Release endpoint since we don't make any transfer
113
118
usbd_edpt_release (rhport , p_cdc -> ep_out );
114
119
return false;
@@ -119,7 +124,7 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) {
119
124
// APPLICATION API
120
125
//--------------------------------------------------------------------+
121
126
122
- bool tud_cdc_configure_fifo (tud_cdc_configure_fifo_t const * cfg ) {
127
+ bool tud_cdc_configure_fifo (const tud_cdc_configure_fifo_t * cfg ) {
123
128
TU_VERIFY (cfg );
124
129
_cdcd_fifo_cfg = (* cfg );
125
130
return true;
@@ -156,7 +161,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) {
156
161
uint32_t tud_cdc_n_read (uint8_t itf , void * buffer , uint32_t bufsize ) {
157
162
cdcd_interface_t * p_cdc = & _cdcd_itf [itf ];
158
163
uint32_t num_read = tu_fifo_read_n (& p_cdc -> rx_ff , buffer , (uint16_t ) TU_MIN (bufsize , UINT16_MAX ));
159
- _prep_out_transaction (p_cdc );
164
+ _prep_out_transaction (itf );
160
165
return num_read ;
161
166
}
162
167
@@ -167,13 +172,13 @@ bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) {
167
172
void tud_cdc_n_read_flush (uint8_t itf ) {
168
173
cdcd_interface_t * p_cdc = & _cdcd_itf [itf ];
169
174
tu_fifo_clear (& p_cdc -> rx_ff );
170
- _prep_out_transaction (p_cdc );
175
+ _prep_out_transaction (itf );
171
176
}
172
177
173
178
//--------------------------------------------------------------------+
174
179
// WRITE API
175
180
//--------------------------------------------------------------------+
176
- uint32_t tud_cdc_n_write (uint8_t itf , void const * buffer , uint32_t bufsize ) {
181
+ uint32_t tud_cdc_n_write (uint8_t itf , const void * buffer , uint32_t bufsize ) {
177
182
cdcd_interface_t * p_cdc = & _cdcd_itf [itf ];
178
183
uint16_t ret = tu_fifo_write_n (& p_cdc -> tx_ff , buffer , (uint16_t ) TU_MIN (bufsize , UINT16_MAX ));
179
184
@@ -191,23 +196,26 @@ uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) {
191
196
192
197
uint32_t tud_cdc_n_write_flush (uint8_t itf ) {
193
198
cdcd_interface_t * p_cdc = & _cdcd_itf [itf ];
199
+ cdcd_epbuf_t * p_epbuf = & _cdcd_epbuf [itf ];
194
200
195
201
// Skip if usb is not ready yet
196
202
TU_VERIFY (tud_ready (), 0 );
197
203
198
204
// No data to send
199
- if (!tu_fifo_count (& p_cdc -> tx_ff )) return 0 ;
205
+ if (!tu_fifo_count (& p_cdc -> tx_ff )) {
206
+ return 0 ;
207
+ }
200
208
201
- uint8_t const rhport = 0 ;
209
+ const uint8_t rhport = 0 ;
202
210
203
211
// Claim the endpoint
204
212
TU_VERIFY (usbd_edpt_claim (rhport , p_cdc -> ep_in ), 0 );
205
213
206
214
// Pull data from FIFO
207
- uint16_t const count = tu_fifo_read_n (& p_cdc -> tx_ff , p_cdc -> epin_buf , sizeof ( p_cdc -> epin_buf ) );
215
+ const uint16_t count = tu_fifo_read_n (& p_cdc -> tx_ff , p_epbuf -> epin , CFG_TUD_CDC_EP_BUFSIZE );
208
216
209
217
if (count ) {
210
- TU_ASSERT (usbd_edpt_xfer (rhport , p_cdc -> ep_in , p_cdc -> epin_buf , count ), 0 );
218
+ TU_ASSERT (usbd_edpt_xfer (rhport , p_cdc -> ep_in , p_epbuf -> epin , count ), 0 );
211
219
return count ;
212
220
} else {
213
221
// Release endpoint since we don't make any transfer
@@ -291,32 +299,37 @@ void cdcd_reset(uint8_t rhport) {
291
299
cdcd_interface_t * p_cdc = & _cdcd_itf [i ];
292
300
293
301
tu_memclr (p_cdc , ITF_MEM_RESET_SIZE );
294
- if (!_cdcd_fifo_cfg .rx_persistent ) tu_fifo_clear (& p_cdc -> rx_ff );
295
- if (!_cdcd_fifo_cfg .tx_persistent ) tu_fifo_clear (& p_cdc -> tx_ff );
302
+ if (!_cdcd_fifo_cfg .rx_persistent ) {
303
+ tu_fifo_clear (& p_cdc -> rx_ff );
304
+ }
305
+ if (!_cdcd_fifo_cfg .tx_persistent ) {
306
+ tu_fifo_clear (& p_cdc -> tx_ff );
307
+ }
296
308
tu_fifo_set_overwritable (& p_cdc -> tx_ff , true);
297
309
}
298
310
}
299
311
300
- uint16_t cdcd_open (uint8_t rhport , tusb_desc_interface_t const * itf_desc , uint16_t max_len ) {
312
+ uint16_t cdcd_open (uint8_t rhport , const tusb_desc_interface_t * itf_desc , uint16_t max_len ) {
301
313
// Only support ACM subclass
302
314
TU_VERIFY ( TUSB_CLASS_CDC == itf_desc -> bInterfaceClass &&
303
315
CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc -> bInterfaceSubClass , 0 );
304
316
305
317
// Find available interface
306
- cdcd_interface_t * p_cdc = NULL ;
307
- for (uint8_t cdc_id = 0 ; cdc_id < CFG_TUD_CDC ; cdc_id ++ ) {
308
- if (_cdcd_itf [cdc_id ].ep_in == 0 ) {
309
- p_cdc = & _cdcd_itf [cdc_id ];
318
+ cdcd_interface_t * p_cdc ;
319
+ uint8_t cdc_id ;
320
+ for (cdc_id = 0 ; cdc_id < CFG_TUD_CDC ; cdc_id ++ ) {
321
+ p_cdc = & _cdcd_itf [cdc_id ];
322
+ if (p_cdc -> ep_in == 0 ) {
310
323
break ;
311
324
}
312
325
}
313
- TU_ASSERT (p_cdc , 0 );
326
+ TU_ASSERT (cdc_id < CFG_TUD_CDC , 0 );
314
327
315
328
//------------- Control Interface -------------//
316
329
p_cdc -> itf_num = itf_desc -> bInterfaceNumber ;
317
330
318
331
uint16_t drv_len = sizeof (tusb_desc_interface_t );
319
- uint8_t const * p_desc = tu_desc_next (itf_desc );
332
+ const uint8_t * p_desc = tu_desc_next (itf_desc );
320
333
321
334
// Communication Functional Descriptors
322
335
while (TUSB_DESC_CS_INTERFACE == tu_desc_type (p_desc ) && drv_len <= max_len ) {
@@ -326,7 +339,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1
326
339
327
340
if (TUSB_DESC_ENDPOINT == tu_desc_type (p_desc )) {
328
341
// notification endpoint
329
- tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const * ) p_desc ;
342
+ const tusb_desc_endpoint_t * desc_ep = (const tusb_desc_endpoint_t * ) p_desc ;
330
343
331
344
TU_ASSERT (usbd_edpt_open (rhport , desc_ep ), 0 );
332
345
p_cdc -> ep_notif = desc_ep -> bEndpointAddress ;
@@ -337,7 +350,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1
337
350
338
351
//------------- Data Interface (if any) -------------//
339
352
if ((TUSB_DESC_INTERFACE == tu_desc_type (p_desc )) &&
340
- (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const * ) p_desc )-> bInterfaceClass )) {
353
+ (TUSB_CLASS_CDC_DATA == ((const tusb_desc_interface_t * ) p_desc )-> bInterfaceClass )) {
341
354
// next to endpoint descriptor
342
355
drv_len += tu_desc_len (p_desc );
343
356
p_desc = tu_desc_next (p_desc );
@@ -349,35 +362,39 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1
349
362
}
350
363
351
364
// Prepare for incoming data
352
- _prep_out_transaction (p_cdc );
365
+ _prep_out_transaction (cdc_id );
353
366
354
367
return drv_len ;
355
368
}
356
369
357
370
// Invoked when a control transfer occurred on an interface of this class
358
371
// Driver response accordingly to the request and the transfer stage (setup/data/ack)
359
372
// return false to stall control endpoint (e.g unsupported request)
360
- bool cdcd_control_xfer_cb (uint8_t rhport , uint8_t stage , tusb_control_request_t const * request ) {
373
+ bool cdcd_control_xfer_cb (uint8_t rhport , uint8_t stage , const tusb_control_request_t * request ) {
361
374
// Handle class request only
362
375
TU_VERIFY (request -> bmRequestType_bit .type == TUSB_REQ_TYPE_CLASS );
363
376
364
- uint8_t itf = 0 ;
365
- cdcd_interface_t * p_cdc = _cdcd_itf ;
377
+ uint8_t itf ;
378
+ cdcd_interface_t * p_cdc ;
366
379
367
380
// Identify which interface to use
368
- for (;; itf ++ , p_cdc ++ ) {
369
- if (itf >= TU_ARRAY_SIZE (_cdcd_itf )) return false;
370
-
371
- if (p_cdc -> itf_num == request -> wIndex ) break ;
381
+ for (itf = 0 ; itf < CFG_TUD_CDC ; itf ++ ) {
382
+ p_cdc = & _cdcd_itf [itf ];
383
+ if (p_cdc -> itf_num == request -> wIndex ) {
384
+ break ;
385
+ }
372
386
}
387
+ TU_VERIFY (itf < CFG_TUD_CDC );
373
388
374
389
switch (request -> bRequest ) {
375
390
case CDC_REQUEST_SET_LINE_CODING :
376
391
if (stage == CONTROL_STAGE_SETUP ) {
377
392
TU_LOG_DRV (" Set Line Coding\r\n" );
378
393
tud_control_xfer (rhport , request , & p_cdc -> line_coding , sizeof (cdc_line_coding_t ));
379
394
} else if (stage == CONTROL_STAGE_ACK ) {
380
- if (tud_cdc_line_coding_cb ) tud_cdc_line_coding_cb (itf , & p_cdc -> line_coding );
395
+ if (tud_cdc_line_coding_cb ) {
396
+ tud_cdc_line_coding_cb (itf , & p_cdc -> line_coding );
397
+ }
381
398
}
382
399
break ;
383
400
@@ -408,7 +425,9 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
408
425
TU_LOG_DRV (" Set Control Line State: DTR = %d, RTS = %d\r\n" , dtr , rts );
409
426
410
427
// Invoke callback
411
- if (tud_cdc_line_state_cb ) tud_cdc_line_state_cb (itf , dtr , rts );
428
+ if (tud_cdc_line_state_cb ) {
429
+ tud_cdc_line_state_cb (itf , dtr , rts );
430
+ }
412
431
}
413
432
break ;
414
433
@@ -417,7 +436,9 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
417
436
tud_control_status (rhport , request );
418
437
} else if (stage == CONTROL_STAGE_ACK ) {
419
438
TU_LOG_DRV (" Send Break\r\n" );
420
- if (tud_cdc_send_break_cb ) tud_cdc_send_break_cb (itf , request -> wValue );
439
+ if (tud_cdc_send_break_cb ) {
440
+ tud_cdc_send_break_cb (itf , request -> wValue );
441
+ }
421
442
}
422
443
break ;
423
444
@@ -437,36 +458,43 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
437
458
// Identify which interface to use
438
459
for (itf = 0 ; itf < CFG_TUD_CDC ; itf ++ ) {
439
460
p_cdc = & _cdcd_itf [itf ];
440
- if ((ep_addr == p_cdc -> ep_out ) || (ep_addr == p_cdc -> ep_in )) break ;
461
+ if ((ep_addr == p_cdc -> ep_out ) || (ep_addr == p_cdc -> ep_in )) {
462
+ break ;
463
+ }
441
464
}
442
465
TU_ASSERT (itf < CFG_TUD_CDC );
466
+ cdcd_epbuf_t * p_epbuf = & _cdcd_epbuf [itf ];
443
467
444
468
// Received new data
445
469
if (ep_addr == p_cdc -> ep_out ) {
446
- tu_fifo_write_n (& p_cdc -> rx_ff , p_cdc -> epout_buf , (uint16_t ) xferred_bytes );
470
+ tu_fifo_write_n (& p_cdc -> rx_ff , p_epbuf -> epout , (uint16_t ) xferred_bytes );
447
471
448
472
// Check for wanted char and invoke callback if needed
449
473
if (tud_cdc_rx_wanted_cb && (((signed char ) p_cdc -> wanted_char ) != -1 )) {
450
474
for (uint32_t i = 0 ; i < xferred_bytes ; i ++ ) {
451
- if ((p_cdc -> wanted_char == p_cdc -> epout_buf [i ]) && !tu_fifo_empty (& p_cdc -> rx_ff )) {
475
+ if ((p_cdc -> wanted_char == p_epbuf -> epout [i ]) && !tu_fifo_empty (& p_cdc -> rx_ff )) {
452
476
tud_cdc_rx_wanted_cb (itf , p_cdc -> wanted_char );
453
477
}
454
478
}
455
479
}
456
480
457
481
// invoke receive callback (if there is still data)
458
- if (tud_cdc_rx_cb && !tu_fifo_empty (& p_cdc -> rx_ff )) tud_cdc_rx_cb (itf );
482
+ if (tud_cdc_rx_cb && !tu_fifo_empty (& p_cdc -> rx_ff )) {
483
+ tud_cdc_rx_cb (itf );
484
+ }
459
485
460
486
// prepare for OUT transaction
461
- _prep_out_transaction (p_cdc );
487
+ _prep_out_transaction (itf );
462
488
}
463
489
464
490
// Data sent to host, we continue to fetch from tx fifo to send.
465
491
// Note: This will cause incorrect baudrate set in line coding.
466
492
// Though maybe the baudrate is not really important !!!
467
493
if (ep_addr == p_cdc -> ep_in ) {
468
494
// invoke transmit callback to possibly refill tx fifo
469
- if (tud_cdc_tx_complete_cb ) tud_cdc_tx_complete_cb (itf );
495
+ if (tud_cdc_tx_complete_cb ) {
496
+ tud_cdc_tx_complete_cb (itf );
497
+ }
470
498
471
499
if (0 == tud_cdc_n_write_flush (itf )) {
472
500
// If there is no data left, a ZLP should be sent if
0 commit comments