This is an automated email from the ASF dual-hosted git repository.

utzig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 5cc9e6910045d425f813496f3c2eb2e047237dfb
Author: Fabio Utzig <[email protected]>
AuthorDate: Wed Sep 25 14:40:14 2019 -0300

    Add initial STM32WBxx MCU support
---
 hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c         |  16 ++
 hw/mcu/stm/stm32wbxx/include/mcu/cmsis_nvic.h      |  29 +++
 hw/mcu/stm/stm32wbxx/include/mcu/cortex_m4.h       |  35 ++++
 hw/mcu/stm/stm32wbxx/include/mcu/mcu.h             |  35 ++++
 hw/mcu/stm/stm32wbxx/include/mcu/stm32_hal.h       |  86 ++++++++
 hw/mcu/stm/stm32wbxx/include/mcu/stm32wb_bsp.h     |  58 ++++++
 .../stm32wbxx/include/mcu/stm32wbxx_mynewt_hal.h   |  66 +++++++
 hw/mcu/stm/stm32wbxx/pkg.yml                       |  39 ++++
 .../src/clock_stm32wbxx.c}                         | 200 +++++++++++++------
 hw/mcu/stm/stm32wbxx/src/hal_flash.c               |  45 +++++
 hw/mcu/stm/stm32wbxx/src/hal_reset_cause.c         |  49 +++++
 hw/mcu/stm/stm32wbxx/src/hal_timer_freq.c          |  74 +++++++
 hw/mcu/stm/stm32wbxx/src/system_stm32wbxx.c        | 219 +++++++++++++++++++++
 hw/mcu/stm/stm32wbxx/stm32wb55.ld                  | 203 +++++++++++++++++++
 hw/mcu/stm/stm32wbxx/syscfg.yml                    | 199 +++++++++++++++++++
 15 files changed, 1289 insertions(+), 64 deletions(-)

diff --git a/hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c 
b/hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c
index 5b0ac63..1c25c8b 100644
--- a/hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c
+++ b/hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c
@@ -62,6 +62,22 @@ SystemClock_Config(void)
      */
     
__HAL_PWR_VOLTAGESCALING_CONFIG(MYNEWT_VAL(STM32_CLOCK_VOLTAGESCALING_CONFIG));
 
+    /*
+     * Configure HSI as PLL source; this avoids an error reconfiguring the
+     * PLL when it is already set has the system clock source.
+     */
+    osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSI;
+    osc_init.HSIState = RCC_HSI_ON;
+    osc_init.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
+    osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSI;
+    osc_init.PLL.PLLN = RCC_PLLCFGR_PLLN_0;
+    osc_init.PLL.PLLP = RCC_PLLCFGR_PLLP_0;
+
+    status = HAL_RCC_OscConfig(&osc_init);
+    if (status != HAL_OK) {
+        assert(0);
+    }
+
     osc_init.OscillatorType = RCC_OSCILLATORTYPE_NONE;
 
     /*
diff --git a/hw/mcu/stm/stm32wbxx/include/mcu/cmsis_nvic.h 
b/hw/mcu/stm/stm32wbxx/include/mcu/cmsis_nvic.h
new file mode 100644
index 0000000..8e268d3
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/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 MBED_CMSIS_NVIC_H
+#define MBED_CMSIS_NVIC_H
+
+#include <stdint.h>
+
+#define NVIC_NUM_VECTORS      (16 + 63)   // CORE + MCU Peripherals
+#define NVIC_USER_IRQ_OFFSET  16
+
+#include "stm32wbxx.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/stm32wbxx/include/mcu/cortex_m4.h 
b/hw/mcu/stm/stm32wbxx/include/mcu/cortex_m4.h
new file mode 100644
index 0000000..27377da
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/include/mcu/cortex_m4.h
@@ -0,0 +1,35 @@
+/*
+ * 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_M4_H__
+#define __MCU_CORTEX_M4_H__
+
+#include "stm32wbxx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_TICKS_PER_SEC    (1000)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_CORTEX_M4_H__ */
diff --git a/hw/mcu/stm/stm32wbxx/include/mcu/mcu.h 
b/hw/mcu/stm/stm32wbxx/include/mcu/mcu.h
new file mode 100644
index 0000000..2ac5e96
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/include/mcu/mcu.h
@@ -0,0 +1,35 @@
+/*
+ * 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 <stm32_common/mcu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SVC_IRQ_NUMBER SVC_IRQn
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_MCU_H_ */
diff --git a/hw/mcu/stm/stm32wbxx/include/mcu/stm32_hal.h 
b/hw/mcu/stm/stm32wbxx/include/mcu/stm32_hal.h
new file mode 100644
index 0000000..89e4d48
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/include/mcu/stm32_hal.h
@@ -0,0 +1,86 @@
+/*
+ * 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_m4.h>
+
+#include "stm32wbxx.h"
+#include "stm32wbxx_hal.h"
+#include "stm32wbxx_hal_def.h"
+#include "stm32wbxx_hal_dma.h"
+#include "stm32wbxx_hal_spi.h"
+#include "stm32wbxx_hal_gpio.h"
+#include "stm32wbxx_hal_gpio_ex.h"
+#include "stm32wbxx_hal_rcc.h"
+#include "stm32wbxx_hal_i2c.h"
+#include "stm32wbxx_hal_uart.h"
+#include "mcu/stm32wb_bsp.h"
+#include "stm32wbxx_hal_tim.h"
+#include "stm32wbxx_ll_bus.h"
+#include "stm32wbxx_ll_tim.h"
+#include "stm32wbxx_mynewt_hal.h"
+#include "stm32wbxx_hal_iwdg.h"
+#include "stm32wbxx_hal_rng.h"
+#include "stm32wbxx_hal_cryp.h"
+#include "stm32wbxx_hal_rcc_ex.h"
+#include "stm32wbxx_hal_flash.h"
+#include "stm32wbxx_hal_flash_ex.h"
+
+/* hal_watchdog */
+#define STM32_HAL_WATCHDOG_CUSTOM_INIT(x)           \
+    do {                                            \
+        (x)->Init.Window = IWDG_WINDOW_DISABLE;     \
+    } while (0)
+
+/* hal_system_start */
+#define STM32_HAL_FLASH_REMAP()                  \
+    do {                                         \
+        SYSCFG->MEMRMP = 0;                      \
+        __DSB();                                 \
+    } while (0)
+
+/* hal_spi */
+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_DOUBLEWORD
+#define STM32_HAL_FLASH_CLEAR_ERRORS()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_HAL_H */
diff --git a/hw/mcu/stm/stm32wbxx/include/mcu/stm32wb_bsp.h 
b/hw/mcu/stm/stm32wbxx/include/mcu/stm32wb_bsp.h
new file mode 100644
index 0000000..e45dc67
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/include/mcu/stm32wb_bsp.h
@@ -0,0 +1,58 @@
+/*
+ * 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_STM32WB_BSP_H_
+#define __MCU_STM32WB_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 stm32wbxx 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 stm32wb_flash_dev;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MCU_STM32WB_BSP_H_ */
diff --git a/hw/mcu/stm/stm32wbxx/include/mcu/stm32wbxx_mynewt_hal.h 
b/hw/mcu/stm/stm32wbxx/include/mcu/stm32wbxx_mynewt_hal.h
new file mode 100644
index 0000000..71313f3
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/include/mcu/stm32wbxx_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_STM32WB_MYNEWT_HAL_H
+#define __MCU_STM32WB_MYNEWT_HAL_H
+
+#include "stm32wbxx.h"
+#include "stm32wbxx_hal_dma.h"
+#include "stm32wbxx_hal_gpio.h"
+#include "stm32wbxx_hal_i2c.h"
+#include "stm32wbxx_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_STM32WB_MYNEWT_HAL_H */
diff --git a/hw/mcu/stm/stm32wbxx/pkg.yml b/hw/mcu/stm/stm32wbxx/pkg.yml
new file mode 100644
index 0000000..47b63cf
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/pkg.yml
@@ -0,0 +1,39 @@
+#
+# 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/stm32wbxx
+pkg.description: MCU definition for STM32WB ARM Cortex-M0+ chips.
+pkg.author: "Apache Mynewt <[email protected]>"
+pkg.homepage: "http://mynewt.apache.org/";
+pkg.keywords:
+    - stm32
+    - stm32wb
+
+pkg.type: sdk
+
+pkg.ign_files:
+    - ".*template.*"
+
+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"
diff --git a/hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c 
b/hw/mcu/stm/stm32wbxx/src/clock_stm32wbxx.c
similarity index 57%
copy from hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c
copy to hw/mcu/stm/stm32wbxx/src/clock_stm32wbxx.c
index 5b0ac63..b00bf1e 100644
--- a/hw/mcu/stm/stm32f4xx/src/clock_stm32f4xx.c
+++ b/hw/mcu/stm/stm32wbxx/src/clock_stm32wbxx.c
@@ -24,22 +24,30 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "stm32f4xx_hal_pwr_ex.h"
-#include "stm32f4xx_hal.h"
+#include "stm32wbxx_hal_pwr_ex.h"
+#include "stm32wbxx_hal_rcc.h"
+#include "stm32wbxx_hal.h"
 #include <assert.h>
 
 /*
  * This allows an user to have a custom clock configuration by zeroing
  * every possible clock source in the syscfg.
  */
-#if MYNEWT_VAL(STM32_CLOCK_HSE) || MYNEWT_VAL(STM32_CLOCK_LSE) || \
-    MYNEWT_VAL(STM32_CLOCK_HSI) || MYNEWT_VAL(STM32_CLOCK_LSI)
+#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_LSI1) || \
+    MYNEWT_VAL(STM32_CLOCK_LSI2)
+
+#define TRNG_ENABLED (MYNEWT_VAL(TRNG) != 0)
 
 /*
- * HSI is turned on by default, but can be turned off and use HSE instead.
+ * HSI is turned on by default, but can be turned off and use HSE/HSI48 
instead.
  */
-#if (((MYNEWT_VAL(STM32_CLOCK_HSE) != 0) + (MYNEWT_VAL(STM32_CLOCK_HSI) != 0)) 
< 1)
-#error "At least one of HSE or HSI clock source must be enabled"
+#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
@@ -48,11 +56,9 @@ SystemClock_Config(void)
     RCC_OscInitTypeDef osc_init;
     RCC_ClkInitTypeDef clk_init;
     HAL_StatusTypeDef status;
-
-    /*
-     * Enable Power Control clock
-     */
-    __HAL_RCC_PWR_CLK_ENABLE();
+#if TRNG_ENABLED
+    RCC_PeriphCLKInitTypeDef  pclk_init;
+#endif
 
     /*
      * The voltage scaling allows optimizing the power consumption when the
@@ -65,20 +71,41 @@ SystemClock_Config(void)
     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 is automatically enabled again
-     * when the IWDG is started.
+     * LSI1/2 is used to clock the independent watchdog and optionally the RTC.
+     * LSI2 can also be used for auto-wakeup from the RF system. When LSI2 is
+     * enabled LSI1 is automatically enabled no matter which config was set.
+     *
+     * Both can be disabled per user request, but LSI1 is 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.
+     * disabling LSI1 through syscfg.
      */
-    osc_init.OscillatorType |= RCC_OSCILLATORTYPE_LSI;
-#if MYNEWT_VAL(STM32_CLOCK_LSI)
-    osc_init.LSIState = RCC_LSI_ON;
-#else
+#if (MYNEWT_VAL(STM32_CLOCK_LSI1) == 0) && (MYNEWT_VAL(STM32_CLOCK_LSI2) == 0)
+
+    osc_init.OscillatorType |= RCC_OSCILLATORTYPE_LSI1 | 
RCC_OSCILLATORTYPE_LSI2;
     osc_init.LSIState = RCC_LSI_OFF;
+
+#else
+
+    osc_init.LSIState = RCC_LSI_ON;
+
+#if MYNEWT_VAL(STM32_CLOCK_LSI1)
+    osc_init.OscillatorType |= RCC_OSCILLATORTYPE_LSI1;
 #endif
 
+#if MYNEWT_VAL(STM32_CLOCK_LSI2)
+
+#if !IS_RCC_LSI2_CALIBRATION_VALUE(MYNEWT_VAL(STM32_CLOCK_LSI2_CALIBRATION))
+#error "Invalid LSI2 calibration value"
+#endif
+
+    osc_init.OscillatorType |= RCC_OSCILLATORTYPE_LSI2;
+    osc_init.LSI2CalibrationValue = MYNEWT_VAL(STM32_CLOCK_LSI2_CALIBRATION);
+#endif /* MYNEWT_VAL(STM32_CLOCK_LSI2) */
+
+#endif /* (MYNEWT_VAL(STM32_CLOCK_LSI1) == 0) && (MYNEWT_VAL(STM32_CLOCK_LSI2) 
== 0) */
+
     /*
      * LSE is only used to clock the RTC.
      */
@@ -92,6 +119,28 @@ SystemClock_Config(void)
 #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)
@@ -101,6 +150,11 @@ SystemClock_Config(void)
 #else
     osc_init.HSEState = RCC_HSE_ON;
 #endif
+#if MYNEWT_VAL(STM32_CLOCK_HSEPRE)
+    __HAL_RCC_HSE_DIV2_ENABLE();
+#else
+    __HAL_RCC_HSE_DIV2_DISABLE();
+#endif
 #endif
 
     /*
@@ -115,20 +169,27 @@ SystemClock_Config(void)
     /* HSI calibration is not optional when HSI is enabled */
     osc_init.HSICalibrationValue = MYNEWT_VAL(STM32_CLOCK_HSI_CALIBRATION);
 
-#if MYNEWT_VAL(STM32_CLOCK_HSI) && \
-        !IS_RCC_CALIBRATION_VALUE(MYNEWT_VAL(STM32_CLOCK_HSI_CALIBRATION))
+#if (MYNEWT_VAL(STM32_CLOCK_HSI_CALIBRATION) > 127)
 #error "Invalid HSI calibration value"
 #endif
 #endif
 
     /*
-     * Default to HSE as source, when both HSE and HSI are enabled.
-     *
-     * TODO: option to let the PLL turned off could be added, because
-     * both HSI and HSE can be used as SYSCLK source.
+     * Can be used to drive USB and the TRNG
+     */
+#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_HSE)
+#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;
@@ -150,60 +211,56 @@ SystemClock_Config(void)
 #error "PLLQ 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);
-
-#if MYNEWT_VAL(STM32_CLOCK_PLL_PLLR)
-
 #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);
 
-#endif /* MYNEWT_VAL(STM32_CLOCK_PLL_PLLR) */
-
     status = HAL_RCC_OscConfig(&osc_init);
     if (status != HAL_OK) {
         assert(0);
     }
 
-#if MYNEWT_VAL(STM32_CLOCK_ENABLE_OVERDRIVE)
-    /*
-     * Activate the Over-Drive mode
-     */
-    status = HAL_PWREx_EnableOverDrive();
-    if (status != HAL_OK) {
-        assert(0);
-    }
-#endif
-
     /*
-     * Select PLL as system clock source and configure the HCLK, PCLK1 and
-     * PCLK2 clocks dividers. HSI and HSE are also valid system clock sources,
-     * although there is no much point in supporting them now.
+     * 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.ClockType = RCC_CLOCKTYPE_HCLK4 | RCC_CLOCKTYPE_HCLK2 |
+        RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 |
+        RCC_CLOCKTYPE_PCLK2;
     clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 
-#if !IS_RCC_HCLK(MYNEWT_VAL(STM32_CLOCK_AHB_DIVIDER))
+#if !IS_RCC_HCLKx(MYNEWT_VAL(STM32_CLOCK_AHB_DIVIDER))
 #error "AHB clock divider is invalid"
 #endif
 
-#if !IS_RCC_PCLK(MYNEWT_VAL(STM32_CLOCK_APB1_DIVIDER))
+#if !IS_RCC_PCLKx(MYNEWT_VAL(STM32_CLOCK_APB1_DIVIDER))
 #error "APB1 clock divider is invalid"
 #endif
 
-#if !IS_RCC_PCLK(MYNEWT_VAL(STM32_CLOCK_APB2_DIVIDER))
+#if !IS_RCC_PCLKx(MYNEWT_VAL(STM32_CLOCK_APB2_DIVIDER))
 #error "APB2 clock divider is invalid"
 #endif
 
+#if !IS_RCC_HCLKx(MYNEWT_VAL(STM32_CLOCK_AHBCLK2_DIVIDER))
+#error "HCLK2 divider is invalid"
+#endif
+
+#if !IS_RCC_HCLKx(MYNEWT_VAL(STM32_CLOCK_AHBCLK4_DIVIDER))
+#error "HCLK4 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);
+    clk_init.AHBCLK2Divider = MYNEWT_VAL(STM32_CLOCK_AHBCLK2_DIVIDER);
+    clk_init.AHBCLK4Divider = MYNEWT_VAL(STM32_CLOCK_AHBCLK4_DIVIDER);
 
 #if !IS_FLASH_LATENCY(MYNEWT_VAL(STM32_FLASH_LATENCY))
 #error "Flash latency value is invalid"
@@ -214,9 +271,10 @@ SystemClock_Config(void)
         assert(0);
     }
 
-#if ((MYNEWT_VAL(STM32_CLOCK_HSI) == 0) || (MYNEWT_VAL(STM32_CLOCK_HSE) == 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 oscillator; this must be done at the end because
+     * 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;
@@ -228,25 +286,39 @@ SystemClock_Config(void)
     osc_init.OscillatorType |= RCC_OSCILLATORTYPE_HSI;
     osc_init.HSIState = RCC_HSI_OFF;
 #endif
+#if (MYNEWT_VAL(STM32_CLOCK_HSI48) == 0)
+    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
-#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || \
-    defined(STM32F417xx)
-    /* RevA (prefetch must be off) or RevZ (prefetch can be on/off) */
-    if (HAL_GetREVID() == 0x1001) {
-        __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
-    }
-#else
     __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
 #endif
-#endif
 
 #if INSTRUCTION_CACHE_ENABLE
     __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
diff --git a/hw/mcu/stm/stm32wbxx/src/hal_flash.c 
b/hw/mcu/stm/stm32wbxx/src/hal_flash.c
new file mode 100644
index 0000000..2406563
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/src/hal_flash.c
@@ -0,0 +1,45 @@
+/*
+ * 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 <string.h>
+#include <syscfg/syscfg.h>
+#include <mcu/stm32_hal.h>
+#include "hal/hal_flash_int.h"
+
+#define _FLASH_SECTOR_SIZE  MYNEWT_VAL(STM32_FLASH_SECTOR_SIZE)
+
+int
+stm32_mcu_flash_erase_sector(const struct hal_flash *dev, uint32_t 
sector_address)
+{
+    FLASH_EraseInitTypeDef eraseinit;
+    uint32_t PageError;
+    HAL_StatusTypeDef rc;
+
+    if (!(sector_address & (_FLASH_SECTOR_SIZE - 1))) {
+        eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
+        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/stm32wbxx/src/hal_reset_cause.c 
b/hw/mcu/stm/stm32wbxx/src/hal_reset_cause.c
new file mode 100644
index 0000000..5c396f5
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/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 "stm32wbxx_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 WBxx 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/stm32wbxx/src/hal_timer_freq.c 
b/hw/mcu/stm/stm32wbxx/src/hal_timer_freq.c
new file mode 100644
index 0000000..ec9f7c1
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/src/hal_timer_freq.c
@@ -0,0 +1,74 @@
+/*
+ * 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 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
+        freq = HAL_RCC_GetPCLK1Freq();
+        if (clocks.APB1CLKDivider) {
+            freq *= 2;
+        }
+        break;
+    default:
+        return 0;
+    }
+    return freq;
+}
diff --git a/hw/mcu/stm/stm32wbxx/src/system_stm32wbxx.c 
b/hw/mcu/stm/stm32wbxx/src/system_stm32wbxx.c
new file mode 100644
index 0000000..8e729a8
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/src/system_stm32wbxx.c
@@ -0,0 +1,219 @@
+/*
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *                        opensource.org/licenses/BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include "bsp/stm32wbxx_hal_conf.h"
+#include "stm32wbxx.h"
+#include "mcu/cmsis_nvic.h"
+#include "mcu/stm32_hal.h"
+
+/* 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;
+const uint32_t AHBPrescTable[16] = {
+    1UL, 3UL, 5UL, 1UL, 1UL, 6UL, 10UL, 32UL, 2UL, 4UL, 8UL, 16UL, 64UL,
+    128UL, 256UL, 512UL,
+};
+const uint32_t APBPrescTable[8] = {
+    0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL,
+};
+/* 0UL values are incorrect cases */
+const uint32_t MSIRangeTable[16] = {
+    100000UL, 200000UL, 400000UL, 800000UL, 1000000UL, 2000000UL,
+    4000000UL, 8000000UL, 16000000UL, 24000000UL, 32000000UL, 48000000UL,
+    0UL, 0UL, 0UL, 0UL,
+};
+const uint32_t SmpsPrescalerTable[4][6] = {
+    { 1UL,3UL,2UL,2UL,1UL,2UL, },
+    { 2UL,6UL,4UL,3UL,2UL,4UL, },
+    { 4UL,12UL,8UL,6UL,4UL,8UL, },
+    { 4UL,12UL,8UL,6UL,4UL,8UL, },
+};
+
+/*
+ * XXX BSP specific
+ */
+void SystemClock_Config(void);
+
+/**
+  * @brief  Setup the microcontroller system.
+  *         Initialize the default HSI clock source, vector table location and 
the PLL configuration is reset.
+  * @param  None
+  * @retval None
+  */
+void SystemInit(void)
+{
+    #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+        /* Set CP10 and CP11 Full Access */
+        SCB->CPACR |= ((3UL << (10UL*2UL))|(3UL << (11UL*2UL)));
+    #endif
+
+    /*
+     * Reset the RCC clock configuration to the default reset state
+     */
+
+    /* Set MSION bit */
+    RCC->CR |= RCC_CR_MSION;
+
+    /* Reset CFGR register */
+    RCC->CFGR = 0x00070000U;
+
+    /* Reset PLLSAI1ON, PLLON, HSECSSON, HSEON, HSION, and MSIPLLON bits */
+    RCC->CR &= (uint32_t)0xFAF6FEFBU;
+
+    /* Reset LSI1 and LSI2 bits */
+    RCC->CSR &= (uint32_t)0xFFFFFFFAU;
+
+    /* Reset HSI48ON  bit */
+    RCC->CRRCR &= (uint32_t)0xFFFFFFFEU;
+
+    /* Reset PLLCFGR register */
+    RCC->PLLCFGR = 0x22041000U;
+
+    /* Reset PLLSAI1CFGR register */
+    RCC->PLLSAI1CFGR = 0x22041000U;
+
+    /* Reset HSEBYP bit */
+    RCC->CR &= 0xFFFBFFFFU;
+
+    /* Disable all interrupts */
+    RCC->CIER = 0x00000000;
+
+    /* 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 stm32wbxx_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 stm32wbxx_hal_conf.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 stm32wbxx_hal_conf.h file 
(default value
+  *              32 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 tmp;
+    uint32_t msirange;
+    uint32_t pllvco;
+    uint32_t pllr;
+    uint32_t pllsource;
+    uint32_t pllm;
+
+    /*
+     * Get MSI Range frequency
+     */
+
+    /* MSI frequency range in Hz */
+    msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> 
RCC_CR_MSIRANGE_Pos];
+
+    /*
+     * Get SYSCLK source
+     */
+    switch (RCC->CFGR & RCC_CFGR_SWS) {
+    /* HSI used as system clock source */
+    case 0x04:
+        SystemCoreClock = HSI_VALUE;
+        break;
+
+    /* HSE used as system clock source */
+    case 0x08:
+        SystemCoreClock = HSE_VALUE;
+        break;
+
+    /* PLL used as system clock  source */
+    case 0x0C:
+        /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
+         * SYSCLK = PLL_VCO / PLLR
+         */
+        pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
+        pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 
1UL;
+
+        if (pllsource == 0x02UL) {
+            /* HSI used as PLL clock source */
+            pllvco = (HSI_VALUE / pllm);
+        } else if (pllsource == 0x03UL) {
+            /* HSE used as PLL clock source */
+            pllvco = (HSE_VALUE / pllm);
+        } else {
+            /* MSI used as PLL clock source */
+            pllvco = (msirange / pllm);
+        }
+
+        pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 
RCC_PLLCFGR_PLLN_Pos);
+        pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 
1UL);
+        SystemCoreClock = pllvco/pllr;
+        break;
+
+    /* MSI used as system clock source */
+    default:
+        SystemCoreClock = msirange;
+        break;
+    }
+
+    /*
+     * Compute HCLK clock frequency
+     */
+
+    /* Get HCLK1 prescaler */
+    tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
+
+    /* HCLK clock frequency */
+    SystemCoreClock = SystemCoreClock / tmp;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF 
FILE****/
diff --git a/hw/mcu/stm/stm32wbxx/stm32wb55.ld 
b/hw/mcu/stm/stm32wbxx/stm32wb55.ld
new file mode 100644
index 0000000..11219cd
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/stm32wb55.ld
@@ -0,0 +1,203 @@
+/**
+*****************************************************************************
+**
+**  File        : stm32wb55xx_flash_cm4.ld
+**
+**  Abstract    : System Workbench Minimal System calls file
+**
+**                       For more information about which c-functions
+**                need which of these lowlevel functions
+**                please consult the Newlib libc-manual
+**
+**  Environment : System Workbench for MCU
+**
+**  Distribution: The file is distributed “as is,” without any warranty
+**                of any kind.
+**
+*****************************************************************************
+**
+** <h2><center>&copy; COPYRIGHT(c) 2019 Ac6</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 Ac6 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.
+**
+*****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+_estack = ORIGIN(RAM) + LENGTH(RAM);
+
+/* Define output sections */
+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))
+
+        /* .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*)
+
+        /* 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 = .);
+
+        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/stm32wbxx/syscfg.yml b/hw/mcu/stm/stm32wbxx/syscfg.yml
new file mode 100644
index 0000000..e2b04c7
--- /dev/null
+++ b/hw/mcu/stm/stm32wbxx/syscfg.yml
@@ -0,0 +1,199 @@
+# 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_STM32WB:
+        description: MCUs are of STM32WBxx family
+        value: 1
+
+    STM32_CLOCK_VOLTAGESCALING_CONFIG:
+        description: Adjust voltage scale
+        value: 0
+
+    STM32_CLOCK_LSI1:
+        description: Enable low-speed internal clock source
+        value: 0
+
+    STM32_CLOCK_LSI2:
+        description: Enable low-speed internal clock source
+        value: 0
+
+    STM32_CLOCK_LSI2_CALIBRATION:
+        description: LSI2 calibration value
+        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_MSICALIBRATION_DEFAULT'
+
+    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_HSEPRE:
+        description: Enable HSE prescaler divider
+        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_AHB_DIVIDER:
+        description: AHB CLK1 prescaler (64MHz max)
+        value: 0
+
+    STM32_CLOCK_APB1_DIVIDER:
+        description: APB low-speed prescaler (64MHz max)
+        value: 0
+
+    STM32_CLOCK_APB2_DIVIDER:
+        description: APB high-speed prescaler (64MHz max)
+        value: 0
+
+    STM32_CLOCK_AHBCLK2_DIVIDER:
+        description: AHB CLK2 prescaler (32MHz max)
+        value: 0
+
+    STM32_CLOCK_AHBCLK4_DIVIDER:
+        description: AHB CLK4 prescaler (64MHz max)
+        value: 0
+
+    STM32_FLASH_LATENCY:
+        description: Number of wait-states
+        value: 0
+
+    STM32_FLASH_PREFETCH_ENABLE:
+        description: Enable pre-fetch of instructions (when latency > 0)
+        value: 0
+
+    STM32_INSTRUCTION_CACHE_ENABLE:
+        description: Enable flash instruction cache
+        value: 0
+
+    STM32_DATA_CACHE_ENABLE:
+        description: Enable flash data cache
+        value: 0
+
+    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
+
+    STM32_FLASH_IS_LINEAR:
+        description: All flash sectors have same size.
+        value: 1
+
+    STM32_FLASH_SECTOR_SIZE:
+        description: This MCU's Flash sector size in bytes.
+        value: 4096
+
+    I2C_0:
+        description: 'I2C (TWI) interface I2C1'
+        value:  0
+
+    I2C_0_PIN_SCL:
+        description: 'SCL pin for I2C1, PB6, PB8, PG14'
+        value: MCU_GPIO_PORTB(8)
+
+    I2C_0_PIN_SDA:
+        description: 'SDA pin for I2C1, PB7, PB9, PG13'
+        value: MCU_GPIO_PORTB(9)
+
+    SPI_0_MASTER:
+        description: 'SPI 0 master'
+        value:  0
+        restrictions:
+            - "!SPI_0_SLAVE"
+    SPI_0_SLAVE:
+        description: 'SPI 0 slave'
+        value:  0
+        restrictions:
+            - "!SPI_0_MASTER"
+
+    TRNG:
+        description: 'Enable True Random Number Generator (RNG)'
+        value: 0
+
+    CRYPTO:
+        description: 'Enable HW Cryptography module (CRYP)'
+        value: 0

Reply via email to