espressif / arduino-esp32

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

Restart in bootmode via software not work when USB cable connected directly to PC #10204

Open rafaelgerges opened 3 months ago

rafaelgerges commented 3 months ago

Board

ESP32-S3-WROOM-1-N16R8

Device Description

Plain module ESP32-S3-WROOM-1-N16R8 in a custom PCB.

Hardware Configuration

GPIO 19 and 20 are connected to a host USB (PC or USB HUB).

ESP32-S3 WROOM is power by a external source (not USB powered).

Version

Arduino v2.0.14 and v2.0.17

IDE Name

PlatformIO

Operating System

Windows 10

Flash frequency

40 Mhz

PSRAM enabled

yes

Upload speed

115200

Description

I am trying to restart the ESP32-S3 in download mode via a command in the firmware. I am using the internal PHY (pins 19 and 20) for CDC communication using the tinyUSB library through the 'USBCDC' class.

I am executing the following command and experiencing two different behaviors.

usb_persist_restart(RESTART_BOOTLOADER);

Sketch

#include <Arduino.h>

void setup()
{
    // A API do USB CDC deve ser iniciado antes do USB
  USBCDC USBSerial;
  // Instância as características do USB
  USB.VID(0x303a);
  USB.PID(0x303a);
  USB.usbClass(0x02);
  USB.usbSubClass(0x02);
  USB.usbProtocol(0x00);
  USB.begin();

  delay(2000);
  usb_persist_restart(RESTART_BOOTLOADER);
}

void loop()
{  
  while(true)
  {
    delay(1000);
  }
}

Debug Message

When the ESP32-S3 is connect diretly to the PC it shows theses menssages:

- [  9625][E][esp32-hal-tinyusb.c:452] usb_switch_to_cdc_jtag(): reset_sem timeout

This problem occurs on esp32-hal-tinyusb.c on usb_switch_to_cdc_jtag method. For some reason it don't get into this method esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, 0, hw_cdc_reset_handler, reset_sem, &intr_handle).

17:24:08.131 -> ESP-ROM:esp32s3-20210327
17:24:08.166 -> Build:Mar 27 2021
17:24:08.166 -> rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
17:24:08.166 -> SPIWP:0xee
17:24:08.166 -> mode:DIO, clock div:1
17:24:08.166 -> load:0x3fce3808,len:0x44c
17:24:08.166 -> load:0x403c9700,len:0xbd8
17:24:08.166 -> load:0x403cc700,len:0x2a80
17:24:08.166 -> entry 0x403c98d0
17:24:11.245 -> �������ESP-ROM:esp32s3-20210327
17:24:11.245 -> Build:Mar 27 2021
17:24:11.281 -> rst:0xc (RTC_SW_CPU_RST),boot:0x0 (DOWNLOAD(USB/UART0))
17:24:11.281 -> Saved PC:0x4202c4f2
17:24:11.281 -> waiting for download
17:24:11.390 -> Guru Meditation Error: Core 0 panic'ed (LoadProhibited)
17:24:11.390 -> Core 0 register dump:
17:24:11.390 -> PC      : 0x400511b1  PS      : 0x00060330  A0      : 0x80049188  A1      : 0x3fceb640
17:24:11.390 -> A2      : 0x00000000  A3      : 0x3ff1e3fb  A4      : 0x00000001  A5      : 0x00000000
17:24:11.390 -> A6      : 0x00000000  A7      : 0x00000088  A8      : 0x800533dc  A9      : 0x3fceb620
17:24:11.390 -> A10     : 0xfffffffb  A11     : 0x3fceeebc  A12     : 0x3fceefbc  A13     : 0x00000000
17:24:11.390 -> A14     : 0x00000000  A15     : 0x00000006  SAR     : 0x0000000f  EXCCAUSE: 0x0000001c
17:24:11.390 -> EXCVADDR: 0x00000000  LBEG    : 0x400570e8  LEND    : 0x400570f3  LCOUNT  : 0x00000000
17:24:11.390 -> 
17:24:11.390 -> Backtrace: 0x400511b1:0x3fceb640 0x40049185:0x3fceb670 0x400491e5:0x3fceb690 0x40043917:0x3fceb6b0 0x4004392a:0x3fceb6d0 0x40043c33:0x3fceb6f0 0x40034c45:0x3fceb710
17:24:11.390 ->

Other Steps to Reproduce

To reproduce this issue you will need a USB HUB.

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

me-no-dev commented 3 months ago

usb_persist_restart() is not to be used directly. Also persist does not work on S3 at all

rafaelgerges commented 3 months ago

Well, if it shouldn't be accessed directly then it should be a private method, that would be an improvement. And, if it doesn't work on all ESP32-S3s, would that be a bug? What would be the correct way to put the ESP32-S3 in download mode via software?

Jason2866 commented 3 months ago

put the ESP32-S3 in download mode via software?

Short answer. There is no software solution for bringing the S3 in download mode.

atanisoft commented 3 months ago

Using REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT); and forcing a reboot seems to work on the ESP32-S3 from my tests. But it's a bit problematic from TinyUSB usage.

rafaelgerges commented 3 months ago

put the ESP32-S3 in download mode via software?

Short answer. There is no software solution for bringing the S3 in download mode.

What would you suggest as a hardware solution? Perhaps using a LATCH circuit connected to the BOOT pin?

rafaelgerges commented 3 months ago

Using REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT); and forcing a reboot seems to work on the ESP32-S3 from my tests. But it's a bit problematic from TinyUSB usage.

I tried this solution, unfortunately it didn't work for my case, maybe due to TinyUSB as you commented.

atanisoft commented 3 months ago

That's unfortunate. For my use case (TinyUSB operating a CDC endpoint) I jumped through a number of hoops to get the download mode working and it's far from ideal since esptool.py requires two invocations (first triggers the download mode but times out waiting for the device readiness, second does the actual download). I'm investigating further how to avoid the double execution of esptool but it's a lower priority since it is working right now.

Make sure you fully deinitialize the TinyUSB stack before you trigger the reboot.

rafaelgerges commented 3 months ago

That's unfortunate. For my use case (TinyUSB operating a CDC endpoint) I jumped through a number of hoops to get the download mode working and it's far from ideal since esptool.py requires two invocations (first triggers the download mode but times out waiting for the device readiness, second does the actual download). I'm investigating further how to avoid the double execution of esptool but it's a lower priority since it is working right now.

Make sure you fully deinitialize the TinyUSB stack before you trigger the reboot.

Thanks, any suggestion on how to fully deinitialize TinyUSB?

me-no-dev commented 3 months ago

if usb_persist_restart(RESTART_BOOTLOADER); does not work, this was our best bet. We have had this issue since S3 was released and were not able to make it work fully ever.

rafaelgerges commented 3 months ago

if usb_persist_restart(RESTART_BOOTLOADER); does not work, this was our best bet. We have had this issue since S3 was released and were not able to make it work fully ever.

But somehow it worked, as I mentioned earlier, when ESP32-S3 is connected to a USB HUB, this method works perfectly but when ESP32-S3 is connected directly to the PC's USB port it really doesn't work.

me-no-dev commented 3 months ago

you said that it gave exception. Any chance you decode that backtrace with the ESP Exception Decoder?

rafaelgerges commented 3 months ago

you said that it gave exception. Any chance you decode that backtrace with the ESP Exception Decoder?

Sure, give me a couple o days and I will send you back.

rafaelgerges commented 2 months ago

@me-no-dev sorry about the delay, I will probably do that on this week. Just wait a little bit more.

rafaelgerges commented 1 month ago

you said that it gave exception. Any chance you decode that backtrace with the ESP Exception Decoder?

Ok, below is the code with the backtrace and the decoder, unfortunately it was not able to provide very clear information about what happens. I run it on PlatformIO with build_flag = debug and monitor_filters = esp32_exception_decoder

Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x0 (DOWNLOAD(USB/UART0))
Saved PC:0x42046152
waiting for download
Guru Meditation Error: Core 0 panic'ed (LoadProhibited)
Core 0 register dump:
PC      : 0x400511b1  PS      : 0x00060330  A0      : 0x80049188  A1      : 0x3fceb640
A2      : 0x00000000  A3      : 0x3ff1e3fb  A4      : 0x00000001  A5      : 0x00000000
A6      : 0x00000000  A7      : 0x00000088  A8      : 0x800533dc  A9      : 0x3fceb620
A10     : 0xfffffffb  A11     : 0x3fceeebc  A12     : 0x3fceefbc  A13     : 0x00000000
A14     : 0x00000000  A15     : 0x00000006  SAR     : 0x0000000f  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000  LBEG    : 0x400570e8  LEND    : 0x400570f3  LCOUNT  : 0x00000000

Backtrace: 0x400511b1:0x3fceb640 0x40049185:0x3fceb670 0x400491e5:0x3fceb690 0x40043917:0x3fceb6b0 0x4004392a:0x3fceb6d0 0x40043c33:0x3fceb6f0 0x40034c45:0x3fceb710

  #0  0x400511b1:0x3fceb640 in ?? ??:0
  #1  0x40049185:0x3fceb670 in ?? ??:0
  #2  0x400491e5:0x3fceb690 in ?? ??:0
  #3  0x40043917:0x3fceb6b0 in ?? ??:0
  #4  0x4004392a:0x3fceb6d0 in ?? ??:0
  #5  0x40043c33:0x3fceb6f0 in ?? ??:0
  #6  0x40034c45:0x3fceb710 in ?? ??:0

Any clue or suggestion?

txf- commented 2 weeks ago

Yeah, I have the same issue and my backtrace is the same as above. The backtrace decoder does not decode this, presumably because this crash is happening in the bootloader?

rafaelgerges commented 2 weeks ago

Yeah, I have the same issue and my backtrace is the same as above. The backtrace decoder does not decode this, presumably because this crash is happening in the bootloader?

Hi Thiago, welcome to the team, thanks for your participation. @me-no-dev did you have time to return to this issue? Thank you in advance.

txf- commented 2 weeks ago

I should note that I tried this, tried stopping any TinyUSB services but to no avail. I then tied IO0 to a user button to enter into download mode of the bootloader with that mechanism.

nickdaria commented 1 week ago

I found the weirdest pattern.

Executing this works one time until I enter download mode via GPIO 0 again.

UPDATE: Must have been a lucky streak. Seems it is back to sporadic behavior and working intermittently.

ESP_LOGI(TAG, "Enter download mode");
tusb_cdc_acm_deinit(itf);
tinyusb_driver_uninstall();

REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
abort();

I also verified EFUSE_DIS_FORCE_DOWNLOAD was disabled, although there is a chip errata posted as early revisions had this eFuse set.

rafaelgerges commented 3 days ago

I found the weirdest pattern.

Executing this works one time until I enter download mode via GPIO 0 again.

UPDATE: Must have been a lucky streak. Seems it is back to sporadic behavior and working intermittently.

ESP_LOGI(TAG, "Enter download mode");
tusb_cdc_acm_deinit(itf);
tinyusb_driver_uninstall();

REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
abort();

I also verified EFUSE_DIS_FORCE_DOWNLOAD was disabled, although there is a chip errata posted as early revisions had this eFuse set.

Hi Nick, how are you? Thanks for your contribution, I will try it this week and get back to you.