From 4247921c4ebfced79aa7ccfbb835c9f60ad6f0fc Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 23 May 2024 17:23:41 +1000 Subject: [PATCH 1/6] esp32: Use shared/tinyusb integration for S2 and S3 USB. Uses newer TinyUSB synopsys/dwc2 driver for esp32s2 and esp32s3 rather than the IDF tinyusb component. This allows re-use of other tinyusb integration code and features shared between ports. Signed-off-by: Andrew Leech --- ports/esp32/esp32_common.cmake | 40 ++++++++++++ ports/esp32/main.c | 3 +- ports/esp32/main_esp32s2/CMakeLists.txt | 2 + ports/esp32/main_esp32s3/CMakeLists.txt | 2 + ports/esp32/mpconfigport.h | 77 ++++++++++++++++++----- ports/esp32/mphalport.c | 27 ++++++-- ports/esp32/usb.c | 83 +++++++------------------ ports/esp32/usb.h | 1 - pyproject.toml | 2 +- 9 files changed, 156 insertions(+), 81 deletions(-) diff --git a/ports/esp32/esp32_common.cmake b/ports/esp32/esp32_common.cmake index 7c5089639a5f2..e59e2dcd7a444 100644 --- a/ports/esp32/esp32_common.cmake +++ b/ports/esp32/esp32_common.cmake @@ -53,6 +53,37 @@ list(APPEND MICROPY_SOURCE_DRIVERS ${MICROPY_DIR}/drivers/dht/dht.c ) +string(CONCAT GIT_SUBMODULES "${GIT_SUBMODULES} " lib/tinyusb) +if(MICROPY_PY_TINYUSB) + set(TINYUSB_SRC "${MICROPY_DIR}/lib/tinyusb/src") + string(TOUPPER OPT_MCU_${IDF_TARGET} tusb_mcu) + + list(APPEND MICROPY_DEF_TINYUSB + CFG_TUSB_MCU=${tusb_mcu} + ) + + list(APPEND MICROPY_SOURCE_TINYUSB + ${TINYUSB_SRC}/tusb.c + ${TINYUSB_SRC}/common/tusb_fifo.c + ${TINYUSB_SRC}/device/usbd.c + ${TINYUSB_SRC}/device/usbd_control.c + ${TINYUSB_SRC}/class/cdc/cdc_device.c + ${TINYUSB_SRC}/portable/synopsys/dwc2/dcd_dwc2.c + ${MICROPY_DIR}/shared/tinyusb/mp_usbd.c + ${MICROPY_DIR}/shared/tinyusb/mp_usbd_cdc.c + ${MICROPY_DIR}/shared/tinyusb/mp_usbd_descriptor.c + ) + + list(APPEND MICROPY_INC_TINYUSB + ${TINYUSB_SRC} + ${MICROPY_DIR}/shared/tinyusb/ + ) + + list(APPEND MICROPY_LINK_TINYUSB + -Wl,--wrap=dcd_event_handler + ) +endif() + list(APPEND MICROPY_SOURCE_PORT panichandler.c adc.c @@ -100,6 +131,7 @@ list(APPEND MICROPY_SOURCE_QSTR ${MICROPY_SOURCE_LIB} ${MICROPY_SOURCE_PORT} ${MICROPY_SOURCE_BOARD} + ${MICROPY_SOURCE_TINYUSB} ) list(APPEND IDF_COMPONENTS @@ -134,6 +166,7 @@ list(APPEND IDF_COMPONENTS soc spi_flash ulp + usb vfs ) @@ -147,9 +180,11 @@ idf_component_register( ${MICROPY_SOURCE_DRIVERS} ${MICROPY_SOURCE_PORT} ${MICROPY_SOURCE_BOARD} + ${MICROPY_SOURCE_TINYUSB} INCLUDE_DIRS ${MICROPY_INC_CORE} ${MICROPY_INC_USERMOD} + ${MICROPY_INC_TINYUSB} ${MICROPY_PORT_DIR} ${MICROPY_BOARD_DIR} ${CMAKE_BINARY_DIR} @@ -171,6 +206,7 @@ endif() target_compile_definitions(${MICROPY_TARGET} PUBLIC ${MICROPY_DEF_CORE} ${MICROPY_DEF_BOARD} + ${MICROPY_DEF_TINYUSB} MICROPY_ESP_IDF_4=1 MICROPY_VFS_FAT=1 MICROPY_VFS_LFS2=1 @@ -186,6 +222,10 @@ target_compile_options(${MICROPY_TARGET} PUBLIC -Wno-missing-field-initializers ) +target_link_options(${MICROPY_TARGET} PUBLIC + ${MICROPY_LINK_TINYUSB} +) + # Additional include directories needed for private NimBLE headers. target_include_directories(${MICROPY_TARGET} PUBLIC ${IDF_PATH}/components/bt/host/nimble/nimble diff --git a/ports/esp32/main.c b/ports/esp32/main.c index ca5a0e3c2097c..03dc0807a025c 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -52,6 +52,7 @@ #include "shared/readline/readline.h" #include "shared/runtime/pyexec.h" #include "shared/timeutils/timeutils.h" +#include "shared/tinyusb/mp_usbd.h" #include "mbedtls/platform_time.h" #include "uart.h" @@ -101,7 +102,7 @@ void mp_task(void *pvParameter) { #endif #if MICROPY_HW_ESP_USB_SERIAL_JTAG usb_serial_jtag_init(); - #elif MICROPY_HW_USB_CDC + #elif MICROPY_HW_ENABLE_USBDEV usb_init(); #endif #if MICROPY_HW_ENABLE_UART_REPL diff --git a/ports/esp32/main_esp32s2/CMakeLists.txt b/ports/esp32/main_esp32s2/CMakeLists.txt index 40188abff8e57..bc5ab939c3ce3 100644 --- a/ports/esp32/main_esp32s2/CMakeLists.txt +++ b/ports/esp32/main_esp32s2/CMakeLists.txt @@ -8,4 +8,6 @@ if(NOT MICROPY_PORT_DIR) get_filename_component(MICROPY_PORT_DIR ${MICROPY_DIR}/ports/esp32 ABSOLUTE) endif() +set(MICROPY_PY_TINYUSB ON) + include(${MICROPY_PORT_DIR}/esp32_common.cmake) diff --git a/ports/esp32/main_esp32s3/CMakeLists.txt b/ports/esp32/main_esp32s3/CMakeLists.txt index 40188abff8e57..bc5ab939c3ce3 100644 --- a/ports/esp32/main_esp32s3/CMakeLists.txt +++ b/ports/esp32/main_esp32s3/CMakeLists.txt @@ -8,4 +8,6 @@ if(NOT MICROPY_PORT_DIR) get_filename_component(MICROPY_PORT_DIR ${MICROPY_DIR}/ports/esp32 ABSOLUTE) endif() +set(MICROPY_PY_TINYUSB ON) + include(${MICROPY_PORT_DIR}/esp32_common.cmake) diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index 5dfb16447dec0..f1687cf168ff6 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -194,6 +194,69 @@ #define MP_STATE_PORT MP_STATE_VM +#ifndef MICROPY_HW_ENABLE_USBDEV +#define MICROPY_HW_ENABLE_USBDEV (SOC_USB_OTG_SUPPORTED) +#endif + +#if MICROPY_HW_ENABLE_USBDEV +#define MICROPY_SCHEDULER_STATIC_NODES (1) + +#ifndef MICROPY_HW_USB_VID +#define USB_ESPRESSIF_VID 0x303A +#if CONFIG_TINYUSB_DESC_USE_ESPRESSIF_VID +#define MICROPY_HW_USB_VID (USB_ESPRESSIF_VID) +#else +#define MICROPY_HW_USB_VID (CONFIG_TINYUSB_DESC_CUSTOM_VID) +#endif +#endif + +#ifndef MICROPY_HW_USB_PID +#if CONFIG_TINYUSB_DESC_USE_DEFAULT_PID +#define _PID_MAP(itf, n) ((CFG_TUD_##itf) << (n)) +// A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. +// Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. +// Auto ProductID layout's Bitmap: +// [MSB] HID | MSC | CDC [LSB] +#define USB_TUSB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3)) // | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) ) +#define MICROPY_HW_USB_PID (USB_TUSB_PID) +#else +#define MICROPY_HW_USB_PID (CONFIG_TINYUSB_DESC_CUSTOM_PID) +#endif +#endif + +#ifndef MICROPY_HW_USB_MANUFACTURER_STRING +#ifdef CONFIG_TINYUSB_DESC_MANUFACTURER_STRING +#define MICROPY_HW_USB_MANUFACTURER_STRING CONFIG_TINYUSB_DESC_MANUFACTURER_STRING +#else +#define MICROPY_HW_USB_MANUFACTURER_STRING "MicroPython" +#endif +#endif + +#ifndef MICROPY_HW_USB_PRODUCT_FS_STRING +#ifdef CONFIG_TINYUSB_DESC_PRODUCT_STRING +#define MICROPY_HW_USB_PRODUCT_FS_STRING CONFIG_TINYUSB_DESC_PRODUCT_STRING +#else +#define MICROPY_HW_USB_PRODUCT_FS_STRING "Board in FS mode" +#endif +#endif + +#endif // MICROPY_HW_ENABLE_USBDEV + +// Enable stdio over native USB peripheral CDC via TinyUSB +#ifndef MICROPY_HW_USB_CDC +#define MICROPY_HW_USB_CDC (MICROPY_HW_ENABLE_USBDEV) +#endif + +// Enable stdio over USB Serial/JTAG peripheral +#ifndef MICROPY_HW_ESP_USB_SERIAL_JTAG +#define MICROPY_HW_ESP_USB_SERIAL_JTAG (SOC_USB_SERIAL_JTAG_SUPPORTED && !MICROPY_HW_USB_CDC) +#endif + +#if MICROPY_HW_USB_CDC && MICROPY_HW_ESP_USB_SERIAL_JTAG +#error "Invalid build config: Can't enable both native USB and USB Serial/JTAG peripheral" +#endif + // type definitions for the specific machine #define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p))) @@ -253,20 +316,6 @@ typedef long mp_off_t; // board specifics #define MICROPY_PY_SYS_PLATFORM "esp32" -// Enable stdio over native USB peripheral CDC via TinyUSB -#ifndef MICROPY_HW_USB_CDC -#define MICROPY_HW_USB_CDC (SOC_USB_OTG_SUPPORTED) -#endif - -// Enable stdio over USB Serial/JTAG peripheral -#ifndef MICROPY_HW_ESP_USB_SERIAL_JTAG -#define MICROPY_HW_ESP_USB_SERIAL_JTAG (SOC_USB_SERIAL_JTAG_SUPPORTED && !MICROPY_HW_USB_CDC) -#endif - -#if MICROPY_HW_USB_CDC && MICROPY_HW_ESP_USB_SERIAL_JTAG -#error "Invalid build config: Can't enable both native USB and USB Serial/JTAG peripheral" -#endif - // ESP32-S3 extended IO for 47 & 48 #ifndef MICROPY_HW_ESP32S3_EXTENDED_IO #define MICROPY_HW_ESP32S3_EXTENDED_IO (1) diff --git a/ports/esp32/mphalport.c b/ports/esp32/mphalport.c index 7d0154cc05315..3f267401366cb 100644 --- a/ports/esp32/mphalport.c +++ b/ports/esp32/mphalport.c @@ -42,6 +42,8 @@ #include "extmod/misc.h" #include "shared/timeutils/timeutils.h" #include "shared/runtime/pyexec.h" +#include "shared/tinyusb/mp_usbd.h" +#include "shared/tinyusb/mp_usbd_cdc.h" #include "mphalport.h" #include "usb.h" #include "usb_serial_jtag.h" @@ -106,13 +108,19 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { uintptr_t ret = 0; #if MICROPY_HW_ESP_USB_SERIAL_JTAG usb_serial_jtag_poll_rx(); - #endif - if ((poll_flags & MP_STREAM_POLL_RD) && stdin_ringbuf.iget != stdin_ringbuf.iput) { + if ((poll_flags & MP_STREAM_POLL_RD) && ringbuf_peek(&stdin_ringbuf) != -1) { ret |= MP_STREAM_POLL_RD; } if (poll_flags & MP_STREAM_POLL_WR) { ret |= MP_STREAM_POLL_WR; } + #endif + #if MICROPY_HW_USB_CDC + ret |= mp_usbd_cdc_poll_interfaces(poll_flags); + #endif + #if MICROPY_PY_OS_DUPTERM + ret |= mp_os_dupterm_poll(poll_flags); + #endif return ret; } @@ -121,6 +129,9 @@ int mp_hal_stdin_rx_chr(void) { #if MICROPY_HW_ESP_USB_SERIAL_JTAG usb_serial_jtag_poll_rx(); #endif + #if MICROPY_HW_USB_CDC + mp_usbd_cdc_poll_interfaces(0); + #endif int c = ringbuf_get(&stdin_ringbuf); if (c != -1) { return c; @@ -133,6 +144,7 @@ mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) { // Only release the GIL if many characters are being sent mp_uint_t ret = len; bool did_write = false; + #if MICROPY_HW_ENABLE_UART_REPL || CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED bool release_gil = len > MICROPY_PY_STRING_TX_GIL_THRESHOLD; #if MICROPY_DEBUG_PRINTERS && MICROPY_DEBUG_VERBOSE && MICROPY_PY_THREAD_GIL // If verbose debug output is enabled some strings are printed before the @@ -146,9 +158,6 @@ mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) { #if MICROPY_HW_ESP_USB_SERIAL_JTAG usb_serial_jtag_tx_strn(str, len); did_write = true; - #elif MICROPY_HW_USB_CDC - usb_tx_strn(str, len); - did_write = true; #endif #if MICROPY_HW_ENABLE_UART_REPL uart_stdout_tx_strn(str, len); @@ -157,6 +166,14 @@ mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) { if (release_gil) { MP_THREAD_GIL_ENTER(); } + #endif // MICROPY_HW_ENABLE_UART_REPL || CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED + #if MICROPY_HW_USB_CDC + mp_uint_t cdc_res = mp_usbd_cdc_tx_strn(str, len); + if (cdc_res > 0) { + did_write = true; + ret = MIN(cdc_res, ret); + } + #endif int dupterm_res = mp_os_dupterm_tx_strn(str, len); if (dupterm_res >= 0) { did_write = true; diff --git a/ports/esp32/usb.c b/ports/esp32/usb.c index 4207e77df210b..d643a7bc77410 100644 --- a/ports/esp32/usb.c +++ b/ports/esp32/usb.c @@ -29,75 +29,40 @@ #include "usb.h" #if MICROPY_HW_USB_CDC +#include "esp_rom_gpio.h" +#include "esp_mac.h" +#include "esp_private/usb_phy.h" -#include "esp_timer.h" -#ifndef NO_QSTR -#include "tinyusb.h" -#include "tusb_cdc_acm.h" -#endif +#include "shared/tinyusb/mp_usbd.h" -#define CDC_ITF TINYUSB_CDC_ACM_0 +static usb_phy_handle_t phy_hdl; -static uint8_t usb_rx_buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE]; - -// This is called from FreeRTOS task "tusb_tsk" in espressif__esp_tinyusb (not an ISR). -static void usb_callback_rx(int itf, cdcacm_event_t *event) { - // espressif__esp_tinyusb places tinyusb rx data onto freertos ringbuffer which - // this function forwards onto our stdin_ringbuf. - for (;;) { - size_t len = 0; - esp_err_t ret = tinyusb_cdcacm_read(itf, usb_rx_buf, sizeof(usb_rx_buf), &len); - if (ret != ESP_OK) { - break; - } - if (len == 0) { - break; - } - for (size_t i = 0; i < len; ++i) { - if (usb_rx_buf[i] == mp_interrupt_char) { - mp_sched_keyboard_interrupt(); - } else { - ringbuf_put(&stdin_ringbuf, usb_rx_buf[i]); - } - } - mp_hal_wake_main_task(); - } -} void usb_init(void) { - // Initialise the USB with defaults. - tinyusb_config_t tusb_cfg = {0}; - ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + // ref: https://github.com/espressif/esp-usb/blob/4b6a798d0bed444fff48147c8dcdbbd038e92892/device/esp_tinyusb/tinyusb.c - // Initialise the USB serial interface. - tinyusb_config_cdcacm_t acm_cfg = { - .usb_dev = TINYUSB_USBDEV_0, - .cdc_port = CDC_ITF, - .rx_unread_buf_sz = 256, - .callback_rx = &usb_callback_rx, - #ifdef MICROPY_HW_USB_CUSTOM_RX_WANTED_CHAR_CB - .callback_rx_wanted_char = &MICROPY_HW_USB_CUSTOM_RX_WANTED_CHAR_CB, - #endif - #ifdef MICROPY_HW_USB_CUSTOM_LINE_STATE_CB - .callback_line_state_changed = (tusb_cdcacm_callback_t)&MICROPY_HW_USB_CUSTOM_LINE_STATE_CB, - #endif - #ifdef MICROPY_HW_USB_CUSTOM_LINE_CODING_CB - .callback_line_coding_changed = &MICROPY_HW_USB_CUSTOM_LINE_CODING_CB, - #endif + // Configure USB PHY + usb_phy_config_t phy_conf = { + .controller = USB_PHY_CTRL_OTG, + .otg_mode = USB_OTG_MODE_DEVICE, }; - ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg)); + // Internal USB PHY + phy_conf.target = USB_PHY_TARGET_INT; + + // Init ESP USB Phy + usb_new_phy(&phy_conf, &phy_hdl); + + // Init MicroPython / TinyUSB + mp_usbd_init(); } -void usb_tx_strn(const char *str, size_t len) { - // Write out the data to the CDC interface, but only while the USB host is connected. - uint64_t timeout = esp_timer_get_time() + (uint64_t)(MICROPY_HW_USB_CDC_TX_TIMEOUT_MS * 1000); - while (tud_cdc_n_connected(CDC_ITF) && len && esp_timer_get_time() < timeout) { - size_t l = tinyusb_cdcacm_write_queue(CDC_ITF, (uint8_t *)str, len); - str += l; - len -= l; - tud_cdc_n_write_flush(CDC_ITF); - } +void mp_usbd_port_get_serial_number(char *serial_buf) { + // use factory default MAC as serial ID + uint8_t mac[8]; + esp_efuse_mac_get_default(mac); + MP_STATIC_ASSERT(sizeof(mac) * 2 <= MICROPY_HW_USB_DESC_STR_MAX); + mp_usbd_hex_str(serial_buf, mac, sizeof(mac)); } #endif // MICROPY_HW_USB_CDC diff --git a/ports/esp32/usb.h b/ports/esp32/usb.h index a4c7d40701dfc..5e5eea34e5694 100644 --- a/ports/esp32/usb.h +++ b/ports/esp32/usb.h @@ -29,6 +29,5 @@ #define MICROPY_HW_USB_CDC_TX_TIMEOUT_MS (500) void usb_init(void); -void usb_tx_strn(const char *str, size_t len); #endif // MICROPY_INCLUDED_ESP32_USB_H diff --git a/pyproject.toml b/pyproject.toml index e44afe37e0ebb..1650bd088ea22 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.codespell] count = "" ignore-regex = '\b[A-Z]{3}\b' -ignore-words-list = "ans,asend,deques,dout,extint,hsi,iput,mis,numer,shft,technic,ure" +ignore-words-list = "ans,asend,deques,dout,extint,hsi,iput,mis,numer,shft,synopsys,technic,ure" quiet-level = 3 skip = """ */build*,\ From 641f60045f8014ad480e4297b982753edcb5b5c6 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 23 May 2024 17:23:41 +1000 Subject: [PATCH 2/6] shared/tinyusb: Remove MICROPY_HW_USB_EXTERNAL_TINYUSB. No longer needed as shared tinyusb is now used by the esp32 port. Signed-off-by: Andrew Leech --- shared/tinyusb/mp_usbd_cdc.c | 8 +------- shared/tinyusb/mp_usbd_cdc.h | 4 ---- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/shared/tinyusb/mp_usbd_cdc.c b/shared/tinyusb/mp_usbd_cdc.c index c6a88e467d398..0fbecb0a8657f 100644 --- a/shared/tinyusb/mp_usbd_cdc.c +++ b/shared/tinyusb/mp_usbd_cdc.c @@ -149,13 +149,7 @@ static void usbd_cdc_run_bootloader_task(mp_sched_node_t *node) { } #endif -void -#if MICROPY_HW_USB_EXTERNAL_TINYUSB -mp_usbd_line_state_cb -#else -tud_cdc_line_state_cb -#endif - (uint8_t itf, bool dtr, bool rts) { +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { #if MICROPY_HW_USB_CDC && !MICROPY_EXCLUDE_SHARED_TINYUSB_USBD_CDC if (dtr) { // A host application has started to open the cdc serial port. diff --git a/shared/tinyusb/mp_usbd_cdc.h b/shared/tinyusb/mp_usbd_cdc.h index 1abe0fa0a41b3..648cf12881e31 100644 --- a/shared/tinyusb/mp_usbd_cdc.h +++ b/shared/tinyusb/mp_usbd_cdc.h @@ -35,8 +35,4 @@ uintptr_t mp_usbd_cdc_poll_interfaces(uintptr_t poll_flags); void tud_cdc_rx_cb(uint8_t itf); mp_uint_t mp_usbd_cdc_tx_strn(const char *str, mp_uint_t len); -#if MICROPY_HW_USB_EXTERNAL_TINYUSB -void mp_usbd_line_state_cb(uint8_t itf, bool dtr, bool rts); -#endif - #endif // MICROPY_INCLUDED_SHARED_TINYUSB_MP_USBD_CDC_H From 5ae622ef7b31881cb38b56baa66d8aec3d132cf9 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 23 May 2024 22:08:12 +1000 Subject: [PATCH 3/6] 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 | 12 ++++++++++ ports/esp32/mpconfigport.h | 3 ++- ports/esp32/usb.c | 12 ++++++++++ ports/esp32/usb.h | 1 + shared/tinyusb/mp_usbd_cdc.c | 23 +++++++++++++++++-- shared/tinyusb/mp_usbd_cdc.h | 6 +++++ 15 files changed, 54 insertions(+), 12 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..5e05a261b70c7 100644 --- a/ports/esp32/modmachine.c +++ b/ports/esp32/modmachine.c @@ -222,7 +222,19 @@ 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_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(); + usb_dc_prepare_persist(); + chip_usb_set_persist_flags(USBDC_BOOT_DFU); + #endif REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT); esp_restart(); } diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index f1687cf168ff6..4c94fd16e2c58 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -199,7 +199,8 @@ #endif #if MICROPY_HW_ENABLE_USBDEV -#define MICROPY_SCHEDULER_STATIC_NODES (1) +#define MICROPY_SCHEDULER_STATIC_NODES (1) +#define MICROPY_HW_USB_CDC_DTR_RTS_BOOTLOADER (1) #ifndef MICROPY_HW_USB_VID #define USB_ESPRESSIF_VID 0x303A diff --git a/ports/esp32/usb.c b/ports/esp32/usb.c index d643a7bc77410..3ce3d045810af 100644 --- a/ports/esp32/usb.c +++ b/ports/esp32/usb.c @@ -57,6 +57,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/shared/tinyusb/mp_usbd_cdc.c b/shared/tinyusb/mp_usbd_cdc.c index 0fbecb0a8657f..b4151f685c41e 100644 --- a/shared/tinyusb/mp_usbd_cdc.c +++ b/shared/tinyusb/mp_usbd_cdc.c @@ -138,9 +138,12 @@ void tud_sof_cb(uint32_t frame_count) { #endif -#if MICROPY_HW_ENABLE_USBDEV && (MICROPY_HW_USB_CDC_1200BPS_TOUCH || MICROPY_HW_USB_CDC) +#if MICROPY_HW_ENABLE_USBDEV && ( \ + MICROPY_HW_USB_CDC_1200BPS_TOUCH || \ + MICROPY_HW_USB_CDC || \ + MICROPY_HW_USB_CDC_DTR_RTS_BOOTLOADER) -#if MICROPY_HW_USB_CDC_1200BPS_TOUCH +#if MICROPY_HW_USB_CDC_1200BPS_TOUCH || MICROPY_HW_USB_CDC_DTR_RTS_BOOTLOADER static mp_sched_node_t mp_bootloader_sched_node; static void usbd_cdc_run_bootloader_task(mp_sched_node_t *node) { @@ -149,6 +152,13 @@ static void usbd_cdc_run_bootloader_task(mp_sched_node_t *node) { } #endif +#if MICROPY_HW_USB_CDC_DTR_RTS_BOOTLOADER +static struct { + bool dtr : 1; + bool rts : 1; +} prev_line_state = {0}; +#endif + void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { #if MICROPY_HW_USB_CDC && !MICROPY_EXCLUDE_SHARED_TINYUSB_USBD_CDC if (dtr) { @@ -159,6 +169,15 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { tud_sof_cb_enable(true); } #endif + #if MICROPY_HW_USB_CDC_DTR_RTS_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. diff --git a/shared/tinyusb/mp_usbd_cdc.h b/shared/tinyusb/mp_usbd_cdc.h index 648cf12881e31..8d37a77315dcc 100644 --- a/shared/tinyusb/mp_usbd_cdc.h +++ b/shared/tinyusb/mp_usbd_cdc.h @@ -31,6 +31,12 @@ #define MICROPY_HW_USB_CDC_TX_TIMEOUT (500) #endif +// This is typically only enabled on esp32 +// parts which have an internal usb peripheral. +#ifndef MICROPY_HW_USB_CDC_DTR_RTS_BOOTLOADER +#define MICROPY_HW_USB_CDC_DTR_RTS_BOOTLOADER (0) +#endif + uintptr_t mp_usbd_cdc_poll_interfaces(uintptr_t poll_flags); void tud_cdc_rx_cb(uint8_t itf); mp_uint_t mp_usbd_cdc_tx_strn(const char *str, mp_uint_t len); From 386771e052cd0396031705f22bd2ecab5cc30ea5 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 4 Jun 2024 13:46:00 +1000 Subject: [PATCH 4/6] esp32/Makefile: Allow auto-port selection if not passed on cmdline. Signed-off-by: Andrew Leech --- ports/esp32/Makefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile index 3df2af4716fd9..62b1faa571931 100644 --- a/ports/esp32/Makefile +++ b/ports/esp32/Makefile @@ -29,8 +29,12 @@ BUILD ?= build-$(BOARD) endif # Device serial settings. -PORT ?= /dev/ttyUSB0 -BAUD ?= 460800 +ifneq ($(PORT),) +PORT_ARG := -p $(PORT) +endif +ifneq ($(BAUD),) +BAUD_ARG := -b $(BAUD) +endif PYTHON ?= python3 @@ -59,7 +63,7 @@ endif HELP_BUILD_ERROR ?= "See \033[1;31mhttps://github.com/micropython/micropython/wiki/Build-Troubleshooting\033[0m" define RUN_IDF_PY - idf.py $(IDFPY_FLAGS) -B $(BUILD) -p $(PORT) -b $(BAUD) $(1) + idf.py $(IDFPY_FLAGS) -B $(BUILD) $(PORT_ARG) $(BAUD_ARG) $(1) endef all: From 11bc7d0fc1074b01aaddc325209a281ee9acbba4 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 24 Sep 2024 11:35:53 +1000 Subject: [PATCH 5/6] esp32/boards: Update ARDUINO_NANO_ESP32 USB configuration. The custom line state handling is no longer needed as MicroPython runs it directly now. Signed-off-by: Andrew Leech --- ports/esp32/boards/ARDUINO_NANO_ESP32/board_init.c | 8 -------- ports/esp32/boards/ARDUINO_NANO_ESP32/mpconfigboard.h | 5 ----- 2 files changed, 13 deletions(-) diff --git a/ports/esp32/boards/ARDUINO_NANO_ESP32/board_init.c b/ports/esp32/boards/ARDUINO_NANO_ESP32/board_init.c index 69a414cd5d9e3..3394bb1e2e219 100644 --- a/ports/esp32/boards/ARDUINO_NANO_ESP32/board_init.c +++ b/ports/esp32/boards/ARDUINO_NANO_ESP32/board_init.c @@ -35,9 +35,6 @@ #include "double_tap.h" #include "usb.h" -#include "tinyusb.h" -#include "tusb_cdc_acm.h" - #define LED_RED GPIO_NUM_46 #define LED_GREEN GPIO_NUM_0 #define LED_BLUE GPIO_NUM_45 @@ -87,11 +84,6 @@ void NANO_ESP32_enter_bootloader(void) { esp_restart(); } -void NANO_ESP32_usb_callback_line_state_changed(int itf, void *event_in) { - cdcacm_event_t *event = event_in; - mp_usbd_line_state_cb(itf, event->line_state_changed_data.dtr, event->line_state_changed_data.rts); -} - void NANO_ESP32_board_startup(void) { boardctrl_startup(); diff --git a/ports/esp32/boards/ARDUINO_NANO_ESP32/mpconfigboard.h b/ports/esp32/boards/ARDUINO_NANO_ESP32/mpconfigboard.h index 8c2aa88e9f2ec..31b2a49bf8c31 100644 --- a/ports/esp32/boards/ARDUINO_NANO_ESP32/mpconfigboard.h +++ b/ports/esp32/boards/ARDUINO_NANO_ESP32/mpconfigboard.h @@ -19,14 +19,9 @@ #define MICROPY_HW_SPI2_SCK (18) #define MICROPY_HW_ENABLE_USBDEV (1) -#define MICROPY_EXCLUDE_SHARED_TINYUSB_USBD_CDC (1) -#define MICROPY_HW_USB_EXTERNAL_TINYUSB (1) #define MICROPY_HW_USB_CDC_1200BPS_TOUCH (1) #define MICROPY_SCHEDULER_STATIC_NODES (1) -#define MICROPY_HW_USB_CUSTOM_LINE_STATE_CB NANO_ESP32_usb_callback_line_state_changed -void NANO_ESP32_usb_callback_line_state_changed(int itf, void *event); - #define MICROPY_BOARD_STARTUP NANO_ESP32_board_startup void NANO_ESP32_board_startup(void); From 548f88d2bd254f1328014a303f8bf602a0646421 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Wed, 31 Jul 2024 21:40:05 +1000 Subject: [PATCH 6/6] shared/tinyusb: Wake main task if needed at end of USB ISR. Signed-off-by: Andrew Leech --- ports/mimxrt/mphalport.h | 4 ++++ ports/nrf/mphalport.h | 4 ++++ ports/renesas-ra/mphalport.h | 4 ++++ ports/rp2/mphalport.h | 4 ++++ ports/samd/mphalport.h | 4 ++++ shared/tinyusb/mp_usbd.c | 3 ++- 6 files changed, 22 insertions(+), 1 deletion(-) diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index c69ebf58106b2..a0e4575024420 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -109,6 +109,10 @@ __attribute__((always_inline)) static inline uint32_t disable_irq(void) { void mp_hal_set_interrupt_char(int c); +static inline void mp_hal_wake_main_task_from_isr(void) { + // Defined for tinyusb support, nothing needs to be done here. +} + static inline mp_uint_t mp_hal_ticks_ms(void) { return ticks_ms32(); } diff --git a/ports/nrf/mphalport.h b/ports/nrf/mphalport.h index 50c61aefcdd59..a0bca58a625ba 100644 --- a/ports/nrf/mphalport.h +++ b/ports/nrf/mphalport.h @@ -53,6 +53,10 @@ void mp_hal_set_interrupt_char(int c); // -1 to disable int mp_hal_stdin_rx_chr(void); void mp_hal_stdout_tx_str(const char *str); +static inline void mp_hal_wake_main_task_from_isr(void) { + // Defined for tinyusb support, nothing needs to be done here. +} + void mp_hal_delay_ms(mp_uint_t ms); void mp_hal_delay_us(mp_uint_t us); diff --git a/ports/renesas-ra/mphalport.h b/ports/renesas-ra/mphalport.h index 14e6ee0c3eea6..0819abeaf617e 100644 --- a/ports/renesas-ra/mphalport.h +++ b/ports/renesas-ra/mphalport.h @@ -52,6 +52,10 @@ static inline int mp_hal_status_to_neg_errno(HAL_StatusTypeDef status) { NORETURN void mp_hal_raise(HAL_StatusTypeDef status); void mp_hal_set_interrupt_char(int c); // -1 to disable +static inline void mp_hal_wake_main_task_from_isr(void) { + // Defined for tinyusb support, nothing needs to be done here. +} + // timing functions #include "irq.h" diff --git a/ports/rp2/mphalport.h b/ports/rp2/mphalport.h index 16ac4259a6feb..09ad54dd1eb78 100644 --- a/ports/rp2/mphalport.h +++ b/ports/rp2/mphalport.h @@ -77,6 +77,10 @@ void mp_thread_end_atomic_section(uint32_t); void mp_hal_set_interrupt_char(int c); void mp_hal_time_ns_set_from_rtc(void); +static inline void mp_hal_wake_main_task_from_isr(void) { + // Defined for tinyusb support, nothing needs to be done here. +} + static inline void mp_hal_delay_us_fast(mp_uint_t us) { busy_wait_us(us); } diff --git a/ports/samd/mphalport.h b/ports/samd/mphalport.h index ee1ebf7aea2b0..6c9e525bb9162 100644 --- a/ports/samd/mphalport.h +++ b/ports/samd/mphalport.h @@ -50,6 +50,10 @@ uint64_t mp_hal_ticks_us_64(void); void mp_hal_set_interrupt_char(int c); +static inline void mp_hal_wake_main_task_from_isr(void) { + // Defined for tinyusb support, nothing needs to be done here. +} + __attribute__((always_inline)) static inline void enable_irq(uint32_t state) { __set_PRIMASK(state); } diff --git a/shared/tinyusb/mp_usbd.c b/shared/tinyusb/mp_usbd.c index 436314dcde5c8..7ccfa7018d4bc 100644 --- a/shared/tinyusb/mp_usbd.c +++ b/shared/tinyusb/mp_usbd.c @@ -24,7 +24,7 @@ * THE SOFTWARE. */ -#include "py/mpconfig.h" +#include "py/mphal.h" #if MICROPY_HW_ENABLE_USBDEV @@ -55,6 +55,7 @@ extern void __real_dcd_event_handler(dcd_event_t const *event, bool in_isr); TU_ATTR_FAST_FUNC void __wrap_dcd_event_handler(dcd_event_t const *event, bool in_isr) { __real_dcd_event_handler(event, in_isr); mp_usbd_schedule_task(); + mp_hal_wake_main_task_from_isr(); } TU_ATTR_FAST_FUNC void mp_usbd_schedule_task(void) { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy