zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.17k stars 6.23k forks source link

RFC: introduce the STM32 system wakeup pins to exit low power modes #57323

Closed FRASTM closed 1 month ago

FRASTM commented 1 year ago

Introduction

The stm32 mcu has several external wakeup pins (GPIO) that are able to trigger a wakeup from Standby or Shutdown low power modes. The WakeUp pins are fixed GPIO pins. Each WakeUp pin is programmed previous to entering a low power standby/shutdown and will exit the system on edge-detection. The stm32 can identify the source of WakeUp.

Problem description

Depending on the stm32 serie, configuration of the WakeUp pins differs:

Proposed change

  1. Adding a new devicetree binding for each wakeUp pin (of each stm32 device)
  2. Adding a new node for the PWR module of the stme32 device
  3. Adding a new devicetree binding for using the WakeUp pins
  4. Adding a software sequence to enable and configure each WakeUp pin in a new stm32_pwr module

Detailed RFC

  1. The list of possible wakeup pins depends on the stm32 device from 1 to 8. Each WakeUp pin is known by its gpio reference example (PC13). The stm32 associates (hardware fixed) this GPIO pin to a wakeup pin number : example PC13 is wakeup pin 2. Each possible WakeUp pin of the stm32 is a node of the stm32 soc devicetree. Because some wakeup pin configurations depend on the stm32 serie, several bindings are defined (edge rising/falling detection, pull-up down (stm32h7), multiplexing (stm32u5).
  2. When using a Wakeup pin, it is listed in a node of the devicetree of the target platform.
  3. During system Initialisation, the pwr module is parsing this list of wakeUp pins and configures the stm32 PWR registers.

Proposed change (Detailed)

wakeup2_pc13: wakeup2_pc13 {
        compatible = "st,stm32-wkup-pin1";
        #wkpin-cells = <1>;
        syswakeup-pin = <2>;
};
    pwr_wkup: pwr@40007000 {
        compatible = "st,stm32-pwr";
        reg = <0x40007000 0x400>; /* PWR register bank */
        clocks = <&rcc STM32_CLOCK_BUS_APB1 0x10000000>;
        pin-nb = <5>; /* 5 system WakeUp pins */
        pin-pol;  /* -->  the polarity of the pin for triggering is configurable */
        status = "disabled";
    };


- A new module is introduced /soc/arm/st_stm32/common/soc_pwr_config.c 
It configure and enable each wakeup pin listed in the `wkpins` property of the `&pwr_wkup` node.

### Dependencies
power management : CONFIG_PM
--> Using the system wakeup pins is pertinent when the the stm32 supports the standby (PM_STATE_STANDBY)  and/or shutdown (PM_STATE_SOFT_OFF) low power modes.

### Unresolved Questions

--> for each stm32 deice, the stm32XX.dtsi includes the complete list of wakeUp pins : that should be automatically generated in  the [hal_stm32](https://github.com/zephyrproject-rtos/hal_stm32)/[dts](https://github.com/zephyrproject-rtos/hal_stm32/tree/main/dts)/st/
--> Identify the wakeup source when exiting the low power (standby/shutdown) modes
gdb3-ampaworks commented 5 months ago

One unresolved question is easy to answer: Identifying the wakeup source from shutdown mode.

It doesn't seem possible -- the WKUP flag registers are reset when exiting shutdown mode. So they're essentially useless...

https://community.st.com/t5/stm32-mcus-products/stm32l476-wakeup-flag-not-set-when-exit-from-shutdown-after/m-p/309420

Let me know if this isn't correct. This is the behavior I see on STM32L4P5 anyways.

ajarmouni-st commented 5 months ago

One unresolved question is easy to answer: Identifying the wakeup source from shutdown mode.

It doesn't seem possible -- the WKUP flag registers are reset when exiting shutdown mode. So they're essentially useless...

https://community.st.com/t5/stm32-mcus-products/stm32l476-wakeup-flag-not-set-when-exit-from-shutdown-after/m-p/309420

Let me know if this isn't correct. This is the behavior I see on STM32L4P5 anyways.

Yes, does seem so. The best I was able to do was this: https://github.com/zephyrproject-rtos/zephyr/blob/56720088cd57d18e828f98fb22a59f458a0375da/samples/boards/stm32/power_mgmt/wkup_pins_gpio/src/main.c#L39-L43

AGlass0fMilk commented 5 months ago

I will add that if we instead go into standby mode, for an extra 100nA or so we get functional wake-up source registers.

That's what I'm opting to do in my project anyways. I can sacrifice 100nA standby current to know what woke up the processor.

Perhaps we can add a KConfig to choose the system shutdown behavior/mode

Edit: this is my personal account