Skip to content

Commit

Permalink
samples: boards: power_mgmt use wakeup pins of the stm32l4x boards
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
FRASTM committed Oct 15, 2024
1 parent d99b5d4 commit 00f9bfb
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 42 deletions.
21 changes: 12 additions & 9 deletions samples/boards/st/power_mgmt/standby_shutdown/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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
********************
Expand All @@ -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:

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
};
Original file line number Diff line number Diff line change
@@ -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;
};
1 change: 1 addition & 0 deletions samples/boards/st/power_mgmt/standby_shutdown/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ CONFIG_PM_DEVICE=n
CONFIG_PM_DEVICE_RUNTIME=n
CONFIG_HWINFO=y
CONFIG_POWEROFF=y
CONFIG_STM32_WKUP_PINS=y
50 changes: 17 additions & 33 deletions samples/boards/st/power_mgmt/standby_shutdown/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,30 @@
#include <zephyr/pm/pm.h>
#include <zephyr/sys/poweroff.h>
#include <stm32_ll_pwr.h>

#if !defined(CONFIG_SOC_SERIES_STM32L4X)
#error Not implemented for other series
#endif /* CONFIG_SOC_SERIES_STM32L4X */
#include <zephyr/dt-bindings/gpio/stm32-gpio.h>

#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)
{
Expand All @@ -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");
Expand Down Expand Up @@ -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));
Expand All @@ -122,21 +107,20 @@ 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) {
printk("Error %d: failed to configure interrupt on %s pin %d\n",
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);

Expand Down

0 comments on commit 00f9bfb

Please sign in to comment.