You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by je...@apache.org on 2023/04/13 19:34:02 UTC
[mynewt-core] 02/05: hw/mcu/stm32u5: Add support for STM32U5 family
This is an automated email from the ASF dual-hosted git repository.
jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit e6df3bd750d56da336d44f575c9b85dbf6b19c75
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Tue Mar 28 21:11:14 2023 +0200
hw/mcu/stm32u5: Add support for STM32U5 family
---
hw/mcu/stm/stm32u5xx/include/mcu/cmsis_nvic.h | 29 ++
hw/mcu/stm/stm32u5xx/include/mcu/cortex_m33.h | 41 +++
hw/mcu/stm/stm32u5xx/include/mcu/mcu.h | 38 +++
hw/mcu/stm/stm32u5xx/include/mcu/stm32_hal.h | 77 +++++
hw/mcu/stm/stm32u5xx/include/mcu/stm32u5_bsp.h | 57 ++++
.../stm32u5xx/include/mcu/stm32u5xx_mynewt_hal.h | 66 ++++
hw/mcu/stm/stm32u5xx/pkg.yml | 64 ++++
hw/mcu/stm/stm32u5xx/src/clock_stm32u5xx.c | 314 ++++++++++++++++++
hw/mcu/stm/stm32u5xx/src/hal_flash.c | 56 ++++
hw/mcu/stm/stm32u5xx/src/hal_reset_cause.c | 49 +++
hw/mcu/stm/stm32u5xx/src/hal_timer_freq.c | 96 ++++++
hw/mcu/stm/stm32u5xx/src/system_stm32u5xx.c | 369 +++++++++++++++++++++
hw/mcu/stm/stm32u5xx/stm32u5xx.ld | 208 ++++++++++++
hw/mcu/stm/stm32u5xx/syscfg.yml | 149 +++++++++
14 files changed, 1613 insertions(+)
diff --git a/hw/mcu/stm/stm32u5xx/include/mcu/cmsis_nvic.h b/hw/mcu/stm/stm32u5xx/include/mcu/cmsis_nvic.h
new file mode 100644
index 000000000..d92bc2d8b
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/include/mcu/cmsis_nvic.h
@@ -0,0 +1,29 @@
+/* mbed Microcontroller Library - cmsis_nvic
+ * Copyright (c) 2009-2011 ARM Limited. All rights reserved.
+ *
+ * CMSIS-style functionality to support dynamic vectors
+ */
+
+#ifndef MCU_CMSIS_NVIC_H
+#define MCU_CMSIS_NVIC_H
+
+#include <stdint.h>
+
+#define NVIC_NUM_VECTORS (16 + 125) // CORE + MCU Peripherals
+#define NVIC_USER_IRQ_OFFSET 16
+
+#include <stm32u5xx.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void NVIC_Relocate(void);
+void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
+uint32_t NVIC_GetVector(IRQn_Type IRQn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hw/mcu/stm/stm32u5xx/include/mcu/cortex_m33.h b/hw/mcu/stm/stm32u5xx/include/mcu/cortex_m33.h
new file mode 100644
index 000000000..a49c387d8
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/include/mcu/cortex_m33.h
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __MCU_CORTEX_M33_H__
+#define __MCU_CORTEX_M33_H__
+
+#include <mcu/mcu.h>
+#include <cmsis_gcc.h>
+#include <stm32u5xx.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline void
+hal_debug_break(void)
+{
+ __BKPT(1);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_CORTEX_M33_H__ */
diff --git a/hw/mcu/stm/stm32u5xx/include/mcu/mcu.h b/hw/mcu/stm/stm32u5xx/include/mcu/mcu.h
new file mode 100644
index 000000000..6a909a5bf
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/include/mcu/mcu.h
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __MCU_MCU_H_
+#define __MCU_MCU_H_
+
+#include <stm32u5xx.h>
+#include <stm32_common/mcu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SVC_IRQ_NUMBER SVC_IRQn
+
+#define STM32_SYSTEM_MEMORY 0x0BF90000
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_MCU_H_ */
diff --git a/hw/mcu/stm/stm32u5xx/include/mcu/stm32_hal.h b/hw/mcu/stm/stm32u5xx/include/mcu/stm32_hal.h
new file mode 100644
index 000000000..19df6a173
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/include/mcu/stm32_hal.h
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef STM32_HAL_H
+#define STM32_HAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <mcu/cortex_m33.h>
+
+#include "stm32u5xx_hal.h"
+#include "stm32u5xx_hal_def.h"
+#include "stm32u5xx.h"
+#include "stm32u5xx_hal_dma.h"
+#include "stm32u5xx_hal_spi.h"
+#include "stm32u5xx_hal_gpio.h"
+#include "stm32u5xx_hal_gpio_ex.h"
+#include "stm32u5xx_hal_rcc.h"
+#include "stm32u5xx_hal_iwdg.h"
+#include "stm32u5xx_hal_i2c.h"
+#include "stm32u5xx_hal_uart.h"
+#include "mcu/stm32u5_bsp.h"
+#include "stm32u5xx_hal_tim.h"
+#include "stm32u5xx_ll_bus.h"
+#include "stm32u5xx_ll_tim.h"
+#include "stm32u5xx_hal_def.h"
+#include "stm32u5xx_hal_flash.h"
+#include "stm32u5xx_hal_flash_ex.h"
+#include "stm32u5xx_mynewt_hal.h"
+
+#define STM32_HAL_WATCHDOG_CUSTOM_INIT(x) \
+ do { \
+ (x)->Init.Window = IWDG_WINDOW_DISABLE; \
+ } while (0)
+
+#define STM32_HAL_FLASH_REMAP()
+
+struct stm32_hal_spi_cfg {
+ int ss_pin; /* for slave mode */
+ int sck_pin;
+ int miso_pin;
+ int mosi_pin;
+ int irq_prio;
+};
+
+#define STM32_HAL_TIMER_MAX (3)
+
+#define STM32_HAL_FLASH_INIT() \
+ do { \
+ HAL_FLASH_Unlock(); \
+ } while (0)
+#define FLASH_PROGRAM_TYPE FLASH_TYPEPROGRAM_QUADWORD
+#define STM32_HAL_FLASH_CLEAR_ERRORS()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_HAL_H */
diff --git a/hw/mcu/stm/stm32u5xx/include/mcu/stm32u5_bsp.h b/hw/mcu/stm/stm32u5xx/include/mcu/stm32u5_bsp.h
new file mode 100644
index 000000000..ef7b88747
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/include/mcu/stm32u5_bsp.h
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __MCU_STM32U5_BSP_H_
+#define __MCU_STM32U5_BSP_H_
+
+#include <hal/hal_gpio.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * BSP specific UART settings.
+ */
+struct stm32_uart_cfg {
+ USART_TypeDef *suc_uart; /* UART dev registers */
+ volatile uint32_t *suc_rcc_reg; /* RCC register to modify */
+ uint32_t suc_rcc_dev; /* RCC device ID */
+ int8_t suc_pin_tx; /* pins for IO */
+ int8_t suc_pin_rx;
+ int8_t suc_pin_rts;
+ int8_t suc_pin_cts;
+ uint8_t suc_pin_af; /* AF selection for this */
+ IRQn_Type suc_irqn; /* NVIC IRQn */
+};
+
+/*
+ * Internal API for stm32u5xx mcu specific code.
+ */
+int hal_gpio_init_af(int pin, uint8_t af_type, enum hal_gpio_pull pull, uint8_t od);
+
+struct hal_flash;
+extern struct hal_flash stm32u5_flash_dev;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_STM32U5_BSP_H_ */
diff --git a/hw/mcu/stm/stm32u5xx/include/mcu/stm32u5xx_mynewt_hal.h b/hw/mcu/stm/stm32u5xx/include/mcu/stm32u5xx_mynewt_hal.h
new file mode 100644
index 000000000..1709bf9fe
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/include/mcu/stm32u5xx_mynewt_hal.h
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __MCU_STM32U5_MYNEWT_HAL_H
+#define __MCU_STM32U5_MYNEWT_HAL_H
+
+#include "stm32u5xx.h"
+#include "stm32u5xx_hal_dma.h"
+#include "stm32u5xx_hal_gpio.h"
+#include "stm32u5xx_hal_i2c.h"
+#include "stm32u5xx_hal_spi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Helper functions to enable/disable interrupts. */
+#define __HAL_DISABLE_INTERRUPTS(x) \
+ do { \
+ x = __get_PRIMASK(); \
+ __disable_irq(); \
+ } while(0);
+
+#define __HAL_ENABLE_INTERRUPTS(x) \
+ do { \
+ if (!x) { \
+ __enable_irq(); \
+ } \
+ } while(0);
+
+
+int hal_gpio_init_stm(int pin, GPIO_InitTypeDef *cfg);
+int hal_gpio_deinit_stm(int pin, GPIO_InitTypeDef *cfg);
+
+struct stm32_hal_i2c_cfg {
+ I2C_TypeDef *hic_i2c;
+ volatile uint32_t *hic_rcc_reg; /* RCC register to modify */
+ uint32_t hic_rcc_dev; /* RCC device ID */
+ uint8_t hic_pin_sda;
+ uint8_t hic_pin_scl;
+ uint8_t hic_pin_af;
+ uint8_t hic_10bit;
+ uint32_t hic_timingr; /* TIMINGR register */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_STM32U5_MYNEWT_HAL_H */
diff --git a/hw/mcu/stm/stm32u5xx/pkg.yml b/hw/mcu/stm/stm32u5xx/pkg.yml
new file mode 100644
index 000000000..b639b4c45
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/pkg.yml
@@ -0,0 +1,64 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/mcu/stm/stm32u5xx
+pkg.description: MCU definition for STM32U5 ARM Cortex-M33 chips.
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+ - stm32
+ - stm32u5
+
+pkg.type: sdk
+
+pkg.ign_files:
+ - ".*template.*"
+
+pkg.include_dirs:
+ - "@stm-cmsis_device_u5/Include"
+ - "@stm-stm32u5xx_hal_driver/Inc"
+
+pkg.src_dirs:
+ - "@stm-stm32u5xx_hal_driver/Src"
+ - "src"
+
+pkg.ign_dirs:
+ - "Device"
+
+pkg.deps:
+ - "@apache-mynewt-core/hw/hal"
+ - "@apache-mynewt-core/hw/mcu/stm/stm32_common"
+ - "@apache-mynewt-core/hw/cmsis-core"
+
+pkg.deps.'(SPI_0_MASTER || SPI_1_MASTER || SPI_2_MASTER) && BUS_DRIVER_PRESENT':
+ - "@apache-mynewt-core/hw/bus/drivers/spi_stm32"
+
+repository.stm-cmsis_device_u5:
+ type: github
+ vers: v1.2.0-commit
+ branch: main
+ user: STMicroelectronics
+ repo: cmsis_device_u5
+
+repository.stm-stm32u5xx_hal_driver:
+ type: github
+ vers: v1.2.0-commit
+ branch: main
+ user: STMicroelectronics
+ repo: stm32u5xx_hal_driver
diff --git a/hw/mcu/stm/stm32u5xx/src/clock_stm32u5xx.c b/hw/mcu/stm/stm32u5xx/src/clock_stm32u5xx.c
new file mode 100644
index 000000000..106107a6e
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/src/clock_stm32u5xx.c
@@ -0,0 +1,314 @@
+/*
+ * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <stm32u5xx_hal_pwr_ex.h>
+#include <stm32u5xx_hal_rcc.h>
+#include <stm32u5xx_hal.h>
+
+#define IS_RCC_HCLK(__HCLK__) (((__HCLK__) == RCC_SYSCLK_DIV1) || ((__HCLK__) == RCC_SYSCLK_DIV2) || \
+ ((__HCLK__) == RCC_SYSCLK_DIV4) || ((__HCLK__) == RCC_SYSCLK_DIV8) || \
+ ((__HCLK__) == RCC_SYSCLK_DIV16) || ((__HCLK__) == RCC_SYSCLK_DIV64) || \
+ ((__HCLK__) == RCC_SYSCLK_DIV128) || ((__HCLK__) == RCC_SYSCLK_DIV256) || \
+ ((__HCLK__) == RCC_SYSCLK_DIV512))
+
+#define IS_RCC_PCLK(__PCLK__) (((__PCLK__) == RCC_HCLK_DIV1) || ((__PCLK__) == RCC_HCLK_DIV2) || \
+ ((__PCLK__) == RCC_HCLK_DIV4) || ((__PCLK__) == RCC_HCLK_DIV8) || \
+ ((__PCLK__) == RCC_HCLK_DIV16))
+
+/*
+ * This allows an user to have a custom clock configuration by zeroing
+ * every possible clock source in the syscfg.
+ */
+#if MYNEWT_VAL(STM32_CLOCK_MSI) || MYNEWT_VAL(STM32_CLOCK_HSE) || \
+ MYNEWT_VAL(STM32_CLOCK_LSE) || MYNEWT_VAL(STM32_CLOCK_HSI) || \
+ MYNEWT_VAL(STM32_CLOCK_HSI48) || MYNEWT_VAL(STM32_CLOCK_LSI)
+
+#define TRNG_ENABLED (MYNEWT_VAL(TRNG) != 0)
+
+/*
+ * HSI is turned on by default, but can be turned off and use HSE/HSI48 instead.
+ */
+#if ((MYNEWT_VAL(STM32_CLOCK_MSI) != 0) + \
+ (MYNEWT_VAL(STM32_CLOCK_HSE) != 0) + \
+ (MYNEWT_VAL(STM32_CLOCK_HSI) != 0) + \
+ (MYNEWT_VAL(STM32_CLOCK_HSI48) != 0)) < 1
+#error "At least one of MSI, HSE, HSI or HSI48 clock sources must be enabled"
+#endif
+
+void
+SystemClock_Config(void)
+{
+ RCC_OscInitTypeDef osc_init = {};
+ RCC_ClkInitTypeDef clk_init = {};
+ HAL_StatusTypeDef status;
+#if TRNG_ENABLED
+ RCC_PeriphCLKInitTypeDef pclk_init;
+#endif
+
+ /*
+ * 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.
+ */
+ __HAL_RCC_PWR_CLK_ENABLE();
+ HAL_PWREx_ControlVoltageScaling(MYNEWT_VAL(STM32_CLOCK_VOLTAGESCALING_CONFIG));
+
+ osc_init.OscillatorType = RCC_OSCILLATORTYPE_NONE;
+
+ /*
+ * LSI is used to clock the independent watchdog and optionally the RTC.
+ * It can be disabled per user request, but will be automatically enabled
+ * again when the IWDG is started.
+ *
+ * XXX currently the watchdog is not optional, so there's no point in
+ * disabling LSI through syscfg.
+ */
+ osc_init.OscillatorType |= RCC_OSCILLATORTYPE_LSI;
+#if (MYNEWT_VAL(STM32_CLOCK_LSI) == 0)
+ osc_init.LSIState = RCC_LSI_OFF;
+
+#else
+ osc_init.LSIState = RCC_LSI_ON;
+#endif
+
+ /*
+ * LSE is only used to clock the RTC.
+ */
+ osc_init.OscillatorType |= RCC_OSCILLATORTYPE_LSE;
+#if (MYNEWT_VAL(STM32_CLOCK_LSE) == 0)
+ osc_init.LSEState = RCC_LSE_OFF;
+#elif MYNEWT_VAL(STM32_CLOCK_LSE_BYPASS)
+ osc_init.LSEState = RCC_LSE_BYPASS;
+#else
+ osc_init.LSEState = RCC_LSE_ON;
+#endif
+
+ /*
+ * MSI Oscillator
+ */
+#if MYNEWT_VAL(STM32_CLOCK_MSI)
+
+#if (MYNEWT_VAL(STM32_CLOCK_MSI_CALIBRATION) > 255)
+#error "Invalid MSI calibration value"
+#endif
+#if !IS_RCC_MSI_CLOCK_RANGE(MYNEWT_VAL(STM32_CLOCK_MSI_CLOCK_RANGE))
+#error "Invalid MSI clock range"
+#endif
+
+ /* NOTE: MSI can't be disabled if it's the current PLL or SYSCLK source;
+ * leave it untouched in those cases, and disable later after a new source
+ * has been configured.
+ */
+ osc_init.OscillatorType |= RCC_OSCILLATORTYPE_MSI;
+ osc_init.MSIState = RCC_MSI_ON;
+ osc_init.MSICalibrationValue = MYNEWT_VAL(STM32_CLOCK_MSI_CALIBRATION);
+ osc_init.MSIClockRange = MYNEWT_VAL(STM32_CLOCK_MSI_CLOCK_RANGE);
+#endif
+
+ /*
+ * HSE Oscillator (can be used as PLL, SYSCLK and RTC clock source)
+ */
+#if MYNEWT_VAL(STM32_CLOCK_HSE)
+ osc_init.OscillatorType |= RCC_OSCILLATORTYPE_HSE;
+
+#if MYNEWT_VAL(STM32_CLOCK_HSE_BYPASS)
+ osc_init.HSEState = RCC_HSE_BYPASS;
+#else
+ osc_init.HSEState = RCC_HSE_ON;
+#endif
+
+#endif
+
+ /*
+ * HSI Oscillator (can be used as PLL and SYSCLK clock source). It is
+ * already turned on by default but a new calibration setting might be
+ * used. If the user chooses to turn it off, it must be turned off after
+ * SYSCLK was updated to use HSE/PLL.
+ */
+#if MYNEWT_VAL(STM32_CLOCK_HSI)
+ osc_init.OscillatorType |= RCC_OSCILLATORTYPE_HSI;
+ osc_init.HSIState = RCC_HSI_ON;
+ /* HSI calibration is not optional when HSI is enabled */
+ osc_init.HSICalibrationValue = MYNEWT_VAL(STM32_CLOCK_HSI_CALIBRATION);
+
+#if (MYNEWT_VAL(STM32_CLOCK_HSI_CALIBRATION) > 127)
+#error "Invalid HSI calibration value"
+#endif
+#endif
+
+ /*
+ * HSI48 can be used to drive USB/SDMMC/RNG
+ */
+#if MYNEWT_VAL(STM32_CLOCK_HSI48)
+ osc_init.OscillatorType |= RCC_OSCILLATORTYPE_HSI48;
+ osc_init.HSI48State = RCC_HSI48_ON;
+#endif
+
+ /*
+ * Default to MSI, HSE or HSI48 as PLL source when multiple high-speed
+ * sources are enabled.
+ */
+ osc_init.PLL.PLLState = RCC_PLL_ON;
+#if MYNEWT_VAL(STM32_CLOCK_MSI)
+ osc_init.PLL.PLLSource = RCC_PLLSOURCE_MSI;
+#elif MYNEWT_VAL(STM32_CLOCK_HSE)
+ osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+#else
+ osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSI;
+#endif
+
+#if !IS_RCC_PLLM_VALUE(MYNEWT_VAL(STM32_CLOCK_PLL_PLLM))
+#error "PLLM value is invalid"
+#endif
+
+#if !IS_RCC_PLLN_VALUE(MYNEWT_VAL(STM32_CLOCK_PLL_PLLN))
+#error "PLLN value is invalid"
+#endif
+
+#if !IS_RCC_PLLP_VALUE(MYNEWT_VAL(STM32_CLOCK_PLL_PLLP))
+#error "PLLP value is invalid"
+#endif
+
+#if !IS_RCC_PLLQ_VALUE(MYNEWT_VAL(STM32_CLOCK_PLL_PLLQ))
+#error "PLLQ value is invalid"
+#endif
+
+#if !IS_RCC_PLLR_VALUE(MYNEWT_VAL(STM32_CLOCK_PLL_PLLR))
+#error "PLLR value is invalid"
+#endif
+
+ osc_init.PLL.PLLM = MYNEWT_VAL(STM32_CLOCK_PLL_PLLM);
+ osc_init.PLL.PLLN = MYNEWT_VAL(STM32_CLOCK_PLL_PLLN);
+ osc_init.PLL.PLLP = MYNEWT_VAL(STM32_CLOCK_PLL_PLLP);
+ osc_init.PLL.PLLQ = MYNEWT_VAL(STM32_CLOCK_PLL_PLLQ);
+ osc_init.PLL.PLLR = MYNEWT_VAL(STM32_CLOCK_PLL_PLLR);
+ if (MYNEWT_VAL(STM32_CLOCK_PLL_BOOST_DIV) >= 0) {
+ osc_init.PLL.PLLMBOOST = MYNEWT_VAL(STM32_CLOCK_PLL_BOOST_DIV);
+ }
+
+ status = HAL_RCC_OscConfig(&osc_init);
+ if (status != HAL_OK) {
+ assert(0);
+ }
+
+ /*
+ * Select PLL as system clock source and configure the HCLK*, PCLK* and
+ * SYSCLK clocks dividers. HSI, HSE and MSI are also valid system clock
+ * sources, although there is no much point in supporting them now.
+ */
+ clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |
+ RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
+ clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+
+#if !IS_RCC_HCLK(MYNEWT_VAL(STM32_CLOCK_AHB_DIVIDER))
+#error "AHB clock divider is invalid"
+#endif
+
+#if !IS_RCC_PCLK(MYNEWT_VAL(STM32_CLOCK_APB1_DIVIDER))
+#error "APB1 clock divider is invalid"
+#endif
+
+#if !IS_RCC_PCLK(MYNEWT_VAL(STM32_CLOCK_APB2_DIVIDER))
+#error "APB2 clock divider is invalid"
+#endif
+
+ clk_init.AHBCLKDivider = MYNEWT_VAL(STM32_CLOCK_AHB_DIVIDER);
+ clk_init.APB1CLKDivider = MYNEWT_VAL(STM32_CLOCK_APB1_DIVIDER);
+ clk_init.APB2CLKDivider = MYNEWT_VAL(STM32_CLOCK_APB2_DIVIDER);
+
+#if !IS_FLASH_LATENCY(MYNEWT_VAL(STM32_FLASH_LATENCY))
+#error "Flash latency value is invalid"
+#endif
+
+ status = HAL_RCC_ClockConfig(&clk_init, MYNEWT_VAL(STM32_FLASH_LATENCY));
+ if (status != HAL_OK) {
+ assert(0);
+ }
+
+#if (MYNEWT_VAL(STM32_CLOCK_HSI) == 0) || (MYNEWT_VAL(STM32_CLOCK_HSE) == 0) || \
+ (MYNEWT_VAL(STM32_CLOCK_HSI48) == 0) || (MYNEWT_VAL(STM32_CLOCK_MSI) == 0)
+ /*
+ * Turn off HSE/HSI/HSI48 oscillator; this must be done at the end because
+ * SYSCLK source has to be updated first.
+ */
+ osc_init.OscillatorType = RCC_OSCILLATORTYPE_NONE;
+#if (MYNEWT_VAL(STM32_CLOCK_HSE) == 0)
+ osc_init.OscillatorType |= RCC_OSCILLATORTYPE_HSE;
+ osc_init.HSEState = RCC_HSE_OFF;
+#endif
+#if (MYNEWT_VAL(STM32_CLOCK_HSI) == 0)
+ osc_init.OscillatorType |= RCC_OSCILLATORTYPE_HSI;
+ osc_init.HSIState = RCC_HSI_OFF;
+#endif
+#if (MYNEWT_VAL(STM32_CLOCK_HSI48) == 0) && defined(RCC_HSI48_SUPPORT)
+ osc_init.OscillatorType |= RCC_OSCILLATORTYPE_HSI48;
+ osc_init.HSI48State = RCC_HSI48_OFF;
+#endif
+#if (MYNEWT_VAL(STM32_CLOCK_MSI) == 0)
+ osc_init.OscillatorType |= RCC_OSCILLATORTYPE_MSI;
+ osc_init.MSIState = RCC_MSI_OFF;
+#endif
+
+#endif
+
+ osc_init.PLL.PLLState = RCC_PLL_NONE;
+
+ status = HAL_RCC_OscConfig(&osc_init);
+ if (status != HAL_OK) {
+ assert(0);
+ }
+
+#if TRNG_ENABLED
+ pclk_init.PeriphClockSelection = RCC_PERIPHCLK_RNG;
+ /* Other clock sources are possible, but since right now we always
+ * configure the PLL, this should be ok
+ */
+ pclk_init.RngClockSelection = RCC_RNGCLKSOURCE_PLL;
+ status = HAL_RCCEx_PeriphCLKConfig(&pclk_init);
+ if (status != HAL_OK) {
+ assert(0);
+ }
+#endif
+
+#if PREFETCH_ENABLE
+ __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
+#endif
+
+#if MYNEWT_VAL(STM32_ENABLE_ICACHE)
+ HAL_ICACHE_Enable();
+#endif
+
+#if MYNEWT_VAL(STM32_ENABLE_DCACHE)
+ DCACHE_HandleTypeDef cache = {
+ .Instance = DCACHE1_S,
+ .Init.ReadBurstType = DCACHE_READ_BURST_WRAP,
+ };
+ HAL_DCACHE_Init(&cache);
+#endif
+}
+#endif
diff --git a/hw/mcu/stm/stm32u5xx/src/hal_flash.c b/hw/mcu/stm/stm32u5xx/src/hal_flash.c
new file mode 100644
index 000000000..69b8b7ee6
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/src/hal_flash.c
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <syscfg/syscfg.h>
+#include <mcu/stm32_hal.h>
+#include "hal/hal_flash_int.h"
+
+#define STM32_FLASH_SIZE (MYNEWT_VAL(STM32_FLASH_SIZE_KB) * 1024)
+
+int
+stm32_mcu_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
+{
+ FLASH_EraseInitTypeDef eraseinit;
+ uint32_t PageError;
+ HAL_StatusTypeDef rc;
+
+ (void)PageError;
+
+ if (!(sector_address & (FLASH_PAGE_SIZE - 1))) {
+ eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
+#ifdef FLASH_BANK_2
+ if ((sector_address - dev->hf_base_addr) < (STM32_FLASH_SIZE / 2)) {
+ eraseinit.Banks = FLASH_BANK_1;
+ }
+ else {
+ eraseinit.Banks = FLASH_BANK_2;
+ }
+#else
+ eraseinit.Banks = FLASH_BANK_1;
+#endif
+ eraseinit.Page = (sector_address - dev->hf_base_addr) / FLASH_PAGE_SIZE;
+ eraseinit.NbPages = 1;
+ rc = HAL_FLASHEx_Erase(&eraseinit, &PageError);
+ if (rc == HAL_OK) {
+ return 0;
+ }
+ }
+
+ return -1;
+}
diff --git a/hw/mcu/stm/stm32u5xx/src/hal_reset_cause.c b/hw/mcu/stm/stm32u5xx/src/hal_reset_cause.c
new file mode 100644
index 000000000..6dc6c006e
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/src/hal_reset_cause.c
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include <hal/hal_system.h>
+
+#include "stm32u5xx_hal_def.h"
+
+enum hal_reset_reason
+hal_reset_cause(void)
+{
+ static enum hal_reset_reason reason;
+ uint32_t reg;
+
+ if (reason) {
+ return reason;
+ }
+
+ reg = RCC->CSR;
+
+ if (reg & RCC_CSR_WWDGRSTF) {
+ reason = HAL_RESET_WATCHDOG;
+ } else if (reg & RCC_CSR_SFTRSTF) {
+ reason = HAL_RESET_SOFT;
+ } else if (reg & RCC_CSR_PINRSTF) {
+ reason = HAL_RESET_PIN;
+ } else if (reg & RCC_CSR_LPWRRSTF) {
+ /* For L1xx this is low-power reset */
+ reason = HAL_RESET_BROWNOUT;
+ } else {
+ reason = HAL_RESET_POR;
+ }
+ RCC->CSR |= RCC_CSR_RMVF;
+ return reason;
+}
diff --git a/hw/mcu/stm/stm32u5xx/src/hal_timer_freq.c b/hw/mcu/stm/stm32u5xx/src/hal_timer_freq.c
new file mode 100644
index 000000000..0cdb3b714
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/src/hal_timer_freq.c
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <inttypes.h>
+#include <assert.h>
+
+#include "os/mynewt.h"
+
+#include <hal/hal_timer.h>
+#include "mcu/stm32_hal.h"
+#include "stm32_common/stm32_hal.h"
+
+
+/*
+ * Generic implementation for determining the frequency
+ * of a timer.
+ */
+
+uint32_t
+stm32_hal_timer_get_freq(void *regs)
+{
+ RCC_ClkInitTypeDef clocks;
+ uint32_t fl;
+ uint32_t freq;
+
+ HAL_RCC_GetClockConfig(&clocks, &fl);
+
+ /*
+ * Assuming RCC_DCKCFGR->TIMPRE is 0.
+ * There's just APB2 timers here.
+ */
+ switch ((uintptr_t)regs) {
+#ifdef TIM1
+ case (uintptr_t)TIM1:
+#endif
+#ifdef TIM8
+ case (uintptr_t)TIM8:
+#endif
+#ifdef TIM9
+ case (uintptr_t)TIM9:
+#endif
+#ifdef TIM10
+ case (uintptr_t)TIM10:
+#endif
+#ifdef TIM11
+ case (uintptr_t)TIM11:
+#endif
+#ifdef TIM15
+ case (uintptr_t)TIM15:
+#endif
+#ifdef TIM16
+ case (uintptr_t)TIM16:
+#endif
+#ifdef TIM17
+ case (uintptr_t)TIM17:
+#endif
+ freq = HAL_RCC_GetPCLK2Freq();
+ if (clocks.APB2CLKDivider) {
+ freq *= 2;
+ }
+ break;
+#ifdef TIM2
+ case (uintptr_t)TIM2:
+#endif
+#ifdef TIM3
+ case (uintptr_t)TIM3:
+#endif
+#ifdef TIM4
+ case (uintptr_t)TIM4:
+#endif
+ freq = HAL_RCC_GetPCLK1Freq();
+ if (clocks.APB1CLKDivider) {
+ freq *= 2;
+ }
+ break;
+ default:
+ return 0;
+ }
+ return freq;
+}
diff --git a/hw/mcu/stm/stm32u5xx/src/system_stm32u5xx.c b/hw/mcu/stm/stm32u5xx/src/system_stm32u5xx.c
new file mode 100644
index 000000000..5a4aae695
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/src/system_stm32u5xx.c
@@ -0,0 +1,369 @@
+/**
+ ******************************************************************************
+ * @file system_stm32u5xx.c
+ * @author MCD Application Team
+ * @brief CMSIS Cortex-M33 Device Peripheral Access Layer System Source File
+ *
+ * This file provides two functions and one global variable to be called from
+ * user application:
+ * - SystemInit(): This function is called at startup just after reset and
+ * before branch to main program. This call is made inside
+ * the "startup_stm32u5xx.s" file.
+ *
+ * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+ * by the user application to setup the SysTick
+ * timer or configure other parameters.
+ *
+ * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+ * be called whenever the core clock is changed
+ * during program execution.
+ *
+ * After each device reset the MSI (4 MHz) is used as system clock source.
+ * Then SystemInit() function is called, in "startup_stm32u5xx.s" file, to
+ * configure the system clock before to branch to main program.
+ *
+ * This file configures the system clock as follows:
+ *=============================================================================
+ *-----------------------------------------------------------------------------
+ * System Clock source | MSI
+ *-----------------------------------------------------------------------------
+ * SYSCLK(Hz) | 4000000
+ *-----------------------------------------------------------------------------
+ * HCLK(Hz) | 4000000
+ *-----------------------------------------------------------------------------
+ * AHB Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB1 Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB2 Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB3 Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * PLL1_SRC | No clock
+ *-----------------------------------------------------------------------------
+ * PLL1_M | 1
+ *-----------------------------------------------------------------------------
+ * PLL1_N | 8
+ *-----------------------------------------------------------------------------
+ * PLL1_P | 7
+ *-----------------------------------------------------------------------------
+ * PLL1_Q | 2
+ *-----------------------------------------------------------------------------
+ * PLL1_R | 2
+ *-----------------------------------------------------------------------------
+ * PLL2_SRC | NA
+ *-----------------------------------------------------------------------------
+ * PLL2_M | NA
+ *-----------------------------------------------------------------------------
+ * PLL2_N | NA
+ *-----------------------------------------------------------------------------
+ * PLL2_P | NA
+ *-----------------------------------------------------------------------------
+ * PLL2_Q | NA
+ *-----------------------------------------------------------------------------
+ * PLL2_R | NA
+ *-----------------------------------------------------------------------------
+ * PLL3_SRC | NA
+ *-----------------------------------------------------------------------------
+ * PLL3_M | NA
+ *-----------------------------------------------------------------------------
+ * PLL3_N | NA
+ *-----------------------------------------------------------------------------
+ * PLL3_P | NA
+ *-----------------------------------------------------------------------------
+ * Require 48MHz for USB FS, | Disabled
+ * SDIO and RNG clock |
+ *-----------------------------------------------------------------------------
+ *=============================================================================
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup STM32U5xx_system
+ * @{
+ */
+
+/** @addtogroup STM32U5xx_System_Private_Includes
+ * @{
+ */
+
+#include <math.h>
+#include <mcu/cmsis_nvic.h>
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32U5xx_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32U5xx_System_Private_Defines
+ * @{
+ */
+
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE 16000000U /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (MSI_VALUE)
+ #define MSI_VALUE 4000000U /*!< Value of the Internal oscillator in Hz*/
+#endif /* MSI_VALUE */
+
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/************************* Miscellaneous Configuration ************************/
+/*!< Uncomment the following line if you need to relocate your vector Table in
+ Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET 0x00000000UL /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+/******************************************************************************/
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32U5xx_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32U5xx_System_Private_Variables
+ * @{
+ */
+ /* The SystemCoreClock variable is updated in three ways:
+ 1) by calling CMSIS function SystemCoreClockUpdate()
+ 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
+ 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
+ Note: If you use this function to configure the system clock; then there
+ is no need to call the 2 first functions listed above, since SystemCoreClock
+ variable is updated automatically.
+ */
+ uint32_t SystemCoreClock = 4000000U;
+
+ const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
+ const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
+ const uint32_t MSIRangeTable[16] = {48000000U,24000000U,16000000U,12000000U, 4000000U, 2000000U, 1500000U,\
+ 1000000U, 3072000U, 1536000U,1024000U, 768000U, 400000U, 200000U, 150000U, 100000U};
+/**
+ * @}
+ */
+
+/** @addtogroup STM32U5xx_System_Private_FunctionPrototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32U5xx_System_Private_Functions
+ * @{
+ */
+
+/*
+ * XXX BSP specific
+ */
+void SystemClock_Config(void);
+
+/**
+ * @brief Setup the microcontroller system.
+ * @param None
+ * @retval None
+ */
+
+void SystemInit(void)
+{
+ /* FPU settings ------------------------------------------------------------*/
+ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
+ #endif
+
+ /* Reset the RCC clock configuration to the default reset state ------------*/
+ /* Set MSION bit */
+ RCC->CR = RCC_CR_MSISON;
+
+ /* Reset CFGR register */
+ RCC->CFGR1 = 0U;
+ RCC->CFGR2 = 0U;
+ RCC->CFGR3 = 0U;
+
+ /* Reset HSEON, CSSON , HSION, PLLxON bits */
+ RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLL1ON | RCC_CR_PLL2ON | RCC_CR_PLL3ON);
+
+ /* Reset PLLCFGR register */
+ RCC->PLL1CFGR = 0U;
+
+ /* Reset HSEBYP bit */
+ RCC->CR &= ~(RCC_CR_HSEBYP);
+
+ /* Disable all interrupts */
+ RCC->CIER = 0U;
+
+ /* Configure System Clock */
+ SystemClock_Config();
+
+ /* Update SystemCoreClock global variable */
+ SystemCoreClockUpdate();
+
+ /* Relocate the vector table */
+ NVIC_Relocate();
+}
+
+/**
+ * @brief Update SystemCoreClock variable according to Clock Register Values.
+ * The SystemCoreClock variable contains the core clock (HCLK), it can
+ * be used by the user application to setup the SysTick timer or configure
+ * other parameters.
+ *
+ * @note Each time the core clock (HCLK) changes, this function must be called
+ * to update SystemCoreClock variable value. Otherwise, any configuration
+ * based on this variable will be incorrect.
+ *
+ * @note - The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ *
+ * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*)
+ *
+ * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
+ *
+ * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
+ *
+ * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
+ * or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
+ *
+ * (*) MSI_VALUE is a constant defined in stm32u5xx_hal.h file (default value
+ * 4 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (**) HSI_VALUE is a constant defined in stm32u5xx_hal.h file (default value
+ * 16 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (***) HSE_VALUE is a constant defined in stm32u5xx_hal.h file (default value
+ * 8 MHz), user has to ensure that HSE_VALUE is same as the real
+ * frequency of the crystal used. Otherwise, this function may
+ * have wrong result.
+ *
+ * - The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ *
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate(void)
+{
+ uint32_t pllr, pllsource, pllm , tmp, pllfracen, msirange;
+ float_t fracn1, pllvco;
+
+ /* Get MSI Range frequency--------------------------------------------------*/
+ if(READ_BIT(RCC->ICSCR1, RCC_ICSCR1_MSIRGSEL) == 0U)
+ {
+ /* MSISRANGE from RCC_CSR applies */
+ msirange = (RCC->CSR & RCC_CSR_MSISSRANGE) >> RCC_CSR_MSISSRANGE_Pos;
+ }
+ else
+ {
+ /* MSIRANGE from RCC_CR applies */
+ msirange = (RCC->ICSCR1 & RCC_ICSCR1_MSISRANGE) >> RCC_ICSCR1_MSISRANGE_Pos;
+ }
+
+ /*MSI frequency range in HZ*/
+ msirange = MSIRangeTable[msirange];
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ switch (RCC->CFGR1 & RCC_CFGR1_SWS)
+ {
+ case 0x00: /* MSI used as system clock source */
+ SystemCoreClock = msirange;
+ break;
+
+ case 0x04: /* HSI used as system clock source */
+ SystemCoreClock = HSI_VALUE;
+ break;
+
+ case 0x08: /* HSE used as system clock source */
+ SystemCoreClock = HSE_VALUE;
+ break;
+
+ case 0x0C: /* PLL used as system clock source */
+ /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
+ SYSCLK = PLL_VCO / PLLR
+ */
+ pllsource = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC);
+ pllm = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M)>> RCC_PLL1CFGR_PLL1M_Pos) + 1U;
+ pllfracen = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN)>>RCC_PLL1CFGR_PLL1FRACEN_Pos);
+ fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN)>> RCC_PLL1FRACR_PLL1FRACN_Pos));
+
+ switch (pllsource)
+ {
+ case 0x00: /* No clock sent to PLL*/
+ pllvco = (float_t)0U;
+ break;
+
+ case 0x02: /* HSI used as PLL clock source */
+ pllvco = ((float_t)HSI_VALUE / (float_t)pllm);
+ break;
+
+ case 0x03: /* HSE used as PLL clock source */
+ pllvco = ((float_t)HSE_VALUE / (float_t)pllm);
+ break;
+
+ default: /* MSI used as PLL clock source */
+ pllvco = ((float_t)msirange / (float_t)pllm);
+ break;
+ }
+
+ pllvco = pllvco * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + (fracn1/(float_t)0x2000) + (float_t)1U);
+ pllr = (((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1U );
+ SystemCoreClock = (uint32_t)((uint32_t)pllvco/pllr);
+ break;
+
+ default:
+ SystemCoreClock = msirange;
+ break;
+ }
+ /* Compute HCLK clock frequency --------------------------------------------*/
+ /* Get HCLK prescaler */
+ tmp = AHBPrescTable[((RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos)];
+ /* HCLK clock frequency */
+ SystemCoreClock >>= tmp;
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
diff --git a/hw/mcu/stm/stm32u5xx/stm32u5xx.ld b/hw/mcu/stm/stm32u5xx/stm32u5xx.ld
new file mode 100644
index 000000000..26f817624
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/stm32u5xx.ld
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ * Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ * __exidx_start
+ * __exidx_end
+ * __etext
+ * __data_start__
+ * __preinit_array_start
+ * __preinit_array_end
+ * __init_array_start
+ * __init_array_end
+ * __fini_array_start
+ * __fini_array_end
+ * __data_end__
+ * __bss_start__
+ * __bss_end__
+ * __end__
+ * end
+ * __HeapBase
+ * __HeapLimit
+ * __StackLimit
+ * __StackTop
+ * __stack
+ * __coredata_start__
+ * __coredata_end__
+ * __corebss_start__
+ * __corebss_end__
+ * __ecoredata
+ * __ecorebss
+ */
+ENTRY(Reset_Handler)
+
+_estack = ORIGIN(RAM) + LENGTH(RAM);
+
+SECTIONS
+{
+ /* Reserve space at the start of the image for the header. */
+ .imghdr (NOLOAD):
+ {
+ . = . + _imghdr_size;
+ } > FLASH
+
+ .text :
+ {
+ . = ALIGN(8);
+ __isr_vector_start = .;
+ KEEP(*(.isr_vector))
+ __isr_vector_end = .;
+ *(.text*)
+
+ KEEP(*(.init))
+ KEEP(*(.fini))
+
+ /* preinit data */
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+
+ . = ALIGN(8);
+ /* init data */
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+
+ . = ALIGN(8);
+ /* finit data */
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ /* .ctors */
+ *crtbegin.o(.ctors)
+ *crtbegin?.o(.ctors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+ *(SORT(.ctors.*))
+ *(.ctors)
+
+ /* .dtors */
+ *crtbegin.o(.dtors)
+ *crtbegin?.o(.dtors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ *(SORT(.dtors.*))
+ *(.dtors)
+
+ *(.rodata*)
+
+ KEEP(*(.eh_frame*))
+ } > FLASH
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > FLASH
+
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > FLASH
+
+ __exidx_end = .;
+
+ __etext = .;
+
+ .vector_relocation :
+ {
+ . = ALIGN(8);
+ __vector_tbl_reloc__ = .;
+ . = . + (__isr_vector_end - __isr_vector_start);
+ } > RAM
+
+ .coredata :
+ {
+ . = ALIGN(8);
+ __coredata_start__ = .;
+ *(.data.core)
+ __coredata_end__ = .;
+ } > RAM AT > FLASH
+
+ __ecoredata = __etext + SIZEOF(.coredata);
+
+ _sidata = LOADADDR(.data);
+
+ .data :
+ {
+ . = ALIGN(8);
+ _sdata = .;
+ __data_start__ = _sdata;
+ *(vtable)
+ *(.data*)
+
+ KEEP(*(.jcr*))
+ . = ALIGN(8);
+ /* All data end */
+ _edata = .;
+ __data_end__ = _edata;
+
+ } > RAM AT > FLASH
+
+ .corebss (NOLOAD):
+ {
+ . = ALIGN(4);
+ __corebss_start__ = .;
+ *(.bss.core)
+ . = ALIGN(4);
+ __corebss_end__ = .;
+ *(.corebss*)
+ *(.bss.core.nz)
+ . = ALIGN(4);
+ __ecorebss = .;
+ } > RAM
+
+ .bss :
+ {
+ . = ALIGN(4);
+ _sbss = .;
+ __bss_start__ = _sbss;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ __bss_end__ = _ebss;
+ } > RAM
+
+ . = ALIGN(8);
+ __HeapBase = .;
+ __HeapLimit = ORIGIN(RAM) + LENGTH(RAM);
+
+ _ram_start = ORIGIN(RAM);
+
+ /* .stack_dummy section doesn't contains any symbols. It is only
+ * used for linker to calculate size of stack sections, and assign
+ * values to stack symbols later */
+ .stack_dummy (COPY):
+ {
+ *(.stack*)
+ } > RAM
+
+ /* Set stack top to end of RAM; stack limit is bottom of stack */
+ __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+ __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+ PROVIDE(__stack = __StackTop);
+}
+
diff --git a/hw/mcu/stm/stm32u5xx/syscfg.yml b/hw/mcu/stm/stm32u5xx/syscfg.yml
new file mode 100644
index 000000000..5dd68c53a
--- /dev/null
+++ b/hw/mcu/stm/stm32u5xx/syscfg.yml
@@ -0,0 +1,149 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+ MCU_FLASH_MIN_WRITE_SIZE:
+ description: >
+ Specifies the required alignment for internal flash writes.
+ Used internally by the newt tool.
+ value: 8
+
+ MCU_STM32U5:
+ description: MCUs are of STM32U5xx family
+ value: 1
+
+ STM32_CLOCK_VOLTAGESCALING_CONFIG:
+ description: Adjust voltage scale
+ value: 0
+
+ STM32_CLOCK_LSI:
+ description: Enable low-speed internal clock source
+ value: 0
+
+ STM32_CLOCK_LSE:
+ description: Enable low-speed external clock source (aka RTC xtal)
+ value: 0
+
+ STM32_CLOCK_LSE_BYPASS:
+ description: 0 for 32768 xtal; 1 for input clock
+ value: 0
+
+ STM32_CLOCK_MSI:
+ description: Enable multi-speed internal clock source
+ value: 1
+
+ STM32_CLOCK_MSI_CALIBRATION:
+ description: MSI calibration value
+ value: 'RCC_MSICALIBRATION_DEFAULT'
+
+ STM32_CLOCK_MSI_CLOCK_RANGE:
+ description: MSI clock range
+ value: 'RCC_MSIRANGE_4'
+
+ STM32_CLOCK_HSE:
+ description: Enable high-speed external clock source
+ value: 0
+
+ STM32_CLOCK_HSE_BYPASS:
+ description: 0 for xtal; 1 for input clock
+ value: 0
+
+ STM32_CLOCK_HSI:
+ description: Enable high-speed internal clock source
+ value: 1
+
+ STM32_CLOCK_HSI_CALIBRATION:
+ description: HSI calibration value
+ value: 'RCC_HSICALIBRATION_DEFAULT'
+
+ STM32_CLOCK_HSI48:
+ description: Enable high-speed 48MHz internal clock source
+ value: 0
+
+ STM32_CLOCK_PLL_PLLM:
+ description: PLL config M parameter
+ value: 0
+
+ STM32_CLOCK_PLL_PLLN:
+ description: PLL config N parameter
+ value: 0
+
+ STM32_CLOCK_PLL_PLLP:
+ description: PLL config P parameter
+ value: 0
+
+ STM32_CLOCK_PLL_PLLQ:
+ description: PLL config Q parameter
+ value: 0
+
+ STM32_CLOCK_PLL_PLLR:
+ description: PLL config R parameter
+ value: 0
+
+ STM32_CLOCK_PLL_BOOST_DIV:
+ description: >
+ Divider for PLL boost required when target SYSCLK > 55MHz.
+ Must result in boot frequency being in range 4-16MHz.
+ For MSI at 4MHz set it to RCC_PLLMBOOST_DIV1.
+ When left to -1, boost will be off and SYSCLK must be lower then 55MHz
+ value: RCC_PLLMBOOST_DIV1
+
+ STM32_CLOCK_AHB_DIVIDER:
+ description: AHB CLK1 prescaler (80MHz max)
+ value: 0
+
+ STM32_CLOCK_APB1_DIVIDER:
+ description: APB low-speed prescaler (80MHz max)
+ value: 0
+
+ STM32_CLOCK_APB2_DIVIDER:
+ description: APB high-speed prescaler (80MHz max)
+ value: 0
+
+ STM32_FLASH_LATENCY:
+ description: Number of wait-states
+ value: 0
+
+ STM32_ENABLE_ICACHE:
+ description: Enable instruction caching
+ value: 1
+
+ STM32_ENABLE_DCACHE:
+ description: Enable instruction caching
+ value: 1
+
+ STM32_FLASH_PREFETCH_ENABLE:
+ description: Enable pre-fetch of instructions (when latency > 0)
+ value: 1
+
+ STM32_HAL_SPI_HAS_FIFO:
+ description: This MCU has a SPI with FIFO
+ value: 1
+
+ STM32_HAL_I2C_HAS_CLOCKSPEED:
+ description: This MCU's I2C has no clock speed register (has TIMINGR)
+ value: 0
+
+ STM32_HAL_UART_HAS_SR:
+ description: This MCU's UART uses ISR register (not SR) for status.
+ value: 0
+
+ MCU_FLASH_ERASED_VAL:
+ description: Value read from erased flash.
+ value: 0xff
+