diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/CMakeLists.txt b/samples/boards/stm32/power_mgmt/wkup_pins/CMakeLists.txt new file mode 100644 index 000000000000000..f0d58364d27aa9d --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/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_wkup_pins) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/README.rst b/samples/boards/stm32/power_mgmt/wkup_pins/README.rst new file mode 100644 index 000000000000000..3592ca0da55eed2 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/README.rst @@ -0,0 +1,38 @@ +.. _gpio-as-a-wkup-pin-src-sample: + +GPIO As A Wake-up Pin Source +############################ + +Overview +******** + +This sample is a minimum application to demonstrate using a wake-up pin with a GPIO as +a source to power on an STM32 SoC after Poweroff. + +The system will power off automatically ``WAIT_TIME_US`` us after boot. +Press the user button designated in boards's devicetree overlay as "wkup-src" to power it on again. + +.. _gpio-as-a-wkup-pin-src-sample-requirements: + +Requirements +************ + +The SoC should support POWEROFF functionality & have a wake-up pin that corresponds +to the GPIO pin of a user button. +To support another board, add an overlay in boards folder. +Make sure that wake-up pins are configured in SoC dtsi file. + +Building and Running +******************** + +Build and flash wkup_pins as follows, changing ``nucleo_u5a5zj_q`` for your board: + +.. zephyr-app-commands:: + :zephyr-app: samples/boards/stm32/power_mgmt/wkup_pins + :board: nucleo_u5a5zj_q + :goals: build flash + :compact: + +After flashing, the LED in ON. +The LED will be turned off when the system is powered off. +Press the user button to power on the system again. diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/boards/b_u585i_iot02a.overlay b/samples/boards/stm32/power_mgmt/wkup_pins/boards/b_u585i_iot02a.overlay new file mode 100644 index 000000000000000..155c5dfa6435395 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/boards/b_u585i_iot02a.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + wkup-src = &user_button; + }; +}; + +&user_button { + gpios = <&gpioc 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP | ST_STM32_GPIO_WKUP)>; +}; + +&pwr { + status = "okay"; +}; diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_l4r5zi.overlay b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_l4r5zi.overlay new file mode 100644 index 000000000000000..b07f1d6a7b1a796 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_l4r5zi.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + wkup-src = &user_button; + }; +}; + +&user_button { + gpios = <&gpioc 13 (GPIO_ACTIVE_HIGH | ST_STM32_GPIO_WKUP)>; +}; + +&pwr { + status = "okay"; +}; diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_u5a5zj_q.overlay b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_u5a5zj_q.overlay new file mode 100644 index 000000000000000..b07f1d6a7b1a796 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_u5a5zj_q.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + wkup-src = &user_button; + }; +}; + +&user_button { + gpios = <&gpioc 13 (GPIO_ACTIVE_HIGH | ST_STM32_GPIO_WKUP)>; +}; + +&pwr { + status = "okay"; +}; diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_wl55jc.overlay b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_wl55jc.overlay new file mode 100644 index 000000000000000..6acca86e08f54b0 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/boards/nucleo_wl55jc.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + wkup-src = &user_button_1; + }; +}; + +&user_button_1 { + gpios = <&gpioa 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP | ST_STM32_GPIO_WKUP)>; +}; + +&pwr { + status = "okay"; +}; diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/prj.conf b/samples/boards/stm32/power_mgmt/wkup_pins/prj.conf new file mode 100644 index 000000000000000..34e1de95dfb2f31 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/prj.conf @@ -0,0 +1,8 @@ +CONFIG_PM=n +CONFIG_PM_DEVICE=n +CONFIG_PM_DEVICE_RUNTIME=n +CONFIG_HWINFO=y +CONFIG_POWEROFF=y +CONFIG_STM32_WKUP_PINS=y +CONFIG_INPUT=y +CONFIG_INPUT_GPIO_KEYS=y diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/sample.yaml b/samples/boards/stm32/power_mgmt/wkup_pins/sample.yaml new file mode 100644 index 000000000000000..1cf66ca25c3834e --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/sample.yaml @@ -0,0 +1,11 @@ +sample: + name: GPIO As A Wake-up Pin Source +tests: + sample.boards.stm32.power_mgmt.wkup_pins: + build_only: true + filter: dt_enabled_alias_with_parent_compat("wkup-src", + "gpio-keys") and dt_compat_enabled("st,stm32-pwr") + platform_allow: + - nucleo_l4r5zi + - nucleo_u5a5zj_q + - nucleo_wl55jc diff --git a/samples/boards/stm32/power_mgmt/wkup_pins/src/main.c b/samples/boards/stm32/power_mgmt/wkup_pins/src/main.c new file mode 100644 index 000000000000000..468892dd87b9988 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/wkup_pins/src/main.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define WAIT_TIME_US (1 << 22) + +#define WKUP_SRC_NODE DT_ALIAS(wkup_src) +#if !DT_NODE_HAS_STATUS(WKUP_SRC_NODE, okay) +#error "Unsupported board: wkup_src devicetree alias is not defined" +#endif + +static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(WKUP_SRC_NODE, gpios, {0}); + +static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); + +int main(void) +{ + uint32_t cause; + + hwinfo_get_reset_cause(&cause); + hwinfo_clear_reset_cause(); + + if (cause & RESET_BROWNOUT) { + printk("\nReset cause: wake-up pin or reset pin\n\n"); + } else if (cause & RESET_PIN) { + printk("\nReset cause: Reset pin\n\n"); + } + + printk("Wake-up button set up at %s pin %d\n", button.port->name, button.pin); + + __ASSERT_NO_MSG(gpio_is_ready_dt(&led)); + gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE); + gpio_pin_set(led.port, led.pin, 1); + + printk("Device is ready\n"); + + printk("Will wait %d s before powering the system off\n", (WAIT_TIME_US >> 20)); + k_busy_wait(WAIT_TIME_US); + + printk("Powering off\n"); + printk("Press the user button to power the system on\n\n"); + + sys_poweroff(); + /* Will remain powered off until wakeup pin is activated */ + + return 0; +}