Browse Source

soc: st: stm32: add STM32WB0 series

Adds support for the STM32WB0 MCU series.

Signed-off-by: Mathieu Choplain <mathieu.choplain@st.com>
pull/77806/head
Mathieu Choplain 1 year ago committed by Carles Cufí
parent
commit
16ab346f28
  1. 5
      soc/st/stm32/common/soc_config.c
  2. 6
      soc/st/stm32/soc.yml
  3. 10
      soc/st/stm32/stm32wb0x/CMakeLists.txt
  4. 15
      soc/st/stm32/stm32wb0x/Kconfig
  5. 11
      soc/st/stm32/stm32wb0x/Kconfig.defconfig
  6. 33
      soc/st/stm32/stm32wb0x/Kconfig.soc
  7. 22
      soc/st/stm32/stm32wb0x/ram_sections.ld
  8. 178
      soc/st/stm32/stm32wb0x/soc.c
  9. 22
      soc/st/stm32/stm32wb0x/soc.h

5
soc/st/stm32/common/soc_config.c

@ -14,6 +14,7 @@ @@ -14,6 +14,7 @@
#include <zephyr/arch/cpu.h>
#include <stm32_ll_system.h>
#include <stm32_ll_bus.h>
#include <stm32_ll_pwr.h>
/**
* @brief Perform SoC configuration at boot.
@ -80,6 +81,8 @@ static int st_stm32_common_config(void) @@ -80,6 +81,8 @@ static int st_stm32_common_config(void)
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_DBGMCU);
LL_DBGMCU_EnableDBGStopMode();
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_DBGMCU);
#elif defined(CONFIG_SOC_SERIES_STM32WB0X)
LL_PWR_EnableDEEPSTOP2();
#else /* all other parts */
LL_DBGMCU_EnableDBGStopMode();
#endif
@ -102,6 +105,8 @@ static int st_stm32_common_config(void) @@ -102,6 +105,8 @@ static int st_stm32_common_config(void)
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_DBGMCU);
LL_DBGMCU_DisableDBGStopMode();
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_DBGMCU);
#elif defined(CONFIG_SOC_SERIES_STM32WB0X)
LL_PWR_DisableDEEPSTOP2();
#else /* all other parts */
LL_DBGMCU_DisableDBGStopMode();
#endif

6
soc/st/stm32/soc.yml

@ -197,6 +197,12 @@ family: @@ -197,6 +197,12 @@ family:
- name: stm32wbx
socs:
- name: stm32wb55xx
- name: stm32wb0x
socs:
- name: stm32wb05
- name: stm32wb06
- name: stm32wb07
- name: stm32wb09
- name: stm32wbax
socs:
- name: stm32wba52xx

10
soc/st/stm32/stm32wb0x/CMakeLists.txt

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_sources(soc.c)
zephyr_include_directories(.)
zephyr_linker_sources(RAM_SECTIONS ram_sections.ld)
set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "")

15
soc/st/stm32/stm32wb0x/Kconfig

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
# STMicroelectronics STM32W0 MCU series
# Copyright (c) 2024 STMicroelectronics
# SPDX-License-Identifier: Apache-2.0
config SOC_SERIES_STM32WB0X
select ARM
select CPU_CORTEX_M0PLUS
select CPU_CORTEX_M_HAS_VTOR
select CPU_CORTEX_M_HAS_SYSTICK
select CPU_HAS_ARM_MPU
select HAS_STM32CUBE
# WB0x has a ROM bootloader executed at reset,
# which makes the following option required
select INIT_ARCH_HW_AT_BOOT

11
soc/st/stm32/stm32wb0x/Kconfig.defconfig

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
# STMicroelectronics STM32WB0 MCU series
# Copyright (c) 2024 STMicroelectronics
# SPDX-License-Identifier: Apache-2.0
if SOC_SERIES_STM32WB0X
config NUM_IRQS
default 32
endif # SOC_SERIES_STM32WB0X

33
soc/st/stm32/stm32wb0x/Kconfig.soc

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
# STMicroelectronics STM32WB0 MCU series
# Copyright (c) 2024 STMicroelectronics
# SPDX-License-Identifier: Apache-2.0
config SOC_SERIES_STM32WB0X
bool
select SOC_FAMILY_STM32
config SOC_SERIES
default "stm32wb0x" if SOC_SERIES_STM32WB0X
config SOC_STM32WB05XX
bool
select SOC_SERIES_STM32WB0X
config SOC_STM32WB06XX
bool
select SOC_SERIES_STM32WB0X
config SOC_STM32WB07XX
bool
select SOC_SERIES_STM32WB0X
config SOC_STM32WB09XX
bool
select SOC_SERIES_STM32WB0X
config SOC
default "stm32wb05" if SOC_STM32WB05XX
default "stm32wb06" if SOC_STM32WB06XX
default "stm32wb07" if SOC_STM32WB07XX
default "stm32wb09" if SOC_STM32WB09XX

22
soc/st/stm32/stm32wb0x/ram_sections.ld

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
/*
* Copyright (c) 2024 STMicroelectronics
*
* SPDX-License-Identifier: Apache-2.0
*/
/** Refer to `soc.c` for more information about these areas. */
SECTION_PROLOGUE(stm32wb0_RAM_VR, 0x20000000 (NOLOAD), )
{
/* For historical reasons, leave the first word of
* SRAM0 unused, even though it could store data.
* The structure MUST start at address 0x2000_0004.
*/
. += 4;
KEEP(*(stm32wb0_RAM_VR));
} GROUP_LINK_IN(RAMABLE_REGION)
SECTION_PROLOGUE(stm32wb0_BLUE_RAM, 0x200000C0 (NOLOAD), )
{
KEEP(*(stm32wb0_BLUE_RAM));
} GROUP_LINK_IN(RAMABLE_REGION)

178
soc/st/stm32/stm32wb0x/soc.c

@ -0,0 +1,178 @@ @@ -0,0 +1,178 @@
/*
* Copyright (c) 2024 STMicroelectronics
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief System/hardware module for STM32WB0 processor
*/
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <stm32_ll_bus.h>
#include <stm32_ll_pwr.h>
#include <stm32_ll_system.h>
#include <stm32_ll_radio.h>
#include <zephyr/logging/log.h>
#include <zephyr/toolchain.h>
#include <cmsis_core.h>
#include <stdint.h>
#include <system_stm32wb0x.h>
#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL
LOG_MODULE_REGISTER(soc);
/**
* CMSIS System Core Clock: global variable holding the system core clock,
* which is the frequency supplied to the SysTick timer and processor core.
*
* On STM32WB0 series, after RESET, the system clock frequency is 16MHz.
*/
uint32_t SystemCoreClock = 16000000U;
/**
* RAM Virtual Register: special structure located at the start
* of SRAM0; used by the UART bootloader and the Low Power Manager.
* Data type definition comes from @ref system_stm32wb0xx.h
*/
Z_GENERIC_SECTION("stm32wb0_RAM_VR")
__used RAM_VR_TypeDef RAM_VR;
/** Power Controller node */
#define PWRC DT_INST(0, st_stm32wb0_pwr)
/** SMPS modes */
#define STM32WB0_SMPS_MODE_OFF 0
#define STM32WB0_SMPS_MODE_PRECHARGE 1
#define STM32WB0_SMPS_MODE_RUN 2
#define SMPS_MODE _CONCAT(STM32WB0_SMPS_MODE_, DT_STRING_UNQUOTED(PWRC, smps_mode))
/* Convert DTS properties to LL macros */
#define SMPS_PRESCALER _CONCAT(LL_RCC_SMPS_DIV_, DT_PROP(PWRC, smps_clock_prescaler))
#if SMPS_MODE != STM32WB0_SMPS_MODE_OFF
BUILD_ASSERT(DT_NODE_HAS_PROP(PWRC, smps_bom),
"smps-bom must be specified");
#define SMPS_BOM \
_CONCAT(LL_PWR_SMPS_BOM, DT_PROP(PWRC, smps_bom))
#define SMPS_LP_MODE \
COND_CODE_1( \
DT_PROP(PWRC, smps_lp_floating), \
(LL_PWR_SMPS_LPOPEN), \
(LL_PWR_NO_SMPS_LPOPEN))
#define SMPS_CURRENT_LIMIT \
_CONCAT(LL_PWR_SMPS_PRECH_LIMIT_CUR_, \
DT_STRING_UNQUOTED(PWRC, smps_current_limit))
#define SMPS_OUTPUT_VOLTAGE \
_CONCAT(LL_PWR_SMPS_OUTPUT_VOLTAGE_, \
DT_STRING_UNQUOTED(PWRC, smps_output_voltage))
#endif /* SMPS_MODE != STM32WB0_SMPS_MODE_OFF */
static void configure_smps(void)
{
/* Configure SMPS clock prescaler */
LL_RCC_SetSMPSPrescaler(SMPS_PRESCALER);
#if SMPS_MODE == STM32WB0_SMPS_MODE_OFF
/* Disable SMPS */
LL_PWR_SetSMPSMode(LL_PWR_NO_SMPS);
while (LL_PWR_IsSMPSReady()) {
/* Wait for SMPS to turn off */
}
#else
/* Select correct BOM */
LL_PWR_SetSMPSBOM(SMPS_BOM);
/* Configure low-power mode */
LL_PWR_SetSMPSOpenMode(SMPS_LP_MODE);
/* Enable SMPS */
LL_PWR_SetSMPSMode(LL_PWR_SMPS);
while (!LL_PWR_IsSMPSReady()) {
/* Wait for SMPS to turn on */
}
/* Place SMPS in PRECHARGE (BYPASS) mode.
* This is required to change SMPS output voltage,
* so we can do it unconditionally.
*/
LL_PWR_SetSMPSPrechargeMode(LL_PWR_SMPS_PRECHARGE);
while (LL_PWR_IsSMPSinRUNMode()) {
/* Wait for SMPS to enter PRECHARGE mode */
}
if (SMPS_MODE == STM32WB0_SMPS_MODE_PRECHARGE) {
/**
* SMPS should remain in PRECHARGE mode, but
* we still have to configure the current limit.
*/
LL_PWR_SetSMPSPrechargeLimitCurrent(SMPS_CURRENT_LIMIT);
} else {
/**
* SMPS mode requested is RUN mode. Configure the output
* voltage to the desired value then exit PRECHARGE mode.
*/
LL_PWR_SMPS_SetOutputVoltageLevel(SMPS_OUTPUT_VOLTAGE);
/* Exit PRECHARGE mode (returns in RUN mode) */
LL_PWR_SetSMPSPrechargeMode(LL_PWR_NO_SMPS_PRECHARGE);
while (!LL_PWR_IsSMPSinRUNMode()) {
/* Wait for SMPS to enter RUN mode */
}
}
#endif /* SMPS_MODE == STM32WB0_SMPS_MODE_OFF */
}
/**
* @brief Perform basic hardware initialization at boot.
*
* This needs to be run from the very beginning,
* so the init priority has to be 0 (zero).
*
* @return 0
*/
static int stm32wb0_init(void)
{
/* Update CMSIS SystemCoreClock variable (CLK_SYS) */
/* On reset, the 64MHz HSI is selected as input to
* the SYSCLKPRE prescaler, set to 4, resulting in
* CLK_SYS being equal to 16MHz.
*/
SystemCoreClock = 16000000U;
/* Remap address 0 to user flash memory */
LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_FLASH);
/**
* Save application exception vector address in RAM_VR.
* By now, SCB->VTOR should point to _vector_table,
* so use that value instead of _vector_table directly.
*/
RAM_VR.AppBase = SCB->VTOR;
/* Enable retention of all RAM banks in Deepstop */
LL_PWR_EnableRAMBankRet(LL_PWR_RAMRET_1);
#if defined(LL_PWR_RAMRET_2)
LL_PWR_EnableRAMBankRet(LL_PWR_RAMRET_2);
#endif
#if defined(LL_PWR_RAMRET_3)
LL_PWR_EnableRAMBankRet(LL_PWR_RAMRET_3);
#endif
/* Configure SMPS step-down converter */
configure_smps();
return 0;
}
SYS_INIT(stm32wb0_init, PRE_KERNEL_1, 0);

22
soc/st/stm32/stm32wb0x/soc.h

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
/*
* Copyright (c) 2024 STMicroelectronics
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file SoC configuration macros for the STM32WB0 family processors.
*
*/
#ifndef _STM32WB0_SOC_H_
#define _STM32WB0_SOC_H_
#ifndef _ASMLANGUAGE
#include <stm32wb0x.h>
#endif /* !_ASMLANGUAGE */
#endif /* _STM32WB0_SOC_H_ */
Loading…
Cancel
Save