Skip to content

Commit 4f69acc

Browse files
Oleh-Kravchenkokartben
authored andcommitted
soc: stm32f1x: Add support for stop/standby modes
Add config and overlay to samples for testing stop/standby modes: - samples/boards/st/power_mgmt/blinky - samples/boards/st/power_mgmt/wkup_pins I've measured consumption for each low-power mode: - stop (regulator in run mode) ~217 uA - stop (regulator in low-power mode) ~206 uA - standby mode ~3.5 uA Low-power mode wakeup timings from the datasheet, but it barely meets these in reality: - stop (regulator in run mode) 3.6 us - stop (regulator in low-power mode) 5.4 us - standby 50 us It's possible to use RTC as idle timer to exit from stop mode. Signed-off-by: Oleh Kravchenko <oleg@kaa.org.ua>
1 parent 90a48e8 commit 4f69acc

File tree

10 files changed

+182
-5
lines changed

10 files changed

+182
-5
lines changed

dts/arm/st/f1/stm32f1.dtsi

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
#include <zephyr/dt-bindings/adc/stm32f1_adc.h>
1616
#include <zephyr/dt-bindings/reset/stm32f0_1_3_reset.h>
1717
#include <zephyr/dt-bindings/adc/adc.h>
18+
#include <zephyr/dt-bindings/power/stm32_pwr.h>
1819
#include <freq.h>
1920

2021
/ {
2122
chosen {
2223
zephyr,flash-controller = &flash;
24+
zephyr,cortex-m-idle-timer = &rtc;
2325
};
2426

2527
cpus {
@@ -29,8 +31,27 @@
2931
cpu0: cpu@0 {
3032
device_type = "cpu";
3133
compatible = "arm,cortex-m3";
34+
cpu-power-states = <&stop0 &stop1>;
3235
reg = <0>;
3336
};
37+
38+
power-states {
39+
stop0: stop0 {
40+
compatible = "zephyr,power-state";
41+
power-state-name = "suspend-to-idle";
42+
substate-id = <0>;
43+
min-residency-us = <1000000>;
44+
exit-latency-us = <400>;
45+
};
46+
47+
stop1: stop1 {
48+
compatible = "zephyr,power-state";
49+
power-state-name = "suspend-to-idle";
50+
substate-id = <1>;
51+
min-residency-us = <1000000>;
52+
exit-latency-us = <600>;
53+
};
54+
};
3455
};
3556

3657
sram0: memory@20000000 {
@@ -362,6 +383,22 @@
362383
};
363384
};
364385

386+
pwr: power@40007000 {
387+
compatible = "st,stm32-pwr";
388+
reg = <0x40007000 0x400>; /* PWR register bank */
389+
status = "disabled";
390+
391+
wkup-pins-nb = <1>;
392+
393+
#address-cells = <1>;
394+
#size-cells = <0>;
395+
396+
wkup-pin@1 {
397+
reg = <0x1>;
398+
wkup-gpios = <&gpioa 0 STM32_PWR_WKUP_PIN_NOT_MUXED>;
399+
};
400+
};
401+
365402
die_temp: dietemp {
366403
compatible = "st,stm32-temp";
367404
io-channels = <&adc1 16>;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) 2025 Oleh Kravchenko <oleh@kaa.org.ua>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
aliases {
9+
wkup-src = &wkup_button;
10+
};
11+
12+
gpio_keys {
13+
wkup_button: wkup {
14+
label = "WKUP";
15+
gpios = <&gpioa 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
16+
zephyr,code = <INPUT_KEY_POWER>;
17+
};
18+
};
19+
};
20+
21+
&pwr {
22+
status = "okay";
23+
};

samples/boards/st/power_mgmt/wkup_pins/sample.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ tests:
1111
- nucleo_u575zi_q
1212
- nucleo_u5a5zj_q
1313
- nucleo_wl55jc
14+
- nucleo_f103rb
1415
integration_platforms:
1516
- nucleo_l4r5zi

soc/st/stm32/common/soc_config.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ static int st_stm32_common_config(void)
6969

7070
#if defined(CONFIG_STM32_ENABLE_DEBUG_SLEEP_STOP)
7171

72-
#if defined(CONFIG_SOC_SERIES_STM32H7X)
72+
#if defined(SOC_SERIES_STM32F1X)
73+
LL_DBGMCU_EnableDBGSleepMode();
74+
LL_DBGMCU_EnableDBGStopMode();
75+
LL_DBGMCU_EnableDBGStandbyMode();
76+
#elif defined(CONFIG_SOC_SERIES_STM32H7X)
7377
LL_DBGMCU_EnableD1DebugInStopMode();
7478
LL_DBGMCU_EnableD1DebugInSleepMode();
7579
#elif defined(CONFIG_SOC_SERIES_STM32MP1X)
@@ -85,7 +89,11 @@ static int st_stm32_common_config(void)
8589
#else
8690

8791
/* keeping in mind that debugging draws a lot of power we explcitly disable when not needed */
88-
#if defined(CONFIG_SOC_SERIES_STM32H7X)
92+
#if defined(SOC_SERIES_STM32F1X)
93+
LL_DBGMCU_DisableDBGSleepMode();
94+
LL_DBGMCU_DisableDBGStopMode();
95+
LL_DBGMCU_DisableDBGStandbyMode();
96+
#elif defined(CONFIG_SOC_SERIES_STM32H7X)
8997
LL_DBGMCU_DisableD1DebugInStopMode();
9098
LL_DBGMCU_DisableD1DebugInSleepMode();
9199
#elif defined(CONFIG_SOC_SERIES_STM32MP1X)

soc/st/stm32/stm32f1x/CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# SPDX-License-Identifier: Apache-2.0
22

33
zephyr_include_directories(${ZEPHYR_BASE}/drivers)
4-
zephyr_sources(
5-
soc.c
6-
)
4+
zephyr_sources(soc.c)
5+
6+
zephyr_sources_ifdef(CONFIG_PM power.c)
7+
zephyr_sources_ifdef(CONFIG_POWEROFF poweroff.c)
78

89
zephyr_include_directories(.)
910

soc/st/stm32/stm32f1x/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ config SOC_SERIES_STM32F1X
88
select CPU_CORTEX_M3
99
select CPU_CORTEX_M_HAS_DWT
1010
select HAS_STM32CUBE
11+
select HAS_PM
12+
select HAS_POWEROFF
1113
select HAS_SWO
1214
select SOC_EARLY_INIT_HOOK

soc/st/stm32/stm32f1x/Kconfig.defconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,11 @@ config TASK_WDT_HW_FALLBACK_DELAY
1414
depends on TASK_WDT_HW_FALLBACK
1515
default 200
1616

17+
if PM
18+
19+
config COUNTER
20+
default y
21+
22+
endif # PM
23+
1724
endif # SOC_SERIES_STM32F1X

soc/st/stm32/stm32f1x/power.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2025 Oleh Kravchenko <oleh@kaa.org.ua>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <clock_control/clock_stm32_ll_common.h>
8+
#include <stm32f1xx_ll_cortex.h>
9+
#include <stm32f1xx_ll_pwr.h>
10+
11+
#include <zephyr/kernel.h>
12+
#include <zephyr/logging/log.h>
13+
#include <zephyr/pm/pm.h>
14+
15+
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
16+
17+
__weak void pm_state_set(enum pm_state state, uint8_t substate_id)
18+
{
19+
switch (state) {
20+
case PM_STATE_SUSPEND_TO_IDLE:
21+
LL_LPM_DisableEventOnPend();
22+
LL_PWR_ClearFlag_WU();
23+
24+
if (substate_id == 0) {
25+
/* 250 uA */
26+
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP_MAINREGU);
27+
} else {
28+
/* 245 uA */
29+
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP_LPREGU);
30+
}
31+
32+
LL_LPM_EnableDeepSleep();
33+
k_cpu_idle();
34+
break;
35+
36+
default:
37+
LOG_DBG("Unsupported power state %u", state);
38+
break;
39+
}
40+
}
41+
42+
__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
43+
{
44+
ARG_UNUSED(substate_id);
45+
46+
switch (state) {
47+
case PM_STATE_SUSPEND_TO_IDLE:
48+
LL_LPM_DisableSleepOnExit();
49+
LL_LPM_EnableSleep();
50+
51+
/* Restore the clock setup. */
52+
stm32_clock_control_init(NULL);
53+
break;
54+
55+
default:
56+
LOG_DBG("Unsupported power substate-id %u", state);
57+
break;
58+
}
59+
60+
/*
61+
* System is now in active mode. Reenable interrupts which were
62+
* disabled when OS started idling code.
63+
*/
64+
irq_unlock(0);
65+
}

soc/st/stm32/stm32f1x/poweroff.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2025 Oleh Kravchenko <oleh@kaa.org.ua>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stm32f1xx_ll_cortex.h>
8+
#include <stm32f1xx_ll_pwr.h>
9+
10+
#include <zephyr/drivers/misc/stm32_wkup_pins/stm32_wkup_pins.h>
11+
#include <zephyr/sys/poweroff.h>
12+
13+
void z_sys_poweroff(void)
14+
{
15+
#ifdef CONFIG_STM32_WKUP_PINS
16+
stm32_pwr_wkup_pin_cfg_pupd();
17+
18+
LL_PWR_ClearFlag_WU();
19+
#endif /* CONFIG_STM32_WKUP_PINS */
20+
21+
LL_LPM_DisableEventOnPend();
22+
LL_PWR_SetPowerMode(LL_PWR_MODE_STANDBY);
23+
LL_LPM_EnableDeepSleep();
24+
25+
k_cpu_idle();
26+
27+
CODE_UNREACHABLE;
28+
}

soc/st/stm32/stm32f1x/soc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <zephyr/init.h>
1414

1515
#include <stm32_ll_system.h>
16+
#include <stm32f1xx_ll_bus.h>
1617

1718
#include <cmsis_core.h>
1819

@@ -31,4 +32,8 @@ void soc_early_init_hook(void)
3132
/* Update CMSIS SystemCoreClock variable (HCLK) */
3233
/* At reset, system core clock is set to 8 MHz from HSI */
3334
SystemCoreClock = 8000000;
35+
36+
#if defined(CONFIG_PM) || defined(CONFIG_POWEROFF)
37+
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
38+
#endif
3439
}

0 commit comments

Comments
 (0)