From f5378424f7f492a8ae0d173a015bc1186fcc7127 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 28 Jun 2022 16:54:49 +0200 Subject: [PATCH] samples: boards: stm32: Add a serial wakeup sample Add a sample to demonstrate use of (LP)U(S)ART with wakeup capability This sample is provided with 2 configurations - nucleo_wb55rg: Basic configuration that could be exercised in CI - stm32l562e_dk: "Full feature" configuration that require some set up configuration (be able to display console from lpuart) and allows to achieve lowest power consumption. Signed-off-by: Erwan Gouriou --- .../power_mgmt/serial_wakeup/CMakeLists.txt | 7 ++ .../stm32/power_mgmt/serial_wakeup/README.rst | 86 +++++++++++++++++++ .../boards/nucleo_wb55rg.overlay | 19 ++++ .../boards/stm32l562e_dk.overlay | 50 +++++++++++ .../stm32/power_mgmt/serial_wakeup/prj.conf | 7 ++ .../power_mgmt/serial_wakeup/sample.yaml | 17 ++++ .../stm32/power_mgmt/serial_wakeup/src/main.c | 57 ++++++++++++ 7 files changed, 243 insertions(+) create mode 100644 samples/boards/stm32/power_mgmt/serial_wakeup/CMakeLists.txt create mode 100644 samples/boards/stm32/power_mgmt/serial_wakeup/README.rst create mode 100644 samples/boards/stm32/power_mgmt/serial_wakeup/boards/nucleo_wb55rg.overlay create mode 100644 samples/boards/stm32/power_mgmt/serial_wakeup/boards/stm32l562e_dk.overlay create mode 100644 samples/boards/stm32/power_mgmt/serial_wakeup/prj.conf create mode 100644 samples/boards/stm32/power_mgmt/serial_wakeup/sample.yaml create mode 100644 samples/boards/stm32/power_mgmt/serial_wakeup/src/main.c diff --git a/samples/boards/stm32/power_mgmt/serial_wakeup/CMakeLists.txt b/samples/boards/stm32/power_mgmt/serial_wakeup/CMakeLists.txt new file mode 100644 index 00000000000..ef0dcfbcb26 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/serial_wakeup/CMakeLists.txt @@ -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_serial_wakeup) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/stm32/power_mgmt/serial_wakeup/README.rst b/samples/boards/stm32/power_mgmt/serial_wakeup/README.rst new file mode 100644 index 00000000000..751f43c7fa9 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/serial_wakeup/README.rst @@ -0,0 +1,86 @@ +.. _stm32-pm-serial-wakeup-sample: + +STM32 PM Serial wakeup +###################### + +Overview +******** + +This sample is a minimum application to demonstrate serial wakeup functionality +in low power context. + +.. _stm32-pm-serial-wakeup-sample-requirements: + +Requirements +************ + +1. 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`). + +2. The serial port used by the shell should be configured, using device tree, to +be a functional wakeup source: + + - Clocked by an oscillator available in Stop mode (LSE, LSI) or an oscillator capable + that can be requested dynamically by device on activity detection (HSI on STM32WB). + - Matching oscillator sources should be enabled + - If LSE is selected as clock source and shell serial port is a LPUART current speed + should be adapted (9600 bauds) + - Port should be set as "wakeup-source" + +Note: Using HSI clock is a specific + +Building and Running +******************** + +Build and flash this sample as follows, changing ``nucleo_wb55rg`` for a board +configured to be compatible with this sample. + +.. zephyr-app-commands:: + :zephyr-app: samples/boards/stm32/power_mgmt/serial_wakeup + :board: nucleo_wb55rg + :goals: build flash + :compact: + +After flashing, the shell is enabled and device enter sleep mode. +User is able to wake up the device by typing into the shell + +PM configurations +***************** + +By default, :kconfig:option:`CONFIG_PM_DEVICE` and :kconfig:option:`CONFIG_PM_DEVICE_RUNTIME` +are enabled, but user can also deactivate both or former to see each configuration in play. + +Debugging +********* + +:kconfig:option:`CONFIG_DEBUG` could be enabled to allow debug. Note that debug mode prevents +target to reach low power consumption. +Also note that after debug mode has been disabled, target should also be powered off in order +to get back to normal mode and reach low power consumption. + +PM measurements on stm32l562e_dk using stm32l562e_dk PM shield +************************************************************** + +Plug Power shield +Plug ST-Link +Set JP4 To 5V ST-Link +Set SW1 to PM_SEL_VDD +STM32Cube PowerMonitor settings to be applied: + + - Sampling Freq: max + - Functional Mode: High + +Optimal configuration for low power consumption +*********************************************** + +In order to reach lower power consumption numbers following parameters should be taken +into account: + + - Use a LPUART instead of a basic U(S)ART node + - Chose LSE as clock source + - Ensure no other oscillators are enabled (disable HSI, ...) + - Provide "sleep" pinctrl configuration to other uart nodes. + - Disable Debug mode + + With all these conditions matched, one can reach 10uA on stm32l562e_dk with this sample. diff --git a/samples/boards/stm32/power_mgmt/serial_wakeup/boards/nucleo_wb55rg.overlay b/samples/boards/stm32/power_mgmt/serial_wakeup/boards/nucleo_wb55rg.overlay new file mode 100644 index 00000000000..f924e6fdea5 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/serial_wakeup/boards/nucleo_wb55rg.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&clk_hsi { + status = "okay"; +}; + +&usart1 { + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00004000>, + <&rcc STM32_SRC_HSI USART1_SEL(2)>; + + wakeup-source; + + pinctrl-1 = <&analog_pb6 &analog_pb7>; + pinctrl-names = "default", "sleep"; +}; diff --git a/samples/boards/stm32/power_mgmt/serial_wakeup/boards/stm32l562e_dk.overlay b/samples/boards/stm32/power_mgmt/serial_wakeup/boards/stm32l562e_dk.overlay new file mode 100644 index 00000000000..7f297264980 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/serial_wakeup/boards/stm32l562e_dk.overlay @@ -0,0 +1,50 @@ +/ { + chosen { + /* Comment out these lines to use usart1 as console/shell */ + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + }; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_hsi { + /* Comment out this line to use HSI as clk source */ + status = "disabled"; +}; + +&lpuart1 { + pinctrl-0 = <&lpuart1_rx_pb10 &lpuart1_tx_pb11>; + pinctrl-1 = <&analog_pb10 &analog_pb11>; + pinctrl-names = "default", "sleep"; + + clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000001>, + <&rcc STM32_SRC_LSE LPUART1_SEL(3)>; + + current-speed = <9600>; + + wakeup-source; + + status = "okay"; +}; + +&usart1 { + pinctrl-1 = <&analog_pa9 &analog_pa10>; + pinctrl-names = "default", "sleep"; + + /* Uncomment out this line to use usart1 as wakeup source */ + /* wakeup-source; */ + + clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00004000>, + <&rcc STM32_SRC_HSI USART1_SEL(2)>; + + status = "okay"; +}; + +&usart3 { + status = "okay"; + pinctrl-1 = <&analog_pc10 &analog_pc11>; + pinctrl-names = "default", "sleep"; +}; diff --git a/samples/boards/stm32/power_mgmt/serial_wakeup/prj.conf b/samples/boards/stm32/power_mgmt/serial_wakeup/prj.conf new file mode 100644 index 00000000000..3e1a61bf9db --- /dev/null +++ b/samples/boards/stm32/power_mgmt/serial_wakeup/prj.conf @@ -0,0 +1,7 @@ +CONFIG_PM=y +CONFIG_PM_DEVICE=y +CONFIG_PM_DEVICE_RUNTIME=n +CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=n +CONFIG_SHELL=y + +CONFIG_DEBUG=n diff --git a/samples/boards/stm32/power_mgmt/serial_wakeup/sample.yaml b/samples/boards/stm32/power_mgmt/serial_wakeup/sample.yaml new file mode 100644 index 00000000000..416d94056dd --- /dev/null +++ b/samples/boards/stm32/power_mgmt/serial_wakeup/sample.yaml @@ -0,0 +1,17 @@ +sample: + name: STM32 Power Management Serial Wakeup +tests: + sample.boards.stm32.power_mgmt.serial_wakeup: + tags: UART Wake up power + harness: console + harness_config: + type: multi_line + regex: + - "Device ready" + - "Device is wakeup capable" + - "Wakeup source enable ok" + - "Wakeup source enabled" + integration_platforms: + - nucleo_wb55rg + filter: dt_compat_enabled("zephyr,power-state") + extra_args: "CONFIG_DEBUG=y" diff --git a/samples/boards/stm32/power_mgmt/serial_wakeup/src/main.c b/samples/boards/stm32/power_mgmt/serial_wakeup/src/main.c new file mode 100644 index 00000000000..8ba5aefed72 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/serial_wakeup/src/main.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define DEV_NAME DT_CHOSEN(zephyr_console) + +void main(void) +{ + static const struct device *dev; + + dev = DEVICE_DT_GET(DEV_NAME); + if (dev < 0) { + printk("Failed to get device"); + } + + printk("Device ready\n"); + +#if CONFIG_PM_DEVICE + /* In PM_DEVICE modes, enable device as a wakeup source will prevent + * system to switch it off (clock off, set pins to sleep configuration, ...) + * It is not requested in PM mode only since this mode will not + */ + + bool ret; + + ret = pm_device_wakeup_is_capable(dev); + if (!ret) { + printk("Device is not wakeup capable\n"); + } else { + printk("Device is wakeup capable\n"); + + ret = pm_device_wakeup_enable(dev, true); + if (!ret) { + printk("Could not enable wakeup source\n"); + } else { + printk("Wakeup source enable ok\n"); + } + + ret = pm_device_wakeup_is_enabled(dev); + if (!ret) { + printk("Wakeup source not enabled\n"); + } else { + printk("Wakeup source enabled\n"); + } + } +#endif + +}