Skip to content

Commit e4e666b

Browse files
jurenatkartben
authored andcommitted
soc: st: stm32: stm32c0x: Add stop mode support
Enables low power stop mode for C0. Code is taken from F4 family, tested on nucleo-c71rb with samples/basic/blinky. Power consumption in run mode 3.7 mA, in stop mode ~87 uA. Signed-off-by: Tomáš Juřena <[email protected]>
1 parent e38ba02 commit e4e666b

File tree

5 files changed

+82
-0
lines changed

5 files changed

+82
-0
lines changed

soc/st/stm32/stm32c0x/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ zephyr_sources(
66
)
77

88
zephyr_sources_ifdef(CONFIG_POWEROFF poweroff.c)
9+
zephyr_sources_ifdef(CONFIG_PM power.c)
910

1011
zephyr_include_directories(.)
1112

soc/st/stm32/stm32c0x/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ config SOC_SERIES_STM32C0X
1010
select CPU_HAS_ARM_MPU
1111
select HAS_STM32CUBE
1212
select CPU_CORTEX_M_HAS_SYSTICK
13+
select HAS_PM
1314
select HAS_POWEROFF
1415
select SOC_EARLY_INIT_HOOK

soc/st/stm32/stm32c0x/Kconfig.defconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,14 @@ if SOC_SERIES_STM32C0X
77

88
rsource "Kconfig.defconfig.stm32c0*"
99

10+
if PM
11+
12+
config COUNTER
13+
default y
14+
15+
config COUNTER_RTC_STM32_SUBSECONDS
16+
default y if DT_HAS_ST_STM32_RTC_ENABLED
17+
18+
endif # PM
19+
1020
endif # SOC_SERIES_STM32C0X

soc/st/stm32/stm32c0x/power.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2023 Google LLC
3+
* Copyright (c) 2025 Tomas Jurena
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#include <clock_control/clock_stm32_ll_common.h>
9+
#include <soc.h>
10+
11+
#include <stm32c0xx_ll_cortex.h>
12+
#include <stm32c0xx_ll_pwr.h>
13+
#include <stm32c0xx.h>
14+
15+
#include <zephyr/kernel.h>
16+
#include <zephyr/logging/log.h>
17+
18+
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
19+
20+
BUILD_ASSERT(DT_SAME_NODE(DT_CHOSEN(zephyr_cortex_m_idle_timer), DT_NODELABEL(rtc)),
21+
"STM32C0x series needs RTC as an additional IDLE timer for power management");
22+
23+
void pm_state_set(enum pm_state state, uint8_t substate_id)
24+
{
25+
ARG_UNUSED(substate_id);
26+
27+
switch (state) {
28+
case PM_STATE_SUSPEND_TO_IDLE:
29+
LL_LPM_DisableEventOnPend();
30+
LL_PWR_ClearFlag_WU();
31+
32+
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP0);
33+
LL_LPM_EnableDeepSleep();
34+
35+
k_cpu_idle();
36+
37+
break;
38+
default:
39+
LOG_WRN("Unsupported power state %u", state);
40+
break;
41+
}
42+
}
43+
44+
void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
45+
{
46+
ARG_UNUSED(substate_id);
47+
48+
switch (state) {
49+
case PM_STATE_SUSPEND_TO_IDLE:
50+
LL_LPM_DisableSleepOnExit();
51+
LL_LPM_EnableSleep();
52+
53+
/* Restore the clock setup. */
54+
stm32_clock_control_init(NULL);
55+
break;
56+
default:
57+
LOG_WRN("Unsupported power substate-id %u", state);
58+
break;
59+
}
60+
61+
/*
62+
* System is now in active mode. Reenable interrupts which were
63+
* disabled when OS started idling code.
64+
*/
65+
irq_unlock(0);
66+
}

soc/st/stm32/stm32c0x/soc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <zephyr/linker/linker-defs.h>
1515
#include <string.h>
1616

17+
#include <stm32_ll_bus.h>
1718
#include <stm32_ll_system.h>
1819

1920
#include <cmsis_core.h>
@@ -32,4 +33,7 @@ void soc_early_init_hook(void)
3233
/* Update CMSIS SystemCoreClock variable (HCLK) */
3334
/* At reset, system core clock is set to 48 MHz from HSI */
3435
SystemCoreClock = 48000000;
36+
37+
/* Enable PWR clock */
38+
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
3539
}

0 commit comments

Comments
 (0)