esp32S3 The USB function is occupied by USB jtag/serial (VID_303A&PID_1001)
Port, board and/or hardware
esp32S3
MicroPython version
MicroPython v1.24.1
Reproduction
No, I've provided everything above.
Expected behaviour
Like 1.19, there is no need to plug or unplug the USB cable, and USB related functions can be used normally
Observed behaviour
on win10
After connecting the USB cable and booting up, the pc system will generate a USB jtag port. After entering micropython, all USBs do not work (such as my microPython USB CDC repl), and the USB jtag port will continue to exist (not work,VID_303A&PID_1001). Only by plugging and unplugging the USB cable once can the relevant USB functions work properly
V1.19 does not have this issue (but on 1.19, IDF's bootloder performs some pin detection to enter different OTA apps. detection stays for >200ms, the same issue will also occur)
Additional Information
No, I've provided everything above.
Code of Conduct
Yes, I agree
esp32: Re-initialise USB after soft reset.
Summary
Necessary if runtime USBDevice has been active on ESP32-S3 along with the default USB-CDC REPL. Without this fix, two things happen after a soft reset:
- The USB host sees the device disappear and not come back.
- Inside MicroPython, the CDC driver thinks it's still connected and active but eventually the TX FIFO fills up and significantly slows down stdout (visible on boards with a separate UART REPL).
This also fixes the init order for mp_usbd_init() so that USB is initialised after boot.py completes, the same as on other ports like rp2. This allows setting up a custom USB device in boot.py without it enumerating twice.
Testing
Note this PR needs to be cherry-picked onto #18332 or #18407 if PSRAM is enabled.
mpremote a0 run pr18332.py- where the file has the sample code from #18332- If using the USB-CDC interface for
mpremote runthen mpremote will error out as it disconnects to change USB device config. mpremote a0- Use Ctrl-C and Ctrl-B to stop the sample code and drop to an interactive REPL.
- Type Ctrl-D to soft reset.
Without fix: USB-CDC disappears along with the keyboard device, never comes back. Connecting to the UART REPL and interacting with it will eventually slow UART TX down to a trickle (quickest way to trigger is print("a"*500).)
With fix: USB-CDC disappears and re-enumerates again as plain USB-CDC device.
Second test is to put some custom usb device init code in boot.py and check that initial enumerationand soft reset work as expected there. I used:
import usb.device
from usb.device.mouse import MouseInterface
m = MouseInterface()
usb.device.get().init(m, builtin_driver=True)
Related bugs
There is still a related bug here, because calling TinyUSB tud_disconnect() on ESP32-S3 doesn't trigger any DCD_EVENT_UNPLUGGED or DCD_EVENT_BUS_RESET event. This means that the USB device driver state goes out of sync (i.e. TinyUSB thinks it's still connected).
This PR avoids this in soft reset because the host will reconfigure the USB device and the state will correct itself, but there's still a problem if Python code does something like this:
mpremote a0 run pr18332.py- (errors out as expected)
mpremote a0- Ctrl-C, Ctrl-B to get interactive REPL.
import machine; u = machine.USBDevice(); u.active(0)
In this situation the USB device disappears from the host as expected, but the issue with very slow stdout will happen as the CDC device driver still thinks it's connected and configured.
I've opened a Discussion on the TinyUSB repo to try and find out the expected behaviour: https://github.com/hathach/tinyusb/discussions/3331
This work was funded through GitHub Sponsors.