diff options
50 files changed, 1617 insertions, 177 deletions
| diff --git a/lib/stm32lib b/lib/stm32lib -Subproject 8b2bb4ef44fbfab5075ed9d09e83ddc3754b925 +Subproject 07619754261b571fb2f7c9f36ab94c203880d9f diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 3af1d892a..b43f284b1 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,12 +248,15 @@ 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 \  	usbd_msc_interface.c \  	mphalport.c \ +	msc_disk.c \  	mpnetworkport.c \  	mpthreadport.c \  	irq.c \ @@ -277,7 +286,6 @@ SRC_C += \  	can.c \  	fdcan.c \  	pyb_can.c \ -	usb.c \  	eth.c \  	eth_phy.c \  	gccollect.c \ @@ -367,7 +375,7 @@ HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\  	)  endif -ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 g0 g4 h5 h7 l0 l1 l4 n6 wb)) +ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 g0 g4 h5 h7 l0 l1 l4 n6 u5 wb))  HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\  	hal_pcd.c \  	hal_pcd_ex.c \ @@ -408,7 +416,7 @@ $(BUILD)/$(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_hal_mmc.o: CFLAGS += -Wno  endif  endif -ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 g0 g4 h5 h7 n6)) +ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 g0 g4 h5 h7 n6 u5))  HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\  	hal_dma_ex.c \  	) @@ -460,6 +468,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 +517,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/adc.c b/ports/stm32/adc.c index 27f6c5c23..326fc97b2 100644 --- a/ports/stm32/adc.c +++ b/ports/stm32/adc.c @@ -107,7 +107,7 @@  #define ADC_CAL2                ((uint16_t *)(ADC_CAL_ADDRESS + 4))  #define ADC_CAL_BITS            (12) -#elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L1) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) +#elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L1) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB)  #define ADC_SCALE_V             (((float)VREFINT_CAL_VREF) / 1000.0f)  #define ADC_CAL_ADDRESS         (VREFINT_CAL_ADDR) @@ -116,6 +116,8 @@  #if defined(STM32H7)  #define ADC_CAL_BITS            (16) +#elif defined(STM32U5) +#define ADC_CAL_BITS            (14)  #else  #define ADC_CAL_BITS            (12) // UM2319/UM2570, __HAL_ADC_CALC_TEMPERATURE: 'corresponds to a resolution of 12 bits'  #endif @@ -166,6 +168,8 @@  #elif defined(STM32N6)  // ADC2 VINP 16  #define VBAT_DIV (4) +#elif defined(STM32U5) +#define VBAT_DIV (4)  #else  #error Unsupported processor  #endif @@ -233,6 +237,14 @@ static inline uint32_t adc_get_internal_channel(uint32_t channel) {      } else if (channel == 18) {          channel = ADC_CHANNEL_VBAT;      } +    #elif defined(STM32U5) +    if (channel == 0) { +        channel = ADC_CHANNEL_VREFINT; +    } else if (channel == 18) { +        channel = ADC_CHANNEL_VBAT; +    } else if (channel == 19) { +        channel = ADC_CHANNEL_TEMPSENSOR; +    }      #endif      return channel;  } @@ -247,7 +259,7 @@ static bool is_adcx_channel(int channel) {      // The HAL of STM32L1 defines some channels those may not be available on package      return __HAL_ADC_IS_CHANNEL_INTERNAL(channel)             || (channel < MP_ARRAY_SIZE(pin_adcall_table) && pin_adcall_table[channel]); -    #elif defined(STM32G0) || defined(STM32H7) +    #elif defined(STM32G0) || defined(STM32H7) || defined(STM32U5)      return __HAL_ADC_IS_CHANNEL_INTERNAL(channel)             || IS_ADC_CHANNEL(__HAL_ADC_DECIMAL_NB_TO_CHANNEL(channel));      #elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB) @@ -268,7 +280,7 @@ static void adc_wait_for_eoc_or_timeout(ADC_HandleTypeDef *adcHandle, int32_t ti      uint32_t tickstart = HAL_GetTick();      #if defined(STM32F4) || defined(STM32F7) || defined(STM32L1)      while ((adcHandle->Instance->SR & ADC_FLAG_EOC) != ADC_FLAG_EOC) { -    #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) +    #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB)      while (READ_BIT(adcHandle->Instance->ISR, ADC_FLAG_EOC) != ADC_FLAG_EOC) {      #else      #error Unsupported processor @@ -303,6 +315,8 @@ static void adcx_clock_enable(ADC_HandleTypeDef *adch) {          __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_SYSCLK);      }      __HAL_RCC_ADC_CLK_ENABLE(); +    #elif defined(STM32U5) +    __HAL_RCC_ADC12_CLK_ENABLE();      #else      #error Unsupported processor      #endif @@ -353,12 +367,12 @@ static void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {      adch->Init.LowPowerAutoWait = DISABLE;      adch->Init.DataAlign = ADC_DATAALIGN_RIGHT;      adch->Init.DMAContinuousRequests = DISABLE; -    #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32WB) +    #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32U5) || defined(STM32WB)      #if defined(STM32G0)      adch->Init.SamplingTimeCommon1 = ADC_SAMPLETIME_12CYCLES_5;      adch->Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;      #endif -    #if defined(STM32G4) || defined(STM32H5) +    #if defined(STM32G4) || defined(STM32H5) || defined(STM32U5)      adch->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV16;      #else      adch->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; @@ -369,6 +383,12 @@ static void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {      adch->Init.OversamplingMode = DISABLE;      adch->Init.DataAlign = ADC_DATAALIGN_RIGHT;      adch->Init.DMAContinuousRequests = DISABLE; +    #if defined(STM32U5) +    adch->Init.GainCompensation = 0; +    adch->Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH; +    adch->Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; +    adch->Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; +    #endif      #elif defined(STM32N6)      adch->Init.GainCompensation = 0;      adch->Init.ScanConvMode = ADC_SCAN_DISABLE; @@ -384,7 +404,7 @@ static void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {      HAL_ADC_Init(adch); -    #if defined(STM32H7) +    #if defined(STM32H7) || defined(STM32U5)      HAL_ADCEx_Calibration_Start(adch, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);      #endif      #if defined(STM32G0) @@ -415,6 +435,8 @@ static void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel)      if (__HAL_ADC_IS_CHANNEL_INTERNAL(channel) == 0) {          channel = __HAL_ADC_DECIMAL_NB_TO_CHANNEL(channel);      } +    #elif defined(STM32U5) +    sConfig.Rank = ADC_REGULAR_RANK_1;      #else      sConfig.Rank = 1;      #endif @@ -471,6 +493,15 @@ static void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel)      sConfig.OffsetSignedSaturation = DISABLE;      sConfig.OffsetSaturation = DISABLE;      sConfig.OffsetSign = ADC_OFFSET_SIGN_POSITIVE; +    #elif defined(STM32U5) +    if (__HAL_ADC_IS_CHANNEL_INTERNAL(channel)) { +        sConfig.SamplingTime = ADC_SAMPLETIME_391CYCLES_5; +    } else { +        sConfig.SamplingTime = ADC4_SAMPLETIME_3CYCLES_5; +    } +    sConfig.SingleDiff = ADC_SINGLE_ENDED; +    sConfig.OffsetNumber = ADC_OFFSET_NONE; +    sConfig.Offset = 0;      #else      #error Unsupported processor      #endif @@ -692,7 +723,7 @@ static mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_              // for subsequent samples we can just set the "start sample" bit              #if defined(STM32F4) || defined(STM32F7) || defined(STM32L1)              self->handle.Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; -            #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) +            #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB)              SET_BIT(self->handle.Instance->CR, ADC_CR_ADSTART);              #else              #error Unsupported processor @@ -802,7 +833,7 @@ static mp_obj_t adc_read_timed_multi(mp_obj_t adc_array_in, mp_obj_t buf_array_i              // ADC is started: set the "start sample" bit              #if defined(STM32F4) || defined(STM32F7) || defined(STM32L1)              adc->handle.Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; -            #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) +            #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB)              SET_BIT(adc->handle.Instance->CR, ADC_CR_ADSTART);              #else              #error Unsupported processor @@ -953,7 +984,7 @@ float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) {      return 0.0f; // TODO      #else -    #if defined(STM32G0) || defined(STM32G4) || defined(STM32L1) || defined(STM32L4) +    #if defined(STM32G0) || defined(STM32G4) || defined(STM32L1) || defined(STM32L4) || defined(STM32U5)      // Update the reference correction factor before reading tempsensor      // because TS_CAL1 and TS_CAL2 of STM32G0,G4,L1,L4 are at VDDA=3.0V      adc_read_core_vref(adcHandle); @@ -967,7 +998,7 @@ float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) {          return 0;      }      float core_temp_avg_slope = (*ADC_CAL2 - *ADC_CAL1) / 100.0f; -    #elif defined(STM32H5) || defined(STM32WB) +    #elif defined(STM32H5) || defined(STM32U5) || defined(STM32WB)      int32_t raw_value = adc_config_and_read_ref(adcHandle, ADC_CHANNEL_TEMPSENSOR);      float core_temp_avg_slope = (*ADC_CAL2 - *ADC_CAL1) / 100.0f;      #else @@ -980,7 +1011,7 @@ float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) {  }  float adc_read_core_vbat(ADC_HandleTypeDef *adcHandle) { -    #if defined(STM32G0) || defined(STM32G4) || defined(STM32L4) +    #if defined(STM32G0) || defined(STM32G4) || defined(STM32L4) || defined(STM32U5)      // Update the reference correction factor before reading tempsensor      // because VREFINT of STM32G0,G4,L4 is at VDDA=3.0V      adc_read_core_vref(adcHandle); diff --git a/ports/stm32/adc.h b/ports/stm32/adc.h index 0adc9ac2b..96947c326 100644 --- a/ports/stm32/adc.h +++ b/ports/stm32/adc.h @@ -56,6 +56,8 @@ static inline void adc_deselect_vbat(ADC_TypeDef *adc, uint32_t channel) {          adc_common = adc == ADC3 ? ADC3_COMMON : ADC12_COMMON;          #elif defined(STM32L4)          adc_common = __LL_ADC_COMMON_INSTANCE(0); +        #elif defined(STM32U5) +        adc_common = ADC12_COMMON;          #elif defined(STM32WL)          adc_common = ADC_COMMON;          #endif diff --git a/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/board.json b/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/board.json new file mode 100644 index 000000000..4386b7084 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/board.json @@ -0,0 +1,15 @@ +{ +    "deploy": [ +        "../deploy.md" +    ], +    "docs": "", +    "features": [], +    "images": [ +        "nucleo_u5a5zj_q.jpg" +    ], +    "mcu": "stm32u5", +    "product": "Nucleo U5A5ZJ_Q", +    "thumbnail": "", +    "url": "", +    "vendor": "ST Microelectronics" +} diff --git a/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/mpconfigboard.h b/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/mpconfigboard.h new file mode 100644 index 000000000..1b39e136b --- /dev/null +++ b/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/mpconfigboard.h @@ -0,0 +1,82 @@ +#define MICROPY_HW_BOARD_NAME               "NUCLEO_U5A5ZJ_Q" +#define MICROPY_HW_MCU_NAME                 "STM32U5A5ZJ" + +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1) +#define MICROPY_HW_ENABLE_ADC               (1) +#define MICROPY_HW_ENABLE_DAC               (1) +#define MICROPY_HW_ENABLE_USB               (1) +#define MICROPY_HW_ENABLE_RNG               (1) +#define MICROPY_HW_ENABLE_RTC               (1) +#define MICROPY_HW_HAS_FLASH                (1) +#define MICROPY_HW_HAS_SWITCH               (1) + +// The board has a 16MHz oscillator, the following gives 160MHz CPU speed +#define MICROPY_HW_CLK_PLLM                 (1) +#define MICROPY_HW_CLK_PLLN                 (10) +#define MICROPY_HW_CLK_PLLP                 (10) +#define MICROPY_HW_CLK_PLLQ                 (2) +#define MICROPY_HW_CLK_PLLR                 (1) +#define MICROPY_HW_CLK_PLLVCI               (RCC_PLLVCIRANGE_1) +#define MICROPY_HW_CLK_PLLFRAC              (0) + +// 5 wait states, according to Table 37, Reference Manual (RM0481 Rev 1) +#define MICROPY_HW_FLASH_LATENCY            FLASH_LATENCY_4 + +// There is an external 32kHz oscillator +#define MICROPY_HW_RTC_USE_LSE              (1) +#define MICROPY_HW_RCC_RTC_CLKSOURCE        (RCC_RTCCLKSOURCE_LSE) + +// UART config +#define MICROPY_HW_UART1_TX                 (pin_A9) +#define MICROPY_HW_UART1_RX                 (pin_A10) +#define MICROPY_HW_UART2_TX                 (pin_D5) +#define MICROPY_HW_UART2_RX                 (pin_D6) +#define MICROPY_HW_UART2_RTS                (pin_D4) +#define MICROPY_HW_UART2_CTS                (pin_D3) + +// Connect REPL to UART1 which is provided on ST-Link USB interface +#define MICROPY_HW_UART_REPL                PYB_UART_1 +#define MICROPY_HW_UART_REPL_BAUD           115200 + +// I2C buses +#define MICROPY_HW_I2C1_SCL                 (pin_B8) // Arduino Connector CN7-Pin2 (D15) +#define MICROPY_HW_I2C1_SDA                 (pin_B9) // Arduino Connector CN7-Pin4 (D14) +#define MICROPY_HW_I2C2_SCL                 (pin_F1) // Connector CN9-Pin19 +#define MICROPY_HW_I2C2_SDA                 (pin_F0) // Connector CN9-Pin21 + +// SPI buses +#define MICROPY_HW_SPI1_NSS                 (pin_D14) // Arduino Connector CN7-Pin16 (D10) +#define MICROPY_HW_SPI1_SCK                 (pin_A5) // Arduino Connector CN7-Pin10 (D13) +#define MICROPY_HW_SPI1_MISO                (pin_A6) // Arduino Connector CN7-Pin12 (D12) +#define MICROPY_HW_SPI1_MOSI                (pin_A7) // Arduino Connector CN7-Pin14 (D11) +#define MICROPY_HW_SPI2_NSS                 (pin_D0) +#define MICROPY_HW_SPI2_SCK                 (pin_B10) +#define MICROPY_HW_SPI2_MISO                (pin_D3) +#define MICROPY_HW_SPI2_MOSI                (pin_C1) +#define MICROPY_HW_SPI3_NSS                 (pin_A4) +#define MICROPY_HW_SPI3_SCK                 (pin_B3) +#define MICROPY_HW_SPI3_MISO                (pin_B4) +#define MICROPY_HW_SPI3_MOSI                (pin_B5) + +// USRSW is pulled low. Pressing the button makes the input go high. +#define MICROPY_HW_USRSW_PIN                (pin_C13) +#define MICROPY_HW_USRSW_PULL               (GPIO_NOPULL) +#define MICROPY_HW_USRSW_EXTI_MODE          (GPIO_MODE_IT_RISING) +#define MICROPY_HW_USRSW_PRESSED            (1) + +// LEDs +#define MICROPY_HW_LED1                     (pin_C7) // Green +#define MICROPY_HW_LED2                     (pin_B7) // Orange +#define MICROPY_HW_LED3                     (pin_G2) // Red +#define MICROPY_HW_LED_ON(pin)              (mp_hal_pin_high(pin)) +#define MICROPY_HW_LED_OFF(pin)             (mp_hal_pin_low(pin)) + +// USB Configuration +#define MICROPY_HW_USB_HS                   (1) +#define MICROPY_HW_USB_HS_IN_FS             (1) + +#if 0 // FDCAN bus +#define MICROPY_HW_CAN1_NAME                "FDCAN1" +#define MICROPY_HW_CAN1_TX                  (pin_D1) +#define MICROPY_HW_CAN1_RX                  (pin_D0) +#endif diff --git a/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/mpconfigboard.mk b/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/mpconfigboard.mk new file mode 100644 index 000000000..e313f189e --- /dev/null +++ b/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/mpconfigboard.mk @@ -0,0 +1,11 @@ +# MCU settings +MCU_SERIES = u5 +CMSIS_MCU = STM32U5A5xx +MICROPY_FLOAT_IMPL = single +AF_FILE = boards/stm32u5a5_af.csv + +LD_FILES = boards/stm32u5a5xj.ld boards/common_basic.ld +TEXT0_ADDR = 0x08000000 + +# MicroPython settings +MICROPY_HW_ENABLE_ISR_UART_FLASH_FUNCS_IN_RAM = 1 diff --git a/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/pins.csv b/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/pins.csv new file mode 100644 index 000000000..fb0a0d4b9 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/pins.csv @@ -0,0 +1,123 @@ +A0,PA3 +A1,PA2 +A2,PC3 +A3,PB0 +A4,PC1 +A5,PC0 +A6,PB1 +A7,PC2 +A8,PA1 +D0,PG8 +D1,PG7 +D2,PF15 +D3,PE13 +D4,PF14 +D5,PE11 +D6,PE9 +D7,PF13 +D8,PF12 +D9,PD15 +D10,PD14 +D11,PA7 +D12,PA6 +D13,PA5 +D14,PB9 +D15,PB8 +D16,PC6 +D17,PD11 +D18,PB13 +D19,PD12 +D20,PA4 +D21,PB4 +D22,PB5 +D23,PB3 +D24,PA4 +D25,PB4 +D26,PA2 +D27,PB10 +D28,PE15 +D29,PB0 +D30,PE12 +D31,PE14 +D32,PA0 +D33,PA8 +D34,PE0 +D35,PB11 +D36,PB10 +D37,PE15 +D38,PE14 +D39,PE12 +D40,PE10 +D41,PE7 +D42,PE8 +D43,PC8 +D44,PC9 +D45,PC10 +D46,PC11 +D47,PC12 +D48,PD2 +D49,PF3 +D50,PF5 +D51,PD7 +D52,PD6 +D53,PD5 +D54,PD4 +D55,PD3 +D56,PE2 +D57,PE4 +D58,PE5 +D59,PE6 +D60,PE3 +D61,PF8 +D62,PF7 +D63,PF9 +D64,PG1 +D65,PG0 +D66,PD1 +D67,PD0 +D68,PF0 +D69,PF1 +D70,PF2 +D71,PB6 +D72,PB2 +DAC1,PA4 +DAC2,PA5 +LED1,PC7 +LED2,PB7 +LED3,PG2 +SW,PC13 +I2C1_SDA,PB9 +I2C1_SCL,PB8 +I2C2_SDA,PF0 +I2C2_SCL,PF1 +I2C4_SCL,PF14 +I2C4_SDA,PF15 +SD_D0,PC8 +SD_D1,PC9 +SD_D2,PC10 +SD_D3,PC11 +SD_CMD,PD2 +SD_CK,PC12 +SD_SW,PG2 +OTG_FS_POWER,PD10 +OTG_FS_OVER_CURRENT,PG7 +USB_VBUS,PA9 +USB_ID,PA10 +USB_DM,PA11 +USB_DP,PA12 +UART1_TX,PA9 +UART1_RX,PA10 +UART2_TX,PD5 +UART2_RX,PD6 +UART2_RTS,PD4 +UART2_CTS,PD3 +UART3_TX,PD8 +UART3_RX,PD9 +UART5_TX,PB6 +UART5_RX,PB12 +UART6_TX,PC6 +UART6_RX,PC7 +UART7_TX,PF7 +UART7_RX,PF6 +UART8_TX,PE1 +UART8_RX,PE0 diff --git a/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/stm32u5xx_hal_conf.h b/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/stm32u5xx_hal_conf.h new file mode 100644 index 000000000..3af461418 --- /dev/null +++ b/ports/stm32/boards/NUCLEO_U5A5ZJ_Q/stm32u5xx_hal_conf.h @@ -0,0 +1,19 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2023 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32U5XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32U5XX_HAL_CONF_H + +// Oscillator values in Hz +#define HSE_VALUE (16000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (100) +#define LSE_STARTUP_TIMEOUT (5000) + +#include "boards/stm32u5xx_hal_conf_base.h" + +#endif // MICROPY_INCLUDED_STM32U5XX_HAL_CONF_H diff --git a/ports/stm32/boards/stm32u5a5_af.csv b/ports/stm32/boards/stm32u5a5_af.csv new file mode 100644 index 000000000..94afd5aca --- /dev/null +++ b/ports/stm32/boards/stm32u5a5_af.csv @@ -0,0 +1,158 @@ +Port ,Pin ,AF0          ,AF1                ,AF2                           ,AF3                                 ,AF4                                                ,AF5                                                   ,AF6                                                     ,AF7                                                          ,AF8                               ,AF9                                                                  ,AF10                                         ,AF11                                                   ,AF12                                                        ,AF13                                            ,AF14                   ,AF15    ,ADC +     ,    ,CRS/LPTIM1/SYS_AF,LPTIM1/TIM1/2/5/8,I2C5/6/LPTIM1/2/3/TIM1/2/3/4/5,ADF1/I2C4/OCTOSPIM_P1/OTG_HS/SAI1/SPI2/TIM1/8/USART2,DCMI/I2C1/2/3/4/5/LPTIM3,DCMI/I2C4/MDF1/OCTOSPIM_P1/2/SPI1/2/3,I2C3/MDF1/OCTOSPIM_P2/SPI3,LCD/USART1/2/3/6,HSPI1/LCD/LPUART1/SDMMC1/UART4/5,CAN1/TSC,CRS/DCMI/OCTOSPIM_P1/2/OTG_HS,DSI/FMC/LPGPIO1/SDMMC2/UCPD1,COMP1/2/FMC/SDMMC1/2/SYS_AF,LPTIM2/4/SAI1/2,LPTIM2/3/TIM2/15/16/17,SYS     ,ADC +PortA,PA0 ,             ,TIM2_CH1           ,TIM5_CH1                      ,TIM8_ETR                            ,                                                   ,,SPI3_RDY                                                ,USART2_CTS,UART4_TX                          ,,OCTOSPIM_P2_NCS,,SDMMC2_CMD,AUDIOCLK,TIM2_ETR               ,EVENTOUT,ADC1_IN5/ADC2_IN5 +PortA,PA1 ,LPTIM1_CH2,TIM2_CH2           ,TIM5_CH2                      ,                                    ,I2C1_SMBA                                          ,SPI1_SCK,,USART2_RTS_DE,UART4_RX                          ,,OCTOSPIM_P1_DQS,LPGPIO1_P0,                                                            ,                                                ,TIM15_CH1N,EVENTOUT,ADC1_IN6/ADC2_IN6 +PortA,PA2 ,             ,TIM2_CH3           ,TIM5_CH3                      ,                                    ,                                                   ,SPI1_RDY,                                                        ,USART2_TX                                                    ,LPUART1_TX,                                                                     ,OCTOSPIM_P1_NCS,UCPD1_FRSTX1,                                                            ,                                                ,TIM15_CH1,EVENTOUT,ADC1_IN7/ADC2_IN7 +PortA,PA3 ,             ,TIM2_CH4           ,TIM5_CH4                      ,SAI1_CK1,                                                   ,,,USART2_RX                                                    ,LPUART1_RX,                                                                     ,OCTOSPIM_P1_CLK,LPGPIO1_P1,                                                            ,SAI1_MCLK_A,TIM15_CH2,EVENTOUT,ADC1_IN8/ADC2_IN8 +PortA,PA4 ,             ,                   ,,OCTOSPIM_P1_NCS,                                                   ,SPI1_NSS,SPI3_NSS,USART2_CK                                                    ,,                                                                     ,DCMI_HSYNC/PSSI_DE,                                                       ,                                                            ,SAI1_FS_B,LPTIM2_CH1,EVENTOUT,ADC1_IN9/ADC2_IN9/ADC4_IN9 +PortA,PA5 ,CSLEEP,TIM2_CH1           ,TIM2_ETR,TIM8_CH1N                           ,PSSI_D14,SPI1_SCK,                                                        ,USART3_RX,,,,,,,LPTIM2_ETR,EVENTOUT,ADC1_IN10/ADC2_IN10/ADC4_IN10 +PortA,PA6 ,CDSTOP,TIM1_BKIN          ,TIM3_CH1                      ,TIM8_BKIN                           ,DCMI_PIXCLK/PSSI_PDCK,SPI1_MISO,,USART3_CTS,LPUART1_CTS,                                                            ,OCTOSPIM_P1_IO3,LPGPIO1_P2,                                                            ,,TIM16_CH1,EVENTOUT,ADC1_IN11/ADC2_IN11/ADC4_IN11 +PortA,PA7 ,SRDSTOP,TIM1_CH1N          ,TIM3_CH2                      ,TIM8_CH1N                           ,I2C3_SCL,SPI1_MOSI,                                                        ,USART3_TX,,                                                            ,OCTOSPIM_P1_IO2,,,LPTIM2_CH2,TIM17_CH1,EVENTOUT,ADC1_IN12/ADC2_IN12/ADC4_IN20 +PortA,PA8 ,MCO,TIM1_CH1           ,                              ,SAI1_CK2,,SPI1_RDY                                              ,                                                        ,USART1_CK                                                    ,                                  ,                                                                     ,OTG_HS_SOF,,TRACECLK,SAI1_SCK_A,LPTIM2_CH1,EVENTOUT, +PortA,PA9 ,             ,TIM1_CH2           ,                              ,SPI2_SCK,,DCMI_D0/PSSI_D0,                                                        ,USART1_TX                                                    ,,,,,,SAI1_FS_A,TIM15_BKIN,EVENTOUT, +PortA,PA10,CRS_SYNC,TIM1_CH3           ,LPTIM2_IN2,SAI1_D1,,DCMI_D1/PSSI_D1,,USART1_RX                                                    ,                                  ,,OTG_HS_ID,,,SAI1_SD_A,TIM17_BKIN,EVENTOUT, +PortA,PA11,             ,TIM1_CH4           ,TIM1_BKIN2,,                                                   ,SPI1_MISO,,USART1_CTS,                                  ,FDCAN1_RX                                                            ,,,,,,EVENTOUT, +PortA,PA12,             ,TIM1_ETR           ,                              ,,                                                   ,SPI1_MOSI,OCTOSPIM_P2_NCS,USART1_RTS_DE,,FDCAN1_TX                                                            ,,                                                       ,                                                            ,,                       ,EVENTOUT, +PortA,PA13,JTMS/SWDIO   ,IR_OUT,                              ,                                    ,                                                   ,                                                      ,                                                        ,                                                             ,                                  ,                                                                     ,,                                                       ,                                                            ,SAI1_SD_B,                       ,EVENTOUT, +PortA,PA14,JTCK/SWCLK   ,LPTIM1_CH1,                              ,                                    ,I2C1_SMBA,I2C4_SMBA,                                                        ,                                                             ,                                  ,                                                                     ,OTG_HS_SOF,                                                       ,                                                            ,SAI1_FS_B,                       ,EVENTOUT, +PortA,PA15,JTDI         ,TIM2_CH1           ,TIM2_ETR,USART2_RX,,SPI1_NSS,SPI3_NSS,USART3_RTS_DE,UART4_RTS_DE,,,,,SAI2_FS_B,,EVENTOUT, +PortB,PB0 ,             ,TIM1_CH2N          ,TIM3_CH3                      ,TIM8_CH2N,LPTIM3_CH1,SPI1_NSS,,USART3_CK,,                                                                     ,OCTOSPIM_P1_IO1,LPGPIO1_P9,COMP1_OUT,AUDIOCLK,,EVENTOUT,ADC1_IN15/ADC2_IN15/ADC4_IN18 +PortB,PB1 ,             ,TIM1_CH3N          ,TIM3_CH4                      ,TIM8_CH3N,LPTIM3_CH2,                                                      ,MDF1_SDI0,USART3_RTS_DE,LPUART1_RTS_DE,                                                                     ,OCTOSPIM_P1_IO0,LPGPIO1_P3,                                                            ,                                                ,LPTIM2_IN1,EVENTOUT,ADC1_IN16/ADC2_IN16/ADC4_IN19 +PortB,PB2 ,,LPTIM1_CH1,,TIM8_CH4N,I2C3_SMBA,SPI1_RDY,MDF1_CKI0,,LCD_B1,,OCTOSPIM_P1_DQS,UCPD1_FRSTX1,,,                       ,EVENTOUT,ADC1_IN17/ADC2_IN17 +PortB,PB3 ,JTDO/TRACESWO,TIM2_CH2           ,LPTIM1_CH1,ADF1_CCK0,I2C1_SDA,SPI1_SCK,SPI3_SCK,USART1_RTS_DE,,,CRS_SYNC                                     ,LPGPIO1_P11,SDMMC2_D2,SAI1_SCK_B,,EVENTOUT, +PortB,PB4 ,NJTRST       ,LPTIM1_CH2         ,TIM3_CH1                      ,ADF1_SDI0,I2C3_SDA,SPI1_MISO,SPI3_MISO,USART1_CTS,UART5_RTS_DE,TSC_G2_IO1,DCMI_D12/PSSI_D12,LPGPIO1_P12,SDMMC2_D3,SAI1_MCLK_B,TIM17_BKIN,EVENTOUT, +PortB,PB5 ,             ,LPTIM1_IN1         ,TIM3_CH2                      ,OCTOSPI1_NCLK,I2C1_SMBA                                          ,SPI1_MOSI,SPI3_MOSI,USART1_CK,UART5_CTS,TSC_G2_IO2,DCMI_D10/PSSI_D10,,COMP2_OUT,SAI1_SD_B,TIM16_BKIN,EVENTOUT, +PortB,PB6 ,             ,LPTIM1_ETR         ,TIM4_CH1                      ,TIM8_BKIN2,I2C1_SCL                                           ,I2C4_SCL,MDF1_SDI5,USART1_TX                                                    ,,TSC_G2_IO3,DCMI_D5/PSSI_D5,                                                       ,,SAI1_FS_B,TIM16_CH1N,EVENTOUT, +PortB,PB7 ,             ,LPTIM1_IN2,TIM4_CH2                      ,TIM8_BKIN,I2C1_SDA                                           ,I2C4_SDA,MDF1_CKI5,USART1_RX                                                    ,UART4_CTS,TSC_G2_IO4,DCMI_VSYNC/PSSI_RDY,,FMC_NL,,TIM17_CH1N,EVENTOUT, +PortB,PB8 ,             ,                   ,TIM4_CH3                      ,SAI1_CK1,I2C1_SCL                                           ,MDF1_CCK0,SPI3_RDY,LCD_B1,SDMMC1_CKIN,FDCAN1_RX                                                            ,DCMI_D6/PSSI_D6,SDMMC2_D4,SDMMC1_D4,SAI1_MCLK_A,TIM16_CH1,EVENTOUT, +PortB,PB9 ,             ,IR_OUT             ,TIM4_CH4                      ,SAI1_D2,I2C1_SDA                                           ,SPI2_NSS,,,SDMMC1_CDIR,FDCAN1_TX                                                            ,DCMI_D7/PSSI_D7,SDMMC2_D5,SDMMC1_D5,SAI1_FS_A,TIM17_CH1,EVENTOUT, +PortB,PB10,             ,TIM2_CH3           ,LPTIM3_CH1                    ,I2C4_SCL,I2C2_SCL                                           ,SPI2_SCK,                                                        ,USART3_TX                                                    ,LPUART1_RX,TSC_SYNC,OCTOSPIM_P1_CLK,LPGPIO1_P4,COMP1_OUT,SAI1_SCK_A,                       ,EVENTOUT, +PortB,PB11,             ,TIM2_CH4           ,                              ,I2C4_SDA,I2C2_SDA                                           ,SPI2_RDY                                              ,,USART3_RX                                                    ,LPUART1_TX,                                                                     ,OCTOSPIM_P1_NCS,,COMP2_OUT,                                                ,                       ,EVENTOUT, +PortB,PB12,             ,TIM1_BKIN          ,I2C6_SMBA,,I2C2_SMBA,SPI2_NSS,MDF1_SDI1,USART3_CK                                                    ,LPUART1_RTS_DE,TSC_G1_IO1,OCTOSPIM_P1_NCLK,,                                                            ,SAI2_FS_A,TIM15_BKIN,EVENTOUT, +PortB,PB13,             ,TIM1_CH1N          ,LPTIM3_IN1                    ,,I2C2_SCL,SPI2_SCK,MDF1_CKI1,USART3_CTS,LPUART1_CTS,TSC_G1_IO2,,,,SAI2_SCK_A,TIM15_CH1N,EVENTOUT, +PortB,PB14,             ,TIM1_CH2N          ,LPTIM3_ETR,TIM8_CH2N,I2C2_SDA,SPI2_MISO,MDF1_SDI2,USART3_RTS_DE,,TSC_G1_IO3,                                             ,                                                       ,SDMMC2_D0,SAI2_MCLK_A,TIM15_CH1,EVENTOUT, +PortB,PB15,RTC_REFIN    ,TIM1_CH3N          ,LPTIM2_IN2,TIM8_CH3N                           ,                                          ,SPI2_MOSI,MDF1_CKI2,,,,,FMC_NBL1,SDMMC2_D1,SAI2_SD_A,TIM15_CH2,EVENTOUT, +PortC,PC0 ,             ,LPTIM1_IN1         ,                              ,OCTOSPIM_P1_IO7,I2C3_SCL,SPI2_RDY,MDF1_SDI4,USART6_CTS,LPUART1_RX,,,,SDMMC1_D5,SAI2_FS_A,LPTIM2_IN1,EVENTOUT,ADC1_IN1/ADC2_IN1/ADC4_IN1 +PortC,PC1 ,TRACED0      ,LPTIM1_CH1,,SPI2_MOSI,I2C3_SDA,,MDF1_CKI4,USART6_CK,LPUART1_TX,,OCTOSPIM_P1_IO4,,SDMMC2_CK,SAI1_SD_A,                       ,EVENTOUT,ADC1_IN2/ADC2_IN2/ADC4_IN2 +PortC,PC2 ,,LPTIM1_IN2          ,,                                    ,                                                  ,SPI2_MISO,MDF1_CCK1,USART6_RX,                                  ,,OCTOSPIM_P1_IO5,LPGPIO1_P5,,                                                ,                       ,EVENTOUT,ADC1_IN3/ADC2_IN3/ADC4_IN3 +PortC,PC3 ,,LPTIM1_ETR,LPTIM3_CH1,SAI1_D1,                                                   ,SPI2_MOSI,,USART6_TX,                                  ,,OCTOSPIM_P1_IO6,,,SAI1_SD_A,LPTIM2_ETR,EVENTOUT, +PortC,PC4 ,             ,,I2C6_SMBA,,,,,USART3_RX                                                    ,                                  ,                                                                     ,OCTOSPIM_P1_IO7,,,,                       ,EVENTOUT,ADC1_IN13/ADC2_IN13/ADC4_IN22 +PortC,PC5 ,             ,TIM1_CH4N          ,,SAI1_D3,PSSI_D15,                                                      ,,USART3_RX,,,,,,,,EVENTOUT,ADC1_IN14/ADC2_IN14/ADC4_IN23 +PortC,PC6 ,CSLEEP,                   ,TIM3_CH1,TIM8_CH1                            ,                                                   ,,MDF1_CKI3,LCD_R0,SDMMC1_D0DIR                      ,TSC_G4_IO1,DCMI_D0/PSSI_D0,SDMMC2_D6,SDMMC1_D6,SAI2_MCLK_A,                       ,EVENTOUT, +PortC,PC7 ,CDSTOP,                   ,TIM3_CH2                      ,TIM8_CH2                            ,                                                   ,                                                      ,MDF1_SDI3,LCD_R1,SDMMC1_D123DIR                    ,TSC_G4_IO2,DCMI_D1/PSSI_D1,SDMMC2_D7,SDMMC1_D7,SAI2_MCLK_B,LPTIM2_CH2,EVENTOUT, +PortC,PC8 ,SRDSTOP,                   ,TIM3_CH3                      ,TIM8_CH3                            ,                                                   ,                                                      ,                                                        ,USART6_RX,,TSC_G4_IO3,DCMI_D2/PSSI_D2,,SDMMC1_D0                                                   ,,LPTIM3_CH1,EVENTOUT, +PortC,PC9 ,TRACED0,TIM8_BKIN2,TIM3_CH4                      ,TIM8_CH4                            ,DCMI_D3/PSSI_D3,,                                                        ,USART6_TX,,TSC_G4_IO4,,,SDMMC1_D1                                                   ,,LPTIM3_CH2,EVENTOUT, +PortC,PC10,TRACED1,                   ,LPTIM3_ETR                    ,ADF1_CCK1,                                                   ,                                                      ,SPI3_SCK,USART3_TX                                                    ,UART4_TX                          ,TSC_G3_IO2,DCMI_D8/PSSI_D8,LPGPIO1_P8,SDMMC1_D2                                                   ,SAI2_SCK_B,                       ,EVENTOUT, +PortC,PC11,             ,                   ,LPTIM3_IN1                    ,ADF1_SDI0,DCMI_D2/PSSI_D2,OCTOSPIM_P1_NCS,SPI3_MISO,USART3_RX                                                    ,UART4_RX                          ,TSC_G3_IO3,DCMI_D4/PSSI_D4,UCPD1_FRSTX2,SDMMC1_D3                                                   ,SAI2_MCLK_B,                       ,EVENTOUT, +PortC,PC12,TRACED3      ,                   ,                              ,                                    ,                                                   ,,SPI3_MOSI,USART3_CK                                                    ,UART5_TX                          ,TSC_G3_IO4,DCMI_D9/PSSI_D9,LPGPIO1_P10,SAI2_SD_B,,                       ,EVENTOUT, +PortC,PC13,             ,                   ,                              ,                                    ,                                                   ,                                                      ,                                                        ,                                                             ,,,,,,,,EVENTOUT, +PortC,PC14,             ,                   ,                              ,                                    ,                                                   ,                                                      ,                                                        ,                                                             ,,,,,,,,EVENTOUT, +PortC,PC15,             ,                   ,                              ,                                    ,                                                   ,                                                      ,                                                        ,                                                             ,,,,,,,,EVENTOUT, +PortD,PD0 ,             ,                   ,I2C6_SDA,TIM8_CH4N                           ,I2C5_SDA,SPI2_NSS                                                      ,                                                        ,                                                             ,LCD_B4,FDCAN1_RX                                                            ,                                             ,,FMC_D2,                                                ,                       ,EVENTOUT, +PortD,PD1 ,             ,                   ,I2C6_SCL,,I2C5_SCL,SPI2_SCK,                                                        ,                                                             ,LCD_B5,FDCAN1_TX                                                            ,                                             ,                                                       ,FMC_D3,                                                ,                       ,EVENTOUT, +PortD,PD2 ,TRACED2      ,                   ,TIM3_ETR                      ,                                    ,I2C5_SMBA,                                                      ,                                                        ,USART3_RTS_DE,UART5_RX                          ,TSC_SYNC,DCMI_D11/PSSI_D11,LPGPIO1_P7,SDMMC1_CMD                                                  ,LPTIM4_ETR,,EVENTOUT, +PortD,PD3 ,             ,                   ,I2C6_SMBA,SPI2_SCK,DCMI_D5/PSSI_D5,SPI2_MISO                                      ,MDF1_SDI0,USART2_CTS,LCD_CLK,                                                                     ,OCTOSPIM_P2_NCS,                                                       ,FMC_CLK                                                     ,,                       ,EVENTOUT, +PortD,PD4 ,             ,                   ,                              ,                                    ,                                                   ,SPI2_MOSI,MDF1_CKI0,USART2_RTS_DE,                                  ,                                                                     ,OCTOSPIM_P1_IO4,                                                       ,FMC_NOE                                                     ,                                                ,                       ,EVENTOUT, +PortD,PD5 ,             ,,                              ,                                    ,                                                   ,SPI2_RDY                                              ,                                                        ,USART2_TX                                                    ,                                  ,,OCTOSPIM_P1_IO5,                                                       ,FMC_NWE                                                     ,                                                ,                       ,EVENTOUT, +PortD,PD6 ,             ,                   ,,SAI1_D1,DCMI_D10/PSSI_D10,SPI3_MOSI,MDF1_SDI1,USART2_RX                                                    ,LCD_DE,                                                                     ,OCTOSPIM_P1_IO6,SDMMC2_CK                                              ,FMC_NWAIT                                                   ,SAI1_SD_A,                       ,EVENTOUT, +PortD,PD7 ,             ,                   ,                              ,                                    ,                                                   ,SPI1_MOSI/I2S1_SDO                                    ,                                                        ,USART2_CK                                                    ,                                  ,                                                                     ,OCTOSPIM_P1_IO7,SDMMC2_CMD                                             ,FMC_NCE/FMC_NE1                                       ,LPTIM4_OUT,,EVENTOUT, +PortD,PD8 ,             ,                   ,                              ,                                    ,                                                   ,                                                      ,                                                        ,USART3_TX                                                    ,LCD_R3,                                                                     ,DCMI_HSYNC/PSSI_DE,                                                       ,FMC_D13,                                                ,                       ,EVENTOUT, +PortD,PD9 ,             ,                   ,LPTIM2_IN2,                                    ,                                                   ,                                                      ,                                                        ,USART3_RX                                                    ,LCD_R4,,DCMI_PIXCLK/PSSI_PDCK,                                                       ,FMC_D14,SAI2_MCLK_A,LPTIM3_IN1,EVENTOUT, +PortD,PD10,             ,                   ,LPTIM2_CH2,,I2C5_SMBA,                                                      ,                                                        ,USART3_CK                                                    ,LCD_R5,TSC_G6_IO1,                                             ,                                                       ,FMC_D15,SAI2_SCK_A,LPTIM3_ETR,EVENTOUT, +PortD,PD11,             ,                   ,,,I2C4_SMBA                                          ,                                                      ,                                                        ,USART3_CTS,LCD_R6,TSC_G6_IO2,,                                                       ,FMC_A16/FMC_CLE,SAI2_SD_A,LPTIM2_ETR,EVENTOUT,ADC4_IN15 +PortD,PD12,             ,,TIM4_CH1                      ,,I2C4_SCL                                           ,,,USART3_RTS_DE,LCD_R7,TSC_G6_IO3,,,FMC_ALE/FMC_A17,SAI2_FS_A,LPTIM2_IN1,EVENTOUT,ADC4_IN16 +PortD,PD13,             ,,TIM4_CH2                      ,,I2C4_SDA                                           ,,                                                        ,USART6_CTS,LCD_VSYNC,TSC_G6_IO4,,LPGPIO1_P6,FMC_A18                                                     ,LPTIM4_IN1,LPTIM2_CH1,EVENTOUT,ADC4_IN17 +PortD,PD14,             ,                   ,TIM4_CH3                      ,                                    ,                                                   ,                                                      ,                                                        ,USART6_CK,LCD_B2,,,,FMC_D0,                                                ,LPTIM3_CH1,EVENTOUT, +PortD,PD15,             ,                   ,TIM4_CH4                      ,                                    ,                                                   ,                                                      ,                                                        ,USART6_RTS_DE,LCD_B3,                                                                     ,                                             ,,FMC_D1,                                                ,LPTIM3_CH2,EVENTOUT, +PortE,PE0 ,             ,,TIM4_ETR                      ,,,,,USART6_RX,LCD_HSYNC,,DCMI_D2/PSSI_D2,LPGPIO1_P13,FMC_NBL0                                                    ,,TIM16_CH1,EVENTOUT, +PortE,PE1 ,             ,,                              ,                                    ,                                                   ,                                                      ,                                                        ,USART6_TX,LCD_VSYNC,,DCMI_D3/PSSI_D3,                                                       ,FMC_NBL1                                                    ,,TIM17_CH1,EVENTOUT, +PortE,PE2 ,TRACECLK     ,,TIM3_ETR,SAI1_CK1          ,                                                   ,,,USART6_CK,LCD_R0,TSC_G7_IO1,                                             ,LPGPIO1_P14,FMC_A23                                                     ,SAI1_MCLK_A,                       ,EVENTOUT, +PortE,PE3 ,TRACED0      ,                   ,TIM3_CH1,OCTOSPIM_P1_DQS,                                         ,                                                      ,,USART6_CTS,LCD_R1,TSC_G7_IO2,                                             ,LPGPIO1_P15,FMC_A19                                                     ,SAI1_SD_B,                       ,EVENTOUT, +PortE,PE4 ,TRACED1      ,                   ,TIM3_CH2,SAI1_D2,                                         ,,MDF1_SDI3,USART6_RTS_DE,LCD_B0,TSC_G7_IO3,DCMI_D4/PSSI_D4,                                                       ,FMC_A20                                                     ,SAI1_FS_A,                       ,EVENTOUT, +PortE,PE5 ,TRACED2      ,                   ,TIM3_CH3,SAI1_CK2,                                          ,,MDF1_CKI3,                                                             ,LCD_G0,TSC_G7_IO4,DCMI_D6/PSSI_D6,                                                       ,FMC_A21                                                     ,SAI1_SCK_A,                       ,EVENTOUT, +PortE,PE6 ,TRACED3      ,,TIM3_CH4,SAI1_D1,                                          ,,,                                                             ,LCD_G1,                                                                     ,DCMI_D7/PSSI_D7,                                                       ,FMC_A22                                                     ,SAI1_SD_A,                       ,EVENTOUT, +PortE,PE7 ,             ,TIM1_ETR           ,                              ,                                    ,                                                   ,                                                      ,MDF1_SDI2,,LCD_B6,                                                                     ,,                                                       ,FMC_D4,SAI1_SD_B,                       ,EVENTOUT, +PortE,PE8 ,             ,TIM1_CH1N          ,                              ,                                    ,                                                   ,                                                      ,MDF1_CKI2,,LCD_B7,                                                                     ,,                                                       ,FMC_D5,SAI1_SCK_B,                       ,EVENTOUT, +PortE,PE9 ,             ,TIM1_CH1           ,                              ,ADF1_CCK0,                                                   ,                                                      ,MDF1_CCK0,,LCD_G2,                                                                     ,OCTOSPIM_P1_NCLK,                                                       ,FMC_D6,SAI1_FS_B,                       ,EVENTOUT, +PortE,PE10,             ,TIM1_CH2N          ,                              ,ADF1_SDI0,                                                   ,                                                      ,MDF1_SDI4,,LCD_G3,TSC_G5_IO1,OCTOSPIM_P1_CLK,                                                       ,FMC_D7,SAI1_MCLK_B,                       ,EVENTOUT, +PortE,PE11,             ,TIM1_CH2           ,                              ,                                    ,,SPI1_RDY,MDF1_CKI4,,LCD_G4,TSC_G5_IO2,OCTOSPIM_P1_NCS,                                                       ,FMC_D8,                                                ,                       ,EVENTOUT, +PortE,PE12,             ,TIM1_CH3N          ,                              ,                                    ,                                                   ,SPI1_NSS,MDF1_SDI5,                                                             ,LCD_G5,TSC_G5_IO3,OCTOSPIM_P1_IO0,                                                       ,FMC_D9,                                                ,                       ,EVENTOUT, +PortE,PE13,             ,TIM1_CH3           ,                              ,                                    ,                                                   ,SPI1_SCK,MDF1_CKI5,                                                             ,LCD_G6,TSC_G5_IO4,OCTOSPIM_P1_IO1,                                                       ,FMC_D10,                                                ,                       ,EVENTOUT, +PortE,PE14,             ,TIM1_CH4           ,TIM1_BKIN2,                                    ,                                                   ,SPI1_MISO,                                                        ,                                                             ,LCD_G7,                                                                     ,OCTOSPIM_P1_IO2,                                                       ,FMC_D11,                                                ,                       ,EVENTOUT, +PortE,PE15,             ,TIM1_BKIN          ,                              ,TIM1_CH4N,                                                   ,SPI1_MOSI,                                                        ,,LCD_R2,                                                                     ,OCTOSPIM_P1_IO3,                                                       ,FMC_D12,                                                ,                       ,EVENTOUT, +PortF,PF0 ,             ,                   ,I2C6_SDA,                                    ,I2C2_SDA,OCTOSPIM_P2_IO0,                                                        ,USART6_TX,                                  ,                                                                     ,                                             ,                                                       ,FMC_A0                                                      ,,                       ,EVENTOUT, +PortF,PF1 ,             ,                   ,I2C6_SCL,                                    ,I2C2_SCL                                           ,OCTOSPIM_P2_IO1,                                                        ,USART6_RX,                                  ,                                                                     ,                                             ,                                                       ,FMC_A1                                                      ,,                       ,EVENTOUT, +PortF,PF2 ,             ,                   ,LPTIM3_CH2                    ,,I2C2_SMBA                                          ,OCTOSPIM_P2_IO2,,USART6_CK,                                  ,                                                                     ,                                             ,                                                       ,FMC_A2                                                      ,,                       ,EVENTOUT, +PortF,PF3 ,             ,                   ,LPTIM3_IN1                    ,ADF1_CCK0,                                                   ,OCTOSPIM_P2_IO3,MDF1_CCK0,USART6_CTS,UART5_TX,                                                                     ,                                             ,                                                       ,FMC_A3                                                      ,,                       ,EVENTOUT, +PortF,PF4 ,             ,                   ,LPTIM3_ETR                    ,ADF1_SDI0,                                                   ,OCTOSPIM_P2_CLK,MDF1_SDI0,USART6_RTS_DE,UART5_RX,                                                                     ,                                             ,                                                       ,FMC_A4                                                      ,                                                ,                       ,EVENTOUT, +PortF,PF5 ,             ,                   ,LPTIM3_CH1                    ,                                    ,,OCTOSPIM_P2_NCLK,MDF1_CKI0,,                                  ,                                                                     ,                                             ,                                                       ,FMC_A5                                                      ,                                                ,,EVENTOUT, +PortF,PF6 ,             ,TIM5_ETR          ,TIM5_CH1,                                    ,DCMI_D12/PSSI_D12,OCTOSPIM_P2_NCS,,,                                  ,                                                                     ,OCTOSPIM_P1_IO3,                                                       ,                                                            ,SAI1_SD_B,                       ,EVENTOUT, +PortF,PF7 ,             ,          ,TIM5_CH2,,,,,,                                  ,FDCAN1_RX,OCTOSPIM_P1_IO2,                                                       ,                                                            ,SAI1_MCLK_B,                       ,EVENTOUT, +PortF,PF8 ,             ,         ,TIM5_CH3,                                    ,PSSI_D14,,,,                                  ,FDCAN1_TX,OCTOSPIM_P1_IO0,                                                       ,                                                            ,SAI1_SCK_B,                       ,EVENTOUT, +PortF,PF9 ,             ,         ,TIM5_CH4,                                    ,PSSI_D15,,,,                                  ,                                                            ,OCTOSPIM_P1_IO1,                                                       ,                                                            ,SAI1_FS_B,TIM15_CH1,EVENTOUT, +PortF,PF10,             ,         ,,OCTOSPIM_P1_CLK,PSSI_D15                                           ,                                                      ,MDF1_CCK1,                                                             ,                                  ,,DCMI_D11/PSSI_D11,DSI_TE,                                                            ,SAI1_D3,TIM15_CH2,EVENTOUT, +PortF,PF11,             ,                   ,                              ,OCTOSPIM_P1_NCLK,                                                   ,,                                                        ,                                                             ,LCD_DE,,DCMI_D12/PSSI_D12,DSI_TE,,LPTIM4_IN1,,EVENTOUT,ADC1_INP2 +PortF,PF12,             ,                   ,                              ,                                    ,                                                   ,OCTOSPIM_P2_,                                                        ,                                                             ,LCD_B0,                                                                     ,                                             ,                                                       ,FMC_A6                                                      ,LPTIM4_ETR,,EVENTOUT,ADC1_INP6/ADC1_INN2 +PortF,PF13,             ,                   ,                              ,                                    ,I2C4_SMBA                                          ,                                                      ,                                                        ,                                                             ,LCD_B1,                                                                     ,                                             ,UCPD1_FRSTX2,FMC_A7                                                      ,LPTIM4_OUT,,EVENTOUT,ADC2_INP2 +PortF,PF14,             ,                   ,                              ,                                    ,I2C4_SCL,                                                      ,                                                        ,                                                             ,LCD_G0,TSC_G8_IO1,                                             ,                                                       ,FMC_A8                                                      ,                                                ,,EVENTOUT,ADC4_IN5 +PortF,PF15,             ,                   ,                              ,                                    ,I2C4_SDA                                           ,,                                                        ,                                                             ,LCD_G1,TSC_G8_IO2,                                             ,,FMC_A9                                                      ,                                                ,,EVENTOUT,ADC4_IN6 +PortG,PG0 ,             ,                   ,                              ,                                    ,                                                   ,OCTOSPIM_P2_IO4,                                                        ,                                                             ,                                  ,TSC_G8_IO3,                                             ,,FMC_A10                                                     ,                                                ,,EVENTOUT,ADC4_IN7 +PortG,PG1 ,             ,                   ,                              ,                                    ,                                                   ,OCTOSPIM_P2_IO5,                                                        ,,                                  ,TSC_G8_IO4,                                             ,,FMC_A11                                                     ,                                                ,                       ,EVENTOUT,ADC4_IN8 +PortG,PG2 ,,,,,,SPI1_SCK,                                                        ,,                                  ,                                                                     ,                                             ,,FMC_A12                                                     ,SAI2_SCK_B,,EVENTOUT, +PortG,PG3 ,,,,,,SPI1_MISO,                                                        ,,                                  ,                                                                     ,                                             ,,FMC_A13                                                     ,SAI2_FS_B,,EVENTOUT, +PortG,PG4 ,,,,,,SPI1_MOSI,                                                        ,                                                             ,                                  ,                                                                     ,                                             ,                                                       ,FMC_A11                                                     ,SAI2_MCLK_B,,EVENTOUT, +PortG,PG5 ,,,,,,SPI1_NSS,                                                        ,                                                             ,LPUART1_CTS,                                                                     ,,DSI_TE,FMC_A12                                                     ,SAI2_SD_B,                       ,EVENTOUT, +PortG,PG6 ,             ,         ,                              ,OCTOSPIM_P1_DQS,I2C3_SMBA,SPI1_RDY                                              ,                                                        ,LCD_R1,LPUART1_RTS_DE,                                                                     ,,UCPD1_FRSTX1,,,                       ,EVENTOUT, +PortG,PG7 ,             ,                   ,,SAI1_CK1,I2C3_SCL,OCTOSPIM_P2_DQS,MDF1_CCK0,,LPUART1_TX,                                                                     ,                                             ,UCPD1_FRSTX2,FMC_INT                                                     ,SAI1_MCLK_A,                       ,EVENTOUT, +PortG,PG8 ,             ,                   ,                              ,,I2C3_SDA,,                                                        ,,LPUART1_RX,,,,,,                       ,EVENTOUT, +PortG,PG9 ,             ,                   ,                              ,                                    ,                                                   ,OCTOSPIM_P2_IO6,SPI3_SCK,USART1_TX,,,,,FMC_NCE/FMC_NE2,SAI2_SCK_A,TIM15_CH1N,EVENTOUT, +PortG,PG10,             ,LPTIM1_IN1,                              ,                                    ,                                                   ,OCTOSPIM_P2_IO7,SPI3_MISO,USART1_RX,,,,,FMC_NE3                                                     ,SAI2_FS_A,TIM15_CH1,EVENTOUT, +PortG,PG11,             ,LPTIM1_IN2         ,                              ,OCTOSPIM_P1_IO5,                                                   ,,SPI3_MOSI,USART1_CTS,,,,,,SAI2_MCLK_A,TIM15_CH2,EVENTOUT, +PortG,PG12,,LPTIM1_ETR,                              ,                                    ,,OCTOSPIM_P2_NCS,SPI3_NSS,USART1_RTS_DE,                                  ,                                                                     ,,,FMC_NE4                                                     ,SAI2_SD_A,,EVENTOUT, +PortG,PG13,,,                              ,                                    ,I2C1_SDA,,SPI3_RDY,USART1_CK,LCD_R0,                                                                     ,,,FMC_A24                                                     ,,                       ,EVENTOUT, +PortG,PG14,,LPTIM1_CH2,                              ,                                    ,I2C1_SCL,,,,LCD_R1,,,,FMC_A25                                                     ,,                       ,EVENTOUT, +PortG,PG15,,LPTIM1_CH1,                              ,                                    ,I2C1_SMBA,OCTOSPIM_P2_DQS,,,                                  ,DCMI_D13/PSSI_D13,,,,,                       ,EVENTOUT, +PortH,PH0 ,             ,                   ,                              ,                                    ,                                                   ,                                                      ,                                                        ,                                                             ,,,,,,,,EVENTOUT, +PortH,PH1 ,             ,                   ,                              ,                                    ,                                                   ,                                                      ,                                                        ,,,,,,,,,EVENTOUT, +PortH,PH2 ,             ,,                              ,OCTOSPIM_P1_IO4,                                                   ,                                                      ,                                                        ,,,,,,,,,EVENTOUT, +PortH,PH3 ,             ,                   ,                              ,                                    ,                                                   ,                                                      ,                                                        ,,,,,,,,,EVENTOUT, +PortH,PH4 ,             ,,I2C5_SDA,                                    ,I2C2_SCL,OCTOSPIM_P2_DQS,                                                        ,,                                  ,                                                                     ,PSSI_D14,,,,,EVENTOUT, +PortH,PH5 ,             ,,I2C5_SCL,                                    ,I2C2_SDA,,                                                        ,,                                  ,                                                                     ,DCMI_PIXCLK/PSSI_PDCK,,,,,EVENTOUT, +PortH,PH6 ,             ,,I2C5_SMBA,,I2C2_SMBA                                          ,OCTOSPIM_P2_CLK,                                                        ,,                                  ,                                                                     ,DCMI_D8/PSSI_D8,,,,,EVENTOUT, +PortH,PH7 ,             ,,,,I2C3_SCL                                           ,OCTOSPIM_P2_NCLK,                                                        ,,                                  ,                                                                     ,DCMI_D9/PSSI_D9,,,,,EVENTOUT, +PortH,PH8 ,             ,,,,I2C3_SDA                                           ,OCTOSPIM_P2_IO3,                                                        ,,                                  ,                                                                     ,DCMI_HSYNC/PSSI_DE,,,,,EVENTOUT, +PortH,PH9 ,             ,,                     ,,I2C3_SMBA                                          ,OCTOSPIM_P2_IO4,                                                        ,                                                             ,HSPI1_NCS,                                                                     ,DCMI_D0/PSSI_D0,,,,,EVENTOUT, +PortH,PH10,             ,,TIM5_CH1                      ,,,OCTOSPIM_P2_IO5,                                                        ,                                                             ,HSPI1_IO0,                                                                     ,DCMI_D1/PSSI_D1,,,,,EVENTOUT, +PortH,PH11,             ,,TIM5_CH2                      ,,,OCTOSPIM_P2_IO6,                                                        ,                                                             ,HSPI1_IO1,                                                                     ,DCMI_D2/PSSI_D2,,,,,EVENTOUT, +PortH,PH12,             ,,TIM5_CH3                      ,TIM8_CH4N,,OCTOSPIM_P2_IO7,                                                        ,                                                             ,HSPI1_IO2,                                                                     ,DCMI_D3/PSSI_D3,,,,,EVENTOUT, +PortH,PH13,             ,,                              ,TIM8_CH1N                           ,                                                   ,                                                      ,                                                        ,,HSPI1_IO3,FDCAN1_TX                                                            ,                                             ,,,,,EVENTOUT, +PortH,PH14,             ,,                              ,TIM8_CH2N                           ,                                                   ,                                                      ,                                                        ,                                                             ,HSPI1_IO4,FDCAN1_RX                                                            ,DCMI_D4/PSSI_D4,,,,,EVENTOUT, +PortH,PH15,             ,,                              ,TIM8_CH3N                           ,                                                   ,OCTOSPIM_P2_IO6,                                                        ,                                                             ,HSPI1_IO5,                                                                     ,DCMI_D11/PSSI_D11,,,,,EVENTOUT, +PortI,PI0 ,             ,                   ,TIM5_CH4                      ,OCTOSPIM_P1_IO5,                                                   ,SPI2_NSS,                                                        ,                                                             ,HSPI1_IO6,                                                                     ,DCMI_D13/PSSI_D13,,,,,EVENTOUT, +PortI,PI1 ,,,,,,SPI2_SCK,OCTOSPIM_P2_IO2,                                                             ,HSPI1_IO7,                                                                     ,DCMI_D8/PSSI_D8,,,,,EVENTOUT, +PortI,PI2 ,             ,                   ,                              ,TIM8_CH4                            ,                                                   ,SPI2_MISO,OCTOSPIM_P2_IO1,                                                             ,HSPI1_DQS0,                                                                     ,DCMI_D9/PSSI_D9,,,,,EVENTOUT, +PortI,PI3 ,             ,                   ,                              ,TIM8_ETR                            ,                                                   ,SPI2_MOSI,OCTOSPIM_P2_IO0,                                                             ,HSPI1_CLK,                                                                     ,DCMI_D10/PSSI_D10,,,,,EVENTOUT, +PortI,PI4 ,             ,                   ,                              ,TIM8_BKIN                           ,                                                   ,SPI2_RDY,                                                        ,                                                     ,HSPI1_NCLK,                                                                     ,DCMI_D5/PSSI_D5,,,,,EVENTOUT, +PortI,PI5 ,             ,                   ,                              ,TIM8_CH1                            ,                                                   ,OCTOSPIM_P2_NCS,                                                        ,                                                             ,                                  ,                                                                     ,DCMI_VSYNC/PSSI_RDY,,,,,EVENTOUT, +PortI,PI6 ,             ,                   ,                              ,TIM8_CH2                            ,                                                   ,OCTOSPIM_P2_CLK,                                                        ,                                                             ,                                  ,                                                                     ,DCMI_D6/PSSI_D6,,,,,EVENTOUT, +PortI,PI7 ,             ,                   ,                              ,TIM8_CH3                            ,                                                   ,OCTOSPIM_P2_NCLK,                                                        ,                                                             ,                                  ,                                                                     ,DCMI_D7/PSSI_D7,,,,,EVENTOUT, +PortI,PI8 ,             ,                   ,                              ,                                    ,                                                   ,                                                      ,                                                        ,                                                             ,HSPI1_DQS1,,                                             ,,,,,EVENTOUT, +PortI,PI9 ,             ,                   ,                              ,                                    ,                                                   ,                                                      ,                                                        ,                                                             ,HSPI1_IO8,,                                             ,,,,,EVENTOUT, +PortI,PI10,PI11,PI12,PI13,PI14,PI15,PI16,PI17,PI18,HSPI1_IO9,,                                             ,,,,,EVENTOUT, +PortI,PI11,PI12,PI13,PI14,PI15,PI16,PI17,PI18,PI19,HSPI1_IO10,,                                             ,,,,,EVENTOUT, +PortI,PI12,,,,,,,,,HSPI1_IO11,,,,,,,EVENTOUT, +PortI,PI13,,,,,,,,,HSPI1_IO12,,,,,,,EVENTOUT, +PortI,PI14,,,,,,,,,HSPI1_IO13,,,,,,,EVENTOUT, +PortI,PI15,,,,,,,,,HSPI1_IO14,,,,,,,EVENTOUT, +PortJ,PJ0,,,,,I2C5_SMBA,,,,HSPI1_IO15,,,,,,,EVENTOUT, +PortJ,PJ1,,,,,I2C5_SDA,,,,,,,,,,,EVENTOUT, +PortJ,PJ2,,,,,I2C5_SCL,,,,,,,,,,,EVENTOUT, +PortJ,PJ3,,,,,,,,USART6_TX,,,,,,,,EVENTOUT, +PortJ,PJ4,,,,,,,,USART6_RX,,,,,,,,EVENTOUT, +PortJ,PJ5,,,,,,,,USART6_RTS_DE,,,,,,,,EVENTOUT, +PortJ,PJ6,,,,,,,,USART6_CK,,,,,,,,EVENTOUT, +PortJ,PJ7,,,,,,,,USART6_CK,,,,,,,,EVENTOUT, +PortJ,PJ8,,,I2C6_SMBA,,,,,,,,,,,,,EVENTOUT, +PortJ,PJ9,,,I2C6_SDA,,,,,,,,,,,,,EVENTOUT, +PortJ,PJ10,,,I2C6_SCL,,,,,,,,,,,,,EVENTOUT, +PortJ,PJ11,,,,,,,,,,,,,,,,EVENTOUT, diff --git a/ports/stm32/boards/stm32u5a5xj.ld b/ports/stm32/boards/stm32u5a5xj.ld new file mode 100644 index 000000000..356482e9f --- /dev/null +++ b/ports/stm32/boards/stm32u5a5xj.ld @@ -0,0 +1,35 @@ +/* +    GNU linker script for STM32U5A5xJ +*/ + +/* Specify the memory areas */ +MEMORY +{ +    FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 4096K +    FLASH_APP (rx)  : ORIGIN = 0x08008000, LENGTH = 992K    /* sectors 4-127 (for common_bl.ld) */ +    FLASH_FS (rx)   : ORIGIN = 0x08100000, LENGTH = 1024K   /* sectors 128-255 */ +    RAM   (xrw)     : ORIGIN = 0x20000000, LENGTH = 2496K   /* SRAM1/2/3/5: 2496KB */ +    SRAM4 (xrw)     : ORIGIN = 0x28000000, LENGTH = 16K +    FS_CACHE (xrw)  : ORIGIN = 0x28000000, LENGTH = 8K +} + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 2K; +_minimum_heap_size = 16K; + +/* Define the stack.  The stack is full descending so begins just above last byte +   of RAM.  Note that EABI requires the stack to be 8-byte aligned for a call. */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; +_sstack = _estack - 16K; /* tunable */ + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); +_heap_start = _ebss; /* heap starts just after statically allocated memory */ +_heap_end = _sstack; + +/* Filesystem cache in RAM, and storage in flash */ +_micropy_hw_internal_flash_storage_ram_cache_start = ORIGIN(FS_CACHE); +_micropy_hw_internal_flash_storage_ram_cache_end = ORIGIN(FS_CACHE) + LENGTH(FS_CACHE); +_micropy_hw_internal_flash_storage_start = ORIGIN(FLASH_FS); +_micropy_hw_internal_flash_storage_end = ORIGIN(FLASH_FS) + LENGTH(FLASH_FS); diff --git a/ports/stm32/boards/stm32u5xx_hal_conf_base.h b/ports/stm32/boards/stm32u5xx_hal_conf_base.h new file mode 100644 index 000000000..be7ea5246 --- /dev/null +++ b/ports/stm32/boards/stm32u5xx_hal_conf_base.h @@ -0,0 +1,176 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Damien P. George + * + * 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. + */ +#ifndef MICROPY_INCLUDED_STM32U5XX_HAL_CONF_BASE_H +#define MICROPY_INCLUDED_STM32U5XX_HAL_CONF_BASE_H + +// Enable various HAL modules +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +#define HAL_COMP_MODULE_ENABLED +#define HAL_CORDIC_MODULE_ENABLED +#define HAL_CRC_MODULE_ENABLED +#define HAL_CRYP_MODULE_ENABLED +#define HAL_DAC_MODULE_ENABLED +#define HAL_DCACHE_MODULE_ENABLED +#define HAL_DCMI_MODULE_ENABLED +#define HAL_DMA2D_MODULE_ENABLED +#define HAL_DSI_MODULE_ENABLED +#define HAL_FDCAN_MODULE_ENABLED +#define HAL_FMAC_MODULE_ENABLED +#define HAL_GFXMMU_MODULE_ENABLED +#define HAL_GFXTIM_MODULE_ENABLED +#define HAL_GPU2D_MODULE_ENABLED +#define HAL_GTZC_MODULE_ENABLED +#define HAL_HASH_MODULE_ENABLED +#define HAL_HCD_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_ICACHE_MODULE_ENABLED +#define HAL_IRDA_MODULE_ENABLED +#define HAL_IWDG_MODULE_ENABLED +#define HAL_JPEG_MODULE_ENABLED +#define HAL_LPTIM_MODULE_ENABLED +#define HAL_LTDC_MODULE_ENABLED +#define HAL_MDF_MODULE_ENABLED +#define HAL_MMC_MODULE_ENABLED +#define HAL_NAND_MODULE_ENABLED +#define HAL_NOR_MODULE_ENABLED +#define HAL_OPAMP_MODULE_ENABLED +#define HAL_OSPI_MODULE_ENABLED +#define HAL_OTFDEC_MODULE_ENABLED +#define HAL_PCD_MODULE_ENABLED +#define HAL_PKA_MODULE_ENABLED +#define HAL_PSSI_MODULE_ENABLED +#define HAL_RAMCFG_MODULE_ENABLED +#define HAL_RNG_MODULE_ENABLED +#define HAL_RTC_MODULE_ENABLED +#define HAL_SAI_MODULE_ENABLED +#define HAL_SD_MODULE_ENABLED +#define HAL_SDIO_MODULE_ENABLED +#define HAL_SMARTCARD_MODULE_ENABLED +#define HAL_SMBUS_MODULE_ENABLED +#define HAL_SPI_MODULE_ENABLED +#define HAL_SRAM_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_TSC_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED +#define HAL_USART_MODULE_ENABLED +#define HAL_WWDG_MODULE_ENABLED +#define HAL_XSPI_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +// Oscillator values in Hz +#define CSI_VALUE (4000000) +#define HSI_VALUE (16000000UL) +#define HSI48_VALUE (48000000UL) +#define LSI_VALUE (32000UL) +#define MSI_VALUE (4000000UL) + +// SysTick has the highest priority +#define TICK_INT_PRIORITY (0x00) + +// Miscellaneous HAL settings +#define USE_RTOS              0 +#define USE_SPI_CRC           1 +#define USE_SDIO_TRANSCEIVER  0U +#define SDIO_MAX_IO_NUMBER    7U +#define PREFETCH_ENABLE      1U + +// Include various HAL modules for convenience +#include "stm32u5xx_hal_rcc.h" +#include "stm32u5xx_hal_gpio.h" +#include "stm32u5xx_hal_icache.h" +#include "stm32u5xx_hal_dcache.h" +#include "stm32u5xx_hal_gtzc.h" +#include "stm32u5xx_hal_dma.h" +#include "stm32u5xx_hal_dma2d.h" +#include "stm32u5xx_hal_dsi.h" +#include "stm32u5xx_hal_cortex.h" +#include "stm32u5xx_hal_pka.h" +#include "stm32u5xx_hal_adc.h" +#include "stm32u5xx_hal_comp.h" +#include "stm32u5xx_hal_crc.h" +#include "stm32u5xx_hal_cryp.h" +#include "stm32u5xx_hal_dac.h" +#include "stm32u5xx_hal_flash.h" +#include "stm32u5xx_hal_hash.h" +#include "stm32u5xx_hal_sram.h" +#include "stm32u5xx_hal_mmc.h" +#include "stm32u5xx_hal_nor.h" +#include "stm32u5xx_hal_nand.h" +#include "stm32u5xx_hal_i2c.h" +#include "stm32u5xx_hal_iwdg.h" +#include "stm32u5xx_hal_jpeg.h" +#include "stm32u5xx_hal_lptim.h" +#include "stm32u5xx_hal_ltdc.h" +#include "stm32u5xx_hal_opamp.h" +#include "stm32u5xx_hal_pwr.h" +#include "stm32u5xx_hal_ospi.h" +#include "stm32u5xx_hal_rng.h" +#include "stm32u5xx_hal_rtc.h" +#include "stm32u5xx_hal_sai.h" +#include "stm32u5xx_hal_sd.h" +#include "stm32u5xx_hal_sdio.h" +#include "stm32u5xx_hal_smbus.h" +#include "stm32u5xx_hal_spi.h" +#include "stm32u5xx_hal_tim.h" +#include "stm32u5xx_hal_tsc.h" +#include "stm32u5xx_hal_uart.h" +#include "stm32u5xx_hal_usart.h" +#include "stm32u5xx_hal_irda.h" +#include "stm32u5xx_hal_smartcard.h" +#include "stm32u5xx_hal_wwdg.h" +#include "stm32u5xx_hal_pcd.h" +#include "stm32u5xx_hal_hcd.h" +#include "stm32u5xx_hal_cordic.h" +#include "stm32u5xx_hal_dcmi.h" +#include "stm32u5xx_hal_exti.h" +#include "stm32u5xx_hal_fdcan.h" +#include "stm32u5xx_hal_fmac.h" +#include "stm32u5xx_hal_gfxmmu.h" +#include "stm32u5xx_hal_gfxtim.h" +#include "stm32u5xx_hal_gpu2d.h" +#include "stm32u5xx_hal_otfdec.h" +#include "stm32u5xx_hal_pssi.h" +#include "stm32u5xx_hal_ramcfg.h" +#include "stm32u5xx_hal_mdf.h" +#include "stm32u5xx_hal_xspi.h" +#include "stm32u5xx_ll_usart.h" +#include "stm32u5xx_ll_lpuart.h" +#include "stm32u5xx_ll_rtc.h" +#include "stm32u5xx_ll_adc.h" +#include "stm32u5xx_ll_pwr.h" +#include "stm32u5xx_ll_rcc.h" + +// HAL parameter assertions are disabled +#define assert_param(expr) ((void)0) + +#endif /* MICROPY_INCLUDED_STM32U5XX_HAL_CONF_BASE_H */ diff --git a/ports/stm32/dac.c b/ports/stm32/dac.c index 8022fd274..eb729a6d4 100644 --- a/ports/stm32/dac.c +++ b/ports/stm32/dac.c @@ -66,7 +66,7 @@  #if defined(MICROPY_HW_ENABLE_DAC) && MICROPY_HW_ENABLE_DAC -#if defined(STM32H5) || defined(STM32H7) +#if defined(STM32H5) || defined(STM32H7) || defined(STM32U5)  #define DAC DAC1  #endif @@ -124,7 +124,7 @@ static uint32_t TIMx_Config(mp_obj_t timer) {  static void dac_deinit(uint32_t dac_channel) {      DAC->CR &= ~(DAC_CR_EN1 << dac_channel); -    #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) +    #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32U5)      DAC->MCR = (DAC->MCR & ~(DAC_MCR_MODE1_Msk << dac_channel)) | (DAC_OUTPUTBUFFER_DISABLE << dac_channel);      #else      DAC->CR |= DAC_CR_BOFF1 << dac_channel; @@ -142,7 +142,7 @@ static void dac_config_channel(uint32_t dac_channel, uint32_t trig, uint32_t out      DAC->CR &= ~(DAC_CR_EN1 << dac_channel);      uint32_t cr_off = DAC_CR_DMAEN1 | DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1;      uint32_t cr_on = trig; -    #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) +    #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32U5)      DAC->MCR = (DAC->MCR & ~(DAC_MCR_MODE1_Msk << dac_channel)) | (outbuf << dac_channel);      #else      cr_off |= DAC_CR_BOFF1; @@ -173,7 +173,7 @@ static void dac_start_dma(uint32_t dac_channel, const dma_descr_t *dma_descr, ui          #if defined(STM32G4)          // For STM32G4, DAC registers have to be accessed by words (32-bit).          dma_align = DMA_MDATAALIGN_BYTE | DMA_PDATAALIGN_WORD; -        #elif defined(STM32H5) +        #elif defined(STM32H5) || defined(STM32U5)          dma_align = DMA_SRC_DATAWIDTH_BYTE | DMA_DEST_DATAWIDTH_WORD;          #else          dma_align = DMA_MDATAALIGN_BYTE | DMA_PDATAALIGN_BYTE; @@ -182,7 +182,7 @@ static void dac_start_dma(uint32_t dac_channel, const dma_descr_t *dma_descr, ui          #if defined(STM32G4)          // For STM32G4, DAC registers have to be accessed by words (32-bit).          dma_align = DMA_MDATAALIGN_HALFWORD | DMA_PDATAALIGN_WORD; -        #elif defined(STM32H5) +        #elif defined(STM32H5) || defined(STM32U5)          dma_align = DMA_SRC_DATAWIDTH_HALFWORD | DMA_DEST_DATAWIDTH_WORD;          #else          dma_align = DMA_MDATAALIGN_HALFWORD | DMA_PDATAALIGN_HALFWORD; @@ -273,7 +273,7 @@ static mp_obj_t pyb_dac_init_helper(pyb_dac_obj_t *self, size_t n_args, const mp      __DAC_CLK_ENABLE();      #elif defined(STM32H7)      __HAL_RCC_DAC12_CLK_ENABLE(); -    #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L4) +    #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32U5)      __HAL_RCC_DAC1_CLK_ENABLE();      #elif defined(STM32L1)      __HAL_RCC_DAC_CLK_ENABLE(); @@ -493,8 +493,8 @@ mp_obj_t pyb_dac_write_timed(size_t n_args, const mp_obj_t *pos_args, mp_map_t *          align = DAC_ALIGN_8B_R;      } else {          align = DAC_ALIGN_12B_R; -        // For STM32H5, the length is the amount of data to be transferred from source to destination in bytes. -        #if !defined(STM32H5) +        // For STM32H5/U5, the length is the amount of data to be transferred from source to destination in bytes. +        #if !defined(STM32H5) && !defined(STM32U5)          bufinfo.len /= 2;          #endif      } diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index ad199b1fb..346b6b6f7 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -81,7 +81,7 @@ typedef union {  struct _dma_descr_t {      #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7)      DMA_Stream_TypeDef *instance; -    #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +    #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)      DMA_Channel_TypeDef *instance;      #else      #error "Unsupported Processor" @@ -93,7 +93,7 @@ struct _dma_descr_t {  // Default parameters to dma_init() shared by spi and i2c; Channel and Direction  // vary depending on the peripheral instance so they get passed separately -#if defined(STM32H5) || defined(STM32N6) +#if defined(STM32H5) || defined(STM32N6) || defined(STM32U5)  static const DMA_InitTypeDef dma_init_struct_spi_i2c = {      .Request = 0, // set by dma_init_handle      .BlkHWRequest = DMA_BREQ_SINGLE_BURST, @@ -186,7 +186,7 @@ static const DMA_InitTypeDef dma_init_struct_sdio = {  #endif  #if defined(MICROPY_HW_ENABLE_DAC) && MICROPY_HW_ENABLE_DAC -#if defined(STM32H5) +#if defined(STM32H5) || defined(STM32U5)  // Default parameters to dma_init() for DAC tx  static const DMA_InitTypeDef dma_init_struct_dac = {      .Request = 0, // set by dma_init_handle @@ -870,6 +870,50 @@ static const uint8_t dma_irqn[NSTREAM] = {      GPDMA1_Channel15_IRQn,  }; +#elif defined(STM32U5) + +#define NCONTROLLERS            (1) +#define NSTREAMS_PER_CONTROLLER (16) +#define NSTREAM                 (NCONTROLLERS * NSTREAMS_PER_CONTROLLER) + +#define DMA_SUB_INSTANCE_AS_UINT8(dma_channel) (dma_channel) + +#define DMA1_ENABLE_MASK (0x00ff) // Bits in dma_enable_mask corresponding to GPDMA1 +#define DMA2_ENABLE_MASK (0xff00) // Bits in dma_enable_mask corresponding to GPDMA2 + +const dma_descr_t dma_SPI_1_RX = { GPDMA1_Channel0, GPDMA1_REQUEST_SPI1_RX, dma_id_0, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_1_TX = { GPDMA1_Channel1, GPDMA1_REQUEST_SPI1_TX, dma_id_1, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_2_RX = { GPDMA1_Channel2, GPDMA1_REQUEST_SPI2_RX, dma_id_2, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_2_TX = { GPDMA1_Channel3, GPDMA1_REQUEST_SPI2_TX, dma_id_3, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_3_RX = { GPDMA1_Channel4, GPDMA1_REQUEST_SPI3_RX, dma_id_4, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_3_TX = { GPDMA1_Channel5, GPDMA1_REQUEST_SPI3_TX, dma_id_5, &dma_init_struct_spi_i2c }; +#if MICROPY_HW_ENABLE_DAC +const dma_descr_t dma_DAC_1_TX = { GPDMA1_Channel6, GPDMA1_REQUEST_DAC1_CH1, dma_id_6, &dma_init_struct_dac }; +const dma_descr_t dma_DAC_2_TX = { GPDMA1_Channel7, GPDMA1_REQUEST_DAC1_CH2, dma_id_7, &dma_init_struct_dac }; +#endif +const dma_descr_t dma_I2C_1_TX = { GPDMA1_Channel8, GPDMA1_REQUEST_I2C1_TX,  dma_id_8,   &dma_init_struct_spi_i2c }; +const dma_descr_t dma_I2C_1_RX = { GPDMA1_Channel9, GPDMA1_REQUEST_I2C1_RX,  dma_id_9,   &dma_init_struct_spi_i2c }; +const dma_descr_t dma_I2C_2_TX = { GPDMA1_Channel10, GPDMA1_REQUEST_I2C2_TX,  dma_id_10,   &dma_init_struct_spi_i2c }; +const dma_descr_t dma_I2C_2_RX = { GPDMA1_Channel11, GPDMA1_REQUEST_I2C2_RX,  dma_id_11,   &dma_init_struct_spi_i2c }; + +static const uint8_t dma_irqn[NSTREAM] = { +    GPDMA1_Channel0_IRQn, +    GPDMA1_Channel1_IRQn, +    GPDMA1_Channel2_IRQn, +    GPDMA1_Channel3_IRQn, +    GPDMA1_Channel4_IRQn, +    GPDMA1_Channel5_IRQn, +    GPDMA1_Channel6_IRQn, +    GPDMA1_Channel7_IRQn, +    GPDMA1_Channel8_IRQn, +    GPDMA1_Channel9_IRQn, +    GPDMA1_Channel10_IRQn, +    GPDMA1_Channel11_IRQn, +    GPDMA1_Channel12_IRQn, +    GPDMA1_Channel13_IRQn, +    GPDMA1_Channel14_IRQn, +    GPDMA1_Channel15_IRQn, +};  #endif  static DMA_HandleTypeDef *dma_handle[NSTREAM] = {NULL}; @@ -886,7 +930,7 @@ volatile dma_idle_count_t dma_idle;  #if defined(DMA2)  #define DMA2_IS_CLK_ENABLED()   ((RCC->AHBENR & RCC_AHBENR_DMA2EN) != 0)  #endif -#elif defined(STM32H5) +#elif defined(STM32H5) || defined(STM32U5)  #define DMA1_IS_CLK_ENABLED()   (__HAL_RCC_GPDMA1_IS_CLK_ENABLED())  #define DMA2_IS_CLK_ENABLED()   (__HAL_RCC_GPDMA2_IS_CLK_ENABLED())  #define __HAL_RCC_DMA1_CLK_ENABLE __HAL_RCC_GPDMA1_CLK_ENABLE @@ -1229,7 +1273,7 @@ void DMA2_Channel8_IRQHandler(void) {  }  #endif -#elif defined(STM32H5) || defined(STM32N6) +#elif defined(STM32H5) || defined(STM32N6) || defined(STM32U5)  #define DEFINE_IRQ_HANDLER(periph, channel, id) \      void GPDMA##periph##_Channel##channel##_IRQHandler(void) { \ @@ -1480,7 +1524,7 @@ void dma_init_handle(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint3      dma->Instance = dma_descr->instance;      dma->Init = *dma_descr->init;      dma->Init.Direction = dir; -    #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +    #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)      dma->Init.Request = dma_descr->sub_instance;      #else      #if !defined(STM32F0) && !defined(STM32L1) @@ -1488,7 +1532,7 @@ void dma_init_handle(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint3      #endif      #endif -    #if defined(STM32H5) || defined(STM32N6) +    #if defined(STM32H5) || defined(STM32N6) || defined(STM32U5)      // Configure src/dest settings based on the DMA direction.      if (dir == DMA_MEMORY_TO_PERIPH) {          dma->Init.SrcInc = DMA_SINC_INCREMENTED; @@ -1519,7 +1563,7 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint32_t dir          dma_enable_clock(dma_id); -        #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +        #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)          // Always reset and configure the H7 and G0/G4/H7/L0/L4/WB/WL DMA peripheral          // (dma->State is set to HAL_DMA_STATE_RESET by memset above)          // TODO: understand how L0/L4 DMA works so this is not needed @@ -1538,6 +1582,9 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint32_t dir          #endif          NVIC_SetPriority(IRQn_NONNEG(dma_irqn[dma_id]), IRQ_PRI_DMA); +        #if defined(STM32U5) +        HAL_DMA_ConfigChannelAttributes(dma, DMA_CHANNEL_NPRIV); +        #endif          #else          // if this stream was previously configured for this channel/request and direction then we          // can skip most of the initialisation @@ -1708,7 +1755,7 @@ void dma_nohal_start(const dma_descr_t *descr, uint32_t src_addr, uint32_t dst_a      dma->CCR |= DMA_CCR_EN;  } -#elif defined(STM32H5) +#elif defined(STM32H5) || defined(STM32U5)  // Fully setup GPDMA linked list entry  typedef struct _dma_ll_full_t { diff --git a/ports/stm32/dma.h b/ports/stm32/dma.h index 2ef3e3f26..ee62a2e20 100644 --- a/ports/stm32/dma.h +++ b/ports/stm32/dma.h @@ -30,13 +30,13 @@  typedef struct _dma_descr_t dma_descr_t; -#if defined(STM32H5) -// STM32H5 GPDMA doesn't feature circular mode directly, so define doesn't exist in +#if defined(STM32H5) || defined(STM32U5) +// STM32H5/U5 GPDMA doesn't feature circular mode directly, so define doesn't exist in  // stm32 driver header. Define it here to make users like DAC driver happy.  #define DMA_CIRCULAR 0x20000000  #endif -#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32G0) || defined(STM32H5) || defined(STM32H7) +#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32G0) || defined(STM32H5) || defined(STM32H7) || defined(STM32U5)  extern const dma_descr_t dma_I2C_1_RX;  extern const dma_descr_t dma_SPI_3_RX; diff --git a/ports/stm32/extint.c b/ports/stm32/extint.c index b1e5c8a8f..9b658dca9 100644 --- a/ports/stm32/extint.c +++ b/ports/stm32/extint.c @@ -92,7 +92,7 @@  #define EXTI_SWIER_BB(line) (*(__IO uint32_t *)(PERIPH_BB_BASE + ((EXTI_OFFSET + offsetof(EXTI_TypeDef, SWIER)) * 32) + ((line) * 4)))  #endif -#if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +#if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)  // The L4 MCU supports 40 Events/IRQs lines of the type configurable and direct.  // Here we only support configurable line types.  Details, see page 330 of RM0351, Rev 1.  // The USB_FS_WAKUP event is a direct type and there is no support for it. @@ -170,7 +170,7 @@ static const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = {      ADC1_COMP_IRQn,      #endif -    #elif defined(STM32N6) || defined(STM32H5) +    #elif defined(STM32N6) || defined(STM32H5) || defined(STM32U5)      EXTI0_IRQn,      EXTI1_IRQn, @@ -314,7 +314,7 @@ void EXTI15_10_IRQHandler(void) {      IRQ_EXIT(EXTI15_10_IRQn);  } -#elif defined(STM32H5) || defined(STM32N6) +#elif defined(STM32H5) || defined(STM32N6) || defined(STM32U5)  DEFINE_EXTI_IRQ_HANDLER(0)  DEFINE_EXTI_IRQ_HANDLER(1) @@ -447,7 +447,7 @@ void extint_register_pin(const machine_pin_obj_t *pin, uint32_t mode, bool hard_          #if !defined(STM32H5) && !defined(STM32WB) && !defined(STM32WL)          __HAL_RCC_SYSCFG_CLK_ENABLE();          #endif -        #if defined(STM32G0) || defined(STM32H5) || defined(STM32N6) +        #if defined(STM32G0) || defined(STM32H5) || defined(STM32N6) || defined(STM32U5)          EXTI->EXTICR[line >> 2] =              (EXTI->EXTICR[line >> 2] & ~(0xff << (8 * (line & 0x03))))              | ((uint32_t)(GPIO_GET_INDEX(pin->gpio)) << (8 * (line & 0x03))); @@ -490,7 +490,7 @@ void extint_set(const machine_pin_obj_t *pin, uint32_t mode) {          #if !defined(STM32H5) && !defined(STM32N6) && !defined(STM32WB) && !defined(STM32WL)          __HAL_RCC_SYSCFG_CLK_ENABLE();          #endif -        #if defined(STM32G0) || defined(STM32H5) || defined(STM32N6) +        #if defined(STM32G0) || defined(STM32H5) || defined(STM32N6) || defined(STM32U5)          EXTI->EXTICR[line >> 2] =              (EXTI->EXTICR[line >> 2] & ~(0xff << (8 * (line & 0x03))))              | ((uint32_t)(GPIO_GET_INDEX(pin->gpio)) << (8 * (line & 0x03))); @@ -533,7 +533,7 @@ void extint_enable(uint line) {      if (pyb_extint_mode[line] == EXTI_Mode_Interrupt) {          #if defined(STM32H7)          EXTI_D1->IMR1 |= (1 << line); -        #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +        #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)          EXTI->IMR1 |= (1 << line);          #else          EXTI->IMR |= (1 << line); @@ -541,7 +541,7 @@ void extint_enable(uint line) {      } else {          #if defined(STM32H7)          EXTI_D1->EMR1 |= (1 << line); -        #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +        #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)          EXTI->EMR1 |= (1 << line);          #else          EXTI->EMR |= (1 << line); @@ -567,7 +567,7 @@ void extint_disable(uint line) {      #if defined(STM32H7)      EXTI_D1->IMR1 &= ~(1 << line);      EXTI_D1->EMR1 &= ~(1 << line); -    #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +    #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)      EXTI->IMR1 &= ~(1 << line);      EXTI->EMR1 &= ~(1 << line);      #else @@ -589,7 +589,7 @@ void extint_swint(uint line) {          return;      }      // we need 0 to 1 transition to trigger the interrupt -    #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +    #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)      EXTI->SWIER1 &= ~(1 << line);      EXTI->SWIER1 |= (1 << line);      #else @@ -708,6 +708,12 @@ static mp_obj_t extint_regs(void) {      mp_printf(print, "EXTI_PR1    %08x\n", (unsigned int)EXTI_D1->PR1);      mp_printf(print, "EXTI_PR2    %08x\n", (unsigned int)EXTI_D1->PR2);      mp_printf(print, "EXTI_PR3    %08x\n", (unsigned int)EXTI_D1->PR3); +    #elif defined(STM32U5) +    mp_printf(print, "EXTI_IMR1   %08x\n", (unsigned int)EXTI->IMR1); +    mp_printf(print, "EXTI_EMR1   %08x\n", (unsigned int)EXTI->EMR1); +    mp_printf(print, "EXTI_RTSR1  %08x\n", (unsigned int)EXTI->RTSR1); +    mp_printf(print, "EXTI_FTSR1  %08x\n", (unsigned int)EXTI->FTSR1); +    mp_printf(print, "EXTI_SWIER1 %08x\n", (unsigned int)EXTI->SWIER1);      #else      mp_printf(print, "EXTI_IMR   %08x\n", (unsigned int)EXTI->IMR);      mp_printf(print, "EXTI_EMR   %08x\n", (unsigned int)EXTI->EMR); @@ -803,10 +809,32 @@ void extint_init0(void) {      }  } +static inline bool is_rtc_interrupt(uint32_t line) { +    return false +           #if defined(STM32U5) +           || line == EXTI_RTC_WAKEUP +           || line == EXTI_RTC_ALARM +           || line == EXTI_RTC_TIMESTAMP +           #endif +    ; +} +  // Interrupt handler  void Handle_EXTI_Irq(uint32_t line) { +    bool is_exti_irq; +      if (__HAL_GPIO_EXTI_GET_FLAG(1 << line)) {          __HAL_GPIO_EXTI_CLEAR_FLAG(1 << line); +        is_exti_irq = true; +    } else if (is_rtc_interrupt(line)) { +        // For STM32U5, __HAL_GPIO_EXTI_GET_FLAG cannot detect RTC interrupt. +        // To handle RTC interrupt, check whether line is rtc interrupt. +        is_exti_irq = true; +    } else { +        is_exti_irq = false; +    } + +    if (is_exti_irq) {          if (line < EXTI_NUM_VECTORS) {              mp_obj_t *cb = &MP_STATE_PORT(pyb_extint_callback)[line];              #if MICROPY_PY_NETWORK_CYW43 && defined(pyb_pin_WL_HOST_WAKE) diff --git a/ports/stm32/extint.h b/ports/stm32/extint.h index cdebf6eb8..7406eb967 100644 --- a/ports/stm32/extint.h +++ b/ports/stm32/extint.h @@ -37,7 +37,7 @@  #if defined(STM32L4)  #define EXTI_RTC_ALARM          (18)  #define EXTI_USB_OTG_FS_WAKEUP  (17) -#else +#elif !defined(STM32U5)  #define EXTI_RTC_ALARM          (17)  #define EXTI_USB_OTG_FS_WAKEUP  (18)  #endif @@ -55,6 +55,11 @@  #elif defined(STM32G0)  #define EXTI_RTC_WAKEUP         (19)  #define EXTI_RTC_TIMESTAMP      (21) +#elif defined(STM32U5) +#define EXTI_RTC_TIMESTAMP      (26) +#define EXTI_RTC_WAKEUP         (27) +#define EXTI_RTC_ALARM          (28) +#define EXTI_USB_OTG_FS_WAKEUP  (29)  #else  #define EXTI_RTC_TIMESTAMP      (21)  #define EXTI_RTC_WAKEUP         (22) diff --git a/ports/stm32/flash.c b/ports/stm32/flash.c index f050ca5ac..fcf46049c 100644 --- a/ports/stm32/flash.c +++ b/ports/stm32/flash.c @@ -148,7 +148,7 @@ static const flash_layout_t flash_layout[] = {  #define FLASH_LAYOUT_SECTOR_SIZE    (0x200)  #define FLASH_LAYOUT_NUM_SECTORS    (1024) -#elif defined(STM32H5) +#elif defined(STM32H5) || defined(STM32U5)  #define FLASH_LAYOUT_IS_HOMOGENEOUS (1)  #define FLASH_LAYOUT_START_ADDR     (FLASH_BASE_NS) @@ -225,7 +225,7 @@ static uint32_t get_page(uint32_t addr) {      return (addr - FLASH_LAYOUT_START_ADDR) / FLASH_LAYOUT_SECTOR_SIZE;  } -#elif defined(STM32G0) || defined(STM32G4) +#elif defined(STM32G0) || defined(STM32G4) || defined(STM32U5)  static uint32_t get_page(uint32_t addr) {      return (addr - FLASH_LAYOUT_START_ADDR) / FLASH_LAYOUT_SECTOR_SIZE; @@ -332,12 +332,12 @@ int flash_erase(uint32_t flash_dest) {      // ... the erase type and number of pages/sectors,      #if defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32L0) \ -    || defined(STM32L1) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) +    || defined(STM32L1) || defined(STM32L4) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)      EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;      EraseInitStruct.NbPages = num_sectors; -    #elif defined(STM32F4) || defined(STM32F7) || defined(STM32H5) || defined(STM32H7) +    #elif defined(STM32F4) || defined(STM32F7) || defined(STM32H5) || defined(STM32H7) || defined(STM32U5)      EraseInitStruct.TypeErase = TYPEERASE_SECTORS;      EraseInitStruct.NbSectors = num_sectors; @@ -354,7 +354,7 @@ int flash_erase(uint32_t flash_dest) {      // ... and the flash bank and page/sector.      #if defined(STM32F0) || defined(STM32L0) || defined(STM32L1)      EraseInitStruct.PageAddress = flash_dest; -    #elif defined(STM32G0) || defined(STM32G4) || (defined(STM32L4) && defined(SYSCFG_MEMRMP_FB_MODE)) +    #elif defined(STM32G0) || defined(STM32G4) || (defined(STM32L4) && defined(SYSCFG_MEMRMP_FB_MODE)) || defined(STM32U5)      EraseInitStruct.Page = get_page(flash_dest);      EraseInitStruct.Banks = get_bank(flash_dest);      #elif (defined(STM32L4) && !defined(SYSCFG_MEMRMP_FB_MODE)) || defined(STM32WB) || defined(STM32WL) @@ -458,9 +458,9 @@ int flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {          #endif      } -    #elif defined(STM32H5) || defined(STM32H7) +    #elif defined(STM32H5) || defined(STM32H7) || defined(STM32U5) -    #if defined(STM32H5) +    #if defined(STM32H5) || defined(STM32U5)      static const unsigned int WORD32_PER_FLASHWORD = 4;      static const unsigned int PROGRAM_TYPE = FLASH_TYPEPROGRAM_QUADWORD;      #else diff --git a/ports/stm32/i2c.c b/ports/stm32/i2c.c index 2460a36cb..46b55f940 100644 --- a/ports/stm32/i2c.c +++ b/ports/stm32/i2c.c @@ -271,12 +271,12 @@ int i2c_write(i2c_t *i2c, const uint8_t *src, size_t len, size_t next_len) {      return num_acks;  } -#elif defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) +#elif defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32U5)  #if defined(STM32H7)  #define APB1ENR            APB1LENR  #define RCC_APB1ENR_I2C1EN RCC_APB1LENR_I2C1EN -#elif defined(STM32G4) || defined(STM32L4) +#elif defined(STM32G4) || defined(STM32L4) || defined(STM32U5)  #define APB1ENR            APB1ENR1  #define RCC_APB1ENR_I2C1EN RCC_APB1ENR1_I2C1EN  #endif @@ -337,6 +337,16 @@ int i2c_init(i2c_t *i2c, mp_hal_pin_obj_t scl, mp_hal_pin_obj_t sda, uint32_t fr      } else {          return -MP_EINVAL;      } +    #elif defined(STM32U5) +    if (freq >= 1000000) { +        i2c->TIMINGR = 0x30909DEC; +    } else if (freq >= 400000) { +        i2c->TIMINGR = 0x00F07BFF; +    } else if (freq >= 100000) { +        i2c->TIMINGR = 0x00701F6B; +    } else { +        return -MP_EINVAL; +    }      #else      // These timing values are for f_I2CCLK=54MHz and are only approximate      if (freq >= 1000000) { @@ -512,7 +522,7 @@ int i2c_write(i2c_t *i2c, const uint8_t *src, size_t len, size_t next_len) {  #endif -#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) +#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32U5)  int i2c_readfrom(i2c_t *i2c, uint16_t addr, uint8_t *dest, size_t len, bool stop) {      int ret; diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c index 14384429c..a6e960911 100644 --- a/ports/stm32/machine_adc.c +++ b/ports/stm32/machine_adc.c @@ -30,7 +30,7 @@  #include "py/mphal.h"  #include "adc.h" -#if defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +#if defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)  #define ADC_V2 (1)  #else  #define ADC_V2 (0) @@ -88,6 +88,9 @@  #elif defined(STM32N6)  #define ADC_SAMPLETIME_DEFAULT      ADC_SAMPLETIME_46CYCLES_5  #define ADC_SAMPLETIME_DEFAULT_INT  ADC_SAMPLETIME_246CYCLES_5 +#elif defined(STM32U5) +#define ADC_SAMPLETIME_DEFAULT      ADC_SAMPLETIME_5CYCLES +#define ADC_SAMPLETIME_DEFAULT_INT  ADC_SAMPLETIME_391CYCLES_5  #endif  // Timeout for waiting for end-of-conversion @@ -175,6 +178,8 @@ static void adc_wait_eoc(ADC_TypeDef *adc, int32_t timeout_ms) {  #if defined(STM32H7)  static const uint8_t adc_cr_to_bits_table[] = {16, 14, 12, 10, 8, 8, 8, 8}; +#elif defined(STM32U5) +static const uint8_t adc_cr_to_bits_table[] = {14, 12, 10, 8};  #else  static const uint8_t adc_cr_to_bits_table[] = {12, 10, 8, 6};  #endif @@ -188,7 +193,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {      if (adc == ADC1) {          #if defined(STM32H5)          __HAL_RCC_ADC_CLK_ENABLE(); -        #elif defined(STM32G4) || defined(STM32H7) || defined(STM32N6) +        #elif defined(STM32G4) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5)          __HAL_RCC_ADC12_CLK_ENABLE();          #else          __HAL_RCC_ADC1_CLK_ENABLE(); @@ -198,7 +203,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {      if (adc == ADC2) {          #if defined(STM32H5)          __HAL_RCC_ADC_CLK_ENABLE(); -        #elif defined(STM32G4) || defined(STM32H7) || defined(STM32N6) +        #elif defined(STM32G4) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5)          __HAL_RCC_ADC12_CLK_ENABLE();          #else          __HAL_RCC_ADC2_CLK_ENABLE(); @@ -221,7 +226,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {      adc->CFGR2 = 2 << ADC_CFGR2_CKMODE_Pos; // PCLK/4 (synchronous clock mode)      #elif defined(STM32F4) || defined(STM32F7) || defined(STM32L4)      ADCx_COMMON->CCR = 0; // ADCPR=PCLK/2 -    #elif defined(STM32G4) || defined(STM32H5) +    #elif defined(STM32G4) || defined(STM32H5) || defined(STM32U5)      ADC12_COMMON->CCR = 7 << ADC_CCR_PRESC_Pos; // PCLK/16 (asynchronous clock mode)      #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)      ADC12_COMMON->CCR = 3 << ADC_CCR_CKMODE_Pos; @@ -240,13 +245,13 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {      ADC_COMMON->CCR = 0 << ADC_CCR_PRESC_Pos; // PRESC=1      #endif -    #if defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) +    #if defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB)      if (adc->CR & ADC_CR_DEEPPWD) {          adc->CR = 0; // disable deep powerdown      }      #endif -    #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) +    #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)      if (!(adc->CR & ADC_CR_ADVREGEN)) {          adc->CR = ADC_CR_ADVREGEN; // enable VREG          #if defined(STM32H7) @@ -262,7 +267,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {          // ADC isn't enabled so calibrate it now          #if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) || defined(STM32WL)          LL_ADC_StartCalibration(adc); -        #elif defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32WB) +        #elif defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32U5) || defined(STM32WB)          LL_ADC_StartCalibration(adc, LL_ADC_SINGLE_ENDED);          #elif defined(STM32N6)          ADC_HandleTypeDef hadc; @@ -324,7 +329,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {      uint32_t cfgr = res << ADC_CFGR_RES_Pos;      adc->CFGR = (adc->CFGR & ~cfgr_clr) | cfgr; -    #elif defined(STM32N6) +    #elif defined(STM32N6) || defined(STM32U5)      uint32_t cfgr1_clr = ADC_CFGR1_CONT | ADC_CFGR1_EXTEN | ADC_CFGR1_RES;      uint32_t cfgr1 = res << ADC_CFGR1_RES_Pos; @@ -334,7 +339,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {  }  static int adc_get_bits(ADC_TypeDef *adc) { -    #if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) || defined(STM32N6) || defined(STM32WL) +    #if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) || defined(STM32N6) || defined(STM32U5) || defined(STM32WL)      uint32_t res = (adc->CFGR1 & ADC_CFGR1_RES) >> ADC_CFGR1_RES_Pos;      #elif defined(STM32F4) || defined(STM32F7) || defined(STM32L1)      uint32_t res = (adc->CR1 & ADC_CR1_RES) >> ADC_CR1_RES_Pos; @@ -436,9 +441,9 @@ static void adc_config_channel(ADC_TypeDef *adc, uint32_t channel, uint32_t samp      }      *smpr = (*smpr & ~(7 << (channel * 3))) | sample_time << (channel * 3); // select sample time -    #elif defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) +    #elif defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) -    #if defined(STM32G4) || defined(STM32H5) || defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) || defined(STM32N6) +    #if defined(STM32G4) || defined(STM32H5) || defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) || defined(STM32N6) || defined(STM32U5)      ADC_Common_TypeDef *adc_common = ADC12_COMMON;      #elif defined(STM32H7)      ADC_Common_TypeDef *adc_common = adc == ADC3 ? ADC3_COMMON : ADC12_COMMON; @@ -453,6 +458,9 @@ static void adc_config_channel(ADC_TypeDef *adc, uint32_t channel, uint32_t samp      #if defined(STM32G4)      } else if (channel == ADC_CHANNEL_TEMPSENSOR_ADC1) {          adc_common->CCR |= ADC_CCR_VSENSESEL; +    #elif defined(STM32U5) +    } else if (channel == ADC_CHANNEL_TEMPSENSOR) { +        adc_common->CCR |= ADC_CCR_VSENSEEN;      #else      } else if (channel == ADC_CHANNEL_TEMPSENSOR) {          adc_common->CCR |= ADC_CCR_TSEN; @@ -471,7 +479,7 @@ static void adc_config_channel(ADC_TypeDef *adc, uint32_t channel, uint32_t samp      #endif      } -    #if defined(STM32G4) || defined(STM32H5) || defined(STM32N6) || defined(STM32WB) +    #if defined(STM32G4) || defined(STM32H5) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB)      // MCU uses encoded literals for internal channels -> extract ADC channel for following code      if (__LL_ADC_IS_CHANNEL_INTERNAL(channel)) {          channel = __LL_ADC_CHANNEL_TO_DECIMAL_NB(channel); diff --git a/ports/stm32/machine_i2c.c b/ports/stm32/machine_i2c.c index 0fb9cf83c..a057b25e7 100644 --- a/ports/stm32/machine_i2c.c +++ b/ports/stm32/machine_i2c.c @@ -34,7 +34,7 @@  #define I2C_POLL_DEFAULT_TIMEOUT_US (50000) // 50ms -#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L1) || defined(STM32L4) +#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L1) || defined(STM32L4) || defined(STM32U5)  typedef struct _machine_hard_i2c_obj_t {      mp_obj_base_t base; @@ -182,7 +182,7 @@ static void machine_hard_i2c_init(machine_hard_i2c_obj_t *self, uint32_t freq, u  /******************************************************************************/  /* MicroPython bindings for machine API                                       */ -#if defined(STM32F0) || defined(STM32F7) || defined(STM32H7) || defined(STM32L4) +#if defined(STM32F0) || defined(STM32F7) || defined(STM32H7) || defined(STM32L4) || defined(STM32U5)  #define MACHINE_I2C_TIMINGR (1)  #else  #define MACHINE_I2C_TIMINGR (0) diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c index c93eade5d..4f251bd66 100644 --- a/ports/stm32/machine_uart.c +++ b/ports/stm32/machine_uart.c @@ -37,11 +37,20 @@  #include "irq.h"  #include "pendsv.h" +#if defined(STM32H7) +#define MICROPY_PY_MACHINE_UART_INV_ENTRY \ +    { MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_ADVFEATURE_TXINVERT_INIT) }, \ +    { MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_ADVFEATURE_RXINVERT_INIT) }, +#else +#define MICROPY_PY_MACHINE_UART_INV_ENTRY +#endif +  #define MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS \      { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) }, \      { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HWCONTROL_CTS) }, \      { MP_ROM_QSTR(MP_QSTR_IRQ_RXIDLE), MP_ROM_INT(UART_FLAG_IDLE) }, \      { MP_ROM_QSTR(MP_QSTR_IRQ_RX), MP_ROM_INT(UART_FLAG_RXNE) }, \ +    MICROPY_PY_MACHINE_UART_INV_ENTRY \  static void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {      machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -125,11 +134,27 @@ static void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_          if (self->mp_irq_trigger != 0) {              mp_printf(print, "; irq=0x%x", self->mp_irq_trigger);          } +        #if defined(STM32H7) +        mp_print_str(print, ", invert="); +        if (!(cr2 & (USART_CR2_TXINV | USART_CR2_RXINV))) { +            mp_print_str(print, "0"); +        } else { +            if (cr2 & USART_CR2_TXINV) { +                mp_print_str(print, "INV_TX"); +                if (cr2 & USART_CR2_RXINV) { +                    mp_print_str(print, "|"); +                } +            } +            if (cr2 & USART_CR2_RXINV) { +                mp_print_str(print, "INV_RX"); +            } +        } +        #endif          mp_print_str(print, ")");      }  } -/// \method init(baudrate, bits=8, parity=None, stop=1, *, timeout=1000, timeout_char=0, flow=0, read_buf_len=64) +/// \method init(baudrate, bits=8, parity=None, stop=1, *, timeout=1000, timeout_char=0, flow=0, read_buf_len=64, invert=0)  ///  /// Initialise the UART bus with the given parameters:  /// @@ -141,6 +166,7 @@ static void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_  ///   - `timeout_char` is the timeout in milliseconds to wait between characters.  ///   - `flow` is RTS | CTS where RTS == 256, CTS == 512  ///   - `read_buf_len` is the character length of the read buffer (0 to disable). +///   - `invert` specifies which lines to invert. INV_TX | INV_RX (0 to disable). --> Only for STM32H7  static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {      static const mp_arg_t allowed_args[] = {          { MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 9600} }, @@ -152,11 +178,17 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,          { MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },          { MP_QSTR_rxbuf, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },          { MP_QSTR_read_buf_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, // legacy +        #if defined(STM32H7) +        { MP_QSTR_invert, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, +        #endif      };      // parse args      struct {          mp_arg_val_t baudrate, bits, parity, stop, flow, timeout, timeout_char, rxbuf, read_buf_len; +        #if defined(STM32H7) +        mp_arg_val_t invert; +        #endif      } args;      mp_arg_parse_all(n_args, pos_args, kw_args,          MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args); @@ -202,11 +234,18 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,      // flow control      uint32_t flow = args.flow.u_int; +    // inverted +    #if defined(STM32H7) +    uint32_t invert = args.invert.u_int; +    #else +    uint32_t invert = 0; +    #endif +      // Save attach_to_repl setting because uart_init will disable it.      bool attach_to_repl = self->attached_to_repl;      // init UART (if it fails, it's because the port doesn't exist) -    if (!uart_init(self, baudrate, bits, parity, stop, flow)) { +    if (!uart_init(self, baudrate, bits, parity, stop, flow, invert)) {          mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%d) doesn't exist"), self->uart_id);      } @@ -399,7 +438,7 @@ static bool mp_machine_uart_txdone(machine_uart_obj_t *self) {  // Send a break condition.  static void mp_machine_uart_sendbreak(machine_uart_obj_t *self) { -    #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +    #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)      self->uartx->RQR = USART_RQR_SBKRQ; // write-only register      #else      self->uartx->CR1 |= USART_CR1_SBK; diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 9ac2b4490..2d97adb1d 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_USB_MSC              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 @@ -502,7 +505,7 @@ void stm32_main(uint32_t reset_mode) {      pyb_uart_repl_obj.is_static = true;      pyb_uart_repl_obj.timeout = 0;      pyb_uart_repl_obj.timeout_char = 2; -    uart_init(&pyb_uart_repl_obj, MICROPY_HW_UART_REPL_BAUD, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1, 0); +    uart_init(&pyb_uart_repl_obj, MICROPY_HW_UART_REPL_BAUD, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1, 0, 0);      uart_set_rxbuf(&pyb_uart_repl_obj, sizeof(pyb_uart_repl_rxbuf), pyb_uart_repl_rxbuf);      uart_attach_to_repl(&pyb_uart_repl_obj, true);      MP_STATE_PORT(machine_uart_obj_all)[MICROPY_HW_UART_REPL - 1] = &pyb_uart_repl_obj; @@ -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_USB_MSC      // 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/mpbthciport.c b/ports/stm32/mpbthciport.c index 3f7114683..d8be24765 100644 --- a/ports/stm32/mpbthciport.c +++ b/ports/stm32/mpbthciport.c @@ -184,7 +184,7 @@ int mp_bluetooth_hci_uart_init(uint32_t port, uint32_t baudrate) {      MP_STATE_PORT(machine_uart_obj_all)[mp_bluetooth_hci_uart_obj.uart_id - 1] = &mp_bluetooth_hci_uart_obj;      // Initialise the UART. -    uart_init(&mp_bluetooth_hci_uart_obj, baudrate, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1, UART_HWCONTROL_RTS | UART_HWCONTROL_CTS); +    uart_init(&mp_bluetooth_hci_uart_obj, baudrate, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1, UART_HWCONTROL_RTS | UART_HWCONTROL_CTS, 0);      uart_set_rxbuf(&mp_bluetooth_hci_uart_obj, sizeof(hci_uart_rxbuf), hci_uart_rxbuf);      // Add IRQ handler for IDLE (i.e. packet finished). diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index d5cef1fec..eefd5c05c 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_ENABLE_USB) +#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) @@ -484,6 +542,20 @@  #define MICROPY_HW_MAX_UART (10)  #define MICROPY_HW_MAX_LPUART (1) +// Configuration for STM32U5 series +#elif defined(STM32U5) + +#define MP_HAL_UNIQUE_ID_ADDRESS (UID_BASE) +// STM32U5 has 26 EXTI vectors but does not have line for RTC/USB. +// To treat these interrupts as same as exti, add virtual vectors for +// EXTI_RTC_TIMESTAMP (26), EXTI_RTC_WAKEUP (27), +// EXTI_RTC_ALARM (28), and EXTI_USB_OTG_FS_WAKEUP  (29) +#define PYB_EXTI_NUM_VECTORS (30) +#define MICROPY_HW_MAX_I2C (6) +#define MICROPY_HW_MAX_TIMER (17) +#define MICROPY_HW_MAX_UART (6) +#define MICROPY_HW_MAX_LPUART (1) +  // Configuration for STM32WB series  #elif defined(STM32WB) @@ -494,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 @@ -577,6 +651,11 @@  #define MICROPY_HW_CLK_AHB_DIV (RCC_SYSCLK_DIV1)  #define MICROPY_HW_CLK_APB1_DIV (RCC_HCLK_DIV1)  #define MICROPY_HW_CLK_APB2_DIV (RCC_HCLK_DIV1) +#elif defined(STM32U5) +#define MICROPY_HW_CLK_AHB_DIV (RCC_SYSCLK_DIV1) +#define MICROPY_HW_CLK_APB1_DIV (RCC_HCLK_DIV1) +#define MICROPY_HW_CLK_APB2_DIV (RCC_HCLK_DIV1) +#define MICROPY_HW_CLK_APB3_DIV (RCC_HCLK_DIV1)  #else  #define MICROPY_HW_CLK_AHB_DIV (RCC_SYSCLK_DIV1)  #define MICROPY_HW_CLK_APB1_DIV (RCC_HCLK_DIV4) @@ -616,8 +695,13 @@  #define MICROPY_HW_BDEV_WRITEBLOCKS(src, bl, n) spi_bdev_writeblocks(MICROPY_HW_BDEV_SPIFLASH, (src), MICROPY_HW_BDEV_SPIFLASH_OFFSET_BLOCKS + (bl), (n))  #endif +// Define the FATFS maximum sector size. +#ifndef MICROPY_FATFS_MAX_SS  #if defined(STM32N6)  #define MICROPY_FATFS_MAX_SS                    (4096) +#else +#define MICROPY_FATFS_MAX_SS                    (512) +#endif  #endif  // Whether to enable caching for external SPI flash, to allow block writes that are @@ -696,17 +780,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 fcd08cbd8..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 @@ -90,7 +118,7 @@ void mp_hal_ticks_cpu_enable(void) {  #endif  void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio) { -    #if defined(STM32L476xx) || defined(STM32L496xx) +    #if defined(STM32L476xx) || defined(STM32L496xx) || defined(STM32U5)      if (gpio == GPIOG) {          // Port G pins 2 thru 15 are powered using VddIO2 on these MCUs.          HAL_PWREx_EnableVddIO2(); @@ -117,6 +145,9 @@ void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio) {      #elif defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)      #define AHBxENR AHB2ENR      #define AHBxENR_GPIOAEN_Pos RCC_AHB2ENR_GPIOAEN_Pos +    #elif defined(STM32U5) +    #define AHBxENR AHB2ENR1 +    #define AHBxENR_GPIOAEN_Pos RCC_AHB2ENR1_GPIOAEN_Pos      #endif      uint32_t gpio_idx = ((uint32_t)gpio - GPIOA_BASE) / (GPIOB_BASE - GPIOA_BASE); diff --git a/ports/stm32/mphalport.h b/ports/stm32/mphalport.h index 03b0f8e77..098a848fb 100644 --- a/ports/stm32/mphalport.h +++ b/ports/stm32/mphalport.h @@ -1,10 +1,12 @@  // 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]; -// F0-1.9.0+F4-1.16.0+F7-1.7.0+G0-1.5.1+G4-1.3.0+H7-1.6.0+L0-1.11.2+L4-1.17.0+WB-1.10.0+WL-1.1.0 +// F0-1.9.0+F4-1.16.0+F7-1.7.0+G0-1.5.1+G4-1.3.0+H5-1.0.0+H7-1.11.0+L0-1.11.2+L1-1.10.3+L4-1.17.0+N6-1.2.0+U5-1.8.0+WB-1.23.0+WL-1.1.0  #if defined(STM32F0)  #define MICROPY_PLATFORM_VERSION "HAL1.9.0"  #elif defined(STM32F4) @@ -25,8 +27,12 @@ extern uint8_t mp_hal_unique_id_address[12];  #define MICROPY_PLATFORM_VERSION "HAL1.10.3"  #elif defined(STM32L4)  #define MICROPY_PLATFORM_VERSION "HAL1.17.0" +#elif defined(STM32N6) +#define MICROPY_PLATFORM_VERSION "HAL1.2.0" +#elif defined(STM32U5) +#define MICROPY_PLATFORM_VERSION "HAL1.8.0"  #elif defined(STM32WB) -#define MICROPY_PLATFORM_VERSION "HAL1.10.0" +#define MICROPY_PLATFORM_VERSION "HAL1.23.0"  #elif defined(STM32WL)  #define MICROPY_PLATFORM_VERSION "HAL1.1.0"  #endif @@ -37,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 @@ -144,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/msc_disk.c b/ports/stm32/msc_disk.c new file mode 100644 index 000000000..f32957cde --- /dev/null +++ b/ports/stm32/msc_disk.c @@ -0,0 +1,191 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020-2021 Damien P. George + * 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_USB_MSC && MICROPY_HW_TINYUSB_STACK + +#include "py/misc.h" +#include "tusb.h" +#include "storage.h" +#include "sdcard.h" +#include "usb.h" + +// Storage medium selection (shared with main.c for compatibility) +pyb_usb_storage_medium_t pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_NONE; + +// Ejection state +static bool msc_ejected = false; + +// Invoked on SCSI_CMD_INQUIRY. +// Fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively. +void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) { +    (void)lun; +    memcpy(vendor_id, MICROPY_HW_USB_MSC_INQUIRY_VENDOR_STRING, MIN(strlen(MICROPY_HW_USB_MSC_INQUIRY_VENDOR_STRING), 8)); +    memcpy(product_id, MICROPY_HW_USB_MSC_INQUIRY_PRODUCT_STRING, MIN(strlen(MICROPY_HW_USB_MSC_INQUIRY_PRODUCT_STRING), 16)); +    memcpy(product_rev, MICROPY_HW_USB_MSC_INQUIRY_REVISION_STRING, MIN(strlen(MICROPY_HW_USB_MSC_INQUIRY_REVISION_STRING), 4)); +} + +// Invoked on Test-Unit-Ready command. +// Return true allowing host to read/write this LUN (e.g., SD card inserted). +bool tud_msc_test_unit_ready_cb(uint8_t lun) { +    (void)lun; + +    if (msc_ejected || pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_NONE) { +        tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); +        return false; +    } + +    #if MICROPY_HW_ENABLE_SDCARD +    if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_SDCARD) { +        if (!sdcard_is_present()) { +            tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); +            return false; +        } +    } +    #endif + +    return true; +} + +// Invoked on SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size. +void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) { +    (void)lun; + +    if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_FLASH) { +        *block_size = storage_get_block_size(); +        *block_count = storage_get_block_count(); +    #if MICROPY_HW_ENABLE_SDCARD +    } else if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_SDCARD) { +        *block_size = SDCARD_BLOCK_SIZE; +        *block_count = sdcard_get_capacity_in_bytes() / (uint64_t)SDCARD_BLOCK_SIZE; +    #endif +    } else { +        *block_size = 0; +        *block_count = 0; +    } +} + +// Invoked on Start-Stop-Unit command: +// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage +// - Start = 1 : active mode, if load_eject = 1 : load disk storage +bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) { +    (void)lun; +    (void)power_condition; + +    if (load_eject) { +        if (start) { +            // Load disk storage +            msc_ejected = false; +        } else { +            // Unload disk storage +            msc_ejected = true; +        } +    } +    return true; +} + +// Callback invoked on READ10 command. +// Copy disk's data to buffer (up to bufsize) and return number of read bytes. +int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) { +    (void)lun; +    (void)offset; + +    if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_FLASH) { +        uint32_t block_count = bufsize / FLASH_BLOCK_SIZE; +        int ret = storage_read_blocks(buffer, lba, block_count); +        if (ret != 0) { +            return -1; +        } +        return block_count * FLASH_BLOCK_SIZE; +    #if MICROPY_HW_ENABLE_SDCARD +    } else if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_SDCARD) { +        uint32_t block_count = bufsize / SDCARD_BLOCK_SIZE; +        if (sdcard_read_blocks(buffer, lba, block_count) != 0) { +            return -1; +        } +        return block_count * SDCARD_BLOCK_SIZE; +    #endif +    } + +    return -1; +} + +// Callback invoked on WRITE10 command. +// Process data in buffer to disk's storage and return number of written bytes. +int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) { +    (void)lun; +    (void)offset; + +    if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_FLASH) { +        uint32_t block_count = bufsize / FLASH_BLOCK_SIZE; +        int ret = storage_write_blocks(buffer, lba, block_count); +        if (ret != 0) { +            return -1; +        } +        return block_count * FLASH_BLOCK_SIZE; +    #if MICROPY_HW_ENABLE_SDCARD +    } else if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_SDCARD) { +        uint32_t block_count = bufsize / SDCARD_BLOCK_SIZE; +        if (sdcard_write_blocks(buffer, lba, block_count) != 0) { +            return -1; +        } +        return block_count * SDCARD_BLOCK_SIZE; +    #endif +    } + +    return -1; +} + +// Callback invoked on a SCSI command that's not handled by TinyUSB. +int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) { +    (void)lun; +    (void)buffer; +    (void)bufsize; + +    int32_t resplen = 0; +    switch (scsi_cmd[0]) { +        case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: +            // Sync the logical unit if needed. +            #if MICROPY_HW_ENABLE_STORAGE +            if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_FLASH) { +                storage_flush(); +            } +            #endif +            break; + +        default: +            // Set Sense = Invalid Command Operation +            tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); +            // negative means error -> tinyusb could stall and/or response with failed status +            resplen = -1; +            break; +    } +    return resplen; +} + +#endif // MICROPY_HW_USB_MSC && MICROPY_HW_TINYUSB_STACK diff --git a/ports/stm32/powerctrl.c b/ports/stm32/powerctrl.c index a750e8f5b..7211ef873 100644 --- a/ports/stm32/powerctrl.c +++ b/ports/stm32/powerctrl.c @@ -404,7 +404,7 @@ static uint32_t calc_apb2_div(uint32_t wanted_div) {      #endif  } -#if defined(STM32F4) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) +#if defined(STM32F4) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32U5)  int powerctrl_set_sysclk(uint32_t sysclk, uint32_t ahb, uint32_t apb1, uint32_t apb2) {      // Return straight away if the clocks are already at the desired frequency @@ -478,7 +478,7 @@ set_clk:      // Determine the bus clock dividers      // Note: AHB freq required to be >= 14.2MHz for USB operation      RCC_ClkInitStruct.AHBCLKDivider = calc_ahb_div(sysclk / ahb); -    #if defined(STM32H5) +    #if defined(STM32H5) || defined(STM32U5)      ahb = sysclk >> AHBPrescTable[RCC_ClkInitStruct.AHBCLKDivider >> RCC_CFGR2_HPRE_Pos];      #elif defined(STM32H7)      // Do nothing. @@ -819,7 +819,7 @@ void powerctrl_enter_stop_mode(void) {      __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);      #endif -    #if !defined(STM32F0) && !defined(STM32G0) && !defined(STM32G4) && !defined(STM32L0) && !defined(STM32L1) && !defined(STM32L4) && !defined(STM32N6) && !defined(STM32WB) && !defined(STM32WL) +    #if !defined(STM32F0) && !defined(STM32G0) && !defined(STM32G4) && !defined(STM32L0) && !defined(STM32L1) && !defined(STM32L4) && !defined(STM32N6) && !defined(STM32U5) && !defined(STM32WB) && !defined(STM32WL)      // takes longer to wake but reduces stop current      HAL_PWREx_EnableFlashPowerDown();      #endif @@ -939,17 +939,25 @@ void powerctrl_enter_stop_mode(void) {      #else // defined(STM32H5) +    #if defined(STM32U5) +    #define RCC_FLAG_PLLRDY RCC_FLAG_PLL1RDY +    #endif +      // enable PLL      __HAL_RCC_PLL_ENABLE();      while (!__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)) {      }      // select PLL as system clock source +    #if defined(STM32U5) +    MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SW, RCC_SYSCLKSOURCE_PLLCLK); +    #else      MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_SYSCLKSOURCE_PLLCLK); +    #endif      #if defined(STM32H7)      while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL1) {      } -    #elif defined(STM32G0) || defined(STM32WB) || defined(STM32WL) +    #elif defined(STM32G0) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)      while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) {      }      #else @@ -1120,7 +1128,7 @@ MP_NORETURN void powerctrl_enter_standby_mode(void) {      #if defined(STM32F0) || defined(STM32L0)      #define CR_BITS (RTC_CR_ALRAIE | RTC_CR_WUTIE | RTC_CR_TSIE)      #define ISR_BITS (RTC_ISR_ALRAF | RTC_ISR_WUTF | RTC_ISR_TSF) -    #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32WL) +    #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32U5) || defined(STM32WL)      #define CR_BITS (RTC_CR_ALRAIE | RTC_CR_ALRBIE | RTC_CR_WUTIE | RTC_CR_TSIE)      #define ISR_BITS (RTC_MISR_ALRAMF | RTC_MISR_ALRBMF | RTC_MISR_WUTMF | RTC_MISR_TSMF)      #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) @@ -1144,7 +1152,7 @@ MP_NORETURN void powerctrl_enter_standby_mode(void) {      // clear RTC wake-up flags      #if defined(SR_BITS)      RTC->SR &= ~SR_BITS; -    #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32WL) +    #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32U5) || defined(STM32WL)      RTC->MISR &= ~ISR_BITS;      #else      RTC->ISR &= ~ISR_BITS; @@ -1159,7 +1167,7 @@ MP_NORETURN void powerctrl_enter_standby_mode(void) {      PWR->CR2 |= PWR_CR2_CWUPF6 | PWR_CR2_CWUPF5 | PWR_CR2_CWUPF4 | PWR_CR2_CWUPF3 | PWR_CR2_CWUPF2 | PWR_CR2_CWUPF1;      // Restore EWUP state      PWR->CSR2 |= csr2_ewup; -    #elif defined(STM32H5) +    #elif defined(STM32H5) || defined(STM32U5)      LL_PWR_ClearFlag_WU();      #elif defined(STM32H7)      // Clear and mask D1 EXTIs. @@ -1203,6 +1211,8 @@ MP_NORETURN void powerctrl_enter_standby_mode(void) {      #if defined(STM32WB)      powerctrl_low_power_prep_wb55(); +    #elif defined(STM32U5) +    HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN7_HIGH_3);      #endif      #endif diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c index 7e1489010..dc907c638 100644 --- a/ports/stm32/pyb_i2c.c +++ b/ports/stm32/pyb_i2c.c @@ -128,7 +128,7 @@ const pyb_i2c_obj_t pyb_i2c_obj[] = {      #endif  }; -#if defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) +#if defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32U5)  // The STM32F0, F3, F7, H7 and L4 use a TIMINGR register rather than ClockSpeed and  // DutyCycle. @@ -215,6 +215,16 @@ const pyb_i2c_obj_t pyb_i2c_obj[] = {  #define MICROPY_HW_I2C_BAUDRATE_DEFAULT (PYB_I2C_SPEED_FULL)  #define MICROPY_HW_I2C_BAUDRATE_MAX (PYB_I2C_SPEED_FAST) +#elif defined(STM32U5) +// generated using CubeMX +#define MICROPY_HW_I2C_BAUDRATE_TIMING { \ +        {PYB_I2C_SPEED_STANDARD, 0x30909DEC}, \ +        {PYB_I2C_SPEED_FULL, 0x00F07BFF}, \ +        {PYB_I2C_SPEED_FAST, 0x00701F6B}, \ +} +#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (PYB_I2C_SPEED_FULL) +#define MICROPY_HW_I2C_BAUDRATE_MAX (PYB_I2C_SPEED_FAST) +  #else  #error "no I2C timings for this MCU"  #endif diff --git a/ports/stm32/rtc.c b/ports/stm32/rtc.c index fb106e179..72abcd75f 100644 --- a/ports/stm32/rtc.c +++ b/ports/stm32/rtc.c @@ -108,7 +108,7 @@ void rtc_init_start(bool force_init) {      // Enable the RTC APB bus clock, to communicate with the RTC.      #if defined(STM32H5)      __HAL_RCC_RTC_CLK_ENABLE(); -    #elif defined(STM32G0) || defined(STM32WL) +    #elif defined(STM32G0) || defined(STM32U5) || defined(STM32WL)      __HAL_RCC_RTCAPB_CLK_ENABLE();      #endif @@ -179,7 +179,7 @@ void rtc_init_start(bool force_init) {              // Clear source Reset Flag              __HAL_RCC_CLEAR_RESET_FLAGS();              // Turn the LSI on (it may need this even if the RTC is running) -            #if defined(STM32H5) +            #if defined(STM32H5) || defined(STM32U5)              RCC->BDCR |= RCC_BDCR_LSION;              #else              RCC->CSR |= RCC_CSR_LSION; @@ -192,7 +192,7 @@ void rtc_init_start(bool force_init) {          if (rtc_running) {              // Provide information about the registers that indicated the RTC is running.              // Bits are (MSB first): LSIRDY LSION LSEBYP LSERDY LSEON -            #if defined(STM32H5) +            #if defined(STM32H5) || defined(STM32U5)              rtc_info |= (RCC->BDCR >> RCC_BDCR_LSEON_Pos & 7) | (RCC->BDCR >> RCC_BDCR_LSION_Pos & 3) << 8;              #else              rtc_info |= (RCC->BDCR & 7) | (RCC->CSR & 3) << 8; @@ -276,7 +276,7 @@ void rtc_init_finalise() {      RTC_CalendarConfig();      #if defined(STM32G0)      if (__HAL_RCC_GET_FLAG(RCC_FLAG_PWRRST) != RESET) { -    #elif defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) +    #elif defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)      if (__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST) != RESET) {      #else      if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET) { @@ -327,7 +327,7 @@ static HAL_StatusTypeDef PYB_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct                  return HAL_TIMEOUT;              }          } -        #elif defined(STM32H5) || defined(STM32N6) +        #elif defined(STM32H5) || defined(STM32N6) || defined(STM32U5)          // Wait for Backup domain Write protection disable          while (!LL_PWR_IsEnabledBkUpAccess()) {              if (HAL_GetTick() - tickstart > RCC_DBP_TIMEOUT_VALUE) { @@ -412,7 +412,7 @@ static HAL_StatusTypeDef PYB_RTC_Init(RTC_HandleTypeDef *hrtc) {          #elif defined(STM32F7)          hrtc->Instance->OR &= (uint32_t) ~RTC_OR_ALARMTYPE;          hrtc->Instance->OR |= (uint32_t)(hrtc->Init.OutPutType); -        #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32N6) || defined(STM32WL) +        #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32N6) || defined(STM32U5) || defined(STM32WL)          hrtc->Instance->CR &= (uint32_t) ~RTC_CR_TAMPALRM_TYPE_Msk;          hrtc->Instance->CR |= (uint32_t)(hrtc->Init.OutPutType);          #else @@ -521,6 +521,11 @@ static HAL_StatusTypeDef PYB_RTC_MspInit_Finalise(RTC_HandleTypeDef *hrtc) {      // enable RTC peripheral clock      __HAL_RCC_RTC_ENABLE(); + +    #if defined(STM32U5) +    __HAL_RCC_RTCAPB_CLK_ENABLE(); +    __HAL_RCC_RTCAPB_CLKAM_ENABLE(); +    #endif      return HAL_OK;  } @@ -685,7 +690,7 @@ mp_obj_t pyb_rtc_datetime(size_t n_args, const mp_obj_t *args) {  }  MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_datetime_obj, 1, 2, pyb_rtc_datetime); -#if defined(STM32F0) || defined(STM32H5) || defined(STM32L0) +#if defined(STM32F0) || defined(STM32H5) || defined(STM32L0) || defined(STM32U5)  #define RTC_WKUP_IRQn RTC_IRQn  #elif defined(STM32G0)  #define RTC_WKUP_IRQn RTC_TAMP_IRQn @@ -806,6 +811,8 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {          #elif defined(STM32H7)          EXTI_D1->IMR1 |= 1 << EXTI_RTC_WAKEUP;          EXTI->RTSR1 |= 1 << EXTI_RTC_WAKEUP; +        #elif defined(STM32U5) +        // do nothing          #else          EXTI->IMR |= 1 << EXTI_RTC_WAKEUP;          EXTI->RTSR |= 1 << EXTI_RTC_WAKEUP; @@ -814,7 +821,7 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {          // clear interrupt flags          #if defined(STM32G0) || defined(STM32G4) || defined(STM32WL)          RTC->ICSR &= ~RTC_ICSR_WUTWF; -        #elif defined(STM32H5) || defined(STM32N6) +        #elif defined(STM32H5) || defined(STM32N6) || defined(STM32U5)          LL_RTC_ClearFlag_WUT(RTC);          #elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)          RTC->SR &= ~RTC_SR_WUTF; @@ -825,7 +832,7 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {          EXTI->PR1 = 1 << EXTI_RTC_WAKEUP;          #elif defined(STM32H7)          EXTI_D1->PR1 = 1 << EXTI_RTC_WAKEUP; -        #elif defined(STM32G0) || defined(STM32H5) || defined(STM32N6) +        #elif defined(STM32G0) || defined(STM32H5) || defined(STM32N6) || defined(STM32U5)          // Do nothing          #else          EXTI->PR = 1 << EXTI_RTC_WAKEUP; @@ -841,7 +848,7 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {          RTC->WPR = 0xff;          // disable external interrupts on line EXTI_RTC_WAKEUP -        #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +        #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)          EXTI->IMR1 &= ~(1 << EXTI_RTC_WAKEUP);          #elif defined(STM32H7)          EXTI_D1->IMR1 |= 1 << EXTI_RTC_WAKEUP; diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c index 248075579..330e4d474 100644 --- a/ports/stm32/spi.c +++ b/ports/stm32/spi.c @@ -106,8 +106,8 @@ const spi_t spi_obj[6] = {  #error "spi_obj needs updating for new value of MICROPY_HW_SUBGHZSPI_ID"  #endif -#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6) -// STM32H5/H7 HAL requires SPI IRQs to be enabled and handled. +#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) +// STM32H5/H7/U5 HAL requires SPI IRQs to be enabled and handled.  #if defined(MICROPY_HW_SPI1_SCK)  void SPI1_IRQHandler(void) {      IRQ_ENTER(SPI1_IRQn); @@ -499,7 +499,7 @@ int spi_init(const spi_t *self, bool enable_nss_pin) {      dma_invalidate_channel(self->tx_dma_descr);      dma_invalidate_channel(self->rx_dma_descr); -    #if defined(STM32H5) || defined(STM32H7) || defined(STM32N6) +    #if defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5)      NVIC_SetPriority(irqn, IRQ_PRI_SPI);      HAL_NVIC_EnableIRQ(irqn);      #else @@ -753,7 +753,7 @@ void spi_print(const mp_print_t *print, const spi_t *spi_obj, bool legacy) {      if (spi->State != HAL_SPI_STATE_RESET) {          if (spi->Init.Mode == SPI_MODE_MASTER) {              // compute baudrate -            #if defined(STM32H5) || defined(STM32H7) || defined(STM32N6) +            #if defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5)              uint log_prescaler = (spi->Init.BaudRatePrescaler >> 28) + 1;              #else              uint log_prescaler = (spi->Init.BaudRatePrescaler >> 3) + 1; diff --git a/ports/stm32/stm32.mk b/ports/stm32/stm32.mk index e6526fc6b..b63cb0cc5 100644 --- a/ports/stm32/stm32.mk +++ b/ports/stm32/stm32.mk @@ -67,6 +67,7 @@ CFLAGS_MCU_l4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4  CFLAGS_MCU_h5 = $(CFLAGS_CORTEX_M) -mtune=cortex-m33 -mcpu=cortex-m33  CFLAGS_MCU_h7 = $(CFLAGS_CORTEX_M) -mtune=cortex-m7 -mcpu=cortex-m7  CFLAGS_MCU_n6 = $(CFLAGS_CORTEX_M) -mtune=cortex-m55 -mcpu=cortex-m55 -mcmse +CFLAGS_MCU_u5 = $(CFLAGS_CORTEX_M) -mtune=cortex-m33 -mcpu=cortex-m33  CFLAGS_MCU_wb = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4  CFLAGS_MCU_wl = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 @@ -81,6 +82,7 @@ MPY_CROSS_MCU_ARCH_l4 = armv7m  MPY_CROSS_MCU_ARCH_h5 = armv7m  MPY_CROSS_MCU_ARCH_h7 = armv7m  MPY_CROSS_MCU_ARCH_n6 = armv7m # really armv8m +MPY_CROSS_MCU_ARCH_u5 = armv7m  MPY_CROSS_MCU_ARCH_wb = armv7m  MPY_CROSS_MCU_ARCH_wl = armv7m diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c index 052550a8f..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 @@ -384,16 +418,28 @@ static void OTG_CMD_WKUP_Handler(PCD_HandleTypeDef *pcd_handle) {          /* Enable the main PLL. */          __HAL_RCC_PLL_ENABLE(); +        #if defined(STM32U5) +        /* Wait till PLL is ready */ +        while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL1RDY) == RESET) { +        } + +        /* Select PLL as SYSCLK */ +        MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SW, RCC_SYSCLKSOURCE_PLLCLK); +        #else          /* Wait till PLL is ready */          while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) {          }          /* Select PLL as SYSCLK */          MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_SYSCLKSOURCE_PLLCLK); +        #endif          #if defined(STM32H7)          while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL1) {          } +        #elif defined(STM32U5) +        while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) { +        }          #else          while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL) {          } @@ -402,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 @@ -439,7 +488,7 @@ void OTG_HS_WKUP_IRQHandler(void) {      OTG_CMD_WKUP_Handler(&pcd_hs_handle); -    #if !defined(STM32H5) && !defined(STM32H7) +    #if !defined(STM32H5) && !defined(STM32H7) && !defined(STM32U5)      /* Clear EXTI pending Bit*/      __HAL_USB_HS_EXTI_CLEAR_FLAG();      #endif @@ -507,6 +556,7 @@ void TAMP_STAMP_IRQHandler(void) {  }  #endif +#if !defined(STM32U5)  #if defined(STM32H5)  void RTC_IRQHandler(void)  #elif defined(STM32N6) @@ -529,6 +579,7 @@ void RTC_WKUP_IRQHandler(void)      Handle_EXTI_Irq(EXTI_RTC_WAKEUP); // clear EXTI flag and execute optional callback      IRQ_EXIT(RTC_WKUP_IRQn);  } +#endif  #if defined(STM32N6)  void RTC_IRQHandler(void) { @@ -573,6 +624,26 @@ void TIM1_BRK_UP_TRG_COM_IRQHandler(void) {  #endif +#if defined(STM32U5) +extern RTC_HandleTypeDef RTCHandle; +void RTC_IRQHandler(void) { +    IRQ_ENTER(RTC_IRQn); +    if (RTC->SR & RTC_SR_WUTF) { +        RTC->SCR = RTC_SCR_CWUTF; // clear wakeup interrupt flag +        Handle_EXTI_Irq(EXTI_RTC_WAKEUP); // clear EXTI flag and execute optional callback +    } +    if (RTC->SR & RTC_SR_ALRAF) { +        RTC->SCR &= ~RTC_SCR_CALRAF; // clear Alarm A flag +        Handle_EXTI_Irq(EXTI_RTC_ALARM); // clear EXTI flag and execute optional callback +    } +    if (RTC->SR & RTC_SR_TSF) { +        RTC->SR &= ~RTC_SR_TSF; // clear timestamp flag +        Handle_EXTI_Irq(EXTI_RTC_TIMESTAMP); // clear EXTI flag and execute optional callback +    } +    IRQ_EXIT(RTC_IRQn); +} +#endif +  void TIM1_BRK_TIM9_IRQHandler(void) {      IRQ_ENTER(TIM1_BRK_TIM9_IRQn);      timer_irq_handler(9); diff --git a/ports/stm32/storage.c b/ports/stm32/storage.c index d26ac821e..066fb48a6 100644 --- a/ports/stm32/storage.c +++ b/ports/stm32/storage.c @@ -171,6 +171,12 @@ bool storage_read_block(uint8_t *dest, uint32_t block) {          return true; +    } else if (block < FLASH_PART1_START_BLOCK) { +        // Blocks between MBR and first partition: return zeros +        // (This handles blocks 1 to FLASH_PART1_START_BLOCK-1) +        memset(dest, 0, FLASH_BLOCK_SIZE); +        return true; +      #if defined(MICROPY_HW_BDEV_READBLOCK)      } else if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + MICROPY_HW_BDEV_IOCTL(BDEV_IOCTL_NUM_BLOCKS, 0)) {          return MICROPY_HW_BDEV_READBLOCK(dest, block - FLASH_PART1_START_BLOCK); @@ -184,6 +190,10 @@ bool storage_write_block(const uint8_t *src, uint32_t block) {      if (block == 0) {          // can't write MBR, but pretend we did          return true; +    } else if (block < FLASH_PART1_START_BLOCK) { +        // Blocks between MBR and first partition: ignore writes +        // (This handles blocks 1 to FLASH_PART1_START_BLOCK-1) +        return true;      #if defined(MICROPY_HW_BDEV_WRITEBLOCK)      } else if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + MICROPY_HW_BDEV_IOCTL(BDEV_IOCTL_NUM_BLOCKS, 0)) {          return MICROPY_HW_BDEV_WRITEBLOCK(src, block - FLASH_PART1_START_BLOCK); diff --git a/ports/stm32/system_stm32.c b/ports/stm32/system_stm32.c index 5a9fef1c2..514bf9178 100644 --- a/ports/stm32/system_stm32.c +++ b/ports/stm32/system_stm32.c @@ -79,7 +79,7 @@  #include "boardctrl.h"  #include "powerctrl.h" -#if defined(STM32F4) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) +#if defined(STM32F4) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32U5)  /**    * @brief  System Clock Configuration @@ -168,15 +168,23 @@ MP_WEAK void SystemClock_Config(void) {      // on reset value, so we set it back here, so the clocksources are the same      // whether we were started from DFU or from a power on reset.      RCC->DCKCFGR2 = 0; +    #elif defined(STM32U5) +    __HAL_RCC_PWR_CLK_ENABLE(); +    #if MICROPY_HW_ENABLE_USB +    HAL_PWREx_EnableVddUSB(); +    #endif +    #if MICROPY_HW_ENABLE_ADC || MICROPY_HW_ENABLE_DAC +    HAL_PWREx_EnableVddA(); +    #endif      #endif      RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};      RCC_OscInitTypeDef RCC_OscInitStruct = {0}; -    #if defined(STM32G4) || defined(STM32H7) +    #if defined(STM32G4) || defined(STM32H7) || defined(STM32U5)      RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};      #endif -    #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) +    #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32U5)      #if defined(STM32H7) && defined(SMPS)      // H7 MCUs with SMPS must provide a power supply configuration. @@ -184,6 +192,11 @@ MP_WEAK void SystemClock_Config(void) {      #elif defined(STM32H7)      // H7 MCUs without SMPS, lock the power supply configuration update.      MODIFY_REG(PWR->CR3, PWR_CR3_SCUEN, 0); +    #elif defined(STM32U5) +    HAL_PWREx_DisableUCPDDeadBattery(); +    if (HAL_PWREx_ConfigSupply(PWR_SMPS_SUPPLY) != HAL_OK) { +        MICROPY_BOARD_FATAL_ERROR("HAL_PWREx_ConfigSupply"); +    }      #else      // other MCUs, enable power control clock.      __PWR_CLK_ENABLE(); @@ -204,6 +217,12 @@ MP_WEAK void SystemClock_Config(void) {      #endif // defined(STM32H7) +    #if defined(STM32U5) +    __HAL_RCC_SYSCFG_CLK_ENABLE(); +    if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) { +        MICROPY_BOARD_FATAL_ERROR("HAL_PWREx_ControlVoltageScaling"); +    } +    #else      /* The voltage scaling allows optimizing the power consumption when the device is         clocked below the maximum system frequency, to update the voltage scaling value         regarding system frequency refer to product datasheet.  */ @@ -217,6 +236,7 @@ MP_WEAK void SystemClock_Config(void) {      {          __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);      } +    #endif      #elif defined(STM32G4)      // Configure the main internal regulator output voltage @@ -233,7 +253,7 @@ MP_WEAK void SystemClock_Config(void) {      #endif      /* Enable HSE Oscillator and activate PLL with HSE as source */ -    #if defined(STM32F4) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) +    #if defined(STM32F4) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32U5)      RCC_OscInitStruct.OscillatorType = MICROPY_HW_RCC_OSCILLATOR_TYPE;      RCC_OscInitStruct.HSEState = MICROPY_HW_RCC_HSE_STATE;      RCC_OscInitStruct.HSIState = MICROPY_HW_RCC_HSI_STATE; @@ -305,6 +325,8 @@ MP_WEAK void SystemClock_Config(void) {      RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);      #if defined(STM32H7)      RCC_ClkInitStruct.ClockType |= (RCC_CLOCKTYPE_D3PCLK1 | RCC_CLOCKTYPE_D1PCLK1); +    #elif defined(STM32U5) +    RCC_ClkInitStruct.ClockType |= (RCC_CLOCKTYPE_PCLK3);      #endif      #if defined(MICROPY_HW_CLK_LAST_FREQ) && MICROPY_HW_CLK_LAST_FREQ @@ -354,7 +376,7 @@ MP_WEAK void SystemClock_Config(void) {      RCC_OscInitStruct.PLL.PLLN = MICROPY_HW_CLK_PLLN;      RCC_OscInitStruct.PLL.PLLP = MICROPY_HW_CLK_PLLP;      RCC_OscInitStruct.PLL.PLLQ = MICROPY_HW_CLK_PLLQ; -    #if defined(STM32G4) || defined(STM32H7) || defined(STM32L4) +    #if defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32U5)      RCC_OscInitStruct.PLL.PLLR = MICROPY_HW_CLK_PLLR;      #endif @@ -362,6 +384,15 @@ MP_WEAK void SystemClock_Config(void) {      RCC_OscInitStruct.PLL.PLLRGE = MICROPY_HW_CLK_PLLVCI;      RCC_OscInitStruct.PLL.PLLVCOSEL = MICROPY_HW_CLK_PLLVCO;      RCC_OscInitStruct.PLL.PLLFRACN = MICROPY_HW_CLK_PLLFRAC; +    #elif defined(STM32U5) +    #if MICROPY_HW_RTC_USE_LSE +    RCC_OscInitStruct.LSEState = RCC_LSE_ON; +    #else +    RCC_OscInitStruct.LSIState = RCC_LSI_ON; +    #endif +    RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1; +    RCC_OscInitStruct.PLL.PLLRGE = MICROPY_HW_CLK_PLLVCI; +    RCC_OscInitStruct.PLL.PLLFRACN = MICROPY_HW_CLK_PLLFRAC;      #endif      #if defined(STM32F4) || defined(STM32F7) @@ -385,6 +416,12 @@ MP_WEAK void SystemClock_Config(void) {      RCC_ClkInitStruct.APB1CLKDivider = MICROPY_HW_CLK_APB1_DIV;      RCC_ClkInitStruct.APB2CLKDivider = MICROPY_HW_CLK_APB2_DIV;      RCC_ClkInitStruct.APB4CLKDivider = MICROPY_HW_CLK_APB4_DIV; +    #elif defined(STM32U5) +    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; +    RCC_ClkInitStruct.AHBCLKDivider = MICROPY_HW_CLK_AHB_DIV; +    RCC_ClkInitStruct.APB1CLKDivider = MICROPY_HW_CLK_APB1_DIV; +    RCC_ClkInitStruct.APB2CLKDivider = MICROPY_HW_CLK_APB2_DIV; +    RCC_ClkInitStruct.APB3CLKDivider = MICROPY_HW_CLK_APB3_DIV;      #endif      #endif @@ -509,6 +546,37 @@ MP_WEAK void SystemClock_Config(void) {      if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {          MICROPY_BOARD_FATAL_ERROR("HAL_RCCEx_PeriphCLKConfig");      } +    #elif defined(STM32U5) +    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, MICROPY_HW_FLASH_LATENCY) != HAL_OK) { +        MICROPY_BOARD_FATAL_ERROR("HAL_RCC_ClockConfig"); +    } + +    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 +        | RCC_PERIPHCLK_SPI1 | RCC_PERIPHCLK_SPI2 | RCC_PERIPHCLK_SPI3; +    PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1; +    PeriphClkInitStruct.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1; +    PeriphClkInitStruct.Spi1ClockSelection = RCC_SPI1CLKSOURCE_SYSCLK; +    PeriphClkInitStruct.Spi2ClockSelection = RCC_SPI2CLKSOURCE_SYSCLK; +    PeriphClkInitStruct.Spi3ClockSelection = RCC_SPI3CLKSOURCE_SYSCLK; + +    #if defined(MICROPY_HW_ENABLE_ADC) || (MICROPY_HW_ENABLE_DAC) +    PeriphClkInitStruct.PeriphClockSelection |= RCC_PERIPHCLK_ADCDAC | RCC_PERIPHCLK_DAC1; +    PeriphClkInitStruct.AdcDacClockSelection = RCC_ADCDACCLKSOURCE_HSE; +    PeriphClkInitStruct.Dac1ClockSelection = RCC_DAC1CLKSOURCE_LSE; +    #endif +    #if defined(MICROPY_HW_ENABLE_USB) +    PeriphClkInitStruct.PeriphClockSelection |= RCC_PERIPHCLK_USBPHY; +    PeriphClkInitStruct.UsbPhyClockSelection = RCC_USBPHYCLKSOURCE_PLL1; +    #endif + +    #if defined(MICROPY_HW_RCC_RTC_CLKSOURCE) +    PeriphClkInitStruct.PeriphClockSelection |= RCC_PERIPHCLK_RTC; +    PeriphClkInitStruct.RTCClockSelection = MICROPY_HW_RCC_RTC_CLKSOURCE; +    #endif + +    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { +        MICROPY_BOARD_FATAL_ERROR("HAL_RCCEx_PeriphCLKConfig"); +    }      #else      uint32_t vco_out = RCC_OscInitStruct.PLL.PLLN * (MICROPY_HW_CLK_VALUE / 1000000) / RCC_OscInitStruct.PLL.PLLM;      uint32_t sysclk_mhz = vco_out / RCC_OscInitStruct.PLL.PLLP; diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c index 9c4a5f889..aa4109282 100644 --- a/ports/stm32/timer.c +++ b/ports/stm32/timer.c @@ -283,6 +283,9 @@ uint32_t timer_get_source_freq(uint32_t tim_id) {          #elif defined(STM32H7)          source = HAL_RCC_GetPCLK2Freq();          clk_div = RCC->D2CFGR & RCC_D2CFGR_D2PPRE2; +        #elif defined(STM32U5) +        source = HAL_RCC_GetPCLK2Freq(); +        clk_div = RCC->CFGR1 & RCC_CFGR2_PPRE2;          #else          source = HAL_RCC_GetPCLK2Freq();          clk_div = RCC->CFGR & RCC_CFGR_PPRE2; @@ -296,6 +299,8 @@ uint32_t timer_get_source_freq(uint32_t tim_id) {          clk_div = RCC->CDCFGR1 & RCC_CDCFGR2_CDPPRE1;          #elif defined(STM32H7)          clk_div = RCC->D2CFGR & RCC_D2CFGR_D2PPRE1; +        #elif defined(STM32U5) +        clk_div = RCC->CFGR1 & RCC_CFGR2_PPRE1;          #else          clk_div = RCC->CFGR & RCC_CFGR_PPRE1;          #endif @@ -888,7 +893,7 @@ static const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = {      TIM_ENTRY(6, TIM6_IRQn),      #elif defined(STM32G0)      TIM_ENTRY(6, TIM6_DAC_LPTIM1_IRQn), -    #elif defined(STM32H5) || defined(STM32N6) +    #elif defined(STM32H5) || defined(STM32N6) || defined(STM32U5)      TIM_ENTRY(6, TIM6_IRQn),      #else      TIM_ENTRY(6, TIM6_DAC_IRQn), @@ -960,7 +965,7 @@ static const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = {      #endif      #if defined(TIM15) -    #if defined(STM32F0) || defined(STM32G0) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) +    #if defined(STM32F0) || defined(STM32G0) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5)      TIM_ENTRY(15, TIM15_IRQn),      #else      TIM_ENTRY(15, TIM1_BRK_TIM15_IRQn), @@ -970,7 +975,7 @@ static const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = {      #if defined(TIM16)      #if defined(STM32G0B1xx) || defined(STM32G0C1xx)      TIM_ENTRY(16, TIM16_FDCAN_IT0_IRQn), -    #elif defined(STM32F0) || defined(STM32G0) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32WL) +    #elif defined(STM32F0) || defined(STM32G0) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WL)      TIM_ENTRY(16, TIM16_IRQn),      #else      TIM_ENTRY(16, TIM1_UP_TIM16_IRQn), @@ -980,7 +985,7 @@ static const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = {      #if defined(TIM17)      #if defined(STM32G0B1xx) || defined(STM32G0C1xx)      TIM_ENTRY(17, TIM17_FDCAN_IT1_IRQn), -    #elif defined(STM32F0) || defined(STM32G0) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32WL) +    #elif defined(STM32F0) || defined(STM32G0) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WL)      TIM_ENTRY(17, TIM17_IRQn),      #else      TIM_ENTRY(17, TIM1_TRG_COM_TIM17_IRQn), diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index 63de8cc6f..f1637fd49 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -115,6 +115,15 @@  #define USART_CR3_IE_ALL (USART_CR3_IE_BASE | USART_CR3_WUFIE)  #endif +#elif defined(STM32U5) +#define USART_CR1_IE_ALL (USART_CR1_IE_BASE | USART_CR1_EOBIE | USART_CR1_RTOIE | USART_CR1_CMIE) +#define USART_CR2_IE_ALL (USART_CR2_IE_BASE) +#if defined(USART_CR3_TCBGTIE) +#define USART_CR3_IE_ALL (USART_CR3_IE_BASE | USART_CR3_TCBGTIE) +#else +#define USART_CR3_IE_ALL (USART_CR3_IE_BASE) +#endif +  #endif  typedef struct _machine_uart_irq_map_t { @@ -256,7 +265,7 @@ bool uart_exists(int uart_id) {  // assumes Init parameters have been set up correctly  bool uart_init(machine_uart_obj_t *uart_obj, -    uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop, uint32_t flow) { +    uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop, uint32_t flow, uint32_t invert) {      USART_TypeDef *UARTx;      IRQn_Type irqn;      uint8_t uart_fn = AF_FN_UART; @@ -664,6 +673,23 @@ bool uart_init(machine_uart_obj_t *uart_obj,      huart.Init.Mode = UART_MODE_TX_RX;      huart.Init.HwFlowCtl = flow;      huart.Init.OverSampling = UART_OVERSAMPLING_16; +    #if defined(STM32U5) +    huart.Init.ClockPrescaler = UART_PRESCALER_DIV16; +    #endif + +    #if defined(STM32H7) +    huart.AdvancedInit.AdvFeatureInit = (UART_ADVFEATURE_TXINVERT_INIT | UART_ADVFEATURE_RXINVERT_INIT); +    if (invert & UART_ADVFEATURE_RXINVERT_INIT) { +        huart.AdvancedInit.RxPinLevelInvert = UART_ADVFEATURE_RXINV_ENABLE; +    } else { +        huart.AdvancedInit.RxPinLevelInvert = UART_ADVFEATURE_RXINV_DISABLE; +    } +    if (invert & UART_ADVFEATURE_TXINVERT_INIT) { +        huart.AdvancedInit.TxPinLevelInvert = UART_ADVFEATURE_TXINV_ENABLE; +    } else { +        huart.AdvancedInit.TxPinLevelInvert = UART_ADVFEATURE_TXINV_DISABLE; +    } +    #endif      #if defined(STM32G4) || defined(STM32H7) || defined(STM32N6) // WB also has a fifo..      huart.FifoMode = UART_FIFOMODE_ENABLE; @@ -1036,14 +1062,14 @@ uint32_t uart_get_baudrate(machine_uart_obj_t *self) {      #if defined(LPUART1)      if (self->uart_id == PYB_LPUART_1) {          return LL_LPUART_GetBaudRate(self->uartx, uart_get_source_freq(self) -            #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +            #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)              , self->uartx->PRESC              #endif              );      }      #endif      return LL_USART_GetBaudRate(self->uartx, uart_get_source_freq(self), -        #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +        #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)          self->uartx->PRESC,          #endif          LL_USART_OVERSAMPLING_16); @@ -1053,7 +1079,7 @@ void uart_set_baudrate(machine_uart_obj_t *self, uint32_t baudrate) {      #if defined(LPUART1)      if (self->uart_id == PYB_LPUART_1) {          LL_LPUART_SetBaudRate(self->uartx, uart_get_source_freq(self), -            #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +            #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)              LL_LPUART_PRESCALER_DIV1,              #endif              baudrate); @@ -1061,7 +1087,7 @@ void uart_set_baudrate(machine_uart_obj_t *self, uint32_t baudrate) {      }      #endif      LL_USART_SetBaudRate(self->uartx, uart_get_source_freq(self), -        #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +        #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)          LL_USART_PRESCALER_DIV1,          #endif          LL_USART_OVERSAMPLING_16, baudrate); @@ -1112,7 +1138,7 @@ int uart_rx_char(machine_uart_obj_t *self) {          return data;      } else {          // no buffering -        #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +        #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)          int data = self->uartx->RDR & self->char_mask;          self->uartx->ICR = USART_ICR_ORECF; // clear ORE if it was set          return data; @@ -1267,7 +1293,7 @@ void uart_irq_handler(mp_uint_t uart_id) {              uint16_t next_head = (self->read_buf_head + 1) % self->read_buf_len;              if (next_head != self->read_buf_tail) {                  // only read data if room in buf -                #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) +                #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB) || defined(STM32WL)                  int data = self->uartx->RDR; // clears UART_FLAG_RXNE                  #else                  self->mp_irq_flags = self->uartx->SR; // resample to get any new flags since next read of DR will clear SR diff --git a/ports/stm32/uart.h b/ports/stm32/uart.h index d92434c64..448140f17 100644 --- a/ports/stm32/uart.h +++ b/ports/stm32/uart.h @@ -87,7 +87,7 @@ void uart_init0(void);  void uart_deinit_all(void);  bool uart_exists(int uart_id);  bool uart_init(machine_uart_obj_t *uart_obj, -    uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop, uint32_t flow); +    uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop, uint32_t flow, uint32_t invert);  void uart_irq_config(machine_uart_obj_t *self, bool enable);  void uart_set_rxbuf(machine_uart_obj_t *self, size_t len, void *buf);  void uart_deinit(machine_uart_obj_t *uart_obj); diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 2d70dcb26..c17d04912 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) @@ -69,6 +69,8 @@  #define MAX_ENDPOINT(dev_id) ((dev_id) == USB_PHY_FS_ID ? 5 : 8)  #elif defined(STM32H7) || defined(STM32N6)  #define MAX_ENDPOINT(dev_id) (8) +#elif defined(STM32U5) +#define MAX_ENDPOINT(dev_id) (9)  #endif  // Constants for USB_VCP.irq trigger. @@ -90,7 +92,9 @@ typedef struct _usb_device_t {  } usb_device_t;  usb_device_t usb_device = {0}; +#if MICROPY_HW_USB_MSC  pyb_usb_storage_medium_t pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_NONE; +#endif  #if !MICROPY_HW_USB_IS_MULTI_OTG @@ -1154,4 +1158,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/usb.h b/ports/stm32/usb.h index 3c382887a..70e3ee64c 100644 --- a/ports/stm32/usb.h +++ b/ports/stm32/usb.h @@ -26,7 +26,9 @@  #ifndef MICROPY_INCLUDED_STM32_USB_H  #define MICROPY_INCLUDED_STM32_USB_H +#if MICROPY_HW_STM_USB_STACK  #include "usbd_cdc_msc_hid0.h" +#endif  #define PYB_USB_FLAG_USB_MODE_CALLED    (0x0002) @@ -41,10 +43,16 @@ typedef enum {      USB_PHY_HS_ID = 1,  } USB_PHY_ID; +// Storage medium variable used by both USB stacks when MSC is enabled +#if MICROPY_HW_USB_MSC +extern pyb_usb_storage_medium_t pyb_usb_storage_medium; +#endif + +#if MICROPY_HW_STM_USB_STACK +  typedef struct _pyb_usb_vcp_obj_t pyb_usb_vcp_obj_t;  extern mp_uint_t pyb_usb_flags; -extern pyb_usb_storage_medium_t pyb_usb_storage_medium;  extern const struct _mp_rom_obj_tuple_t pyb_usb_hid_mouse_obj;  extern const struct _mp_rom_obj_tuple_t pyb_usb_hid_keyboard_obj;  extern const mp_obj_type_t pyb_usb_vcp_type; @@ -66,5 +74,6 @@ void usb_vcp_attach_to_repl(const pyb_usb_vcp_obj_t *self, bool attached);  void pyb_usb_host_init(void);  void pyb_usb_host_process(void);  uint pyb_usb_host_get_keyboard(void); +#endif  #endif // MICROPY_INCLUDED_STM32_USB_H 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 d4af54b72..76142789d 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,17 +177,38 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) {          HAL_NVIC_EnableIRQ(OTG_FS_IRQn);          #endif +        #if MICROPY_HW_TINYUSB_STACK +        // Configure VBUS sensing for TinyUSB on STM32F4/F7 which have separate GCCFG register +        // The DWC2 PHY init only sets PWRDWN bit, but doesn't configure VBUS sensing +        #if defined(STM32F4) || defined(STM32F7) +        #if defined(MICROPY_HW_USB_VBUS_DETECT_PIN) +        // Enable VBUS sensing in "B device" mode (using PA9) +        USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS; +        USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; +        #else +        // Force VBUS valid (no VBUS detect pin configured) +        USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; +        USB_OTG_FS->GCCFG &= ~(USB_OTG_GCCFG_VBUSBSEN | USB_OTG_GCCFG_VBUSASEN); +        #endif +        #endif +        #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. -        #if defined(STM32H723xx) || (STM32H7A3xx) || defined(STM32H7A3xxQ) +        #if defined(STM32H723xx) || (STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32U5)          // 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. @@ -196,6 +222,33 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) {          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(STM32U5) +        HAL_SYSCFG_SetOTGPHYReferenceClockSelection(SYSCFG_OTG_HS_PHY_CLK_SELECT_1); + +        // Peripheral clock enable +        __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); +        __HAL_RCC_USBPHYC_CLK_ENABLE(); + +        // Enable VDDUSB +        if (__HAL_RCC_PWR_IS_CLK_DISABLED()) { +            __HAL_RCC_PWR_CLK_ENABLE(); +            HAL_PWREx_EnableVddUSB(); + +            // configure VOSR register of USB +            HAL_PWREx_EnableUSBHSTranceiverSupply(); +            __HAL_RCC_PWR_CLK_DISABLE(); +        } else { +            HAL_PWREx_EnableVddUSB(); + +            // configure VOSR register of USB +            HAL_PWREx_EnableUSBHSTranceiverSupply(); +        } + +        // Configuring the SYSCFG registers OTG_HS PHY +        // OTG_HS PHY enable +        HAL_SYSCFG_EnableOTGPHY(SYSCFG_OTG_HS_PHY_ENABLE); +        #endif +          #elif defined(STM32N6)          // These MCUs have dedicated USB pins. @@ -247,7 +300,9 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) {          #else          // Enable calling WFI and correct function of the embedded USB_FS_IN_HS phy +        #if !defined(STM32U5)          __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE(); +        #endif          __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE();          // Enable USB HS Clocks @@ -290,6 +345,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 @@ -550,7 +607,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed, const          #if MICROPY_HW_USB_HS_IN_FS -        #if defined(STM32F723xx) || defined(STM32F733xx) || defined(STM32N6) +        #if defined(STM32F723xx) || defined(STM32F733xx) || defined(STM32N6) || defined(STM32U5)          pcd_hs_handle.Init.phy_itface = USB_OTG_HS_EMBEDDED_PHY;          #else          pcd_hs_handle.Init.phy_itface = PCD_PHY_EMBEDDED; @@ -769,6 +826,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/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c index 65d2fd70e..e541c3213 100644 --- a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c +++ b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c @@ -28,7 +28,7 @@  #include "usbd_ioreq.h"  #include "usbd_cdc_msc_hid.h" -#if MICROPY_HW_ENABLE_USB +#if MICROPY_HW_STM_USB_STACK  #define HEAD_DESC_SIZE (9)  #define MSC_CLASS_DESC_SIZE (9 + 7 + 7) diff --git a/shared/runtime/pyexec.c b/shared/runtime/pyexec.c index 0b253b4ce..7d2a70c01 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 @@ friendly_repl_reset:      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.          MP_STATE_THREAD(gc_lock_depth) = 0; 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 | 
