From e2f26a272c2946ee2ebaa33286e910a705f9d7ae Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Fri, 9 Aug 2024 19:37:10 +1000 Subject: [PATCH 1/2] runtime/pyexec: Remove legacy usb irq enable code. Signed-off-by: Andrew Leech --- shared/runtime/pyexec.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/shared/runtime/pyexec.c b/shared/runtime/pyexec.c index c828c75817940..a1bef6e151a29 100644 --- a/shared/runtime/pyexec.c +++ b/shared/runtime/pyexec.c @@ -35,10 +35,6 @@ #include "py/gc.h" #include "py/frozenmod.h" #include "py/mphal.h" -#if MICROPY_HW_ENABLE_USB -#include "irq.h" -#include "usb.h" -#endif #include "shared/readline/readline.h" #include "shared/runtime/pyexec.h" #include "genhdr/mpversion.h" @@ -582,20 +578,6 @@ int pyexec_friendly_repl(void) { for (;;) { input_restart: - - #if MICROPY_HW_ENABLE_USB - if (usb_vcp_is_enabled()) { - // If the user gets to here and interrupts are disabled then - // they'll never see the prompt, traceback etc. The USB REPL needs - // interrupts to be enabled or no transfers occur. So we try to - // do the user a favor and re-enable interrupts. - if (query_irq() == IRQ_STATE_DISABLED) { - enable_irq(IRQ_STATE_ENABLED); - mp_hal_stdout_tx_str("MPY: enabling IRQs\r\n"); - } - } - #endif - // If the GC is locked at this point there is no way out except a reset, // so force the GC to be unlocked to help the user debug what went wrong. if (MP_STATE_THREAD(gc_lock_depth) != 0) { From 916f5584ff7afbae01a9acd8b2817ee9531dcf9b Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 7 Aug 2025 15:03:47 +1000 Subject: [PATCH 2/2] stm32/usb: Add support for using TinyUSB stack. Signed-off-by: Andrew Leech --- ports/stm32/Makefile | 21 +- ports/stm32/main.c | 24 +- ports/stm32/modmachine.c | 7 +- ports/stm32/modos.c | 6 +- ports/stm32/modpyb.c | 7 +- ports/stm32/mpconfigboard_common.h | 46 +++- ports/stm32/mpconfigport.h | 3 + ports/stm32/mphalport.c | 28 +++ ports/stm32/mphalport.h | 8 + ports/stm32/stm32_it.c | 32 ++- ports/stm32/usb.c | 4 +- ports/stm32/usbd.c | 42 ++++ ports/stm32/usbd_conf.c | 381 +++++++++++++++-------------- ports/stm32/usbd_conf.h | 5 + tools/ci.sh | 1 + 15 files changed, 417 insertions(+), 198 deletions(-) create mode 100644 ports/stm32/usbd.c diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 37ce8fbd8383d..f7bc820ce0590 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -58,7 +58,7 @@ MBOOT_TEXT0_ADDR ?= 0x08000000 include $(TOP)/py/py.mk include $(TOP)/extmod/extmod.mk -GIT_SUBMODULES += lib/libhydrogen lib/stm32lib +GIT_SUBMODULES += lib/libhydrogen lib/stm32lib lib/tinyusb CROSS_COMPILE ?= arm-none-eabi- LD_DIR=boards @@ -110,6 +110,9 @@ INC += -I$(STM32LIB_CMSIS_ABS)/Include INC += -I$(STM32LIB_HAL_ABS)/Inc INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/inc #INC += -I$(USBHOST_DIR) +INC += -I$(TOP)/lib/tinyusb/src +INC += -I$(TOP)/shared/tinyusb/ + INC += -Ilwip_inc CFLAGS += $(INC) -Wall -Wpointer-arith -Werror -Wdouble-promotion -Wfloat-conversion -std=gnu99 -nostdlib $(CFLAGS_EXTRA) @@ -213,6 +216,10 @@ SHARED_SRC_C += $(addprefix shared/,\ runtime/stdout_helpers.c \ runtime/sys_stdio_mphal.c \ timeutils/timeutils.c \ + tinyusb/mp_usbd.c \ + tinyusb/mp_usbd_cdc.c \ + tinyusb/mp_usbd_descriptor.c \ + tinyusb/mp_usbd_runtime.c \ ) ifeq ($(MICROPY_FLOAT_IMPL),double) @@ -238,11 +245,21 @@ DRIVERS_SRC_C += $(addprefix drivers/,\ dht/dht.c \ ) +# TinyUSB Stack source +-include $(TOP)/lib/tinyusb/src/tinyusb.mk +TINYUSB_SRC_C := $(addprefix lib/tinyusb/, \ + $(TINYUSB_SRC_C) \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + ) + SRC_C += \ boardctrl.c \ main.c \ stm32_it.c \ + usbd.c \ usbd_conf.c \ + usb.c \ usbd_desc.c \ usbd_cdc_interface.c \ usbd_hid_interface.c \ @@ -277,7 +294,6 @@ SRC_C += \ can.c \ fdcan.c \ pyb_can.c \ - usb.c \ eth.c \ eth_phy.c \ gccollect.c \ @@ -499,6 +515,7 @@ OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(HAL_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(USBDEV_SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(TINYUSB_SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o)) OBJ += $(GEN_PINS_SRC:.c=.o) diff --git a/ports/stm32/main.c b/ports/stm32/main.c index af4d7f8bbb6d3..26b9c0f03a3c4 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -77,7 +77,6 @@ #include "pin.h" #include "extint.h" #include "usrsw.h" -#include "usb.h" #include "rtc.h" #include "storage.h" #include "sdcard.h" @@ -89,6 +88,13 @@ #include "pyb_can.h" #include "subghz.h" +#if MICROPY_HW_TINYUSB_STACK +#include "usbd_conf.h" +#include "shared/tinyusb/mp_usbd.h" +#else +#include "usb.h" +#endif + #if MICROPY_PY_THREAD static pyb_thread_t pyb_thread_main; #endif @@ -276,14 +282,12 @@ static bool init_sdcard_fs(void) { } } - #if MICROPY_HW_ENABLE_USB + #if MICROPY_HW_ENABLE_USB && !MICROPY_HW_TINYUSB_STACK if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_NONE) { // if no USB MSC medium is selected then use the SD card pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_SDCARD; } - #endif - #if MICROPY_HW_ENABLE_USB // only use SD card as current directory if that's what the USB medium is if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_SDCARD) #endif @@ -604,8 +608,13 @@ void stm32_main(uint32_t reset_mode) { #endif #if MICROPY_HW_ENABLE_USB + #if MICROPY_HW_TINYUSB_STACK + pyb_usbd_init(); + mp_usbd_init(); + #else pyb_usb_init0(); #endif + #endif #if MICROPY_PY_MACHINE_I2S machine_i2s_init0(); @@ -629,7 +638,7 @@ void stm32_main(uint32_t reset_mode) { } #endif - #if MICROPY_HW_ENABLE_USB + #if MICROPY_HW_STM_USB_STACK // if the SD card isn't used as the USB MSC medium then use the internal flash if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_NONE) { pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_FLASH; @@ -663,7 +672,7 @@ void stm32_main(uint32_t reset_mode) { // or whose initialisation can be safely deferred until after running // boot.py. - #if MICROPY_HW_ENABLE_USB + #if MICROPY_HW_STM_USB_STACK // init USB device to default setting if it was not already configured if (!(pyb_usb_flags & PYB_USB_FLAG_USB_MODE_CALLED)) { #if MICROPY_HW_USB_MSC @@ -768,6 +777,9 @@ void stm32_main(uint32_t reset_mode) { #else MP_STATE_PORT(pyb_stdio_uart) = NULL; #endif + #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE && MICROPY_HW_TINYUSB_STACK + mp_usbd_deinit(); + #endif MICROPY_BOARD_END_SOFT_RESET(&state); diff --git a/ports/stm32/modmachine.c b/ports/stm32/modmachine.c index 8123cd8011521..46dc1293f6d4e 100644 --- a/ports/stm32/modmachine.c +++ b/ports/stm32/modmachine.c @@ -47,6 +47,7 @@ #include "rtc.h" #include "i2c.h" #include "spi.h" +#include "shared/tinyusb/mp_usbd.h" #if defined(STM32G0) // G0 has BOR and POR combined @@ -297,9 +298,13 @@ MP_NORETURN static void mp_machine_reset(void) { // Activate the bootloader without BOOT* pins. MP_NORETURN void mp_machine_bootloader(size_t n_args, const mp_obj_t *args) { - #if MICROPY_HW_ENABLE_USB + #if MICROPY_HW_ENABLE_USB && !MICROPY_HW_TINYUSB_STACK pyb_usb_dev_deinit(); #endif + #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE && MICROPY_HW_TINYUSB_STACK + mp_usbd_deinit(); + #endif + #if MICROPY_HW_ENABLE_STORAGE storage_flush(); #endif diff --git a/ports/stm32/modos.c b/ports/stm32/modos.c index 7949cf87cdecd..cd918fe715433 100644 --- a/ports/stm32/modos.c +++ b/ports/stm32/modos.c @@ -52,7 +52,7 @@ bool mp_os_dupterm_is_builtin_stream(mp_const_obj_t stream) { #if MICROPY_PY_MACHINE_UART || type == &machine_uart_type #endif - #if MICROPY_HW_ENABLE_USB + #if MICROPY_HW_STM_USB_STACK || type == &pyb_usb_vcp_type #endif ; @@ -64,7 +64,7 @@ void mp_os_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t s uart_attach_to_repl(MP_OBJ_TO_PTR(stream_detached), false); } #endif - #if MICROPY_HW_ENABLE_USB + #if MICROPY_HW_STM_USB_STACK if (mp_obj_get_type(stream_detached) == &pyb_usb_vcp_type) { usb_vcp_attach_to_repl(MP_OBJ_TO_PTR(stream_detached), false); } @@ -75,7 +75,7 @@ void mp_os_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t s uart_attach_to_repl(MP_OBJ_TO_PTR(stream_attached), true); } #endif - #if MICROPY_HW_ENABLE_USB + #if MICROPY_HW_STM_USB_STACK if (mp_obj_get_type(stream_attached) == &pyb_usb_vcp_type) { usb_vcp_attach_to_repl(MP_OBJ_TO_PTR(stream_attached), true); } diff --git a/ports/stm32/modpyb.c b/ports/stm32/modpyb.c index 3d8696e3c426e..cfc04a81e5df6 100644 --- a/ports/stm32/modpyb.c +++ b/ports/stm32/modpyb.c @@ -49,7 +49,6 @@ #include "servo.h" #include "dac.h" #include "lcd.h" -#include "usb.h" #include "portmodules.h" #include "modmachine.h" #include "extmod/modmachine.h" @@ -57,6 +56,10 @@ #include "extmod/vfs.h" #include "extmod/modtime.h" +#if !MICROPY_HW_TINYUSB_STACK +#include "usb.h" +#endif + #if MICROPY_PY_PYB static mp_obj_t pyb_fault_debug(mp_obj_t value) { @@ -167,7 +170,7 @@ static const mp_rom_map_elem_t pyb_module_globals_table[] = { // Deprecated (use network.country instead). { MP_ROM_QSTR(MP_QSTR_country), MP_ROM_PTR(&mod_network_country_obj) }, - #if MICROPY_HW_ENABLE_USB + #if MICROPY_HW_STM_USB_STACK { MP_ROM_QSTR(MP_QSTR_usb_mode), MP_ROM_PTR(&pyb_usb_mode_obj) }, #if MICROPY_HW_USB_HID { MP_ROM_QSTR(MP_QSTR_hid_mouse), MP_ROM_PTR(&pyb_usb_hid_mouse_obj) }, diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index dcbbbccceb6b0..728368ae46c68 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -136,6 +136,24 @@ #define MICROPY_HW_ENABLE_USB (0) #endif +#if MICROPY_HW_ENABLE_USB +#define MICROPY_HW_USB_CDC (1) +#define MICROPY_HW_USB_FS (1) + +// Select whether TinyUSB or legacy STM stack is used to provide USB. +#ifndef MICROPY_HW_TINYUSB_STACK +#define MICROPY_HW_TINYUSB_STACK (0) +#endif + +// Central definition for STM USB stack (when not using TinyUSB) +#define MICROPY_HW_STM_USB_STACK (MICROPY_HW_ENABLE_USB && !MICROPY_HW_TINYUSB_STACK) + +#if MICROPY_HW_TINYUSB_STACK +#define MICROPY_HW_ENABLE_USBDEV (1) +#endif + +#endif // MICROPY_HW_ENABLE_USB + // Whether to enable the PA0-PA3 servo driver, exposed as pyb.Servo #ifndef MICROPY_HW_ENABLE_SERVO #define MICROPY_HW_ENABLE_SERVO (0) @@ -256,6 +274,8 @@ // Windows needs a different PID to distinguish different device configurations. #ifndef MICROPY_HW_USB_VID #define MICROPY_HW_USB_VID (0xf055) +#define MICROPY_HW_USB_PID (0x9802) + #define MICROPY_HW_USB_PID_CDC_MSC (0x9800) #define MICROPY_HW_USB_PID_CDC_HID (0x9801) #define MICROPY_HW_USB_PID_CDC (0x9802) @@ -369,6 +389,8 @@ #endif #define MICROPY_HW_MAX_LPUART (0) +#define CFG_TUSB_MCU OPT_MCU_STM32F4 + // Configuration for STM32F7 series #elif defined(STM32F7) @@ -384,6 +406,8 @@ #define MICROPY_HW_MAX_UART (8) #define MICROPY_HW_MAX_LPUART (0) +#define CFG_TUSB_MCU OPT_MCU_STM32F7 + // Configuration for STM32G0 series #elif defined(STM32G0) @@ -394,6 +418,8 @@ #define MICROPY_HW_MAX_UART (6) #define MICROPY_HW_MAX_LPUART (2) +#define CFG_TUSB_MCU OPT_MCU_STM32G0 + // Configuration for STM32G4 series #elif defined(STM32G4) @@ -404,6 +430,8 @@ #define MICROPY_HW_MAX_UART (5) // UART1-5 + LPUART1 #define MICROPY_HW_MAX_LPUART (1) +#define CFG_TUSB_MCU OPT_MCU_STM32G4 + // Configuration for STM32H5 series #elif defined(STM32H5) @@ -414,6 +442,8 @@ #define MICROPY_HW_MAX_UART (12) #define MICROPY_HW_MAX_LPUART (1) +#define CFG_TUSB_MCU OPT_MCU_STM32H5 + // Configuration for STM32H7A3/B3 series #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || \ defined(STM32H7B3xx) || defined(STM32H7B3xxQ) @@ -425,6 +455,8 @@ #define MICROPY_HW_MAX_UART (10) #define MICROPY_HW_MAX_LPUART (1) +#define CFG_TUSB_MCU OPT_MCU_STM32H7 + // Configuration for STM32H7 series #elif defined(STM32H7) @@ -435,6 +467,8 @@ #define MICROPY_HW_MAX_UART (8) #define MICROPY_HW_MAX_LPUART (1) +#define CFG_TUSB_MCU OPT_MCU_STM32H7 + #if defined(MICROPY_HW_ANALOG_SWITCH_PA0) \ || defined(MICROPY_HW_ANALOG_SWITCH_PA1) \ || defined(MICROPY_HW_ANALOG_SWITCH_PC2) \ @@ -454,6 +488,8 @@ #define MICROPY_HW_MAX_UART (5) #define MICROPY_HW_MAX_LPUART (1) +#define CFG_TUSB_MCU OPT_MCU_STM32L0 + // Configuration for STM32L1 series #elif defined(STM32L1) #define MP_HAL_UNIQUE_ID_ADDRESS (UID_BASE) @@ -464,6 +500,8 @@ #define MICROPY_HW_MAX_UART (5) #define MICROPY_HW_MAX_LPUART (0) +#define CFG_TUSB_MCU OPT_MCU_STM32L1 + // Configuration for STM32L4 series #elif defined(STM32L4) @@ -474,6 +512,8 @@ #define MICROPY_HW_MAX_UART (5) #define MICROPY_HW_MAX_LPUART (1) +#define CFG_TUSB_MCU OPT_MCU_STM32L4 + // Configuration for STM32N6 series #elif defined(STM32N6) @@ -494,6 +534,8 @@ #define MICROPY_HW_MAX_UART (1) #define MICROPY_HW_MAX_LPUART (1) +#define CFG_TUSB_MCU OPT_MCU_STM32WB + #ifndef MICROPY_HW_STM32WB_FLASH_SYNCRONISATION #define MICROPY_HW_STM32WB_FLASH_SYNCRONISATION (1) #endif @@ -699,10 +741,10 @@ #define MICROPY_HW_USB_CDC_NUM (1) #endif #ifndef MICROPY_HW_USB_MSC -#define MICROPY_HW_USB_MSC (MICROPY_HW_ENABLE_USB) +#define MICROPY_HW_USB_MSC (MICROPY_HW_STM_USB_STACK) #endif #ifndef MICROPY_HW_USB_HID -#define MICROPY_HW_USB_HID (MICROPY_HW_ENABLE_USB) +#define MICROPY_HW_USB_HID (MICROPY_HW_STM_USB_STACK) #endif // Pin definition header file diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 191503cd4956f..a9f5793b8db74 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -179,6 +179,9 @@ #define MICROPY_FATFS_USE_LABEL (1) #define MICROPY_FATFS_RPATH (2) #define MICROPY_FATFS_MULTI_PARTITION (1) +#if MICROPY_HW_TINYUSB_STACK && CFG_TUD_MSC +#define MICROPY_FATFS_MAX_SS (4096) +#endif #if MICROPY_PY_PYB extern const struct _mp_obj_module_t pyb_module; diff --git a/ports/stm32/mphalport.c b/ports/stm32/mphalport.c index fcd08cbd84562..a26dcdb832bda 100644 --- a/ports/stm32/mphalport.c +++ b/ports/stm32/mphalport.c @@ -8,6 +8,17 @@ #include "usb.h" #include "uart.h" +#if MICROPY_HW_TINYUSB_STACK +#include "shared/tinyusb/mp_usbd_cdc.h" + +#ifndef MICROPY_HW_STDIN_BUFFER_LEN +#define MICROPY_HW_STDIN_BUFFER_LEN 128 +#endif + +static uint8_t stdin_ringbuf_array[MICROPY_HW_STDIN_BUFFER_LEN]; +ringbuf_t stdin_ringbuf = { stdin_ringbuf_array, sizeof(stdin_ringbuf_array), 0, 0 }; +#endif + // this table converts from HAL_StatusTypeDef to POSIX errno const byte mp_hal_status_to_errno_table[4] = { [HAL_OK] = 0, @@ -26,6 +37,9 @@ MP_NORETURN void mp_hal_raise(HAL_StatusTypeDef status) { MP_WEAK uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { uintptr_t ret = 0; + #if MICROPY_HW_ENABLE_USBDEV && MICROPY_HW_USB_CDC && MICROPY_HW_TINYUSB_STACK + ret |= mp_usbd_cdc_poll_interfaces(poll_flags); + #endif if (MP_STATE_PORT(pyb_stdio_uart) != NULL) { mp_obj_t pyb_stdio_uart = MP_OBJ_FROM_PTR(MP_STATE_PORT(pyb_stdio_uart)); int errcode; @@ -53,6 +67,13 @@ MP_WEAK int mp_hal_stdin_rx_chr(void) { if (dupterm_c >= 0) { return dupterm_c; } + #if MICROPY_HW_ENABLE_USBDEV && MICROPY_HW_USB_CDC && MICROPY_HW_TINYUSB_STACK + mp_usbd_cdc_poll_interfaces(0); + int c = ringbuf_get(&stdin_ringbuf); + if (c != -1) { + return c; + } + #endif MICROPY_EVENT_POLL_HOOK } } @@ -64,6 +85,13 @@ MP_WEAK mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) { uart_tx_strn(MP_STATE_PORT(pyb_stdio_uart), str, len); did_write = true; } + #if MICROPY_HW_ENABLE_USBDEV && MICROPY_HW_USB_CDC && MICROPY_HW_TINYUSB_STACK + 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 #if 0 && defined(USE_HOST_MODE) && MICROPY_HW_HAS_LCD lcd_print_strn(str, len); #endif diff --git a/ports/stm32/mphalport.h b/ports/stm32/mphalport.h index 03b0f8e7722ae..bc61eaa75b740 100644 --- a/ports/stm32/mphalport.h +++ b/ports/stm32/mphalport.h @@ -1,6 +1,8 @@ // We use the ST Cube HAL library for most hardware peripherals #include STM32_HAL_H #include "pin.h" +#include "py/ringbuf.h" +#include "shared/runtime/interrupt_char.h" extern uint8_t mp_hal_unique_id_address[12]; @@ -37,6 +39,8 @@ static inline int mp_hal_status_to_neg_errno(HAL_StatusTypeDef status) { return -mp_hal_status_to_errno_table[status]; } +extern ringbuf_t stdin_ringbuf; + MP_NORETURN void mp_hal_raise(HAL_StatusTypeDef status); void mp_hal_set_interrupt_char(int c); // -1 to disable @@ -144,3 +148,7 @@ enum { void mp_hal_generate_laa_mac(int idx, uint8_t buf[6]); void mp_hal_get_mac(int idx, uint8_t buf[6]); void mp_hal_get_mac_ascii(int idx, size_t chr_off, size_t chr_len, char *dest); + +static inline void mp_hal_wake_main_task_from_isr(void) { + // Defined for tinyusb support, nothing needs to be done here. +} diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c index 9eda3cb23974f..9d84f743afebd 100644 --- a/ports/stm32/stm32_it.c +++ b/ports/stm32/stm32_it.c @@ -80,7 +80,13 @@ #include "uart.h" #include "storage.h" #include "dma.h" + +#if MICROPY_HW_TINYUSB_STACK +#include "tusb.h" +#include "shared/tinyusb/mp_usbd.h" +#else #include "usb.h" +#endif #if defined(MICROPY_HW_USB_FS) extern PCD_HandleTypeDef pcd_fs_handle; @@ -145,7 +151,7 @@ void HardFault_C_Handler(ExceptionRegisters_t *regs) { powerctrl_mcu_reset(); } - #if MICROPY_HW_ENABLE_USB + #if MICROPY_HW_STM_USB_STACK // We need to disable the USB so it doesn't try to write data out on // the VCP and then block indefinitely waiting for the buffer to drain. pyb_usb_flags = 0; @@ -299,7 +305,11 @@ void DebugMon_Handler(void) { #if MICROPY_HW_USB_FS void USB_UCPD1_2_IRQHandler(void) { + #if MICROPY_HW_TINYUSB_STACK + tud_int_handler(0); + #else HAL_PCD_IRQHandler(&pcd_fs_handle); + #endif } #endif @@ -307,7 +317,11 @@ void USB_UCPD1_2_IRQHandler(void) { #if MICROPY_HW_USB_FS void USB_DRD_FS_IRQHandler(void) { + #if MICROPY_HW_TINYUSB_STACK + tud_int_handler(0); + #else HAL_PCD_IRQHandler(&pcd_fs_handle); + #endif } #endif @@ -315,7 +329,11 @@ void USB_DRD_FS_IRQHandler(void) { #if MICROPY_HW_USB_FS void USB_IRQHandler(void) { + #if MICROPY_HW_TINYUSB_STACK + tud_int_handler(0); + #else HAL_PCD_IRQHandler(&pcd_fs_handle); + #endif } #endif @@ -323,7 +341,11 @@ void USB_IRQHandler(void) { #if MICROPY_HW_USB_FS void USB_LP_IRQHandler(void) { + #if MICROPY_HW_TINYUSB_STACK + tud_int_handler(0); + #else HAL_PCD_IRQHandler(&pcd_fs_handle); + #endif } #endif @@ -337,7 +359,11 @@ void USB_LP_IRQHandler(void) { #if MICROPY_HW_USB_FS void OTG_FS_IRQHandler(void) { IRQ_ENTER(OTG_FS_IRQn); + #if MICROPY_HW_TINYUSB_STACK + tud_int_handler(0); + #else HAL_PCD_IRQHandler(&pcd_fs_handle); + #endif IRQ_EXIT(OTG_FS_IRQn); } #endif @@ -351,7 +377,11 @@ void USB1_OTG_HS_IRQHandler(void) { #else void OTG_HS_IRQHandler(void) { IRQ_ENTER(OTG_HS_IRQn); + #if MICROPY_HW_TINYUSB_STACK + tud_int_handler(0); + #else HAL_PCD_IRQHandler(&pcd_hs_handle); + #endif IRQ_EXIT(OTG_HS_IRQn); } #endif diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 2d70dcb2619c5..b99342ab95e8f 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -45,7 +45,7 @@ #include "sdcard.h" #include "usb.h" -#if MICROPY_HW_ENABLE_USB +#if MICROPY_HW_STM_USB_STACK // Work out which USB device to use as the main one (the one with the REPL) #if !defined(MICROPY_HW_USB_MAIN_DEV) @@ -1154,4 +1154,4 @@ MP_REGISTER_ROOT_POINTER(mp_obj_t pyb_hid_report_desc); #endif MP_REGISTER_ROOT_POINTER(mp_obj_t pyb_usb_vcp_irq[MICROPY_HW_USB_CDC_NUM]); -#endif // MICROPY_HW_ENABLE_USB +#endif // MICROPY_HW_STM_USB_STACK diff --git a/ports/stm32/usbd.c b/ports/stm32/usbd.c new file mode 100644 index 0000000000000..8a894556fcab3 --- /dev/null +++ b/ports/stm32/usbd.c @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2025 Andrew Leech + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/mpconfig.h" + +#if MICROPY_HW_ENABLE_USBDEV && MICROPY_HW_TINYUSB_STACK + +#include "mp_usbd.h" +#include "py/mpconfig.h" +#include "string.h" +#include "mphalport.h" + +void mp_usbd_port_get_serial_number(char *serial_buf) { + uint8_t *id = (uint8_t *)MP_HAL_UNIQUE_ID_ADDRESS; + MP_STATIC_ASSERT(sizeof(MP_HAL_UNIQUE_ID_ADDRESS) * 2 <= MICROPY_HW_USB_DESC_STR_MAX); + mp_usbd_hex_str(serial_buf, id, sizeof(MP_HAL_UNIQUE_ID_ADDRESS)); +} + +#endif diff --git a/ports/stm32/usbd_conf.c b/ports/stm32/usbd_conf.c index 7a9e63c9f32c1..171f16ee92c9f 100644 --- a/ports/stm32/usbd_conf.c +++ b/ports/stm32/usbd_conf.c @@ -56,236 +56,259 @@ PCD_HandleTypeDef pcd_hs_handle; #define OTG_HS_IRQn USB1_OTG_HS_IRQn #endif -/******************************************************************************* - PCD BSP Routines -*******************************************************************************/ - -/** - * @brief Initializes the PCD MSP. - * @param hpcd: PCD handle - * @retval None - */ -void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) { +#if MICROPY_HW_STM_USB_STACK || MICROPY_HW_TINYUSB_STACK +static void pyb_usbd_init_fs(void) { #if MICROPY_HW_USB_FS - if (hpcd->Instance == USB_OTG_FS) { - // Configure USB GPIO's. + // Configure USB GPIO's. - #if defined(STM32G0) || defined(STM32G4) + #if defined(STM32G0) || defined(STM32G4) - // These MCUs don't have an alternate function for USB but rather require - // the pins to be disconnected from all peripherals, ie put in analog mode. + // These MCUs don't have an alternate function for USB but rather require + // the pins to be disconnected from all peripherals, ie put in analog mode. - mp_hal_pin_config(pin_A11, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); - mp_hal_pin_config_speed(pin_A11, GPIO_SPEED_FREQ_VERY_HIGH); - mp_hal_pin_config(pin_A12, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); - mp_hal_pin_config_speed(pin_A12, GPIO_SPEED_FREQ_VERY_HIGH); + mp_hal_pin_config(pin_A11, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config_speed(pin_A11, GPIO_SPEED_FREQ_VERY_HIGH); + mp_hal_pin_config(pin_A12, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config_speed(pin_A12, GPIO_SPEED_FREQ_VERY_HIGH); - #elif defined(STM32L1) + #elif defined(STM32L1) - // STM32L1 doesn't have an alternate function for USB. - // To be disconnected from all peripherals, put in input mode. + // STM32L1 doesn't have an alternate function for USB. + // To be disconnected from all peripherals, put in input mode. - mp_hal_pin_config(pin_A11, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); - mp_hal_pin_config_speed(pin_A11, GPIO_SPEED_FREQ_VERY_HIGH); - mp_hal_pin_config(pin_A12, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); - mp_hal_pin_config_speed(pin_A12, GPIO_SPEED_FREQ_VERY_HIGH); + mp_hal_pin_config(pin_A11, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config_speed(pin_A11, GPIO_SPEED_FREQ_VERY_HIGH); + mp_hal_pin_config(pin_A12, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config_speed(pin_A12, GPIO_SPEED_FREQ_VERY_HIGH); - #else + #else - // Other MCUs have an alternate function for GPIO's to be in USB mode. + // Other MCUs have an alternate function for GPIO's to be in USB mode. - #if defined(STM32H7) - const uint32_t otg_alt = GPIO_AF10_OTG1_FS; - #elif defined(STM32L0) - const uint32_t otg_alt = GPIO_AF0_USB; - #elif defined(STM32L432xx) || defined(STM32L452xx) - const uint32_t otg_alt = GPIO_AF10_USB_FS; - #elif defined(STM32H5) || defined(STM32WB) - const uint32_t otg_alt = GPIO_AF10_USB; - #else - const uint32_t otg_alt = GPIO_AF10_OTG_FS; - #endif + #if defined(STM32H7) + const uint32_t otg_alt = GPIO_AF10_OTG1_FS; + #elif defined(STM32L0) + const uint32_t otg_alt = GPIO_AF0_USB; + #elif defined(STM32L432xx) || defined(STM32L452xx) + const uint32_t otg_alt = GPIO_AF10_USB_FS; + #elif defined(STM32H5) || defined(STM32WB) + const uint32_t otg_alt = GPIO_AF10_USB; + #else + const uint32_t otg_alt = GPIO_AF10_OTG_FS; + #endif - mp_hal_pin_config(pin_A11, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, otg_alt); - mp_hal_pin_config_speed(pin_A11, GPIO_SPEED_FREQ_VERY_HIGH); - mp_hal_pin_config(pin_A12, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, otg_alt); - mp_hal_pin_config_speed(pin_A12, GPIO_SPEED_FREQ_VERY_HIGH); + mp_hal_pin_config(pin_A11, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, otg_alt); + mp_hal_pin_config_speed(pin_A11, GPIO_SPEED_FREQ_VERY_HIGH); + mp_hal_pin_config(pin_A12, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, otg_alt); + mp_hal_pin_config_speed(pin_A12, GPIO_SPEED_FREQ_VERY_HIGH); - #endif + #endif - #if defined(MICROPY_HW_USB_VBUS_DETECT_PIN) - // USB VBUS detect pin is always A9 - mp_hal_pin_config(MICROPY_HW_USB_VBUS_DETECT_PIN, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); - #endif + #if defined(MICROPY_HW_USB_VBUS_DETECT_PIN) + // USB VBUS detect pin is always A9 + mp_hal_pin_config(MICROPY_HW_USB_VBUS_DETECT_PIN, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); + #endif - #if defined(MICROPY_HW_USB_OTG_ID_PIN) - // USB ID pin is always A10 - mp_hal_pin_config(MICROPY_HW_USB_OTG_ID_PIN, MP_HAL_PIN_MODE_ALT_OPEN_DRAIN, MP_HAL_PIN_PULL_UP, otg_alt); - #endif + #if defined(MICROPY_HW_USB_OTG_ID_PIN) + // USB ID pin is always A10 + mp_hal_pin_config(MICROPY_HW_USB_OTG_ID_PIN, MP_HAL_PIN_MODE_ALT_OPEN_DRAIN, MP_HAL_PIN_PULL_UP, otg_alt); + #endif - // Keep USB clock running during sleep or else __WFI() will disable the USB - #if defined(STM32G0) || defined(STM32H5) - __HAL_RCC_USB_CLK_SLEEP_ENABLE(); - #elif defined(STM32H7) - __HAL_RCC_USB2_OTG_FS_CLK_SLEEP_ENABLE(); - __HAL_RCC_USB2_OTG_FS_ULPI_CLK_SLEEP_DISABLE(); - #endif + // Keep USB clock running during sleep or else __WFI() will disable the USB + #if defined(STM32G0) || defined(STM32H5) + __HAL_RCC_USB_CLK_SLEEP_ENABLE(); + #elif defined(STM32H7) + __HAL_RCC_USB2_OTG_FS_CLK_SLEEP_ENABLE(); + __HAL_RCC_USB2_OTG_FS_ULPI_CLK_SLEEP_DISABLE(); + #endif - // Enable USB FS Clocks - #if !MICROPY_HW_USB_IS_MULTI_OTG - __HAL_RCC_USB_CLK_ENABLE(); - #else - __USB_OTG_FS_CLK_ENABLE(); - #endif + // Enable USB FS Clocks + #if !MICROPY_HW_USB_IS_MULTI_OTG + __HAL_RCC_USB_CLK_ENABLE(); + #else + __USB_OTG_FS_CLK_ENABLE(); + #endif - // Enable VDDUSB - #if defined(STM32H5) + // Enable VDDUSB + #if defined(STM32H5) || defined(STM32WB) + HAL_PWREx_EnableVddUSB(); + #elif defined(STM32L4) + if (__HAL_RCC_PWR_IS_CLK_DISABLED()) { + __HAL_RCC_PWR_CLK_ENABLE(); HAL_PWREx_EnableVddUSB(); - #elif defined(STM32L4) - if (__HAL_RCC_PWR_IS_CLK_DISABLED()) { - __HAL_RCC_PWR_CLK_ENABLE(); - HAL_PWREx_EnableVddUSB(); - __HAL_RCC_PWR_CLK_DISABLE(); - } else { - HAL_PWREx_EnableVddUSB(); - } - #endif + __HAL_RCC_PWR_CLK_DISABLE(); + } else { + HAL_PWREx_EnableVddUSB(); + } + #endif - // Configure and enable USB FS interrupt - #if defined(STM32G0) - NVIC_SetPriority(USB_UCPD1_2_IRQn, IRQ_PRI_OTG_FS); - HAL_NVIC_EnableIRQ(USB_UCPD1_2_IRQn); - #elif defined(STM32H5) - NVIC_SetPriority(USB_DRD_FS_IRQn, IRQ_PRI_OTG_FS); - HAL_NVIC_EnableIRQ(USB_DRD_FS_IRQn); - #elif defined(STM32L0) - NVIC_SetPriority(USB_IRQn, IRQ_PRI_OTG_FS); - HAL_NVIC_EnableIRQ(USB_IRQn); - #elif defined(STM32L432xx) || defined(STM32L452xx) - NVIC_SetPriority(USB_FS_IRQn, IRQ_PRI_OTG_FS); - HAL_NVIC_EnableIRQ(USB_FS_IRQn); - #elif defined(STM32G4) || defined(STM32L1) || defined(STM32WB) - NVIC_SetPriority(USB_LP_IRQn, IRQ_PRI_OTG_FS); - HAL_NVIC_EnableIRQ(USB_LP_IRQn); - #else - NVIC_SetPriority(OTG_FS_IRQn, IRQ_PRI_OTG_FS); - HAL_NVIC_EnableIRQ(OTG_FS_IRQn); - #endif + // Configure and enable USB FS interrupt + #if defined(STM32G0) + NVIC_SetPriority(USB_UCPD1_2_IRQn, IRQ_PRI_OTG_FS); + HAL_NVIC_EnableIRQ(USB_UCPD1_2_IRQn); + #elif defined(STM32H5) + NVIC_SetPriority(USB_DRD_FS_IRQn, IRQ_PRI_OTG_FS); + HAL_NVIC_EnableIRQ(USB_DRD_FS_IRQn); + #elif defined(STM32L0) + NVIC_SetPriority(USB_IRQn, IRQ_PRI_OTG_FS); + HAL_NVIC_EnableIRQ(USB_IRQn); + #elif defined(STM32L432xx) || defined(STM32L452xx) + NVIC_SetPriority(USB_FS_IRQn, IRQ_PRI_OTG_FS); + HAL_NVIC_EnableIRQ(USB_FS_IRQn); + #elif defined(STM32G4) || defined(STM32L1) || defined(STM32WB) + NVIC_SetPriority(USB_LP_IRQn, IRQ_PRI_OTG_FS); + HAL_NVIC_EnableIRQ(USB_LP_IRQn); + #else + NVIC_SetPriority(OTG_FS_IRQn, IRQ_PRI_OTG_FS); + HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + #endif + #endif +} - return; - } +#if MICROPY_HW_USB_HS +static void pyb_usbd_init_hs(void) { + #if MICROPY_HW_USB_HS_IN_FS + + // Configure USB GPIO's. + + #if defined(STM32H723xx) + + // These MCUs don't have an alternate function for USB but rather require + // the pins to be disconnected from all peripherals, ie put in analog mode. + + #if defined(MICROPY_HW_USB_OTG_ID_PIN) + const uint32_t otg_alt = GPIO_AF10_OTG1_FS; #endif - #if MICROPY_HW_USB_HS - if (hpcd->Instance == USB_OTG_HS) { - #if MICROPY_HW_USB_HS_IN_FS + mp_hal_pin_config(pin_A11, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config_speed(pin_A11, GPIO_SPEED_FREQ_VERY_HIGH); + mp_hal_pin_config(pin_A12, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config_speed(pin_A12, GPIO_SPEED_FREQ_VERY_HIGH); - // Configure USB GPIO's. + #elif defined(STM32N6) - #if defined(STM32H723xx) + // These MCUs have dedicated USB pins. - // These MCUs don't have an alternate function for USB but rather require - // the pins to be disconnected from all peripherals, ie put in analog mode. + #else - #if defined(MICROPY_HW_USB_OTG_ID_PIN) - const uint32_t otg_alt = GPIO_AF10_OTG1_FS; - #endif + // Other MCUs have an alternate function for GPIO's to be in USB mode. - mp_hal_pin_config(pin_A11, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); - mp_hal_pin_config_speed(pin_A11, GPIO_SPEED_FREQ_VERY_HIGH); - mp_hal_pin_config(pin_A12, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); - mp_hal_pin_config_speed(pin_A12, GPIO_SPEED_FREQ_VERY_HIGH); + #if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + const uint32_t otg_alt = GPIO_AF10_OTG1_FS; + #elif defined(STM32H7) + const uint32_t otg_alt = GPIO_AF12_OTG2_FS; + #else + const uint32_t otg_alt = GPIO_AF12_OTG_HS_FS; + #endif - #elif defined(STM32N6) + mp_hal_pin_config(pin_B14, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, otg_alt); + mp_hal_pin_config_speed(pin_B14, GPIO_SPEED_FREQ_VERY_HIGH); + mp_hal_pin_config(pin_B15, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, otg_alt); + mp_hal_pin_config_speed(pin_B15, GPIO_SPEED_FREQ_VERY_HIGH); - // These MCUs have dedicated USB pins. + #endif - #else + #if defined(MICROPY_HW_USB_VBUS_DETECT_PIN) + // Configure VBUS Pin + mp_hal_pin_config(MICROPY_HW_USB_VBUS_DETECT_PIN, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); + #endif - // Other MCUs have an alternate function for GPIO's to be in USB mode. + #if defined(MICROPY_HW_USB_OTG_ID_PIN) + // Configure ID pin + mp_hal_pin_config(MICROPY_HW_USB_OTG_ID_PIN, MP_HAL_PIN_MODE_ALT_OPEN_DRAIN, MP_HAL_PIN_PULL_UP, otg_alt); + #endif - #if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) - const uint32_t otg_alt = GPIO_AF10_OTG1_FS; - #elif defined(STM32H7) - const uint32_t otg_alt = GPIO_AF12_OTG2_FS; - #else - const uint32_t otg_alt = GPIO_AF12_OTG_HS_FS; - #endif + #if defined(STM32N6) - mp_hal_pin_config(pin_B14, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, otg_alt); - mp_hal_pin_config_speed(pin_B14, GPIO_SPEED_FREQ_VERY_HIGH); - mp_hal_pin_config(pin_B15, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, otg_alt); - mp_hal_pin_config_speed(pin_B15, GPIO_SPEED_FREQ_VERY_HIGH); + __HAL_RCC_USB1_OTG_HS_FORCE_RESET(); + __HAL_RCC_USB1_OTG_HS_PHY_FORCE_RESET(); + __HAL_RCC_USB1_OTG_HS_PHY_RELEASE_RESET(); + __HAL_RCC_USB1_OTG_HS_RELEASE_RESET(); - #endif + LL_AHB5_GRP1_EnableClock(LL_AHB5_GRP1_PERIPH_OTG1); + LL_AHB5_GRP1_EnableClock(LL_AHB5_GRP1_PERIPH_OTGPHY1); + LL_AHB5_GRP1_EnableClockLowPower(LL_AHB5_GRP1_PERIPH_OTG1); + LL_AHB5_GRP1_EnableClockLowPower(LL_AHB5_GRP1_PERIPH_OTGPHY1); - #if defined(MICROPY_HW_USB_VBUS_DETECT_PIN) - // Configure VBUS Pin - mp_hal_pin_config(MICROPY_HW_USB_VBUS_DETECT_PIN, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); - #endif + // Select 24MHz clock. + MODIFY_REG(USB1_HS_PHYC->USBPHYC_CR, USB_USBPHYC_CR_FSEL, 2 << USB_USBPHYC_CR_FSEL_Pos); - #if defined(MICROPY_HW_USB_OTG_ID_PIN) - // Configure ID pin - mp_hal_pin_config(MICROPY_HW_USB_OTG_ID_PIN, MP_HAL_PIN_MODE_ALT_OPEN_DRAIN, MP_HAL_PIN_PULL_UP, otg_alt); - #endif + #else - #if defined(STM32N6) + // Enable calling WFI and correct function of the embedded USB_FS_IN_HS phy + __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE(); + __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE(); - __HAL_RCC_USB1_OTG_HS_FORCE_RESET(); - __HAL_RCC_USB1_OTG_HS_PHY_FORCE_RESET(); - __HAL_RCC_USB1_OTG_HS_PHY_RELEASE_RESET(); - __HAL_RCC_USB1_OTG_HS_RELEASE_RESET(); + // Enable USB HS Clocks - LL_AHB5_GRP1_EnableClock(LL_AHB5_GRP1_PERIPH_OTG1); - LL_AHB5_GRP1_EnableClock(LL_AHB5_GRP1_PERIPH_OTGPHY1); - LL_AHB5_GRP1_EnableClockLowPower(LL_AHB5_GRP1_PERIPH_OTG1); - LL_AHB5_GRP1_EnableClockLowPower(LL_AHB5_GRP1_PERIPH_OTGPHY1); + #if defined(STM32F723xx) || defined(STM32F733xx) + // Needs to remain awake during sleep or else __WFI() will disable the USB + __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE(); + __HAL_RCC_OTGPHYC_CLK_ENABLE(); + __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); + #endif - // Select 24MHz clock. - MODIFY_REG(USB1_HS_PHYC->USBPHYC_CR, USB_USBPHYC_CR_FSEL, 2 << USB_USBPHYC_CR_FSEL_Pos); + __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); - #else + #endif - // Enable calling WFI and correct function of the embedded USB_FS_IN_HS phy - __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE(); - __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE(); + #else // !MICROPY_HW_USB_HS_IN_FS - // Enable USB HS Clocks + // Configure USB HS GPIOs + static const mp_hal_pin_obj_t usb_pins[] = { + pin_A5, pin_C0, MICROPY_HW_USB_HS_ULPI_NXT, MICROPY_HW_USB_HS_ULPI_DIR, // CLK, STP, NXT, DIR + pin_A3, pin_B0, pin_B1, pin_B5, pin_B10, pin_B11, pin_B12, pin_B13, // D0-D7 + }; + for (size_t i = 0; i < MP_ARRAY_SIZE(usb_pins); ++i) { + mp_hal_pin_config(usb_pins[i], MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, GPIO_AF10_OTG_HS); + mp_hal_pin_config_speed(usb_pins[i], GPIO_SPEED_FREQ_VERY_HIGH); + } - #if defined(STM32F723xx) || defined(STM32F733xx) - // Needs to remain awake during sleep or else __WFI() will disable the USB - __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE(); - __HAL_RCC_OTGPHYC_CLK_ENABLE(); - __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); - #endif + // Enable USB HS Clocks + __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); + __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE(); + __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); + __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE(); - __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); + #endif // !MICROPY_HW_USB_HS_IN_FS - #endif + // Configure and enable USB HS interrupt + NVIC_SetPriority(OTG_HS_IRQn, IRQ_PRI_OTG_HS); + HAL_NVIC_EnableIRQ(OTG_HS_IRQn); +} +#endif +#endif - #else // !MICROPY_HW_USB_HS_IN_FS - // Configure USB HS GPIOs - static const mp_hal_pin_obj_t usb_pins[] = { - pin_A5, pin_C0, MICROPY_HW_USB_HS_ULPI_NXT, MICROPY_HW_USB_HS_ULPI_DIR, // CLK, STP, NXT, DIR - pin_A3, pin_B0, pin_B1, pin_B5, pin_B10, pin_B11, pin_B12, pin_B13, // D0-D7 - }; - for (size_t i = 0; i < MP_ARRAY_SIZE(usb_pins); ++i) { - mp_hal_pin_config(usb_pins[i], MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, GPIO_AF10_OTG_HS); - mp_hal_pin_config_speed(usb_pins[i], GPIO_SPEED_FREQ_VERY_HIGH); - } +#if MICROPY_HW_TINYUSB_STACK +void pyb_usbd_init(void) { + pyb_usbd_init_fs(); + #if MICROPY_HW_USB_HS + pyb_usbd_init_hs(); + #endif +} +#endif - // Enable USB HS Clocks - __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); - __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE(); - __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); - __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE(); - #endif // !MICROPY_HW_USB_HS_IN_FS +/******************************************************************************* + PCD BSP Routines +*******************************************************************************/ - // Configure and enable USB HS interrupt - NVIC_SetPriority(OTG_HS_IRQn, IRQ_PRI_OTG_HS); - HAL_NVIC_EnableIRQ(OTG_HS_IRQn); +/** + * @brief Initializes the PCD MSP. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) { + #if MICROPY_HW_USB_FS + if (hpcd->Instance == USB_OTG_FS) { + pyb_usbd_init_fs(); + } + #endif + + #if MICROPY_HW_USB_HS + if (hpcd->Instance == USB_OTG_HS) { + pyb_usbd_init_hs(); } #endif // MICROPY_HW_USB_HS } diff --git a/ports/stm32/usbd_conf.h b/ports/stm32/usbd_conf.h index e61e7ce7efe43..404b48588fe36 100644 --- a/ports/stm32/usbd_conf.h +++ b/ports/stm32/usbd_conf.h @@ -64,6 +64,11 @@ #define USBD_HS_NUM_TX_FIFO (9) #define USBD_HS_NUM_FIFO (1 + USBD_HS_NUM_TX_FIFO) + +#if MICROPY_HW_TINYUSB_STACK +void pyb_usbd_init(void); +#endif + #endif // MICROPY_INCLUDED_STM32_USBD_CONF_H /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/tools/ci.sh b/tools/ci.sh index 8f045639b80c9..6a0134aed3037 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -468,6 +468,7 @@ function ci_stm32_nucleo_build { make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_H743ZI COPT=-O2 CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_L073RZ make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_L476RG DEBUG=1 + make ${MAKEOPTS} -C ports/stm32 BOARD=STM32H573I_DK CFLAGS_EXTRA='-DMICROPY_HW_TINYUSB_STACK=1' # Test building a board with mboot packing enabled (encryption, signing, compression). make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_WB55 USE_MBOOT=1 MBOOT_ENABLE_PACKING=1