@@ -25,8 +25,7 @@ ESP_EVENT_DEFINE_BASE(ARDUINO_USB_CDC_EVENTS);
25
25
esp_err_t arduino_usb_event_post (esp_event_base_t event_base, int32_t event_id, void *event_data, size_t event_data_size, TickType_t ticks_to_wait);
26
26
esp_err_t arduino_usb_event_handler_register_with (esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler, void *event_handler_arg);
27
27
28
- #define MAX_USB_CDC_DEVICES 2
29
- USBCDC *devices[MAX_USB_CDC_DEVICES] = {NULL , NULL };
28
+ USBCDC *devices[CFG_TUD_CDC];
30
29
31
30
static uint16_t load_cdc_descriptor (uint8_t *dst, uint8_t *itf) {
32
31
uint8_t str_index = tinyusb_add_string_descriptor (" TinyUSB CDC" );
@@ -38,23 +37,43 @@ static uint16_t load_cdc_descriptor(uint8_t *dst, uint8_t *itf) {
38
37
return TUD_CDC_DESC_LEN;
39
38
}
40
39
40
+ static uint16_t load_cdc_descriptor2 (uint8_t *dst, uint8_t *itf) {
41
+ uint8_t str_index = tinyusb_add_string_descriptor (" TinyUSB CDC2" );
42
+ uint8_t ep_ntfy = tinyusb_get_free_in_endpoint ();
43
+ TU_VERIFY (ep_ntfy != 0 );
44
+ uint8_t ep_in = tinyusb_get_free_in_endpoint ();
45
+ TU_VERIFY (ep_in != 0 );
46
+ uint8_t ep_out = tinyusb_get_free_out_endpoint ();
47
+ TU_VERIFY (ep_out != 0 );
48
+ uint8_t descriptor[TUD_CDC_DESC_LEN] = {
49
+ // Interface number, string index, EP notification address and size, EP data address (out, in) and size.
50
+ TUD_CDC_DESCRIPTOR (*itf, str_index, (uint8_t )(0x80 | ep_ntfy), CFG_TUD_ENDOINT_SIZE, ep_out, (uint8_t )(0x80 | ep_in), CFG_TUD_ENDOINT_SIZE)
51
+ };
52
+ *itf += 2 ;
53
+ memcpy (dst, descriptor, TUD_CDC_DESC_LEN);
54
+ return TUD_CDC_DESC_LEN;
55
+ }
56
+
41
57
// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE
42
58
void tud_cdc_line_state_cb (uint8_t itf, bool dtr, bool rts) {
43
- if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL ) {
59
+ // log_v("ITF: %u, DTR: %u, RTS: %u", itf, dtr, rts);
60
+ if (itf < CFG_TUD_CDC && devices[itf] != NULL ) {
44
61
devices[itf]->_onLineState (dtr, rts);
45
62
}
46
63
}
47
64
48
65
// Invoked when line coding is change via SET_LINE_CODING
49
66
void tud_cdc_line_coding_cb (uint8_t itf, cdc_line_coding_t const *p_line_coding) {
50
- if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL ) {
67
+ // log_v("ITF: %u, BITRATE: %lu, STOP_BITS: %u, PARITY: %u, DATA_BITS: %u", itf, p_line_coding->bit_rate, p_line_coding->stop_bits, p_line_coding->parity, p_line_coding->data_bits);
68
+ if (itf < CFG_TUD_CDC && devices[itf] != NULL ) {
51
69
devices[itf]->_onLineCoding (p_line_coding->bit_rate , p_line_coding->stop_bits , p_line_coding->parity , p_line_coding->data_bits );
52
70
}
53
71
}
54
72
55
73
// Invoked when received new data
56
74
void tud_cdc_rx_cb (uint8_t itf) {
57
- if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL ) {
75
+ // log_v("ITF: %u", itf);
76
+ if (itf < CFG_TUD_CDC && devices[itf] != NULL ) {
58
77
devices[itf]->_onRX ();
59
78
}
60
79
}
@@ -66,13 +85,13 @@ void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) {
66
85
67
86
// Invoked when space becomes available in TX buffer
68
87
void tud_cdc_tx_complete_cb (uint8_t itf) {
69
- if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL ) {
88
+ if (itf < CFG_TUD_CDC && devices[itf] != NULL ) {
70
89
devices[itf]->_onTX ();
71
90
}
72
91
}
73
92
74
93
static void ARDUINO_ISR_ATTR cdc0_write_char (char c) {
75
- if (devices[0 ] != NULL ) {
94
+ if (CFG_TUD_CDC && devices[0 ] != NULL ) {
76
95
tud_cdc_n_write_char (0 , c);
77
96
}
78
97
}
@@ -84,9 +103,15 @@ static void usb_unplugged_cb(void *arg, esp_event_base_t event_base, int32_t eve
84
103
USBCDC::USBCDC (uint8_t itfn)
85
104
: itf(itfn), bit_rate(0 ), stop_bits(0 ), parity(0 ), data_bits(0 ), dtr(false ), rts(false ), connected(false ), reboot_enable(true ), rx_queue(NULL ), tx_lock(NULL ),
86
105
tx_timeout_ms(250 ) {
87
- tinyusb_enable_interface (USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor);
88
- if (itf < MAX_USB_CDC_DEVICES) {
106
+ if (itf < CFG_TUD_CDC) {
107
+ if (itf == 0 ) {
108
+ tinyusb_enable_interface (USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor);
109
+ } else {
110
+ tinyusb_enable_interface (USB_INTERFACE_CDC2, TUD_CDC_DESC_LEN, load_cdc_descriptor2);
111
+ }
89
112
arduino_usb_event_handler_register_with (ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, usb_unplugged_cb, this );
113
+ } else {
114
+ log_e (" Maximum of %u CDC devices are supported" , CFG_TUD_CDC);
90
115
}
91
116
}
92
117
@@ -142,6 +167,9 @@ size_t USBCDC::setRxBufferSize(size_t rx_queue_len) {
142
167
}
143
168
144
169
void USBCDC::begin (unsigned long baud) {
170
+ if (itf >= CFG_TUD_CDC) {
171
+ return ;
172
+ }
145
173
if (tx_lock == NULL ) {
146
174
tx_lock = xSemaphoreCreateMutex ();
147
175
}
@@ -153,6 +181,9 @@ void USBCDC::begin(unsigned long baud) {
153
181
}
154
182
155
183
void USBCDC::end () {
184
+ if (itf >= CFG_TUD_CDC) {
185
+ return ;
186
+ }
156
187
connected = false ;
157
188
devices[itf] = NULL ;
158
189
setRxBufferSize (0 );
@@ -298,14 +329,14 @@ bool USBCDC::rebootEnabled(void) {
298
329
}
299
330
300
331
int USBCDC::available (void ) {
301
- if (itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL ) {
332
+ if (itf >= CFG_TUD_CDC || rx_queue == NULL ) {
302
333
return -1 ;
303
334
}
304
335
return uxQueueMessagesWaiting (rx_queue);
305
336
}
306
337
307
338
int USBCDC::peek (void ) {
308
- if (itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL ) {
339
+ if (itf >= CFG_TUD_CDC || rx_queue == NULL ) {
309
340
return -1 ;
310
341
}
311
342
uint8_t c;
@@ -316,7 +347,7 @@ int USBCDC::peek(void) {
316
347
}
317
348
318
349
int USBCDC::read (void ) {
319
- if (itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL ) {
350
+ if (itf >= CFG_TUD_CDC || rx_queue == NULL ) {
320
351
return -1 ;
321
352
}
322
353
uint8_t c = 0 ;
@@ -327,7 +358,7 @@ int USBCDC::read(void) {
327
358
}
328
359
329
360
size_t USBCDC::read (uint8_t *buffer, size_t size) {
330
- if (itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL ) {
361
+ if (itf >= CFG_TUD_CDC || rx_queue == NULL ) {
331
362
return -1 ;
332
363
}
333
364
uint8_t c = 0 ;
@@ -339,7 +370,7 @@ size_t USBCDC::read(uint8_t *buffer, size_t size) {
339
370
}
340
371
341
372
void USBCDC::flush (void ) {
342
- if (itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || !tud_cdc_n_connected (itf)) {
373
+ if (itf >= CFG_TUD_CDC || tx_lock == NULL || !tud_cdc_n_connected (itf)) {
343
374
return ;
344
375
}
345
376
if (xSemaphoreTake (tx_lock, tx_timeout_ms / portTICK_PERIOD_MS) != pdPASS) {
@@ -350,7 +381,7 @@ void USBCDC::flush(void) {
350
381
}
351
382
352
383
int USBCDC::availableForWrite (void ) {
353
- if (itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || !tud_cdc_n_connected (itf)) {
384
+ if (itf >= CFG_TUD_CDC || tx_lock == NULL || !tud_cdc_n_connected (itf)) {
354
385
return 0 ;
355
386
}
356
387
if (xSemaphoreTake (tx_lock, tx_timeout_ms / portTICK_PERIOD_MS) != pdPASS) {
@@ -362,7 +393,7 @@ int USBCDC::availableForWrite(void) {
362
393
}
363
394
364
395
size_t USBCDC::write (const uint8_t *buffer, size_t size) {
365
- if (itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || buffer == NULL || size == 0 || !tud_cdc_n_connected (itf)) {
396
+ if (itf >= CFG_TUD_CDC || tx_lock == NULL || buffer == NULL || size == 0 || !tud_cdc_n_connected (itf)) {
366
397
return 0 ;
367
398
}
368
399
if (xPortInIsrContext ()) {
@@ -415,6 +446,9 @@ uint32_t USBCDC::baudRate() {
415
446
}
416
447
417
448
void USBCDC::setDebugOutput (bool en) {
449
+ if (itf) {
450
+ return ;
451
+ }
418
452
if (en) {
419
453
uartSetDebug (NULL );
420
454
ets_install_putc2 ((void (*)(char )) & cdc0_write_char);
@@ -424,7 +458,7 @@ void USBCDC::setDebugOutput(bool en) {
424
458
}
425
459
426
460
USBCDC::operator bool () const {
427
- if (itf >= MAX_USB_CDC_DEVICES ) {
461
+ if (itf >= CFG_TUD_CDC ) {
428
462
return false ;
429
463
}
430
464
return connected;
0 commit comments