diff options
| author | Andrew Leech <andrew.leech@planetinnovation.com.au> | 2025-10-28 16:20:31 +1100 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2025-10-31 10:52:11 +1100 |
| commit | 9bb266e31162ba80ec06a6bc9a6b94b9cbafa9b2 (patch) | |
| tree | e0260ed1414475c9d8659e831f357e079472c4dc | |
| parent | 6b0e1c2701490260cb81bbe884f42a9c18bea020 (diff) | |
stm32/usb: Add support for using TinyUSB stack.
This commit adapts the stm32 port to allow switching from STM USB stack to
TinyUSB stack.
Using TinyUSB improves consistancy with other MicroPython ports and brings
in the ability to use the runtime USB definition support recently added to
other TinyUSB based ports.
By default the existing STM USB stack is used. TinyUSB can be enabled in a
board configuration with:
#define MICROPY_HW_TINYUSB_STACK (1)
Or, it can be enabled from the command line with:
make -C ports/stm32 CFLAGS_EXTRA='-DMICROPY_HW_TINYUSB_STACK=1'
Signed-off-by: Andrew Leech <andrew@alelec.net>
| -rw-r--r-- | ports/stm32/Makefile | 22 | ||||
| -rw-r--r-- | ports/stm32/main.c | 21 | ||||
| -rw-r--r-- | ports/stm32/modmachine.c | 7 | ||||
| -rw-r--r-- | ports/stm32/modos.c | 6 | ||||
| -rw-r--r-- | ports/stm32/modpyb.c | 2 | ||||
| -rw-r--r-- | ports/stm32/mpconfigboard_common.h | 71 | ||||
| -rw-r--r-- | ports/stm32/mphalport.c | 28 | ||||
| -rw-r--r-- | ports/stm32/mphalport.h | 8 | ||||
| -rw-r--r-- | ports/stm32/stm32_it.c | 39 | ||||
| -rw-r--r-- | ports/stm32/usb.c | 4 | ||||
| -rw-r--r-- | ports/stm32/usbd.c | 42 | ||||
| -rw-r--r-- | ports/stm32/usbd_conf.c | 40 | ||||
| -rw-r--r-- | ports/stm32/usbd_conf.h | 4 | ||||
| -rwxr-xr-x | tools/ci.sh | 2 |
14 files changed, 256 insertions, 40 deletions
diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 8b35c82a2..5105b35b1 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,8 @@ 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 +215,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) @@ -242,7 +248,9 @@ 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 +285,6 @@ SRC_C += \ can.c \ fdcan.c \ pyb_can.c \ - usb.c \ eth.c \ eth_phy.c \ gccollect.c \ @@ -460,6 +467,16 @@ USBDEV_SRC_C += $(addprefix $(USBDEV_DIR)/,\ class/src/usbd_msc_scsi.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/portable/synopsys/dwc2/dwc2_common.c \ + src/portable/synopsys/dwc2/hcd_dwc2.c \ + ) + ifeq ($(MICROPY_SSL_MBEDTLS),1) LIB_SRC_C += mbedtls/mbedtls_port.c endif @@ -499,6 +516,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 1c59b6479..d56b4c407 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -88,6 +88,11 @@ #include "pyb_can.h" #include "subghz.h" +#if MICROPY_HW_TINYUSB_STACK +#include "usbd_conf.h" +#include "shared/tinyusb/mp_usbd.h" +#endif + #if MICROPY_PY_THREAD static pyb_thread_t pyb_thread_main; #endif @@ -275,14 +280,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 @@ -606,8 +609,13 @@ soft_reset: #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(); @@ -631,7 +639,7 @@ soft_reset: } #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; @@ -665,7 +673,7 @@ soft_reset: // 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 @@ -770,6 +778,9 @@ soft_reset_exit: #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 8123cd801..c1ac6e086 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_STM_USB_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 7949cf87c..cd918fe71 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 3d8696e3c..a985fa39d 100644 --- a/ports/stm32/modpyb.c +++ b/ports/stm32/modpyb.c @@ -167,7 +167,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 f36cdec8e..47eb7f036 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -250,12 +250,50 @@ #error "Old USBD_xxx configuration option used, renamed to MICROPY_HW_USB_xxx" #endif +// 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 +#ifndef MICROPY_HW_ENABLE_USBDEV +#define MICROPY_HW_ENABLE_USBDEV (1) +#endif + +#ifndef MICROPY_HW_USB_CDC +#define MICROPY_HW_USB_CDC (1) +#endif + +#ifndef MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE +#define MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE (1) // Support machine.USBDevice +#endif +#endif + +// Configure maximum number of CDC VCP interfaces, and whether MSC/HID are supported +#ifndef MICROPY_HW_USB_CDC_NUM +#define MICROPY_HW_USB_CDC_NUM (1) +#endif +#ifndef MICROPY_HW_USB_MSC +#define MICROPY_HW_USB_MSC (MICROPY_HW_STM_USB_STACK) +#endif +#ifndef MICROPY_HW_USB_HID +#define MICROPY_HW_USB_HID (MICROPY_HW_STM_USB_STACK) +#endif + // Default VID and PID values to use for the USB device. If MICROPY_HW_USB_VID // is defined by a board then all needed PID options must also be defined. The // VID and PID can also be set dynamically in pyb.usb_mode(). // Windows needs a different PID to distinguish different device configurations. #ifndef MICROPY_HW_USB_VID #define MICROPY_HW_USB_VID (0xf055) + +// USB PID for TinyUSB Stack. +#define MICROPY_HW_USB_PID (0x9802) + +// USB PID table for STM USB stack. #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 +407,8 @@ #endif #define MICROPY_HW_MAX_LPUART (0) +#define CFG_TUSB_MCU OPT_MCU_STM32F4 + // Configuration for STM32F7 series #elif defined(STM32F7) @@ -384,6 +424,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 +436,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 +448,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 +460,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 +473,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 +485,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 +506,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 +518,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 +530,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) @@ -508,6 +566,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 @@ -715,17 +775,6 @@ #define MICROPY_HW_USB_IS_MULTI_OTG (1) #endif -// Configure maximum number of CDC VCP interfaces, and whether MSC/HID are supported -#ifndef MICROPY_HW_USB_CDC_NUM -#define MICROPY_HW_USB_CDC_NUM (1) -#endif -#ifndef MICROPY_HW_USB_MSC -#define MICROPY_HW_USB_MSC (MICROPY_HW_ENABLE_USB) -#endif -#ifndef MICROPY_HW_USB_HID -#define MICROPY_HW_USB_HID (MICROPY_HW_ENABLE_USB) -#endif - // Pin definition header file #define MICROPY_PIN_DEFS_PORT_H "pin_defs_stm32.h" diff --git a/ports/stm32/mphalport.c b/ports/stm32/mphalport.c index b13ed0ee1..51fb32ae8 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 512 +#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_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_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_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 4d98ce9f1..098a848fb 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]; @@ -41,6 +43,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 @@ -148,3 +152,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 470df4758..19778020d 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 @@ -345,13 +371,21 @@ void OTG_FS_IRQHandler(void) { #if defined(STM32N6) void USB1_OTG_HS_IRQHandler(void) { IRQ_ENTER(USB1_OTG_HS_IRQn); + #if MICROPY_HW_TINYUSB_STACK + tud_int_handler(0); + #else HAL_PCD_IRQHandler(&pcd_hs_handle); + #endif IRQ_EXIT(USB1_OTG_HS_IRQn); } #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 @@ -414,6 +448,9 @@ static void OTG_CMD_WKUP_Handler(PCD_HandleTypeDef *pcd_handle) { /* ungate PHY clock */ __HAL_PCD_UNGATE_PHYCLOCK(pcd_handle); } + #if MICROPY_HW_TINYUSB_STACK + tud_int_handler(0); + #endif } #endif diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 81025e48b..15d563713 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) @@ -1156,4 +1156,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 000000000..35275cd1b --- /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(12 * 2 <= MICROPY_HW_USB_DESC_STR_MAX); + mp_usbd_hex_str(serial_buf, id, 12); +} + +#endif diff --git a/ports/stm32/usbd_conf.c b/ports/stm32/usbd_conf.c index 2cf79e09e..18f350d4a 100644 --- a/ports/stm32/usbd_conf.c +++ b/ports/stm32/usbd_conf.c @@ -37,6 +37,12 @@ #if MICROPY_HW_USB_FS || MICROPY_HW_USB_HS +#if BUILDING_MBOOT +// TinyUSB not used in mboot +#undef MICROPY_HW_TINYUSB_STACK +#endif + +// These handles are also used in Interrupt / Wakeup handlers. #if MICROPY_HW_USB_FS PCD_HandleTypeDef pcd_fs_handle; #endif @@ -56,18 +62,17 @@ 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_TINYUSB_STACK +void pyb_usbd_init(void) +#else +void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) +#endif +{ #if MICROPY_HW_USB_FS - if (hpcd->Instance == USB_OTG_FS) { + #if MICROPY_HW_STM_USB_STACK + if (hpcd->Instance == USB_OTG_FS) + #endif + { // Configure USB GPIO's. #if defined(STM32G0) || defined(STM32G4) @@ -139,7 +144,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) { #endif // Enable VDDUSB - #if defined(STM32H5) + #if defined(STM32H5) || defined(STM32WB) HAL_PWREx_EnableVddUSB(); #elif defined(STM32L4) if (__HAL_RCC_PWR_IS_CLK_DISABLED()) { @@ -172,12 +177,17 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) { HAL_NVIC_EnableIRQ(OTG_FS_IRQn); #endif + #if MICROPY_HW_STM_USB_STACK return; + #endif } #endif #if MICROPY_HW_USB_HS - if (hpcd->Instance == USB_OTG_HS) { + #if MICROPY_HW_STM_USB_STACK + if (hpcd->Instance == USB_OTG_HS) + #endif + { #if MICROPY_HW_USB_HS_IN_FS // Configure USB GPIO's. @@ -319,6 +329,8 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) { #endif // MICROPY_HW_USB_HS } +#if MICROPY_HW_STM_USB_STACK + /** * @brief DeInitializes the PCD MSP. * @param hpcd: PCD handle @@ -798,6 +810,8 @@ void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state) { } #endif +#endif // MICROPY_HW_STM_USB_STACK + #endif // MICROPY_HW_USB_FS || MICROPY_HW_USB_HS /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/ports/stm32/usbd_conf.h b/ports/stm32/usbd_conf.h index e61e7ce7e..cb0457982 100644 --- a/ports/stm32/usbd_conf.h +++ b/ports/stm32/usbd_conf.h @@ -64,6 +64,10 @@ #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 5d401843b..42d231c45 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -511,7 +511,7 @@ function ci_stm32_nucleo_build { # Test building various MCU families, some with additional options. make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_F091RC - make ${MAKEOPTS} -C ports/stm32 BOARD=STM32H573I_DK + make ${MAKEOPTS} -C ports/stm32 BOARD=STM32H573I_DK CFLAGS_EXTRA='-DMICROPY_HW_TINYUSB_STACK=1' 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 |
