Page 1 of 1

[Solved] How do I enable USB CDC on boot?

Posted: Sun Dec 04, 2022 6:49 am
by akolodner25
In Arduino IDE it was very easy to set an option for "USB CDC on Boot" to Enabled. Now that I'm switching to ESP-IDF with Arduino component, I can't get it to work. Setting the output to USB CDC gives an error (static assertion failed: "usb_osglue_*_int is not multicore capable"). Setting it to USB Serial/JTAG works, but Serial.print() doesn't actually show any output. Same with UART.

It looks like Arduino uses the config options CONFIG_USB_CDC_ENABLED and CONFIG_TINYUSB_ENABLED to control USB CDC on boot, but neither of those show up in my sdkconfig file, not even as "not set" comments. Also, turning on TinyUSB Stack in the menuconfig appears to set a different config, CONFIG_TINYUSB, so that seems to be the wrong option or wrong kind of TinyUSB?

In fact, I did a little more digging and Arduino seems to have its own version of TinyUSB, in a folder called arduino_tinyusb, that isn't a library or anything I can copy. Can I use that at all? I tried just doing #include <tusb.h> but it didn't find the file.

This is important because my PCB only has the USB connection and not UART connected*, and I need to get printed output from it through the serial monitor. printf works fine (why?? no idea), but I have 450+ Serial.print statements already that can't easily be converted to use printf, so I really would like to get Serial.print working. Does anyone know how to get this to work?

Chip: esp32s3

*although programming it over UART works through the USB pins, it seems

Re: How do I enable USB CDC on boot?

Posted: Sun Dec 04, 2022 5:02 pm
by akolodner25
UPDATE: Seems like I just have to enable the TinyUSB Stack option, then the Enable TinyUSB CDC feature. However, when I do this, I get the following errors:

Code: Select all

/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:29:25: error: 'tinyusb_add_string_descriptor' was not declared in this scope
     uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB CDC");
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:30:24: error: 'TUD_CDC_DESC_LEN' was not declared in this scope
     uint8_t descriptor[TUD_CDC_DESC_LEN] = {
                        ^~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:32:13: error: 'TUD_CDC_DESCRIPTOR' was not declared in this scope
             TUD_CDC_DESCRIPTOR(*itf, str_index, 0x85, 64, 0x03, 0x84, 64)
             ^~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:35:17: error: 'descriptor' was not declared in this scope
     memcpy(dst, descriptor, TUD_CDC_DESC_LEN);
                 ^~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:35:17: note: suggested alternative: 'encrypt'
     memcpy(dst, descriptor, TUD_CDC_DESC_LEN);
                 ^~~~~~~~~~
                 encrypt
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp: At global scope:
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:48:42: error: 'cdc_line_coding_t' has not been declared
 void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding)
                                          ^~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp: In function 'void tud_cdc_line_coding_cb(uint8_t, const int*)':
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:51:52: error: request for member 'bit_rate' in '* p_line_coding', which is of non-class type 'const int'
         devices[itf]->_onLineCoding(p_line_coding->bit_rate, p_line_coding->stop_bits, p_line_coding->parity, p_line_coding->data_bits);
                                                    ^~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:51:77: error: request for member 'stop_bits' in '* p_line_coding', which is of non-class type 'const int'
         devices[itf]->_onLineCoding(p_line_coding->bit_rate, p_line_coding->stop_bits, p_line_coding->parity, p_line_coding->data_bits);
                                                                             ^~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:51:103: error: request for member 'parity' in '* p_line_coding', which is of non-class type 'const int'
         devices[itf]->_onLineCoding(p_line_coding->bit_rate, p_line_coding->stop_bits, p_line_coding->parity, p_line_coding->data_bits);
                                                                                                       ^~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:51:126: error: request for member 'data_bits' in '* p_line_coding', which is of non-class type 'const int'
         devices[itf]->_onLineCoding(p_line_coding->bit_rate, p_line_coding->stop_bits, p_line_coding->parity, p_line_coding->data_bits);
                                                                                                                              ^~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp: In constructor 'USBCDC::USBCDC(uint8_t)':
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:99:30: error: 'USB_INTERFACE_CDC' was not declared in this scope
     tinyusb_enable_interface(USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor);
                              ^~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:99:49: error: 'TUD_CDC_DESC_LEN' was not declared in this scope
     tinyusb_enable_interface(USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor);
                                                 ^~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:99:5: error: 'tinyusb_enable_interface' was not declared in this scope
     tinyusb_enable_interface(USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor);
     ^~~~~~~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:101:49: error: 'ARDUINO_USB_EVENTS' was not declared in this scope
         arduino_usb_event_handler_register_with(ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, usb_unplugged_cb, this);
                                                 ^~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:101:49: note: suggested alternative: 'ARDUINO_USB_CDC_EVENTS'
         arduino_usb_event_handler_register_with(ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, usb_unplugged_cb, this);
                                                 ^~~~~~~~~~~~~~~~~~
                                                 ARDUINO_USB_CDC_EVENTS
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:101:69: error: 'ARDUINO_USB_STOPPED_EVENT' was not declared in this scope
         arduino_usb_event_handler_register_with(ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, usb_unplugged_cb, this);
                                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:101:69: note: suggested alternative: 'ARDUINO_USB_CDC_MAX_EVENT'
         arduino_usb_event_handler_register_with(ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, usb_unplugged_cb, this);
                                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~
                                                                     ARDUINO_USB_CDC_MAX_EVENT
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp: In member function 'void USBCDC::_onLineState(bool, bool)':
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:229:37: error: 'RESTART_BOOTLOADER' was not declared in this scope
                 usb_persist_restart(RESTART_BOOTLOADER);
                                     ^~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:229:37: note: suggested alternative: 'XCHAL_HAVE_BOOTLOADER'
                 usb_persist_restart(RESTART_BOOTLOADER);
                                     ^~~~~~~~~~~~~~~~~~
                                     XCHAL_HAVE_BOOTLOADER
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:229:17: error: 'usb_persist_restart' was not declared in this scope
                 usb_persist_restart(RESTART_BOOTLOADER);
                 ^~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:229:17: note: suggested alternative: 'esp_restart'
                 usb_persist_restart(RESTART_BOOTLOADER);
                 ^~~~~~~~~~~~~~~~~~~
                 esp_restart
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp: In member function 'void USBCDC::_onLineCoding(uint32_t, uint8_t, uint8_t, uint8_t)':
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:258:33: error: 'RESTART_BOOTLOADER' was not declared in this scope
             usb_persist_restart(RESTART_BOOTLOADER);
                                 ^~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:258:33: note: suggested alternative: 'XCHAL_HAVE_BOOTLOADER'
             usb_persist_restart(RESTART_BOOTLOADER);
                                 ^~~~~~~~~~~~~~~~~~
                                 XCHAL_HAVE_BOOTLOADER
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:258:13: error: 'usb_persist_restart' was not declared in this scope
             usb_persist_restart(RESTART_BOOTLOADER);
             ^~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:258:13: note: suggested alternative: 'esp_restart'
             usb_persist_restart(RESTART_BOOTLOADER);
             ^~~~~~~~~~~~~~~~~~~
             esp_restart
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp: In member function 'void USBCDC::_onRX()':
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:277:22: error: 'tud_cdc_n_read' was not declared in this scope
     uint32_t count = tud_cdc_n_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE);
                      ^~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:277:22: note: suggested alternative: 'tud_cdc_rx_cb'
     uint32_t count = tud_cdc_n_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE);
                      ^~~~~~~~~~~~~~
                      tud_cdc_rx_cb
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp: In member function 'virtual void USBCDC::flush()':
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:352:58: error: 'tud_cdc_n_connected' was not declared in this scope
     if(itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || !tud_cdc_n_connected(itf)){
                                                          ^~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:352:58: note: suggested alternative: 'tud_cdc_tx_complete_cb'
     if(itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || !tud_cdc_n_connected(itf)){
                                                          ^~~~~~~~~~~~~~~~~~~
                                                          tud_cdc_tx_complete_cb
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:358:5: error: 'tud_cdc_n_write_flush' was not declared in this scope
     tud_cdc_n_write_flush(itf);
     ^~~~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp: In member function 'virtual int USBCDC::availableForWrite()':
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:364:58: error: 'tud_cdc_n_connected' was not declared in this scope
     if(itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || !tud_cdc_n_connected(itf)){
                                                          ^~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:364:58: note: suggested alternative: 'tud_cdc_tx_complete_cb'
     if(itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || !tud_cdc_n_connected(itf)){
                                                          ^~~~~~~~~~~~~~~~~~~
                                                          tud_cdc_tx_complete_cb
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:370:16: error: 'tud_cdc_n_write_available' was not declared in this scope
     size_t a = tud_cdc_n_write_available(itf);
                ^~~~~~~~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp: In member function 'virtual size_t USBCDC::write(const uint8_t*, size_t)':
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:377:89: error: 'tud_cdc_n_connected' was not declared in this scope
     if(itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || buffer == NULL || size == 0 || !tud_cdc_n_connected(itf)){
                                                                                         ^~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:377:89: note: suggested alternative: 'tud_cdc_tx_complete_cb'
     if(itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || buffer == NULL || size == 0 || !tud_cdc_n_connected(itf)){
                                                                                         ^~~~~~~~~~~~~~~~~~~
                                                                                         tud_cdc_tx_complete_cb
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:390:13: error: 'tud_cdc_n_connected' was not declared in this scope
         if(!tud_cdc_n_connected(itf)){
             ^~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:390:13: note: suggested alternative: 'tud_cdc_tx_complete_cb'
         if(!tud_cdc_n_connected(itf)){
             ^~~~~~~~~~~~~~~~~~~
             tud_cdc_tx_complete_cb
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:394:24: error: 'tud_cdc_n_write_available' was not declared in this scope
         size_t space = tud_cdc_n_write_available(itf);
                        ^~~~~~~~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:396:13: error: 'tud_cdc_n_write_flush' was not declared in this scope
             tud_cdc_n_write_flush(itf);
             ^~~~~~~~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:402:23: error: 'tud_cdc_n_write' was not declared in this scope
         size_t sent = tud_cdc_n_write(itf, buffer+so_far, space);
                       ^~~~~~~~~~~~~~~
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:402:23: note: suggested alternative: 'tud_cdc_rx_cb'
         size_t sent = tud_cdc_n_write(itf, buffer+so_far, space);
                       ^~~~~~~~~~~~~~~
                       tud_cdc_rx_cb
/Users/USERNAME/esp/esp-idf/components/arduino/cores/esp32/USBCDC.cpp:406:13: error: 'tud_cdc_n_write_flush' was not declared in this scope
             tud_cdc_n_write_flush(itf);
No idea how to fix this since it's not an issue with any of my code but rather USBCDC.cpp (part of the board source)

Re: How do I enable USB CDC on boot?

Posted: Mon Dec 05, 2022 3:17 pm
by RalphD
if I remember right the S2 family has a ROM version of the CDC driver and that is the one available on boot. May be it is the same with the S3 ? It has been a while ago I was dealing with this, not sure

Re: How do I enable USB CDC on boot?

Posted: Mon Dec 05, 2022 11:36 pm
by chegewara
More advanced users can copy arduino-tinyusb component from builder to components/tinyusb folder in your project and try to use it here.

Re: How do I enable USB CDC on boot?

Posted: Wed Dec 07, 2022 5:22 am
by greg-dickson
Have you tried the simple way.
On the esp32s3 and C3 I simply connect D+ and D- to the appropriate pins on the USB connector and the esp on the PCB.
Plug it in.
If the device comes up it is connected if not check the solder joints.

Then just use the device that appears. esp-idf and upload with

idf.py -p /dev/ttyACM1 flash monitor

This just uploads directly and prints the output of printf statements directly to the terminal.

It is that easy.
Vanilla sdkconfig.
You don't need to start the Serial output at all.
https://docs.espressif.com/projects/esp ... ction.html

But if you want to print Serial over it then TinyUSB and other tools are available in esp-idf
or don't start Serial and just add

#define Serial.print printf

That will work with most Serial.print statements.

Re: How do I enable USB CDC on boot?

Posted: Thu Dec 15, 2022 9:48 pm
by akolodner25
Thank you all for the suggestions! Just saw them as I didn't get notified about the replies. Eventually I bit the bullet and changed everything to printf().

Note: #define Serial.print printf doesn't work, as Arduino has a lot of print statements (ex: FlashStringHelper) that printf can't handle.

Re: How do I enable USB CDC on boot?

Posted: Fri Jun 23, 2023 7:07 pm
by liyang5945
I solved this problem, just add a definition in CMakeLists.txt ,then it will work
add_definitions(
-DARDUINO_USB_MODE
-DARDUINO_USB_CDC_ON_BOOT
)

Re: How do I enable USB CDC on boot?

Posted: Mon Jun 26, 2023 1:59 pm
by akolodner25
Thank you liyang5945! This worked!! So glad to finally have this figured out.

As a clarification, you have to add it in {PROJECT ROOT}/CMakeLists.txt, not {PROJECT ROOT}/main/CMakeLists.txt, and I put it before the include, add_compile_definitions, and project calls just in case, though I don't know if that's required.