@@ -25,8 +25,7 @@ ESP_EVENT_DEFINE_BASE(ARDUINO_USB_CDC_EVENTS);
2525esp_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);
2626esp_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);
2727
28- #define MAX_USB_CDC_DEVICES 2
29- USBCDC *devices[MAX_USB_CDC_DEVICES] = {NULL , NULL };
28+ USBCDC *devices[CFG_TUD_CDC];
3029
3130static uint16_t load_cdc_descriptor (uint8_t *dst, uint8_t *itf) {
3231 uint8_t str_index = tinyusb_add_string_descriptor (" TinyUSB CDC" );
@@ -38,23 +37,42 @@ static uint16_t load_cdc_descriptor(uint8_t *dst, uint8_t *itf) {
3837 return TUD_CDC_DESC_LEN;
3938}
4039
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] = {// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
49+ 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)
50+ };
51+ *itf += 2 ;
52+ memcpy (dst, descriptor, TUD_CDC_DESC_LEN);
53+ return TUD_CDC_DESC_LEN;
54+ }
55+
4156// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE
4257void tud_cdc_line_state_cb (uint8_t itf, bool dtr, bool rts) {
43- if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL ) {
58+ // log_v("ITF: %u, DTR: %u, RTS: %u", itf, dtr, rts);
59+ if (itf < CFG_TUD_CDC && devices[itf] != NULL ) {
4460 devices[itf]->_onLineState (dtr, rts);
4561 }
4662}
4763
4864// Invoked when line coding is change via SET_LINE_CODING
4965void 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 ) {
66+ // 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);
67+ if (itf < CFG_TUD_CDC && devices[itf] != NULL ) {
5168 devices[itf]->_onLineCoding (p_line_coding->bit_rate , p_line_coding->stop_bits , p_line_coding->parity , p_line_coding->data_bits );
5269 }
5370}
5471
5572// Invoked when received new data
5673void tud_cdc_rx_cb (uint8_t itf) {
57- if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL ) {
74+ // log_v("ITF: %u", itf);
75+ if (itf < CFG_TUD_CDC && devices[itf] != NULL ) {
5876 devices[itf]->_onRX ();
5977 }
6078}
@@ -66,13 +84,13 @@ void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) {
6684
6785// Invoked when space becomes available in TX buffer
6886void tud_cdc_tx_complete_cb (uint8_t itf) {
69- if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL ) {
87+ if (itf < CFG_TUD_CDC && devices[itf] != NULL ) {
7088 devices[itf]->_onTX ();
7189 }
7290}
7391
7492static void ARDUINO_ISR_ATTR cdc0_write_char (char c) {
75- if (devices[0 ] != NULL ) {
93+ if (CFG_TUD_CDC && devices[0 ] != NULL ) {
7694 tud_cdc_n_write_char (0 , c);
7795 }
7896}
@@ -84,9 +102,15 @@ static void usb_unplugged_cb(void *arg, esp_event_base_t event_base, int32_t eve
84102USBCDC::USBCDC (uint8_t itfn)
85103 : 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 ),
86104 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) {
105+ if (itf < CFG_TUD_CDC) {
106+ if (itf == 0 ) {
107+ tinyusb_enable_interface (USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor);
108+ } else {
109+ tinyusb_enable_interface (USB_INTERFACE_CDC2, TUD_CDC_DESC_LEN, load_cdc_descriptor2);
110+ }
89111 arduino_usb_event_handler_register_with (ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, usb_unplugged_cb, this );
112+ } else {
113+ log_e (" Maximum of %u CDC devices are supported" , CFG_TUD_CDC);
90114 }
91115}
92116
@@ -142,6 +166,9 @@ size_t USBCDC::setRxBufferSize(size_t rx_queue_len) {
142166}
143167
144168void USBCDC::begin (unsigned long baud) {
169+ if (itf >= CFG_TUD_CDC) {
170+ return ;
171+ }
145172 if (tx_lock == NULL ) {
146173 tx_lock = xSemaphoreCreateMutex ();
147174 }
@@ -153,6 +180,9 @@ void USBCDC::begin(unsigned long baud) {
153180}
154181
155182void USBCDC::end () {
183+ if (itf >= CFG_TUD_CDC) {
184+ return ;
185+ }
156186 connected = false ;
157187 devices[itf] = NULL ;
158188 setRxBufferSize (0 );
@@ -298,14 +328,14 @@ bool USBCDC::rebootEnabled(void) {
298328}
299329
300330int USBCDC::available (void ) {
301- if (itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL ) {
331+ if (itf >= CFG_TUD_CDC || rx_queue == NULL ) {
302332 return -1 ;
303333 }
304334 return uxQueueMessagesWaiting (rx_queue);
305335}
306336
307337int USBCDC::peek (void ) {
308- if (itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL ) {
338+ if (itf >= CFG_TUD_CDC || rx_queue == NULL ) {
309339 return -1 ;
310340 }
311341 uint8_t c;
@@ -316,7 +346,7 @@ int USBCDC::peek(void) {
316346}
317347
318348int USBCDC::read (void ) {
319- if (itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL ) {
349+ if (itf >= CFG_TUD_CDC || rx_queue == NULL ) {
320350 return -1 ;
321351 }
322352 uint8_t c = 0 ;
@@ -327,7 +357,7 @@ int USBCDC::read(void) {
327357}
328358
329359size_t USBCDC::read (uint8_t *buffer, size_t size) {
330- if (itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL ) {
360+ if (itf >= CFG_TUD_CDC || rx_queue == NULL ) {
331361 return -1 ;
332362 }
333363 uint8_t c = 0 ;
@@ -339,7 +369,7 @@ size_t USBCDC::read(uint8_t *buffer, size_t size) {
339369}
340370
341371void USBCDC::flush (void ) {
342- if (itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || !tud_cdc_n_connected (itf)) {
372+ if (itf >= CFG_TUD_CDC || tx_lock == NULL || !tud_cdc_n_connected (itf)) {
343373 return ;
344374 }
345375 if (xSemaphoreTake (tx_lock, tx_timeout_ms / portTICK_PERIOD_MS) != pdPASS) {
@@ -350,7 +380,7 @@ void USBCDC::flush(void) {
350380}
351381
352382int USBCDC::availableForWrite (void ) {
353- if (itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || !tud_cdc_n_connected (itf)) {
383+ if (itf >= CFG_TUD_CDC || tx_lock == NULL || !tud_cdc_n_connected (itf)) {
354384 return 0 ;
355385 }
356386 if (xSemaphoreTake (tx_lock, tx_timeout_ms / portTICK_PERIOD_MS) != pdPASS) {
@@ -362,7 +392,7 @@ int USBCDC::availableForWrite(void) {
362392}
363393
364394size_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)) {
395+ if (itf >= CFG_TUD_CDC || tx_lock == NULL || buffer == NULL || size == 0 || !tud_cdc_n_connected (itf)) {
366396 return 0 ;
367397 }
368398 if (xPortInIsrContext ()) {
@@ -415,6 +445,9 @@ uint32_t USBCDC::baudRate() {
415445}
416446
417447void USBCDC::setDebugOutput (bool en) {
448+ if (itf) {
449+ return ;
450+ }
418451 if (en) {
419452 uartSetDebug (NULL );
420453 ets_install_putc2 ((void (*)(char )) & cdc0_write_char);
@@ -424,7 +457,7 @@ void USBCDC::setDebugOutput(bool en) {
424457}
425458
426459USBCDC::operator bool () const {
427- if (itf >= MAX_USB_CDC_DEVICES ) {
460+ if (itf >= CFG_TUD_CDC ) {
428461 return false ;
429462 }
430463 return connected;
0 commit comments