esp-idf
esp-idf copied to clipboard
ESP32-S3 USB Flashing & Serial Communication Issue (IDFGH-14879)
Answers checklist.
- [x] I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
- [x] I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
- [x] I have searched the issue tracker for a similar issue and not found a similar issue.
General issue report
Issue Summary: I am trying to flash my ESP32-S3 using the USB port instead of the traditional COM port. Additionally, I want to use USB for serial read and write operations. However, I am encountering issues with the device behavior after flashing.
Observed Behavior: When I enter boot mode, the virtual COM port appears, and I can successfully flash the ESP32-S3. After flashing, the ESP gets stuck in download mode, waiting for a new firmware upload. If I reset the ESP, the virtual COM port disappears, and the device does not reconnect automatically.
Expected Behavior: After flashing, the ESP should exit boot mode and run the flashed firmware. The virtual COM port should persist after resetting the ESP, allowing serial communication via USB.
`#include <stdint.h> #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "tinyusb.h" #include "tusb_cdc_acm.h" #include "sdkconfig.h"
#define CONFIG_TINYUSB_CDC_COUNT 1
static const char *TAG = "example"; static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1];
void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event) { size_t rx_size = 0; esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); if (ret == ESP_OK) { ESP_LOGI(TAG, "Data from channel %d:", itf); ESP_LOG_BUFFER_HEXDUMP(TAG, buf, rx_size, ESP_LOG_INFO); } else { ESP_LOGE(TAG, "Read error"); } tinyusb_cdcacm_write_queue(itf, buf, rx_size); tinyusb_cdcacm_write_flush(itf, 0); }
void tinyusb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event) { int dtr = event->line_state_changed_data.dtr; int rts = event->line_state_changed_data.rts; ESP_LOGI(TAG, "Line state changed on channel %d: DTR:%d, RTS:%d", itf, dtr, rts); }
void app_main(void) { ESP_LOGI(TAG, "USB initialization"); const tinyusb_config_t tusb_cfg = { .device_descriptor = NULL, .string_descriptor = NULL, .external_phy = false, #if (TUD_OPT_HIGH_SPEED) .fs_configuration_descriptor = NULL, .hs_configuration_descriptor = NULL, .qualifier_descriptor = NULL, #else .configuration_descriptor = NULL, #endif };
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
tinyusb_config_cdcacm_t acm_cfg = {
.usb_dev = TINYUSB_USBDEV_0,
.cdc_port = TINYUSB_CDC_ACM_0,
.rx_unread_buf_sz = 64,
.callback_rx = &tinyusb_cdc_rx_callback,
.callback_rx_wanted_char = NULL,
.callback_line_state_changed = NULL,
.callback_line_coding_changed = NULL};
ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg));
ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback(
TINYUSB_CDC_ACM_0,
CDC_EVENT_LINE_STATE_CHANGED,
&tinyusb_cdc_line_state_changed_callback));
ESP_LOGI(TAG, "USB initialization DONE");
tinyusb_cdcacm_write_queue_char(TINYUSB_CDC_ACM_1, "T");
} `
Log Output
When entering boot mode and flashing:
ESP-ROM:esp32s3-20210327 Build:Mar 27 2021 rst:0x15 (USB_UART_CHIP_RESET),boot:0x20 (DOWNLOAD(USB/UART0)) Saved PC:0x40041a76 waiting for download
When resetting the ESP after flashing:
--- Error: ClearCommError failed (PermissionError(13, 'The device does not recognize the command.', None, 22)) --- Waiting for the device to reconnect...............
Environment Details
- ESP-IDF Version: v5.3.1
- Board: ESP32-S3
- Programming Interface: USB (instead of traditional UART COM port)
- Operating System: Windows (PowerShell)
- Possible Causes
Any insights or recommendations would be greatly appreciated! Thanks in advance.
Hi @Talha-Babar
Can you please check, connected USB device after you put an esp32s3 to a download mode? I am not familiar with windows, but on linux is lsusb command, that lists all the connected USB Devices.
On my PC for example:
- I Connect esp32s3 to my PC via a USB Cable connected to esp32s3's USB port (Not USB-UART Converter)
- I flash a Hello world example (The example does not use USB-OTG peripheral, thus the the esp32s3's USB port is acting as a JTAG Unit by default )
lsusboutput would be:Bus 005 Device 101: ID 303a:1001 Espressif USB JTAG/serial debug unit- I flash any USB Device example to the esp32s3 using USB port
lsusboutput would be:Bus 005 Device 100: ID 303a:4001 Espressif Systems Espressif Device- I reflash the USB Device example, but there is an error you are encountering:
Error log
peter@peter ➜ ~/esp/esp-idf/examples/peripherals/usb/device/tusb_console git:(master) ✗ idf.py flash -p /dev/ttyACM0
Executing action: flash
Running ninja in directory /home/peter/esp/esp-idf/examples/peripherals/usb/device/tusb_console/build
Executing "ninja flash"...
[1/5] cd /home/peter/esp/esp-idf/examples/peripherals/usb/device/tusb_console/build/esp-idf/... /home/peter/esp/esp-idf/examples/peripherals/usb/device/tusb_console/build/tusb_console.bin
tusb_console.bin binary size 0x38890 bytes. Smallest app partition is 0x100000 bytes. 0xc7770 bytes (78%) free.
[1/1] cd /home/peter/esp/esp-idf/examples/peripherals/usb/device/tusb_console/build/bootload...ter/esp/esp-idf/examples/peripherals/usb/device/tusb_console/build/bootloader/bootloader.bin
Bootloader binary size 0x52b0 bytes. 0x2d50 bytes (35%) free.
[2/3] cd /home/peter/esp/esp-idf/components/esptool_py && /usr/bin/cmake -D IDF_PATH=/home/p...ce/tusb_console/build -P /home/peter/esp/esp-idf/components/esptool_py/run_serial_tool.cmake
esptool.py --chip esp32s3 -p /dev/ttyACM0 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 80m --flash_size 2MB 0x0 bootloader/bootloader.bin 0x10000 tusb_console.bin 0x8000 partition_table/partition-table.bin
esptool.py v4.9.dev6
Serial port /dev/ttyACM0
Connecting...
A serial exception error occurred: Write timeout
Note: This error originates from pySerial. It is likely not a problem with esptool, but with the hardware connection or drivers.
For troubleshooting steps visit: https://docs.espressif.com/projects/esptool/en/latest/troubleshooting.html
- Now, I put the esp32s3 to a download mode
lsusboutput:Bus 005 Device 104: ID 303a:1001 Espressif USB JTAG/serial debug unit- the flash passes
Bottom line: Please make sure the esp32s3 is acting as a JTAG unint when flashing.
It could be an issue with the VScode extension settings.
- Can you flash using USB-UART port?
- Do you have a chance to try flashing without the extension? Just using
idf.py flashin CLI for example.. Doing so you would narrow down the problem - Which dev board are you using?
- Do you have a possibility to try using a different dev board?
After flashing, the ESP should exit boot mode and run the flashed firmware.
By the way, I think this issue was fixed in newer versions of esptool. It is now able to detect that the chip is in boot mode, and use a different reset method to get then firmware to run.
The virtual COM port should persist after resetting the ESP, allowing serial communication via USB.
This would indeed be nice but is unfortunately not possible (I think) because the USB device provided by the USB_SERIAL_JTAG peripheral and by UBS_OTG + tinyusb are different devices from the Host perspective. So the COM ports will also be different.
Maybe we can do something in esp_idf_montor to detect that the new port has appeared and automatically switch to monitoring it.
After flashing, the ESP should exit boot mode and run the flashed firmware.
The fix should be available in esptool 4.8 which is available in ESP-IDF v5.3.1. The install script needs to be run to update the environment.
cc @radimkarnis
Hi @Talha-Babar
I have seen an example in idf called "tusb_serial_device" it says we can use USB to read and write from serial port. How can I use the example?
Please, check out a readme of the tusb_serial_device example, if you have not already.
- flash your esp32s3 with the example
- connect both USB ports from the esp32s3 to your PC
- monitor USB-UART port
idf.py monitor -p /dev/ttyUSB0 - in second terminal window open a terminal emulator (picocom for example) and open a USB Device (the esp32s3 acting as as USB Device)
- start typing into the terminal emulator (picocom)
- text from the emulator shall appear on the esp32s3 monitor log
esp32s3 log
peter@peter ➜ ~/esp/esp-idf/examples/peripherals/usb/device/tusb_serial_device git:(master) idf.py monitor -p /dev/ttyUSB0
...
I (241) spi_flash: flash io: dio
W (244) spi_flash: Detected size(4096k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (257) main_task: Started on CPU0
I (257) main_task: Calling app_main()
I (257) example: USB initialization
W (257) tusb_desc: No Device descriptor provided, using default.
W (267) tusb_desc: No FullSpeed configuration descriptor provided, using default.
W (277) tusb_desc: No String descriptors provided, using default.
I (277) tusb_desc:
┌─────────────────────────────────┐
│ USB Device Descriptor Summary │
├───────────────────┬─────────────┤
│bDeviceClass │ 239 │
├───────────────────┼─────────────┤
│bDeviceSubClass │ 2 │
├───────────────────┼─────────────┤
│bDeviceProtocol │ 1 │
├───────────────────┼─────────────┤
│bMaxPacketSize0 │ 64 │
├───────────────────┼─────────────┤
│idVendor │ 0x303a │
├───────────────────┼─────────────┤
│idProduct │ 0x4001 │
├───────────────────┼─────────────┤
│bcdDevice │ 0x100 │
├───────────────────┼─────────────┤
│iManufacturer │ 0x1 │
├───────────────────┼─────────────┤
│iProduct │ 0x2 │
├───────────────────┼─────────────┤
│iSerialNumber │ 0x3 │
├───────────────────┼─────────────┤
│bNumConfigurations │ 0x1 │
└───────────────────┴─────────────┘
I (447) TinyUSB: TinyUSB Driver installed
I (447) example: USB initialization DONE
I (6847) example: Line state changed on channel 0: DTR:1, RTS:1
I (9927) example: Data from channel 0:
I (9927) example: 0x3ffc4480 48 |H|
I (10257) example: Data from channel 0:
I (10257) example: 0x3ffc4480 65 |e|
I (10557) example: Data from channel 0:
I (10557) example: 0x3ffc4480 6c |l|
I (10757) example: Data from channel 0:
I (10757) example: 0x3ffc4480 6c |l|
I (11017) example: Data from channel 0:
I (11017) example: 0x3ffc4480 6f |o|
picocom log
peter@peter ➜ ~ picocom /dev/ttyACM0
picocom v3.1
port is : /dev/ttyACM0
flowcontrol : none
baudrate is : 9600
parity is : none
databits are : 8
stopbits are : 1
escape is : C-a
local echo is : no
noinit is : no
noreset is : no
hangup is : no
nolock is : no
send_cmd is : sz -vv
receive_cmd is : rz -vv -E
imap is :
omap is :
emap is : crcrlf,delbs,
logfile is : none
initstring : none
exit_after is : not set
exit is : no
Type [C-a] [C-h] to see available commands
Terminal ready
Hello
Terminating...
Skipping tty reset...
Thanks for using picocom
peter@peter ➜ ~
@Talha-Babar
The other problem is still there, i need to press the reset button after flashing, otherwise it stuck in download mode.
We have implemented a potential fix, but that is not executed by default in USB-Serial/JTAG mode. Can you please try running esptool manually with the --after watchdog_reset option set? Unfortunately, this can't be set with menuconfig yet, so you'll have to run the esptool command printed by the IDF build system manually.
If you can confirm this solves the issue, we'll try to bring this option to IDF.
By the way, getting stuck in download mode (Waiting for download) should only happen when you enter it while holding down the BOOT button manually (or pulling the DTR line of the onboard USB-to-UART bridge low). Is this the case?
Isn't there an issue about the S3 hanging in download state and needing to be bashed with a reset to un-wedge it? Notice the hundreds of posts in this first one
https://github.com/espressif/arduino-esp32/issues/6762 (Daniel Egnor's 22-07-13 post is the authoritative one there, IMO.) https://github.com/mu-editor/mu/issues/2313
Notice that there are many unrelated issues that invariably get piled on any time an issue of this type gets discussed. I may be doing that here. :-) I'm just saying there are a LOT of S3 people that [think they] have the same problem.
After flashing, the ESP should exit boot mode and run the flashed firmware.
The fix should be available in esptool 4.8 which is available in ESP-IDF v5.3.1. The install script needs to be run to update the environment.
cc @radimkarnis
still not fixed, it does not exit boot mode and still says "waiting for download" after flashing.