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>&copy; 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
+