diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 8b35c82a27..5105b35b16 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 1c59b6479f..d56b4c4076 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 8123cd8011..c1ac6e0862 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 7949cf87cd..cd918fe715 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 3d8696e3c4..a985fa39da 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 f36cdec8ec..47eb7f036c 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 b13ed0ee15..51fb32ae8c 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 4d98ce9f19..098a848fb8 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 470df4758f..19778020d9 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 81025e48ba..15d5637130 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 0000000000..35275cd1bd --- /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 2cf79e09e0..18f350d4a9 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 e61e7ce7ef..cb0457982d 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 5d401843be..42d231c458 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