samples: boards: stm32: Power_mgmt: sample for standby shutdownn mode
STM32L4x power management (ultra_low_power) of Standby mode and shutdown mode Signed-off-by: Marc Desvaux <marc.desvaux-ext@st.com>
This commit is contained in:
parent
ba44549ae8
commit
b3f739476c
5 changed files with 232 additions and 0 deletions
|
@ -0,0 +1,7 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
project(stm32_pm_standby_shutdown)
|
||||||
|
|
||||||
|
target_sources(app PRIVATE src/main.c)
|
47
samples/boards/stm32/power_mgmt/standby_shutdown/README.rst
Normal file
47
samples/boards/stm32/power_mgmt/standby_shutdown/README.rst
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
.. _stm32-pm-standby_shutdown-sample:
|
||||||
|
|
||||||
|
STM32 PM Standby shutdown
|
||||||
|
#########################
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. _stm32-pm-standby_shutdown-sample-requirements:
|
||||||
|
|
||||||
|
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().
|
||||||
|
|
||||||
|
Building and Running
|
||||||
|
********************
|
||||||
|
|
||||||
|
Build and flash standby_shutdown as follows, changing ``nucleo_L476RG`` for your board:
|
||||||
|
|
||||||
|
.. zephyr-app-commands::
|
||||||
|
:zephyr-app: samples/samples/boards/stm32/power_mgmt/standby_shutdown
|
||||||
|
:board: nucleo_L476RG
|
||||||
|
:goals: build flash
|
||||||
|
:compact:
|
||||||
|
|
||||||
|
After flashing, the LED starts to blink.
|
||||||
|
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.
|
||||||
|
|
||||||
|
PM configurations
|
||||||
|
*****************
|
||||||
|
|
||||||
|
By default, :kconfig:option:`CONFIG_PM` is enabled.
|
|
@ -0,0 +1,4 @@
|
||||||
|
CONFIG_PM=y
|
||||||
|
CONFIG_PM_DEVICE=n
|
||||||
|
CONFIG_PM_DEVICE_RUNTIME=n
|
||||||
|
CONFIG_HWINFO=y
|
19
samples/boards/stm32/power_mgmt/standby_shutdown/sample.yaml
Normal file
19
samples/boards/stm32/power_mgmt/standby_shutdown/sample.yaml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
sample:
|
||||||
|
name: STM32 GPIO Power Management
|
||||||
|
tests:
|
||||||
|
sample.boards.stm32.power_mgmt.standby_shutdown:
|
||||||
|
platform_allow: nucleo_l476rg disco_l475_iot1
|
||||||
|
tags: LED power
|
||||||
|
harness: console
|
||||||
|
harness_config:
|
||||||
|
type: multi_line
|
||||||
|
regex:
|
||||||
|
- "Reset cause: Reset pin"
|
||||||
|
- "Device ready: .*"
|
||||||
|
- "Press and hold the user button:"
|
||||||
|
- "when LED2 is OFF to enter to Shutdown Mode"
|
||||||
|
- "when LED2 is ON to enter to Standby Mode"
|
||||||
|
filter: dt_compat_enabled("zephyr,power-state") and
|
||||||
|
dt_enabled_alias_with_parent_compat("led0", "gpio-leds") and
|
||||||
|
dt_compat_enabled("st,stm32-lptim")
|
||||||
|
extra_args: "CONFIG_DEBUG=y"
|
155
samples/boards/stm32/power_mgmt/standby_shutdown/src/main.c
Normal file
155
samples/boards/stm32/power_mgmt/standby_shutdown/src/main.c
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 STMicroelectronics
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/drivers/hwinfo.h>
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
#include <zephyr/devicetree.h>
|
||||||
|
#include <zephyr/drivers/gpio.h>
|
||||||
|
#include <zephyr/sys/printk.h>
|
||||||
|
#include <zephyr/pm/pm.h>
|
||||||
|
#include <stm32_ll_pwr.h>
|
||||||
|
|
||||||
|
#if !defined(CONFIG_SOC_SERIES_STM32L4X)
|
||||||
|
#error Not implemented for other series
|
||||||
|
#endif /* CONFIG_SOC_SERIES_STM32L4X */
|
||||||
|
|
||||||
|
#define STACKSIZE 1024
|
||||||
|
#define PRIORITY 7
|
||||||
|
#define SLEEP_TIME_MS 3000
|
||||||
|
|
||||||
|
#define SW0_NODE DT_ALIAS(sw0)
|
||||||
|
#if !DT_NODE_HAS_STATUS(SW0_NODE, okay)
|
||||||
|
#error "Unsupported board: sw0 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 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 , - active low, pull-up */
|
||||||
|
/* Set pull-ups for standby modes */
|
||||||
|
LL_PWR_EnableGPIOPullUp(LL_PWR_GPIO_C, LL_PWR_GPIO_BIT_13);
|
||||||
|
LL_PWR_IsWakeUpPinPolarityLow(LL_PWR_WAKEUP_PIN2);
|
||||||
|
/* Enable pin pull up configurations and wakeup pins */
|
||||||
|
LL_PWR_EnablePUPDCfg();
|
||||||
|
LL_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN2);
|
||||||
|
/* Clear wakeup flags */
|
||||||
|
LL_PWR_ClearFlag_WU();
|
||||||
|
}
|
||||||
|
|
||||||
|
void button_pressed(const struct device *dev, struct gpio_callback *cb,
|
||||||
|
uint32_t pins)
|
||||||
|
{
|
||||||
|
k_sem_give(&button_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread_shutdown_standby_mode(void)
|
||||||
|
{
|
||||||
|
k_sem_init(&button_sem, 0, 1);
|
||||||
|
k_sem_take(&button_sem, K_FOREVER);
|
||||||
|
gpio_pin_configure(led.port, led.pin, GPIO_DISCONNECTED);
|
||||||
|
printk("User button pressed\n");
|
||||||
|
config_wakeup_features();
|
||||||
|
if (led_is_on == false) {
|
||||||
|
printk("Shutdown Mode requested\n");
|
||||||
|
printk("Release the user button to exit from Shutdown Mode\n\n");
|
||||||
|
#ifdef CONFIG_LOG
|
||||||
|
k_msleep(2000);
|
||||||
|
#endif /* CONFIG_LOG */
|
||||||
|
pm_state_force(0u, &(struct pm_state_info) {PM_STATE_SOFT_OFF, 0, 0});
|
||||||
|
/* stay in Shutdown mode until wakeup line activated */
|
||||||
|
} else {
|
||||||
|
printk("Standby Mode requested\n");
|
||||||
|
printk("Release the user button to exit from Standby Mode\n\n");
|
||||||
|
#ifdef CONFIG_LOG
|
||||||
|
k_msleep(2000);
|
||||||
|
#endif /* CONFIG_LOG */
|
||||||
|
pm_state_force(0u, &(struct pm_state_info) {PM_STATE_STANDBY, 0, 0});
|
||||||
|
/* stay in Standby mode until wakeup line activated */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
K_THREAD_DEFINE(thread_shutdown_standby_mode_id, STACKSIZE, thread_shutdown_standby_mode,
|
||||||
|
NULL, NULL, NULL, PRIORITY, 0, 0);
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint32_t cause;
|
||||||
|
|
||||||
|
hwinfo_get_reset_cause(&cause);
|
||||||
|
hwinfo_clear_reset_cause();
|
||||||
|
|
||||||
|
if ((LL_PWR_IsActiveFlag_SB() == true) && (cause == 0)) {
|
||||||
|
LL_PWR_ClearFlag_SB();
|
||||||
|
LL_PWR_ClearFlag_WU();
|
||||||
|
printk("\nReset cause: Standby mode\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cause == (RESET_PIN | RESET_BROWNOUT)) {
|
||||||
|
LL_PWR_ClearFlag_WU();
|
||||||
|
printk("\nReset cause: Shutdown mode or power up\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cause == RESET_PIN) {
|
||||||
|
LL_PWR_ClearFlag_WU();
|
||||||
|
printk("\nReset cause: Reset pin\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__ASSERT_NO_MSG(device_is_ready(led.port));
|
||||||
|
if (!gpio_is_ready_dt(&button)) {
|
||||||
|
printk("Error: button device %s is not ready\n",
|
||||||
|
button.port->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
|
||||||
|
gpio_add_callback(button.port, &button_cb_data);
|
||||||
|
|
||||||
|
printk("Device ready: %s\n\n\n", CONFIG_BOARD);
|
||||||
|
|
||||||
|
printk("Press and hold the user button:\n");
|
||||||
|
printk(" when LED2 is OFF to enter to Shutdown Mode\n");
|
||||||
|
printk(" when LED2 is ON to enter to Standby Mode\n\n");
|
||||||
|
|
||||||
|
led_is_on = true;
|
||||||
|
while (true) {
|
||||||
|
gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
|
||||||
|
gpio_pin_set(led.port, led.pin, (int)led_is_on);
|
||||||
|
k_msleep(SLEEP_TIME_MS);
|
||||||
|
led_is_on = !led_is_on;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue