diff options
| -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  | 
