diff --git a/soc/st/stm32/common/soc_config.c b/soc/st/stm32/common/soc_config.c index 6e5650850b4..02bff949544 100644 --- a/soc/st/stm32/common/soc_config.c +++ b/soc/st/stm32/common/soc_config.c @@ -14,6 +14,7 @@ #include #include #include +#include /** * @brief Perform SoC configuration at boot. @@ -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) 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 diff --git a/soc/st/stm32/soc.yml b/soc/st/stm32/soc.yml index d9d81881848..f1c625a1569 100644 --- a/soc/st/stm32/soc.yml +++ b/soc/st/stm32/soc.yml @@ -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 diff --git a/soc/st/stm32/stm32wb0x/CMakeLists.txt b/soc/st/stm32/stm32wb0x/CMakeLists.txt new file mode 100644 index 00000000000..8cdf2982e14 --- /dev/null +++ b/soc/st/stm32/stm32wb0x/CMakeLists.txt @@ -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 "") diff --git a/soc/st/stm32/stm32wb0x/Kconfig b/soc/st/stm32/stm32wb0x/Kconfig new file mode 100644 index 00000000000..5816f0b83b4 --- /dev/null +++ b/soc/st/stm32/stm32wb0x/Kconfig @@ -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 diff --git a/soc/st/stm32/stm32wb0x/Kconfig.defconfig b/soc/st/stm32/stm32wb0x/Kconfig.defconfig new file mode 100644 index 00000000000..01c32f34046 --- /dev/null +++ b/soc/st/stm32/stm32wb0x/Kconfig.defconfig @@ -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 diff --git a/soc/st/stm32/stm32wb0x/Kconfig.soc b/soc/st/stm32/stm32wb0x/Kconfig.soc new file mode 100644 index 00000000000..78a50047002 --- /dev/null +++ b/soc/st/stm32/stm32wb0x/Kconfig.soc @@ -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 diff --git a/soc/st/stm32/stm32wb0x/ram_sections.ld b/soc/st/stm32/stm32wb0x/ram_sections.ld new file mode 100644 index 00000000000..c85b3301a32 --- /dev/null +++ b/soc/st/stm32/stm32wb0x/ram_sections.ld @@ -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) diff --git a/soc/st/stm32/stm32wb0x/soc.c b/soc/st/stm32/stm32wb0x/soc.c new file mode 100644 index 00000000000..fbc8dc212c1 --- /dev/null +++ b/soc/st/stm32/stm32wb0x/soc.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for STM32WB0 processor + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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); diff --git a/soc/st/stm32/stm32wb0x/soc.h b/soc/st/stm32/stm32wb0x/soc.h new file mode 100644 index 00000000000..57d14e761c3 --- /dev/null +++ b/soc/st/stm32/stm32wb0x/soc.h @@ -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 + +#endif /* !_ASMLANGUAGE */ + +#endif /* _STM32WB0_SOC_H_ */