From 00f9bfbbaad2af8bd5a0aaadaeff6eb13825f833 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 11 Oct 2024 16:07:46 +0200 Subject: [PATCH] samples: boards: power_mgmt use wakeup pins of the stm32l4x boards This PR is changing the method to use the user button to be the wakeup source to exit from lower power mode Signed-off-by: Francois Ramu --- .../st/power_mgmt/standby_shutdown/README.rst | 21 ++++---- .../boards/disco_l475_iot1.overlay | 17 +++++++ .../boards/nucleo_l476rg.overlay | 17 +++++++ .../st/power_mgmt/standby_shutdown/prj.conf | 1 + .../st/power_mgmt/standby_shutdown/src/main.c | 50 +++++++------------ 5 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 samples/boards/st/power_mgmt/standby_shutdown/boards/disco_l475_iot1.overlay create mode 100644 samples/boards/st/power_mgmt/standby_shutdown/boards/nucleo_l476rg.overlay diff --git a/samples/boards/st/power_mgmt/standby_shutdown/README.rst b/samples/boards/st/power_mgmt/standby_shutdown/README.rst index 22a162f55d4b..ac19b1020d49 100644 --- a/samples/boards/st/power_mgmt/standby_shutdown/README.rst +++ b/samples/boards/st/power_mgmt/standby_shutdown/README.rst @@ -7,13 +7,15 @@ Overview ******** -This sample is a minimum application to demonstrate basic power management of Standby mode and -shutdown mode -behavior in a basic blinking LED set up you can enter in shutdown mode or in standbymode mode. -Press and hold the user button: -when LED2 is OFF to enter to Shutdown Mode -when LED2 is ON to enter to Standby Mode -release the user button to exit from shutdown mode or from shutdown mode. +This sample is a minimum application to demonstrate basic power management of Standby mode and shutdown mode +with WakeUp pins. +User push-button is configured in gpio with interrupt and callback in a basic blinking LED loop. +User can select the low power mode by pressing and holding the push-button: +- when LED2 is OFF, to enter Shutdown Mode +- when LED2 is ON, to enter Standby Mode +The push button is now being configured as WakeUp Source (WakeUp pin) +and system enters in the selected low power mode. +User shall release the push button to exit from standby or from shutdown mode. .. _stm32-pm-standby_shutdown-sample-requirements: @@ -23,7 +25,8 @@ Requirements The board should support enabling PM. For a STM32 based target, it means that it should support a clock source alternative to Cortex Systick that can be used in core sleep states, as LPTIM (:dtcompatible:`st,stm32-lptim`). -For another board than nucleo_L476RG please adjust wakeup pin into config_wakeup_features(). +For another board than nucleo_L476RG please adjust wakeup pin source through wkup-src alias. +Requires wkup-pin to be defined in the &pwr of the board DTS Building and Running ******************** @@ -32,7 +35,7 @@ Build and flash standby_shutdown as follows, changing ``nucleo_L476RG`` for your .. zephyr-app-commands:: :zephyr-app: samples/boards/st/power_mgmt/standby_shutdown - :board: nucleo_L476RG + :board: nucleo_l476rg :goals: build flash :compact: diff --git a/samples/boards/st/power_mgmt/standby_shutdown/boards/disco_l475_iot1.overlay b/samples/boards/st/power_mgmt/standby_shutdown/boards/disco_l475_iot1.overlay new file mode 100644 index 000000000000..356bb255a7c8 --- /dev/null +++ b/samples/boards/st/power_mgmt/standby_shutdown/boards/disco_l475_iot1.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + wkup-src = &user_button; + }; +}; + +&pwr { + status = "okay"; + /delete-property/ wkup-pins-pol; + /delete-property/ wkup-pins-pupd; +}; diff --git a/samples/boards/st/power_mgmt/standby_shutdown/boards/nucleo_l476rg.overlay b/samples/boards/st/power_mgmt/standby_shutdown/boards/nucleo_l476rg.overlay new file mode 100644 index 000000000000..356bb255a7c8 --- /dev/null +++ b/samples/boards/st/power_mgmt/standby_shutdown/boards/nucleo_l476rg.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + wkup-src = &user_button; + }; +}; + +&pwr { + status = "okay"; + /delete-property/ wkup-pins-pol; + /delete-property/ wkup-pins-pupd; +}; diff --git a/samples/boards/st/power_mgmt/standby_shutdown/prj.conf b/samples/boards/st/power_mgmt/standby_shutdown/prj.conf index 885312c4353b..bacbf2383a22 100644 --- a/samples/boards/st/power_mgmt/standby_shutdown/prj.conf +++ b/samples/boards/st/power_mgmt/standby_shutdown/prj.conf @@ -3,3 +3,4 @@ CONFIG_PM_DEVICE=n CONFIG_PM_DEVICE_RUNTIME=n CONFIG_HWINFO=y CONFIG_POWEROFF=y +CONFIG_STM32_WKUP_PINS=y diff --git a/samples/boards/st/power_mgmt/standby_shutdown/src/main.c b/samples/boards/st/power_mgmt/standby_shutdown/src/main.c index c26a33b64a63..13902e768426 100644 --- a/samples/boards/st/power_mgmt/standby_shutdown/src/main.c +++ b/samples/boards/st/power_mgmt/standby_shutdown/src/main.c @@ -13,50 +13,30 @@ #include #include #include - -#if !defined(CONFIG_SOC_SERIES_STM32L4X) -#error Not implemented for other series -#endif /* CONFIG_SOC_SERIES_STM32L4X */ +#include #define STACKSIZE 1024 #define PRIORITY 7 #define SLEEP_TIME_MS 3000 -#define SW0_NODE DT_ALIAS(sw0) -#if !DT_NODE_HAS_STATUS_OKAY(SW0_NODE) -#error "Unsupported board: sw0 devicetree alias is not defined" +#define WKUP_SRC_NODE DT_ALIAS(wkup_src) +#if !DT_NODE_HAS_STATUS_OKAY(WKUP_SRC_NODE) +#error "Unsupported board: wkup_src devicetree alias is not defined" #endif + /* Semaphore used to control button pressed value */ static struct k_sem button_sem; static int led_is_on; -static const struct gpio_dt_spec button = - GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, {0}); +static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET(WKUP_SRC_NODE, gpios); static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); static struct gpio_callback button_cb_data; -void config_wakeup_features(void) -{ - /* - * Configure wake-up features : WKUP2(PC13) only - * - * The Following Wakeup sequence is highly recommended prior to each Standby mode entry - * mainly when using more than one wakeup source this is to not miss any wakeup event: - * - Disable all used wakeup sources, - * - Clear all related wakeup flags, - * - Re-enable all used wakeup sources, - * - Enter the Standby mode. - */ - LL_PWR_DisableWakeUpPin(LL_PWR_WAKEUP_PIN2); - LL_PWR_ClearFlag_WU(); /* Clear wakeup flags */ - LL_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN2); -} - void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins) { @@ -69,7 +49,12 @@ void thread_poweroff_standby_mode(void) k_sem_take(&button_sem, K_FOREVER); gpio_pin_configure(led.port, led.pin, GPIO_DISCONNECTED); printk("User button pressed\n"); - config_wakeup_features(); + + /* Setup button GPIO pin as a wakeup Source for exiting low power mode */ + if (gpio_pin_configure_dt(&button, STM32_GPIO_WKUP) != 0) { + printk("Failed to configure wakeup source\n"); + return; + } if (led_is_on == false) { printk("Powering off\n"); printk("Release the user button to wake-up\n\n"); @@ -102,17 +87,17 @@ int main(void) if (cause == RESET_LOW_POWER_WAKE) { hwinfo_clear_reset_cause(); - printk("\nReset cause: Standby mode\n\n"); + printk("\nReset cause: Standby mode\n"); } if (cause == (RESET_PIN | RESET_BROWNOUT)) { - printk("\nReset cause: Shutdown mode or power up\n\n"); + printk("\nReset cause: Shutdown mode or power up\n"); } if (cause == RESET_PIN) { - printk("\nReset cause: Reset pin\n\n"); + printk("\nReset cause: Reset pin\n"); } /* After flashing the reset cause is 0x3 : RESET_SOFTWARE | RESET_PIN */ if ((cause & RESET_SOFTWARE) == RESET_SOFTWARE) { - printk("\nReset cause: Reset soft\n\n"); + printk("\nReset cause: Reset soft\n"); } __ASSERT_NO_MSG(gpio_is_ready_dt(&led)); @@ -122,13 +107,13 @@ int main(void) return 0; } + /* Configure button to detect key pressed = low power mode selection */ ret = gpio_pin_configure_dt(&button, GPIO_INPUT); if (ret != 0) { printk("Error %d: failed to configure %s pin %d\n", ret, button.port->name, button.pin); return 0; } - ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE); if (ret != 0) { @@ -136,7 +121,6 @@ int main(void) ret, button.port->name, button.pin); return 0; } - gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin)); gpio_add_callback(button.port, &button_cb_data);