diff options
29 files changed, 810 insertions, 109 deletions
diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 3af1d892a..8b35c82a2 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -367,7 +367,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 +408,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 \ ) 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/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..5bb5b6c99 100644 --- a/ports/stm32/machine_uart.c +++ b/ports/stm32/machine_uart.c @@ -399,7 +399,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/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index d5cef1fec..f36cdec8e 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -484,6 +484,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) @@ -577,6 +591,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) diff --git a/ports/stm32/mphalport.c b/ports/stm32/mphalport.c index fcd08cbd8..b13ed0ee1 100644 --- a/ports/stm32/mphalport.c +++ b/ports/stm32/mphalport.c @@ -90,7 +90,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 +117,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/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..470df4758 100644 --- a/ports/stm32/stm32_it.c +++ b/ports/stm32/stm32_it.c @@ -384,16 +384,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) { } @@ -439,7 +451,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 +519,7 @@ void TAMP_STAMP_IRQHandler(void) { } #endif +#if !defined(STM32U5) #if defined(STM32H5) void RTC_IRQHandler(void) #elif defined(STM32N6) @@ -529,6 +542,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 +587,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/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..73e36881a 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 { @@ -664,6 +673,9 @@ 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(STM32G4) || defined(STM32H7) || defined(STM32N6) // WB also has a fifo.. huart.FifoMode = UART_FIFOMODE_ENABLE; @@ -1036,14 +1048,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 +1065,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 +1073,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 +1124,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 +1279,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/usb.c b/ports/stm32/usb.c index 2d70dcb26..81025e48b 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -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. diff --git a/ports/stm32/usbd_conf.c b/ports/stm32/usbd_conf.c index d4af54b72..2cf79e09e 100644 --- a/ports/stm32/usbd_conf.c +++ b/ports/stm32/usbd_conf.c @@ -182,7 +182,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) { // 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 +196,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 +274,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 @@ -550,7 +579,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; |
