esp32: Fix USB deinit/reinit path via soft reset.

Fixes problems with USB-CDC state after soft reset if USBDevice has been
active with the default USB-CDC driver also enabled.

This also brings ESP32 behaviour in line with RP2 and other ports, where
boot.py is executed before the runtime USB device is initialised. This
allows setting up a custom USB device in boot.py.

There is still a bug here, because calling tud_disconnect() doesn't cause
any UNPLUG or BUS_RESET events to arrive from TinyUSB - which means the USB
device state stays out of sync until we call mp_usbd_init() again...

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
Signed-off-by: Angus Gratton <angus@redyak.com.au>
This commit is contained in:
Angus Gratton
2025-11-06 11:05:09 +11:00
parent 8d05a8fc8a
commit 4766f5680e
3 changed files with 10 additions and 8 deletions

View File

@@ -107,7 +107,7 @@ void mp_task(void *pvParameter) {
#if MICROPY_HW_ESP_USB_SERIAL_JTAG #if MICROPY_HW_ESP_USB_SERIAL_JTAG
usb_serial_jtag_init(); usb_serial_jtag_init();
#elif MICROPY_HW_ENABLE_USBDEV #elif MICROPY_HW_ENABLE_USBDEV
usb_init(); usb_phy_init();
#endif #endif
#if MICROPY_HW_ENABLE_UART_REPL #if MICROPY_HW_ENABLE_UART_REPL
uart_stdout_init(); uart_stdout_init();
@@ -145,6 +145,11 @@ soft_reset:
// run boot-up scripts // run boot-up scripts
pyexec_frozen_module("_boot.py", false); pyexec_frozen_module("_boot.py", false);
int ret = pyexec_file_if_exists("boot.py"); int ret = pyexec_file_if_exists("boot.py");
#if MICROPY_HW_ENABLE_USBDEV
mp_usbd_init();
#endif
if (ret & PYEXEC_FORCED_EXIT) { if (ret & PYEXEC_FORCED_EXIT) {
goto soft_reset_exit; goto soft_reset_exit;
} }
@@ -193,7 +198,7 @@ soft_reset_exit:
mp_thread_deinit(); mp_thread_deinit();
#endif #endif
#if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE #if MICROPY_HW_ENABLE_USBDEV
mp_usbd_deinit(); mp_usbd_deinit();
#endif #endif
@@ -219,6 +224,7 @@ soft_reset_exit:
mp_deinit(); mp_deinit();
fflush(stdout); fflush(stdout);
goto soft_reset; goto soft_reset;
} }

View File

@@ -38,7 +38,7 @@
static usb_phy_handle_t phy_hdl; static usb_phy_handle_t phy_hdl;
void usb_init(void) { void usb_phy_init(void) {
// ref: https://github.com/espressif/esp-usb/blob/4b6a798d0bed444fff48147c8dcdbbd038e92892/device/esp_tinyusb/tinyusb.c // ref: https://github.com/espressif/esp-usb/blob/4b6a798d0bed444fff48147c8dcdbbd038e92892/device/esp_tinyusb/tinyusb.c
// Configure USB PHY // Configure USB PHY
@@ -51,10 +51,6 @@ void usb_init(void) {
// Init ESP USB Phy // Init ESP USB Phy
usb_new_phy(&phy_conf, &phy_hdl); usb_new_phy(&phy_conf, &phy_hdl);
// Init MicroPython / TinyUSB
mp_usbd_init();
} }
#if CONFIG_IDF_TARGET_ESP32S3 #if CONFIG_IDF_TARGET_ESP32S3

View File

@@ -28,7 +28,7 @@
#define MICROPY_HW_USB_CDC_TX_TIMEOUT_MS (500) #define MICROPY_HW_USB_CDC_TX_TIMEOUT_MS (500)
void usb_init(void); void usb_phy_init(void);
void usb_usj_mode(void); void usb_usj_mode(void);
#endif // MICROPY_INCLUDED_ESP32_USB_H #endif // MICROPY_INCLUDED_ESP32_USB_H