From 4766f5680e25d608bb4200d01ca414dd503b2e3f Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 6 Nov 2025 11:05:09 +1100 Subject: [PATCH] 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 Signed-off-by: Angus Gratton --- ports/esp32/main.c | 10 ++++++++-- ports/esp32/usb.c | 6 +----- ports/esp32/usb.h | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ports/esp32/main.c b/ports/esp32/main.c index bd5775bc66..74e31647d7 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -107,7 +107,7 @@ void mp_task(void *pvParameter) { #if MICROPY_HW_ESP_USB_SERIAL_JTAG usb_serial_jtag_init(); #elif MICROPY_HW_ENABLE_USBDEV - usb_init(); + usb_phy_init(); #endif #if MICROPY_HW_ENABLE_UART_REPL uart_stdout_init(); @@ -145,6 +145,11 @@ soft_reset: // run boot-up scripts pyexec_frozen_module("_boot.py", false); int ret = pyexec_file_if_exists("boot.py"); + + #if MICROPY_HW_ENABLE_USBDEV + mp_usbd_init(); + #endif + if (ret & PYEXEC_FORCED_EXIT) { goto soft_reset_exit; } @@ -193,7 +198,7 @@ soft_reset_exit: mp_thread_deinit(); #endif - #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE + #if MICROPY_HW_ENABLE_USBDEV mp_usbd_deinit(); #endif @@ -219,6 +224,7 @@ soft_reset_exit: mp_deinit(); fflush(stdout); + goto soft_reset; } diff --git a/ports/esp32/usb.c b/ports/esp32/usb.c index 750dd59ee6..b90f53aa49 100644 --- a/ports/esp32/usb.c +++ b/ports/esp32/usb.c @@ -38,7 +38,7 @@ 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 // Configure USB PHY @@ -51,10 +51,6 @@ void usb_init(void) { // Init ESP USB Phy usb_new_phy(&phy_conf, &phy_hdl); - - // Init MicroPython / TinyUSB - mp_usbd_init(); - } #if CONFIG_IDF_TARGET_ESP32S3 diff --git a/ports/esp32/usb.h b/ports/esp32/usb.h index 2bfa3d31af..99437266d9 100644 --- a/ports/esp32/usb.h +++ b/ports/esp32/usb.h @@ -28,7 +28,7 @@ #define MICROPY_HW_USB_CDC_TX_TIMEOUT_MS (500) -void usb_init(void); +void usb_phy_init(void); void usb_usj_mode(void); #endif // MICROPY_INCLUDED_ESP32_USB_H