Skip to content

Delay with ESP32-S3 USB HW JTAG CDC if no Serial Monitor is open. #9043

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
SuGlider opened this issue Dec 27, 2023 · 4 comments · Fixed by #9275
Closed

Delay with ESP32-S3 USB HW JTAG CDC if no Serial Monitor is open. #9043

SuGlider opened this issue Dec 27, 2023 · 4 comments · Fixed by #9275
Assignees

Comments

@SuGlider
Copy link
Collaborator

SuGlider commented Dec 27, 2023

related to Testing ESP-S3-BOX3 GFX/TouchScreen Arduino drivers:

I also just realised that there is an effect with Serial.print() in the ESP-BOX-3 when the GFX demo sketch is run with no open Serial Monitor. This is a sort of delay in every Serial.print() from loop, related to some issue with the USB HW JTAG CDC driver.

In order to avoid it, it is necessary to disable Serial, by commenting out the Serial initialization:

void setup() {
  //Serial.begin(115200);
  //Serial.setDebugOutput(true);
  //while (!Serial) delay(100);

Originally posted by @SuGlider in #8978 (comment)

@SuGlider SuGlider self-assigned this Dec 27, 2023
@SuGlider SuGlider changed the title Delay with ESP32-S3 USB OTG CDC if no Serial Monitor is open. Delay with ESP32-S3 USB HW JTAG CDC if no Serial Monitor is open. Dec 27, 2023
@SuGlider
Copy link
Collaborator Author

The S3, C3, C6 and H2 that have HW CDC JTAG USB port may cause a delay when using HWCDC in Serial by activating CDC on Boot and selecting the USB Mode for Hardware CDC and JTAG. This happens when no USB application in USB Host side is started to receive the data sent by the ESP32xx.

The USB CDC buffer gets full and the Arduino HW CDC layer will timeout, by default 100ms, until give up trying to send the CDC data.

As a workaround, it is necessary to use HWCDC::setTxTimeoutMs(timeout_ms) and set it to zero.

Example:

void setup() {
  Serial.begin(); // USB HW CDC doesn't need any baudrate
  Serial.setDebugOutput(true);  // sends all log_e(), log_i() messages to USB HW CDC
  Serial.setTxTimeoutMs(0);       // sets no timeout when trying to write to USB HW CDC
}

softhack007 added a commit to MoonModules/WLED-MM that referenced this issue Jan 4, 2024
see espressif/arduino-esp32#9043

"
The S3, C3, C6 and H2 that have HW CDC JTAG USB port may cause a delay when using HWCDC in Serial by activating CDC on Boot and selecting the USB Mode for Hardware CDC and JTAG. This happens when no USB application in USB Host side is started to receive the data sent by the ESP32xx.

The USB CDC buffer gets full and the Arduino HW CDC layer will timeout, by default 100ms, until give up trying to send the CDC data.

As a workaround, it is necessary to use HWCDC::setTxTimeoutMs(timeout_ms) and set it to zero.
"
@TD-er
Copy link
Contributor

TD-er commented Jan 5, 2024

@SuGlider Can this also cause similar issues on the USB CDC layer used on the ESP32-S2?

@SuGlider
Copy link
Collaborator Author

SuGlider commented Jan 5, 2024

@SuGlider Can this also cause similar issues on the USB CDC layer used on the ESP32-S2?

It shoud not affect the ESP32-S2 because it uses OTG USB based on TinyUSB software layer.
S2 has a real full USB interface. I tested the S3 with OTG and this "delay issue" didn't happen.

The S3 has both, the OTG USB and the HW JTAG CDC.
The C3 and C6 has only the HW JTAG CDC.

Djelibeybi pushed a commit to Djelibeybi/WLED-MM that referenced this issue Jan 15, 2024
see espressif/arduino-esp32#9043

"
The S3, C3, C6 and H2 that have HW CDC JTAG USB port may cause a delay when using HWCDC in Serial by activating CDC on Boot and selecting the USB Mode for Hardware CDC and JTAG. This happens when no USB application in USB Host side is started to receive the data sent by the ESP32xx.

The USB CDC buffer gets full and the Arduino HW CDC layer will timeout, by default 100ms, until give up trying to send the CDC data.

As a workaround, it is necessary to use HWCDC::setTxTimeoutMs(timeout_ms) and set it to zero.
"
@SuGlider
Copy link
Collaborator Author

@TD-er @softhack007 @Djelibeybi

The original issue is related to the JTAG/HW CDC Serial peripheral from ESP32-S3, ESP32-C3, ESP32-C6 and ESP32-H2.

One issue is that when USB cable is unplugged, flush() will block and write() will also block as soon as the HWCDC Ringbuffer gets full. The fix shall work even when USB cable is unplugged and/or Serial Monitor is not connected. It is not necessary to set TxBuffer to Zero anymore.

The second issue is that It won't work properly when the sketch waits for the CDC to be connected using a Serial Monitor, using a code like while(!Serial) delay(100);

These and some other issues were fixed by the PR #9275

When USB is unplugged, nothing will block any HW CDC writing or flushing.
When the buffer gets full, its content will be discarted and it will show the latest written data.
By this way, when the sketch connects to a serial monitor, it will display the latest data flow.

bool HWCDC will return true only when CDC is connected using some Serial Monitor Application.
It is possible plug, unplug, open and close the terminal that it will work correctly.
Closing the terminal while using Windows 10/11 will reset the board because for some reason Windows raises USB ACM RTS that makes the board consider that it shall reset. But it is possible to unplug the cable and the software will detect it and adjust its status to indicate that the CDC connection has been terminated. It is possbile to plug back the USB cable and reconnect automatically by opening the serial monitor again.

It has been fixed for arduino core 3.0.0-RC1 and it is available in the master branch.

Check the PR examples.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants