STM32LowPower - Use multiple wakeup sources for sleep

What are you developing?
Post Reply
brixton
Posts: 24
Joined: Thu Mar 30, 2023 11:51 am
Answers: 1

STM32LowPower - Use multiple wakeup sources for sleep

Post by brixton »

Hello everyone,

I’m interested in using the STM32L452RE Nucleo board for a project. For the application that I had in mind I would need the MCU to go into sleep, and in some cases be woken by timer and in other cases by external pin interrupt. And then I’d like the RAM to be retained after wake-up.

However I don’t want the wakeup sources to be active at the same time. I.e. if the MCU goes into sleep and is woken by timer, I don’t want it to also be able to be woken up by pin change. For that to work it essentially means that it should be possible for the pin interrupt to be deactivated again…but I haven’t found any functions that are able to do that.

So my questions about that are:
0) Is this the right place to ask this question? I could also post it on the "issues" page of the github repo.
1) Is what I want possible at all, for any of the sleep states?
2) Is what I want possible for deepSleep specifically? That would have my preference.

See below an Arduino script that illustrates what I would want the LowPower library to be able to do. It does compile, but I am not able to test it because I haven’t bought the Nucleo boad yet.

N.b. I had a look at the source code for the deepSleep function
https://github.com/stm32duino/STM32LowP ... er.cpp#L99, and that seems to only allow the timer and the Serial as interrupt sources for deepSleep. So my third question is, 3) Is that correct?
void STM32LowPower::shutdown(uint32_t ms)
{
if ((ms != 0) || _rtc_wakeup) {
programRtcWakeUp(ms, SHUTDOWN_MODE);
}
LowPower_shutdown();
}
Sample script:

Code: Select all

#include "STM32LowPower.h"

#ifndef USER_BTN
#define USER_BTN pinNametoDigitalPin(SYS_WKUP1)
#endif

const int pin = USER_BTN;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  // Configure low power
  LowPower.attachInterruptWakeup(pin, wake_up_ISR, RISING, DEEP_SLEEP_MODE);
  LowPower.begin();
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(5*1000); 
  digitalWrite(LED_BUILTIN, LOW);
  Serial.println("Going into timed sleep"); 

  LowPower.deepSleep(10*1000);
  
  Serial.println("Waking up from timed sleep"); 
  digitalWrite(LED_BUILTIN, HIGH);
  delay(5*1000); 
  digitalWrite(LED_BUILTIN, LOW);

  Serial.println("Going into sleep - pin wakeup"); 
  LowPower.deepSleep(); // <- wakeup source should only be pin change. 
  Serial.println("Waking up from sleep - pin wakeup"); 

}

void wake_up_ISR(){
  // Disable the pin change interrupt here? 
}


Many thanks!
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: STM32LowPower - Use multiple wakeup sources for sleep

Post by fpiSTM »

Yes it is the right place to ask question, issue is for bug not support.

LowPower library is basic, you program which wakeup source you want (Wakeup pins, RTC,Serial).
Depending of the mode you used RAM will be retained or not, see the README.
brixton
Posts: 24
Joined: Thu Mar 30, 2023 11:51 am
Answers: 1

Re: STM32LowPower - Use multiple wakeup sources for sleep

Post by brixton »

hi @fpiSTM ,

Thanks for the response! Mine is somewhat late :oops:

I got my hands on the STML452RE nucleo board. I managed to write and run a program that demonstrates using timed-based sleep and external-interrupt-based sleep in the same program. It works fine and I've very happy with that. See script below.

However, it only works if Serial/hardwareSerial is not used in the program. As soon as I introduce those into the code (i.e. by uncommenting the sections of code below), the external-interrupt-based sleep is skipped and the MCU proceeds straight to the next piece of code, which is the time-based sleep.

Do you know what could be causing the issue here?

Code: Select all


#include "STM32LowPower.h"

#ifndef USER_BTN
#define USER_BTN pinNametoDigitalPin(SYS_WKUP1)
#endif

const int pin = USER_BTN;

// HardwareSerial Serial1(PA10, PA9);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  // Serial1.begin(115200); 

}

void loop() {
  // Serial1.println("A");
  LowPower.begin();
  digitalWrite(LED_BUILTIN, HIGH);
  LowPower.deepSleep(1000);
  // Serial1.println("B");
  digitalWrite(LED_BUILTIN, LOW);
  LowPower.deepSleep(5*1000);
  digitalWrite(LED_BUILTIN, HIGH);
  // Serial1.println("C");
  delay(1000); 
  // Serial1.println("D");
  digitalWrite(LED_BUILTIN, LOW);

  pinMode(pin, INPUT_PULLUP); 
  LowPower.begin();
  LowPower.attachInterruptWakeup(pin, emptyISR, RISING, SLEEP_MODE);
  LowPower.deepSleep();
  // Serial1.println("E");
}


void emptyISR() {
  // This function will be called once on device wakeup

}
Post Reply

Return to “Projects”