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

akolodner25
Posts: 27
Joined: Tue Nov 22, 2022 5:15 am

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

Postby akolodner25 » Sun Dec 04, 2022 6:49 am

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
Last edited by akolodner25 on Mon Jun 26, 2023 1:59 pm, edited 1 time in total.

akolodner25
Posts: 27
Joined: Tue Nov 22, 2022 5:15 am

Re: How do I enable USB CDC on boot?

Postby akolodner25 » Sun Dec 04, 2022 5:02 pm

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)

RalphD
Posts: 103
Joined: Thu Nov 25, 2021 9:02 pm

Re: How do I enable USB CDC on boot?

Postby RalphD » Mon Dec 05, 2022 3:17 pm

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

chegewara
Posts: 2378
Joined: Wed Jun 14, 2017 9:00 pm

Re: How do I enable USB CDC on boot?

Postby chegewara » Mon Dec 05, 2022 11:36 pm

More advanced users can copy arduino-tinyusb component from builder to components/tinyusb folder in your project and try to use it here.

greg-dickson
Posts: 24
Joined: Sun Nov 01, 2020 1:51 am

Re: How do I enable USB CDC on boot?

Postby greg-dickson » Wed Dec 07, 2022 5:22 am

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.

akolodner25
Posts: 27
Joined: Tue Nov 22, 2022 5:15 am

Re: How do I enable USB CDC on boot?

Postby akolodner25 » Thu Dec 15, 2022 9:48 pm

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.

liyang5945
Posts: 11
Joined: Fri Jun 23, 2023 6:49 pm

Re: How do I enable USB CDC on boot?

Postby liyang5945 » Fri Jun 23, 2023 7:07 pm

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
)

akolodner25
Posts: 27
Joined: Tue Nov 22, 2022 5:15 am

Re: How do I enable USB CDC on boot?

Postby akolodner25 » Mon Jun 26, 2023 1:59 pm

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.

Who is online

Users browsing this forum: Google [Bot] and 83 guests