espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
12.96k stars 7.29k forks source link

ESP32 S3 serial and USB HID stall when DTR is activated a second time #9582

Open ChrGri opened 2 months ago

ChrGri commented 2 months ago

Board

ESP32 S3 dev

ESP32 S3 DevKitC 1 N16R8 ESP32 S3 WROOM1 N16R8 Entwicklungsboard WiFi Bluetooth 5.0 Mesh Entwicklungsboard https://amzn.eu/d/iAX62Sv

Device Description

esp32-s3-devkitc-1

The platformIO file can be found in the code section.

Hardware Configuration

USBOTG connection to PC

Version

latest master (checkout manually)

IDE Name

PlatformIO

Operating System

Win 11

Flash frequency

-

PSRAM enabled

no

Upload speed

-

Description

ESP32 S3 runs simple program that should provided USB HID gamepad and serial messages via USB OTG port. Im using the Windows inbuilt USB gamecontroller program to monitor the gamepad data and this serial monitor app to monitor the serial messages. The serial monitor app allows to set the DTR/RTS states manually, by pressing the red marked software buttons
image

The first activation of DTR enables the serial output as expected. When DTR is disabled, USB HID output continiues, which is also expected. But, when DTR is activated a second time, USB HID and serial output stall, which is not as expected.

https://github.com/espressif/arduino-esp32/assets/21274895/4a82961b-29db-452e-b95e-f4d1f56a183a

Apart from that, when serial and USB HID output are activated, both will stall after a while, see.

Sketch

Can be found here:
https://github.com/ChrGri/DIY-Sim-Racing-FFB-Pedal/tree/develop/Validation/Joystick_Serial_test

Debug Message

-

Other Steps to Reproduce

  1. Flash firmware
  2. Open serial monitor app
  3. Connect to COM port
  4. Enable DTR
  5. Check USB HID and serial output
  6. Deactivate DTR
  7. USB HID output still updating
  8. Activate DTR
  9. USB HID and serial output stall

I have checked existing issues, online documentation and the Troubleshooting Guide

SuGlider commented 1 month ago

Is this about USB Serial Device (CDC-ACM) signals?

SuGlider commented 1 month ago

@ChrGri - please keep in mind that DTR and RTS signals of the USB CDC port actually control "reset" and "boot mode" signals of the ESP32-S3.

SuGlider commented 1 month ago

It may be putting the S3 into download mode... "freezing/halting" the S3 firmware execution...

SuGlider commented 1 month ago

@ChrGri - Please read this: https://github.com/espressif/arduino-esp32/issues/6762#issuecomment-1182821492

image

SuGlider commented 1 month ago

This behaviour can be disabled permanently by burning the correct eFuse.

ChrGri commented 1 month ago

@SuGlider Thank you very much. I understood, that to enter the download mode on a regular ESP, one has to execute a specific DTR/RTS sequence, as shown below image.

From the documentation you referenced, I understood that only the download mode flag is toggled, but the chip is never asked to reset: image

I think setting Serial.enableReboot(false) has improved the behaviour and the USB HID output is continuous independent of the DTR state. However, simultaneous USB HID and serial output while RTS/DTR sates beeing const. are still buggy and both stall after some time. Single output of serial data or single output of USB HID data works fine though.

BR Chris

SuGlider commented 1 month ago

However, simultaneous USB HID and serial output while RTS/DTR sates beeing const. are still buggy and both stall after some time. Single output of serial data or single output of USB HID data works fine though.

I see that you are using PlatformIO. What is the Arduino Core version used with it? If possible, could you test it with Arduino IDE using Arduino Core 3.0.0-RC1?

ChrGri commented 1 month ago

However, simultaneous USB HID and serial output while RTS/DTR sates beeing const. are still buggy and both stall after some time. Single output of serial data or single output of USB HID data works fine though.

I see that you are using PlatformIO. What is the Arduino Core version used with it? If possible, could you test it with Arduino IDE using Arduino Core 3.0.0-RC1?

I've changed the platformIO as shown below. No difference. image

You can find the sample code here. I've played around with Serial.setTxTimeoutMs(0); and Serial.flush(); without success. The observation is always, as soon as USB HID and serial output are activated together, the output will stall at some point.

BR Chris

ChrGri commented 1 month ago

One thing which helped a lot, was adding a delay between the serial write and USB HID output command, as such image.

Wit that delay, the serial and USB HID output don't seem to stall immediately. Reducing the delays to 1ms will make the output stall eventually. I'm a bit confused, that replacing the delays with Serial.flush() doesn't seem to have the same effect.

BR Chris

SuGlider commented 1 month ago

I understand that your project uses USB OTG and TinyUSB for both, HID and CDC. The delay seems to give TinyUSB some room to run different tasks from those 2 endpoints and/or their tasks...

It may be necessary to run a deep investigation of this issue.

ChrGri commented 1 month ago

I understand that your project uses USB OTG and TinyUSB for both, HID and CDC. The delay seems to give TinyUSB some room to run different tasks from those 2 endpoints and/or their tasks...

It may be necessary to run a deep investigation of this issue.

Yes, CDC and HID. Do you have an idea, why Serial.flush() apparently doesn't give that room too?

Is there something I can to help to find a proper fix?

Edit: Btw. setting the first delay to 500ms and disabling the second delay results in a stall again. Seems to be purely related to the immediate HID output call after the serial write call.

BR Chris

SuGlider commented 1 month ago

I'd need to analyse it better and try to understand why it could fail.

Regarding Serial. Flush(), it actually just waits until all the data is sent to the USB Host. By other hand, delay(time_ms) releases the FreeRTOS Scheduler to run another task while waiting for that time to pass.

Arduino has a 1 ms time slice defined for FreeRTOS. delay(5); means waiting for 5 time slices while other tasks could be executed - maybe something related to HID... This is the "room" that I've mentioned about.

It is necessary to see the whole picture and try to understand the sequence of actions and possible reasons for the issue.

ChrGri commented 3 weeks ago

Just want to report that 2.0.17 behaves identical.