Skip to content

stm32/boards: Add NUCLEO-U5A5ZJ-Q board support. #17748

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
url = https://github.com/micropython/berkeley-db-1.xx
[submodule "lib/stm32lib"]
path = lib/stm32lib
url = https://github.com/micropython/stm32lib
branch = work-F0-1.9.0+F4-1.16.0+F7-1.7.0+G0-1.5.1+G4-1.3.0+H7-1.6.0+L0-1.11.2+L1-1.10.3+L4-1.17.0+WB-1.10.0+WL-1.1.0
url = https://github.com/yn386/stm32lib.git
branch = stm32u5-v1.8.0
[submodule "lib/nrfx"]
path = lib/nrfx
url = https://github.com/NordicSemiconductor/nrfx.git
Expand Down
2 changes: 1 addition & 1 deletion lib/stm32lib
Submodule stm32lib updated 310 files
4 changes: 2 additions & 2 deletions ports/stm32/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down Expand Up @@ -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 \
)
Expand Down
56 changes: 44 additions & 12 deletions ports/stm32/adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,17 @@
#define ADC_CAL2 ((uint16_t *)(ADC_CAL_ADDRESS + 4))
#define ADC_CAL_BITS (12)

#elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L1) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB)
#elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || 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)
#define ADC_CAL1 (TEMPSENSOR_CAL1_ADDR)
#define ADC_CAL2 (TEMPSENSOR_CAL2_ADDR)
#if 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

#elif defined(STM32H7)

Expand Down Expand Up @@ -169,6 +173,8 @@
#elif defined(STM32N6)
// ADC2 VINP 16
#define VBAT_DIV (4)
#elif defined(STM32U5)
#define VBAT_DIV (4)
#else
#error Unsupported processor
#endif
Expand Down Expand Up @@ -228,6 +234,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;
}
Expand All @@ -242,7 +256,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)
Expand All @@ -263,7 +277,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
Expand Down Expand Up @@ -297,7 +311,8 @@ static void adcx_clock_enable(ADC_HandleTypeDef *adch) {
if (__HAL_RCC_GET_ADC_SOURCE() == RCC_ADCCLKSOURCE_NONE) {
__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
Expand Down Expand Up @@ -343,8 +358,8 @@ 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)
#if defined(STM32G4) || defined(STM32H5)
#elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32U5) || defined(STM32WB)
#if defined(STM32G4) || defined(STM32H5) || defined(STM32U5)
adch->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV16;
#else
adch->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
Expand All @@ -355,6 +370,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;
Expand All @@ -370,7 +391,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)
Expand Down Expand Up @@ -401,6 +422,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
Expand Down Expand Up @@ -457,6 +480,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
Expand Down Expand Up @@ -678,7 +710,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
Expand Down Expand Up @@ -788,7 +820,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
Expand Down Expand Up @@ -939,7 +971,7 @@ float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) {
return 0.0f; // TODO
#else

#if defined(STM32G4) || defined(STM32L1) || defined(STM32L4)
#if defined(STM32G4) || defined(STM32L1) || defined(STM32L4) || defined(STM32U5)
// Update the reference correction factor before reading tempsensor
// because TS_CAL1 and TS_CAL2 of STM32G4,L1/L4 are at VDDA=3.0V
adc_read_core_vref(adcHandle);
Expand All @@ -953,7 +985,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
Expand All @@ -966,7 +998,7 @@ float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) {
}

float adc_read_core_vbat(ADC_HandleTypeDef *adcHandle) {
#if defined(STM32G4) || defined(STM32L4)
#if defined(STM32G4) || defined(STM32L4) || defined(STM32U5)
// Update the reference correction factor before reading tempsensor
// because VREFINT of STM32G4,L4 is at VDDA=3.0V
adc_read_core_vref(adcHandle);
Expand Down
2 changes: 2 additions & 0 deletions ports/stm32/adc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions ports/stm32/boards/NUCLEO_U5A5ZJ_Q/board.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"deploy": [
"../deploy.md"
],
"docs": "",
"features": [],
"images": [
"nucleo_u5a5zj_q.jpg"
],
"mcu": "stm32u5",
"product": "Nucleo U5A5ZJ_Q",
"thumbnail": "",
"url": "",
"vendor": "ST Microelectronics"
}
82 changes: 82 additions & 0 deletions ports/stm32/boards/NUCLEO_U5A5ZJ_Q/mpconfigboard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#define MICROPY_HW_BOARD_NAME "NUCLEO_U5A5ZJ_Q"
#define MICROPY_HW_MCU_NAME "STM32U5A5ZJ"

#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (1)
#define MICROPY_HW_ENABLE_ADC (1)
#define MICROPY_HW_ENABLE_DAC (1)
#define MICROPY_HW_ENABLE_USB (1)
#define MICROPY_HW_ENABLE_RNG (0)
#define MICROPY_HW_ENABLE_RTC (1)
#define MICROPY_HW_HAS_FLASH (1)
#define MICROPY_HW_HAS_SWITCH (1)

// The board has a 16MHz oscillator, the following gives 160MHz CPU speed
#define MICROPY_HW_CLK_PLLM (1)
#define MICROPY_HW_CLK_PLLN (10)
#define MICROPY_HW_CLK_PLLP (10)
#define MICROPY_HW_CLK_PLLQ (2)
#define MICROPY_HW_CLK_PLLR (1)
#define MICROPY_HW_CLK_PLLVCI (RCC_PLLVCIRANGE_1)
#define MICROPY_HW_CLK_PLLFRAC (0)

// 5 wait states, according to Table 37, Reference Manual (RM0481 Rev 1)
#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_4

// There is an external 32kHz oscillator
#define MICROPY_HW_RTC_USE_LSE (1)
#define MICROPY_HW_RCC_RTC_CLKSOURCE (RCC_RTCCLKSOURCE_LSE)

// UART config
#define MICROPY_HW_UART1_TX (pin_A9)
#define MICROPY_HW_UART1_RX (pin_A10)
#define MICROPY_HW_UART2_TX (pin_D5)
#define MICROPY_HW_UART2_RX (pin_D6)
#define MICROPY_HW_UART2_RTS (pin_D4)
#define MICROPY_HW_UART2_CTS (pin_D3)

// Connect REPL to UART1 which is provided on ST-Link USB interface
#define MICROPY_HW_UART_REPL PYB_UART_1
#define MICROPY_HW_UART_REPL_BAUD 115200

// I2C buses
#define MICROPY_HW_I2C1_SCL (pin_B8) // Arduino Connector CN7-Pin2 (D15)
#define MICROPY_HW_I2C1_SDA (pin_B9) // Arduino Connector CN7-Pin4 (D14)
#define MICROPY_HW_I2C2_SCL (pin_F1) // Connector CN9-Pin19
#define MICROPY_HW_I2C2_SDA (pin_F0) // Connector CN9-Pin21

// SPI buses
#define MICROPY_HW_SPI1_NSS (pin_D14) // Arduino Connector CN7-Pin16 (D10)
#define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino Connector CN7-Pin10 (D13)
#define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino Connector CN7-Pin12 (D12)
#define MICROPY_HW_SPI1_MOSI (pin_A7) // Arduino Connector CN7-Pin14 (D11)
#define MICROPY_HW_SPI2_NSS (pin_D0)
#define MICROPY_HW_SPI2_SCK (pin_B10)
#define MICROPY_HW_SPI2_MISO (pin_D3)
#define MICROPY_HW_SPI2_MOSI (pin_C1)
#define MICROPY_HW_SPI3_NSS (pin_A4)
#define MICROPY_HW_SPI3_SCK (pin_B3)
#define MICROPY_HW_SPI3_MISO (pin_B4)
#define MICROPY_HW_SPI3_MOSI (pin_B5)

// USRSW is pulled low. Pressing the button makes the input go high.
#define MICROPY_HW_USRSW_PIN (pin_C13)
#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL)
#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_RISING)
#define MICROPY_HW_USRSW_PRESSED (1)

// LEDs
#define MICROPY_HW_LED1 (pin_C7) // Green
#define MICROPY_HW_LED2 (pin_B7) // Orange
#define MICROPY_HW_LED3 (pin_G2) // Red
#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))

// USB Configuration
#define MICROPY_HW_USB_HS (1)
#define MICROPY_HW_USB_HS_IN_FS (1)

#if 0 // FDCAN bus
#define MICROPY_HW_CAN1_NAME "FDCAN1"
#define MICROPY_HW_CAN1_TX (pin_D1)
#define MICROPY_HW_CAN1_RX (pin_D0)
#endif
21 changes: 21 additions & 0 deletions ports/stm32/boards/NUCLEO_U5A5ZJ_Q/mpconfigboard.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
USE_MBOOT ?= 0

# MCU settings
MCU_SERIES = u5
CMSIS_MCU = STM32U5A5xx
MICROPY_FLOAT_IMPL = single
AF_FILE = boards/stm32u5a5_af.csv

ifeq ($(USE_MBOOT),1)
# When using Mboot everything goes after the bootloader
# TODO: not tested
LD_FILES = boards/stm32h573xi.ld boards/common_bl.ld
TEXT0_ADDR = 0x08008000
else
# When not using Mboot everything goes at the start of flash
LD_FILES = boards/stm32u5a5xj.ld boards/common_basic.ld
TEXT0_ADDR = 0x08000000
endif

# MicroPython settings
#MICROPY_HW_ENABLE_ISR_UART_FLASH_FUNCS_IN_RAM = 1
Loading
Loading