From 92e43f9e6bb186063ff5f6db2c7cff1501671a3c Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 23 May 2024 22:08:12 +1000 Subject: [PATCH] ports/esp32: Add automatic bootloader handling for S2 and S3. Enables support for the ESP standard DTR/RTS based reboot to bootloader. Switches from OTG to Serial/Jtag mode to workaround issue discussed in: https://github.com/espressif/arduino-esp32/issues/6762 Signed-off-by: Andrew Leech --- .../boards/ESP32_GENERIC_S3/sdkconfig.board | 1 - .../esp32/boards/UM_FEATHERS2/sdkconfig.board | 1 - .../boards/UM_FEATHERS2NEO/sdkconfig.board | 1 - .../esp32/boards/UM_FEATHERS3/sdkconfig.board | 1 - ports/esp32/boards/UM_NANOS3/sdkconfig.board | 1 - ports/esp32/boards/UM_PROS3/sdkconfig.board | 1 - ports/esp32/boards/UM_TINYS2/sdkconfig.board | 1 - ports/esp32/boards/UM_TINYS3/sdkconfig.board | 1 - .../boards/UM_TINYWATCHS3/sdkconfig.board | 1 - ports/esp32/modmachine.c | 17 ++++++++++++++++ ports/esp32/mpconfigport.h | 3 ++- ports/esp32/usb.c | 12 +++++++++++ ports/esp32/usb.h | 1 + ports/renesas-ra/README.md | 2 +- .../boards/EK_RA4W1/mpconfigboard.h | 2 +- ports/renesas-ra/main.c | 1 - shared/tinyusb/mp_usbd_cdc.c | 20 ++++++++++++++++++- 17 files changed, 53 insertions(+), 14 deletions(-) diff --git a/ports/esp32/boards/ESP32_GENERIC_S3/sdkconfig.board b/ports/esp32/boards/ESP32_GENERIC_S3/sdkconfig.board index a36b971162850..9839b0d300510 100644 --- a/ports/esp32/boards/ESP32_GENERIC_S3/sdkconfig.board +++ b/ports/esp32/boards/ESP32_GENERIC_S3/sdkconfig.board @@ -1,6 +1,5 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -CONFIG_ESPTOOLPY_AFTER_NORESET=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB= CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y diff --git a/ports/esp32/boards/UM_FEATHERS2/sdkconfig.board b/ports/esp32/boards/UM_FEATHERS2/sdkconfig.board index c2e1c2b3d3b7c..9ab58f215f2e6 100644 --- a/ports/esp32/boards/UM_FEATHERS2/sdkconfig.board +++ b/ports/esp32/boards/UM_FEATHERS2/sdkconfig.board @@ -1,6 +1,5 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -CONFIG_ESPTOOLPY_AFTER_NORESET=y CONFIG_SPIRAM_MEMTEST= diff --git a/ports/esp32/boards/UM_FEATHERS2NEO/sdkconfig.board b/ports/esp32/boards/UM_FEATHERS2NEO/sdkconfig.board index a624f7fd97fb1..6ef737212f23a 100644 --- a/ports/esp32/boards/UM_FEATHERS2NEO/sdkconfig.board +++ b/ports/esp32/boards/UM_FEATHERS2NEO/sdkconfig.board @@ -1,6 +1,5 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -CONFIG_ESPTOOLPY_AFTER_NORESET=y # LWIP CONFIG_LWIP_LOCAL_HOSTNAME="UMFeatherS2Neo" diff --git a/ports/esp32/boards/UM_FEATHERS3/sdkconfig.board b/ports/esp32/boards/UM_FEATHERS3/sdkconfig.board index c557141ebfc9b..3ca0c4b243e28 100644 --- a/ports/esp32/boards/UM_FEATHERS3/sdkconfig.board +++ b/ports/esp32/boards/UM_FEATHERS3/sdkconfig.board @@ -1,6 +1,5 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -CONFIG_ESPTOOLPY_AFTER_NORESET=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB= CONFIG_ESPTOOLPY_FLASHSIZE_8MB= diff --git a/ports/esp32/boards/UM_NANOS3/sdkconfig.board b/ports/esp32/boards/UM_NANOS3/sdkconfig.board index 31d7528317a1d..2a39c64337b20 100644 --- a/ports/esp32/boards/UM_NANOS3/sdkconfig.board +++ b/ports/esp32/boards/UM_NANOS3/sdkconfig.board @@ -1,6 +1,5 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -CONFIG_ESPTOOLPY_AFTER_NORESET=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB= CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y diff --git a/ports/esp32/boards/UM_PROS3/sdkconfig.board b/ports/esp32/boards/UM_PROS3/sdkconfig.board index 0de84d57d01d9..5752e03e60013 100644 --- a/ports/esp32/boards/UM_PROS3/sdkconfig.board +++ b/ports/esp32/boards/UM_PROS3/sdkconfig.board @@ -1,6 +1,5 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -CONFIG_ESPTOOLPY_AFTER_NORESET=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB= CONFIG_ESPTOOLPY_FLASHSIZE_8MB= diff --git a/ports/esp32/boards/UM_TINYS2/sdkconfig.board b/ports/esp32/boards/UM_TINYS2/sdkconfig.board index 0a2097e242141..c09731431b9e0 100644 --- a/ports/esp32/boards/UM_TINYS2/sdkconfig.board +++ b/ports/esp32/boards/UM_TINYS2/sdkconfig.board @@ -1,6 +1,5 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -CONFIG_ESPTOOLPY_AFTER_NORESET=y # LWIP CONFIG_LWIP_LOCAL_HOSTNAME="UMTinyS2" diff --git a/ports/esp32/boards/UM_TINYS3/sdkconfig.board b/ports/esp32/boards/UM_TINYS3/sdkconfig.board index d1689aaf394c8..d1d19761a0666 100644 --- a/ports/esp32/boards/UM_TINYS3/sdkconfig.board +++ b/ports/esp32/boards/UM_TINYS3/sdkconfig.board @@ -1,6 +1,5 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -CONFIG_ESPTOOLPY_AFTER_NORESET=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB= CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y diff --git a/ports/esp32/boards/UM_TINYWATCHS3/sdkconfig.board b/ports/esp32/boards/UM_TINYWATCHS3/sdkconfig.board index d73f4fe0bc012..1380e15ce8481 100644 --- a/ports/esp32/boards/UM_TINYWATCHS3/sdkconfig.board +++ b/ports/esp32/boards/UM_TINYWATCHS3/sdkconfig.board @@ -1,6 +1,5 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -CONFIG_ESPTOOLPY_AFTER_NORESET=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB= CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c index 759455a59a5d6..853a253476199 100644 --- a/ports/esp32/modmachine.c +++ b/ports/esp32/modmachine.c @@ -222,8 +222,25 @@ static mp_int_t mp_machine_reset_cause(void) { #if MICROPY_ESP32_USE_BOOTLOADER_RTC #include "soc/rtc_cntl_reg.h" +#include "usb.h" +#if CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/rom/usb/usb_dc.h" +#include "esp32s2/rom/usb/usb_persist.h" +#include "esp32s2/rom/usb/chip_usb_dw_wrapper.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/usb/usb_dc.h" +#include "esp32s3/rom/usb/usb_persist.h" +#include "esp32s3/rom/usb/chip_usb_dw_wrapper.h" +#endif + NORETURN static void machine_bootloader_rtc(void) { + #if CONFIG_IDF_TARGET_ESP32S3 + usb_usj_mode(); + #endif + usb_dc_prepare_persist(); + chip_usb_set_persist_flags(USBDC_BOOT_DFU); REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT); + mp_hal_delay_ms(100); esp_restart(); } #endif diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 65d6b074408b7..323f5147fc06e 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -205,6 +205,7 @@ #if MICROPY_HW_ENABLE_USBDEV #define MICROPY_SCHEDULER_STATIC_NODES (1) +#define MICROPY_HW_ESP_AUTOMATIC_BOOTLOADER (1) // Enable USB-CDC serial port #ifndef MICROPY_HW_USB_CDC @@ -291,7 +292,7 @@ void *esp_native_code_commit(void *, size_t, void *); extern void mp_handle_pending(bool); \ mp_handle_pending(true); \ MICROPY_PY_SOCKET_EVENTS_HANDLER \ - MICROPY_HW_USBDEV_TASK_HOOK \ + MICROPY_HW_USBDEV_TASK_HOOK \ asm ("waiti 0"); \ } while (0); #endif diff --git a/ports/esp32/usb.c b/ports/esp32/usb.c index d462f8b9cee95..f45a20411f86f 100644 --- a/ports/esp32/usb.c +++ b/ports/esp32/usb.c @@ -81,6 +81,18 @@ void usb_init(void) { } +#if CONFIG_IDF_TARGET_ESP32S3 +void usb_usj_mode(void) { + // Switch the USB PHY back to Serial/Jtag mode, disabling OTG support + // This should be run before jumping to bootloader. + usb_del_phy(phy_hdl); + usb_phy_config_t phy_conf = { + .controller = USB_PHY_CTRL_SERIAL_JTAG, + }; + usb_new_phy(&phy_conf, &phy_hdl); +} +#endif + void mp_usbd_port_get_serial_number(char *serial_buf) { // use factory default MAC as serial ID uint8_t mac[8]; diff --git a/ports/esp32/usb.h b/ports/esp32/usb.h index 5e5eea34e5694..2bfa3d31aff8b 100644 --- a/ports/esp32/usb.h +++ b/ports/esp32/usb.h @@ -29,5 +29,6 @@ #define MICROPY_HW_USB_CDC_TX_TIMEOUT_MS (500) void usb_init(void); +void usb_usj_mode(void); #endif // MICROPY_INCLUDED_ESP32_USB_H diff --git a/ports/renesas-ra/README.md b/ports/renesas-ra/README.md index 4b3a7696faeb3..248f34bcb9049 100644 --- a/ports/renesas-ra/README.md +++ b/ports/renesas-ra/README.md @@ -43,7 +43,7 @@ when invoking `make`. * Protocol buffer compiler Building for the `ARDUINO_PORTENTA_C33` board will build the `esp_hosted` driver, that depends on the Protocol Buffer Compiler being installed. On Debian/Ubuntu, this can be installed with -`sudo apt-get install protobuf-compiler`. +`sudo apt-get install protobuf-c-compiler`. * Obtain submodules First the submodules must be obtained using: diff --git a/ports/renesas-ra/boards/EK_RA4W1/mpconfigboard.h b/ports/renesas-ra/boards/EK_RA4W1/mpconfigboard.h index 9eda05f0fdd1b..42131c8627ffe 100644 --- a/ports/renesas-ra/boards/EK_RA4W1/mpconfigboard.h +++ b/ports/renesas-ra/boards/EK_RA4W1/mpconfigboard.h @@ -19,7 +19,7 @@ #define MICROPY_HW_ENABLE_ADC (1) #define MICROPY_HW_HAS_FLASH (1) #define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1) - +#define MICROPY_HW_ENABLE_USBDEV (0) // board config // UART diff --git a/ports/renesas-ra/main.c b/ports/renesas-ra/main.c index febb7b6d7aaa3..6f4cedb9ac223 100644 --- a/ports/renesas-ra/main.c +++ b/ports/renesas-ra/main.c @@ -36,7 +36,6 @@ #include "shared/readline/readline.h" #include "shared/runtime/pyexec.h" #include "shared/runtime/softtimer.h" -#include "shared/tinyusb/mp_usbd.h" #include "lib/oofatfs/ff.h" #include "lib/littlefs/lfs1.h" #include "lib/littlefs/lfs1_util.h" diff --git a/shared/tinyusb/mp_usbd_cdc.c b/shared/tinyusb/mp_usbd_cdc.c index 79e1e9b3dbd39..ac564c1958af2 100644 --- a/shared/tinyusb/mp_usbd_cdc.c +++ b/shared/tinyusb/mp_usbd_cdc.c @@ -139,7 +139,7 @@ void tud_sof_cb(uint32_t frame_count) { } } -#if MICROPY_HW_USB_CDC_1200BPS_TOUCH +#if MICROPY_HW_USB_CDC_1200BPS_TOUCH || MICROPY_HW_ESP_AUTOMATIC_BOOTLOADER static mp_sched_node_t mp_bootloader_sched_node; static void usbd_cdc_run_bootloader_task(mp_sched_node_t *node) { @@ -148,6 +148,13 @@ static void usbd_cdc_run_bootloader_task(mp_sched_node_t *node) { } #endif +#if MICROPY_HW_ESP_AUTOMATIC_BOOTLOADER +static struct { + bool dtr : 1; + bool rts : 1; +} prev_line_state = {0}; +#endif + void #if MICROPY_HW_USB_EXTERNAL_TINYUSB mp_usbd_line_state_cb @@ -163,6 +170,17 @@ tud_cdc_line_state_cb cdc_connected_flush_delay = (tud_speed_get() == TUSB_SPEED_HIGH) ? 128 : 16; tud_sof_cb_enable(true); } + + #if MICROPY_HW_ESP_AUTOMATIC_BOOTLOADER + if (dtr && !rts) { + if (prev_line_state.rts && !prev_line_state.dtr) { + mp_sched_schedule_node(&mp_bootloader_sched_node, usbd_cdc_run_bootloader_task); + } + } + prev_line_state.rts = rts; + prev_line_state.dtr = dtr; + #endif + #if MICROPY_HW_USB_CDC_1200BPS_TOUCH if (dtr == false && rts == false) { // Device is disconnected.