ESP32-C3 CDC USB usage

s-light
Posts: 13
Joined: Mon Oct 29, 2018 6:50 pm

ESP32-C3 CDC USB usage

Postby s-light » Tue Nov 09, 2021 8:48 pm

Hello Community,

i currently experiment with the ESP32-C3.

one main focus is to use the internal USB CDC for upload and serial connection.

i just updated to Arduino ESP32 version 2.0.1
and as of the 20.01 RC1 release i do not get the USB CDC thing to work properly..
it says
Improvements:
* Improved USB-CDC support for both ESP32-S2 and ESP32-C3
so there were some changes.


So maybe i just don*t know how to use / who it should work...

I tried the following:

my test sketch

Code: Select all

// ESP32-C3 Serial & CDC test

const uint8_t led_info_pin = 1;

void setup() {
    pinMode(led_info_pin, OUTPUT);

    digitalWrite(led_info_pin, HIGH);
    digitalWrite(led_info_pin, LOW);
    // initialise serial
    // wait for arduino IDE to release all serial ports after upload.
    delay(1000);
    // initialise serial
    Serial.begin(115200);

    digitalWrite(led_info_pin, HIGH);
    delay(500);
    digitalWrite(led_info_pin, LOW);

    // Wait for Serial Connection to be Opend from Host
    // or timeout after 5second
    uint32_t timeStamp_Start = millis();
    while( (! Serial) && ( (millis() - timeStamp_Start) < 5000 ) ) {
        // nothing to do
        delay(1);
    }

    digitalWrite(led_info_pin, HIGH);

    // print some general sketch info..
    Serial.println();
    Serial.println();
    Serial.println(F("serial_test_minimal.ino"));
    Serial.print(F("upload: "));
    Serial.print(F(__DATE__));
    Serial.print(F("  "));
    Serial.print(F(__TIME__));
    Serial.println();
    Serial.println();
}

void loop() {
    Serial.println(millis());
    digitalWrite(led_info_pin, HIGH);
    delay(250);
    digitalWrite(led_info_pin, LOW);
    delay(250);
}

ttyACM0 is `USB JTAG/serial debug unit`
ttyUSB0 is `CP2102N USB to UART Bridge Controller`
(checked by connecting one and then the other and with linux dmesg enumeration events)

the results are the following:

Code: Select all


| Test  | `USB CDC on boot` | upload  | serial timeout | output  | output  |
| :---- | ----------------: | :------ | -------------: | ------: | ------: |
|     1 |          Disabled | ttyACM0 |              - | ttyACM0 | empty   |
|     1 |          Disabled | ttyACM0 |              - | ttyUSB0 | normal  |
|     2 |           Enabled | ttyACM0 |            yes | ttyACM0 | empty   |
|     2 |           Enabled | ttyACM0 |            yes | ttyUSB0 | startup |
|     3 |          Disabled | ttyUSB0 |              - | ttyACM0 | empty   |
|     3 |          Disabled | ttyUSB0 |              - | ttyUSB0 | normal  |
|     4 |           Enabled | ttyUSB0 |            yes | ttyACM0 | empty   |
|     4 |           Enabled | ttyUSB0 |            yes | ttyUSB0 | startup |

a reset with the pushbutton had no changes to the output -
(i see the reconnect of the `USB JTAG/serial debug unit` in the dmesg events)

sometimes the upload with ttyACM0 failed:
A fatal error occurred: Timed out waiting for packet header
i think this was every time the last sketch had `USB CDC on boot`: Enabled
(this was easily worked around by releasing the reset button very shortly before the upload begins)


Conclusions:
- it does make about no difference how i upload :-) that is a good thing :-)
- the code seems to run fine in all cases.
- `USB CDC on boot`: Enabled
i do not get any Serial.println() thing to my laptop

i think i had output with Version 2.0.0
so i will downgrade tomorow and test again..

if anyone has ideas / tips / pointers to documentation
pleas let me know!

sunny greetings
stefan

s-light
Posts: 13
Joined: Mon Oct 29, 2018 6:50 pm

Re: ESP32-C3 CDC USB usage

Postby s-light » Wed Nov 10, 2021 9:30 am

Today i downgraded `Arduino ESP32 version 2.0.0`

and did all the tests again:

Code: Select all

| Test  | `USB CDC on boot` | upload mode  | serial timeout | output  | output  |
| :---- | ----------------: | :----------- | -------------: | ------: | ------: |
|     1 |          Disabled | internal USB |              - | ttyACM0 | empty   |
|     1 |          Disabled | internal USB |              - | ttyUSB0 | normal  |
|     2 |           Enabled | internal USB |             -* | ttyACM0 | normal* |
|     2 |           Enabled | internal USB |            yes | ttyUSB0 | startup |
|     3 |          Disabled | UART0        |              - | ttyACM0 | empty   |
|     3 |          Disabled | UART0        |              - | ttyUSB0 | normal  |
|     4 |           Enabled | UART0        |           yes* | ttyACM0 | empty*  |
|     4 |           Enabled | UART0        |            yes | ttyUSB0 | startup |
`normal*`:
i saw the output from the sketch directly after the upload.
but did not get to show up anything in the serial monitor after a reset or with unplugging / plugging..
in this case it run into the serial timeout.
`normal*` & `yes*`:
Additionally it seems the code is not running properly - as my flashing led is longer on than off -
so the Serial.println() seems to take more time than normally needed.

so minimal other results as with 2.0.1.
and in general i did not find a way to use the intern USB CDC for serial debugging.

so the question stays:
How can i use the `internal USB CDC` for serial debugging?

hopefully someone has an idea or tips for me :-)

sunny greetings
stefan

bobolink
Posts: 98
Joined: Mon Feb 26, 2018 4:17 pm

Re: ESP32-C3 CDC USB usage

Postby bobolink » Fri Nov 12, 2021 12:20 pm

Which ESP32-C3 hardware is this?

s-light
Posts: 13
Joined: Mon Oct 29, 2018 6:50 pm

Re: ESP32-C3 CDC USB usage

Postby s-light » Fri Nov 12, 2021 4:38 pm

arduino ide during upload:

Code: Select all

esptool.py v3.1
Serial port /dev/ttyUSB0
Connecting....
Chip is unknown ESP32-C3 (revision 3)
Features: Wi-Fi
Crystal is 40MHz
says ESP32-C3 (revision 3)

it is on a ESP32-C3-DevKitM-1

s-light
Posts: 13
Joined: Mon Oct 29, 2018 6:50 pm

Re: ESP32-C3 CDC USB usage

Postby s-light » Sun Jan 09, 2022 3:03 pm

just got some pcbs and asselmbled them with some modules...
these boards have the USB-Port connected directly to the ESP32 C3 USB_CDC port.

i also updated the esp board package to 2.0.2.

the hardware reported during upload:

Code: Select all

esptool.py v3.1
Serial port /dev/ttyACM0
Connecting...
Chip is unknown ESP32-C3 (revision 3)
Features: Wi-Fi
Crystal is 40MHz
MAC: 7c:df:a1:b3:b6:80
so the same as the dev-board i have.

and it is the same behavior - as fare as i tested -
i can upload with the USB_CDC port.
but get no serial output.
i know that the board is working with this sketch as the onboard led are blinking:

Code: Select all

// https://github.com/Freenove/Freenove_WS2812_Lib_for_ESP32
#include "Freenove_WS2812_Lib_for_ESP32.h"

#define LEDS_COUNT  1
#define LEDS_PIN	8
#define CHANNEL		0
Freenove_ESP32_WS2812 board_pixel = Freenove_ESP32_WS2812(LEDS_COUNT, LEDS_PIN, CHANNEL);

void setup() {
    delay(2000);
    Serial.begin(115200);
    Serial.println("BoardPixel_Freenove_minimal.ino");
    Serial.print(F("uploaded: "));
    Serial.print(F(__DATE__));
    Serial.print(F("  "));
    Serial.print(F(__TIME__));
    Serial.println();

    board_pixel.begin();
    board_pixel.show();
}

void loop() {
    Serial.print("on  ");
    Serial.println(millis());
    board_pixel.setLedColor(0, 10, 10, 0);
    delay(1000);
    Serial.print("off ");
    Serial.println(millis());
    board_pixel.setLedColor(0, 0, 0, 1);
    delay(1000);
}
20220109_152336__itsalive.jpg
20220109_152336__itsalive.jpg (115.39 KiB) Viewed 31346 times
20220109_152336__itsalive_off.jpg
20220109_152336__itsalive_off.jpg (131.23 KiB) Viewed 31346 times
s there something i am missing?

or is it this hardware revision only?!

if anybody knows anything please let me know!

ESP_Sprite
Posts: 9766
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32-C3 CDC USB usage

Postby ESP_Sprite » Mon Jan 10, 2022 1:16 am

I have no experience with Arduino and the USB-JTAG-serial peripheral, but looking at the source, it only uses that device as the output for Serial if something called 'ARDUINO_HW_CDC_ON_BOOT' is enabled. If not, you should USBSerial instead of Serial to write to the USB-serial-JTAG peripheral.

(Also, that's a really cute little PCB there.)

s-light
Posts: 13
Joined: Mon Oct 29, 2018 6:50 pm

Re: ESP32-C3 CDC USB usage

Postby s-light » Mon Jan 10, 2022 11:57 am

hello ESP_Sprite,

thanks for your answer.
and thanks for looking into the code!

i also tried to trace down where this is handled - last time i did not succed.

so i just try it again for my own understanding :-)

the `ARDUINO_HW_CDC_ON_BOOT` can be activated via a gui menu option.
Arduino 1.8.19   ESP32-C3  USB CDC On Boot.png
Arduino 1.8.19 ESP32-C3 USB CDC On Boot.png (93.96 KiB) Viewed 31231 times
this option can be found at
platform.txt#L63

Code: Select all

build.extra_flags.esp32c3=-DARDUINO_HW_CDC_ON_BOOT={build.cdc_on_boot}
i then traced ARDUINO_HW_CDC_ON_BOOT
this resulted in two sets of files found:
(indentations by me..)

cores/esp32/HWCDC.h#L101
  1. #if ARDUINO_HW_CDC_ON_BOOT //Serial used for USB CDC
  2.     extern HWCDC Serial;
  3. #else
  4.     extern HWCDC USBSerial;
  5. #endif
cores/esp32/HWCDC.cpp#L382
  1. #if ARDUINO_HW_CDC_ON_BOOT //Serial used for USB CDC
  2.     HWCDC Serial;
  3. #else
  4.     HWCDC USBSerial;
  5. #endif

cores/esp32/HardwareSerial.h#L125
  1. #include "HWCDC.h"
  2.  
  3. //.....
  4.  
  5. #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
  6.     #ifndef ARDUINO_USB_CDC_ON_BOOT
  7.         #define ARDUINO_USB_CDC_ON_BOOT 0
  8.     #endif
  9.    
  10.     #if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
  11.         #include "USB.h"
  12.         #include "USBCDC.h"
  13.         extern HardwareSerial Serial0;
  14.     #elif ARDUINO_HW_CDC_ON_BOOT
  15.         extern HardwareSerial Serial0;
  16.     #else
  17.         extern HardwareSerial Serial;
  18.     #endif
  19.  
  20.     #if SOC_UART_NUM > 1
  21.         extern HardwareSerial Serial1;
  22.     #endif
  23.  
  24.     #if SOC_UART_NUM > 2
  25.         extern HardwareSerial Serial2;
  26.     #endif
  27. #endif
cores/esp32/HardwareSerial.cpp#L79
  1. #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
  2.     #if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
  3.         HardwareSerial Serial0(0);
  4.     #elif ARDUINO_HW_CDC_ON_BOOT
  5.         HardwareSerial Serial0(0);
  6.     #else
  7.         HardwareSerial Serial(0);
  8.     #endif
  9.  
  10.     #if SOC_UART_NUM > 1
  11.         HardwareSerial Serial1(1);
  12.     #endif
  13.  
  14.     #if SOC_UART_NUM > 2
  15.         HardwareSerial Serial2(2);
  16.     #endif
  17.  
  18.     void serialEventRun(void) {
  19.     #if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
  20.         if(Serial0.available()) serialEvent();
  21.     #elif ARDUINO_HW_CDC_ON_BOOT
  22.         if(Serial0.available()) serialEvent();
  23.     #else
  24.         if(Serial.available()) serialEvent();
  25.     #endif
  26.  
  27.     #if SOC_UART_NUM > 1
  28.         if(Serial1.available()) serialEvent1();
  29.     #endif
  30.     #if SOC_UART_NUM > 2
  31.         if(Serial2.available()) serialEvent2();
  32.     #endif
  33.     }
  34. #endif
  35.  

conclusions....

Code: Select all

if ARDUINO_HW_CDC_ON_BOOT
    Serial == USB_CDC
    Serial0 == HardwareSerial 
else
    USBSerial == USB_CDC
    Serial == HardwareSerial 
i follow up with some tests..

s-light
Posts: 13
Joined: Mon Oct 29, 2018 6:50 pm

Re: ESP32-C3 CDC USB usage [SOLVED]

Postby s-light » Mon Jan 10, 2022 12:45 pm

Test Setup
both ports connected.
one is showing up as ttyACM0 - that is the HW USB_CDC
the other as ttyUSB0 - that is the USB to UART chip CP2102N

on pin 1 is a led connected.

i use the following code for all the tests:
  1. // ESP32-C3 Serial & CDC test
  2.  
  3. #define  SerialUART Serial
  4. #define  SerialCDC  USBSerial
  5.  
  6. const uint8_t led_info_pin = 1;
  7.  
  8. void setup() {
  9.     pinMode(led_info_pin, OUTPUT);
  10.     digitalWrite(led_info_pin, HIGH);
  11.  
  12.     // wait for arduino IDE to release all serial ports after upload.
  13.     for (size_t i = 0; i < 10; i++) {
  14.         digitalWrite(led_info_pin, HIGH);
  15.         delay(50);
  16.         digitalWrite(led_info_pin, LOW);
  17.         delay(50);
  18.     }
  19.  
  20.     digitalWrite(led_info_pin, HIGH);
  21.     SerialUART.begin(115200);
  22.     SerialUART.println("SerialUART: Hello World!");
  23.     digitalWrite(led_info_pin, LOW);
  24.  
  25.     digitalWrite(led_info_pin, HIGH);
  26.     SerialCDC.begin(115200);
  27.     SerialCDC.println("Hello from SerialCDC");
  28.     digitalWrite(led_info_pin, LOW);
  29.  
  30.     // blink 5sec
  31.     for (size_t i = 0; i < 50; i++) {
  32.         digitalWrite(led_info_pin, HIGH);
  33.         delay(50);
  34.         digitalWrite(led_info_pin, LOW);
  35.         delay(50);
  36.     }
  37. }
  38.  
  39. void loop() {
  40.     SerialUART.print("SerialUART  ");
  41.     SerialUART.println(millis());
  42.  
  43.     SerialCDC.print("SerialCDC ");
  44.     SerialCDC.println(millis());
  45.  
  46.     digitalWrite(led_info_pin, HIGH);
  47.     delay(500);
  48.     digitalWrite(led_info_pin, LOW);
  49.     delay(500);
  50. }
  51.  

i only change the two llines:

Code: Select all

#define SerialUART xxxx
#define  SerialCDC  yyyy
arduino ide is connected to ttyUSB0
and so this is also used for upload.

1 HW_CDC_ON_BOOT = FALSE
config:

Code: Select all

#define SerialUART Serial
#define  SerialCDC USBSerial
expected:
ttyUSB0: output of SerialUART
ttyACM0: output of SerialCDC


actually:
ttyUSB0: ROM message; ouptu of SerialUART
ttyACM0: output of SerialCDC

working!!


2 HW_CDC_ON_BOOT = TRUE
config:

Code: Select all

#define SerialUART Serial0
#define  SerialCDC Serial
expected:
ttyUSB0 output of SerialUART
ttyACM0 output of SerialCDC

actually:
ttyUSB0: ROM message; ouptu of SerialUART
ttyACM0: output of SerialCDC*

*iam missing the first "Hello from SerialCDC" - so maybe i have to wait longer till my computer & terminal program are ready....
so working again!

if i hit reset my terminal does not recover / detects the port comes back....
maybe a signaling / timing thing again...


conclusion
seems i had some different configuration in the last tries....
so now it is all fine and i have understood a little bit more of how this is working ;-)


.
.
ESP_Sprite wrote:(Also, that's a really cute little PCB there.)
thanks ;-) it is a experiment / prototype to test exactly this USB_CDC feature for a later project..


thanks for your help!!

s-light
Posts: 13
Joined: Mon Oct 29, 2018 6:50 pm

Re: ESP32-C3 CDC USB usage

Postby s-light » Mon Jan 10, 2022 4:20 pm

there are some more issues:

often the USB_CDC port seems to be connected but i get no data -
this happens after an upload or after i push the reset button.
(the code runs and on the UART i get output..)

so seems that the USB_CDC is not resetet correclty.
if this happens the code runs but the write to the USB_CDC (some print statements) seems to block/hang for a moment..
i feels like it is similar to the limitation '3.' already stated in the documentation:
The behavior between an actual USB-to-serial bridge chip and the USB Serial/JTAG Controller is slightly different if the ESP-IDF application does not listen for incoming bytes. An USB-to-serial bridge chip will just send the bytes to a (not listening) chip, while the USB Serial/JTAG Controller will block until the application reads the bytes. This can lead to a non-responsive looking terminal program.

also unplug the cable and replug it into my computer - (the ESP32-C3 is powered from another source)
i can see the enumeration in my system log
but it does not help in reconnect to the USB_CDC output...
(or at least it does not show up for me)

any ideas how to get this working are very welcome!


the upload through USB_CDC is working fine for me -
only till now i did not manage to have a reliable debug output with this..

sunny greetings
stefan

s-light
Posts: 13
Joined: Mon Oct 29, 2018 6:50 pm

Re: ESP32-C3 CDC USB usage

Postby s-light » Tue Jun 21, 2022 3:30 pm

seems for me the last board-package update fixed things :-)
now with 2.0.3 it is working as expected.
if i set Tools → `USB CDC on Boot:"Enabled"` and use `Serial.println("Hello World")` i get `Hello World` on the CDC device :-)

Who is online

Users browsing this forum: No registered users and 44 guests