2025-08-08 12:36 PM
I am using the Nucleo-L433RC-P board and have configured pin PC13 as SYS WKUP (for the blue top button).
How can I read the state of this pin when the processor wakes up, because HAL_GPIO_ReadPin will not work.
I am sure I used a function or macro to read the state of this pin before, but can't remember how I did it.
I need to distinguish between an RTC wake or a pin wake from shutdown.
I use wake markers stored in an RTC backup register to detetc an RTC wake. I write to the backup register just before calling shutdown in the function SCH_mcuSleep....
void SCH_mcuSleep (void){
/* The Following Wakeup sequence is highly recommended prior to each Standby mode entry
mainly when using more than one wakeup source this is to not miss any wakeup event.
- Disable all used wakeup sources,
- Clear all related wakeup flags,
- Re-enable all used wakeup sources,
- Enter the shutdown mode.
*/
// write value to RTC backup register to indicate mcu was in sleep
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, WAKE_FROM_SLEEP_RTC);
// Disable all used wakeup sources
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, RTC_WAKE_SEC, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
// Clear all related wakeup flags
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
Enable_PC13_Wakeup();
// Call sleep (note that the terms 'sleep' and 'powerdown' are only used for readability, both call shutdown mode)
HAL_PWREx_EnterSHUTDOWNMode();
}
Then in main I call this function for when the processor wakes...
void MAN_checkWake (void)
{
// read wake marker from RTC backup register to determine if woken from sleep or shutdown
wake_marker = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);
if (wake_marker == WAKE_FROM_SLEEP_RTC)
{
// woken from sleep (RTC wake)
// check if elapsed time is greater then shutdown time
if (elapsedSeconds >= RTC_SHUTDOWN_S)
{
SCH_mcuShutdown();
}
}
else if (wake_marker == WAKE_FROM_SHUTDOWN_WKUP)
{
// woken from shutdown (power switch pressed during shutdown)
wakeConfigReset(); // reset time and date and set default reference pressure
}
else
{
// woken from reset
wakeConfigReset(); // reset time and date and set default reference pressure
// store value in RTC backup register to indicate mcu was reset
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, WAKE_FROM_RESET);
}
}
There is a seperate function to shutdown that only uses pin wake (does not require RTC wake)...
void SCH_mcuShutdown (void){
// write value to RTC backup register to indicate mcu was in shutdown
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, WAKE_FROM_SHUTDOWN_WKUP);
// disable RTC wakeup
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
// enable pin wakeup
Enable_PC13_Wakeup();
// Call power down (note that the terms 'sleep' and 'powerdown' are only used for readability, both call shutdown mode)
HAL_PWREx_EnterSHUTDOWNMode();
}
Solved! Go to Solution.
2025-08-09 3:12 AM - edited 2025-08-10 3:09 AM
Thanks TDK
I've come across the same issue I did weeks ago, but this time I know the cause from previous weeks of debugging shutdown and wake.
Your code works when debugging or running, but not in standalone after a cold reset (power loss).
I used...
if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUF1)) {
Just like the PWR_FLAG_SB flag , the PWR_FLAG_WUF1 flag does not work from shutdown, it only works from standby.
It 'appears' to work from shutdown when debugging or running, but it fails to work after a cold reset.
So to get this working, I have had to use standby mode instead of shutdown mode.
See this post I wrote...
In this case it was with the flag PWR_FLAG_SB, but it looks to be the case with PWR_FLAG_WUF1 too.
To summarise the post above...
In debug or run mode (e.g. via ST-Link or when powered via USB), the power is never fully removed — so:
Certain power control and backup domain registers (like PWR->CSR and RTC backup regs) may retain their values.
The SB flag can remain set, giving the impression it survived SHUTDOWN.
Why it fails in standalone after a cold reset:
In SHUTDOWN mode, only the RTC and backup domain are retained via VBAT.
However, on most STM32s:
The SB flag does not survive SHUTDOWN (it's not designed to — unlike in STANDBY mode).
After a cold power cycle, everything except what’s powered by VBAT is reset — including that flag.
Hence, __HAL_PWR_GET_FLAG(PWR_FLAG_SB) returns false.
TL;DR
PWR_FLAG_SB is only valid for detecting wake from STANDBY, not SHUTDOWN.
It might "appear" to work in debug due to partial power retention or debugger interference — but it's not reliable.
Always use backup register markers or the RTC time to infer wake source across SHUTDOWN.
Oh the joys of shutdown and wake on the STM32, why is it so difficult !
So there is no way around this ?
2025-08-08 12:55 PM
The pin needs to be initialized as an input pin before HAL_GPIO_ReadPin will read its state. By default, the pin is in analog mode.
If a wakeup pin caused the wake up, a flag is set in RCC->SR1. This is latching--it doesn't reflect current state of the pin.
2025-08-08 1:12 PM
Thanks TDK
How do I read the RCC->SR1 register ? Is there a macro or function ?
2025-08-08 3:46 PM
You can just read it and look for the corresponding bit:
if (RCC->SR1 & RCC_SR1_WUF1) {
...
Or you can use the READ_REG macro:
if (READ_REG(RCC->SR1, RCC_SR1_WUF1)) {
...
Of if you prefer HAL:
if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUF1)) {
...
All equivalent.
2025-08-09 3:12 AM - edited 2025-08-10 3:09 AM
Thanks TDK
I've come across the same issue I did weeks ago, but this time I know the cause from previous weeks of debugging shutdown and wake.
Your code works when debugging or running, but not in standalone after a cold reset (power loss).
I used...
if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUF1)) {
Just like the PWR_FLAG_SB flag , the PWR_FLAG_WUF1 flag does not work from shutdown, it only works from standby.
It 'appears' to work from shutdown when debugging or running, but it fails to work after a cold reset.
So to get this working, I have had to use standby mode instead of shutdown mode.
See this post I wrote...
In this case it was with the flag PWR_FLAG_SB, but it looks to be the case with PWR_FLAG_WUF1 too.
To summarise the post above...
In debug or run mode (e.g. via ST-Link or when powered via USB), the power is never fully removed — so:
Certain power control and backup domain registers (like PWR->CSR and RTC backup regs) may retain their values.
The SB flag can remain set, giving the impression it survived SHUTDOWN.
Why it fails in standalone after a cold reset:
In SHUTDOWN mode, only the RTC and backup domain are retained via VBAT.
However, on most STM32s:
The SB flag does not survive SHUTDOWN (it's not designed to — unlike in STANDBY mode).
After a cold power cycle, everything except what’s powered by VBAT is reset — including that flag.
Hence, __HAL_PWR_GET_FLAG(PWR_FLAG_SB) returns false.
TL;DR
PWR_FLAG_SB is only valid for detecting wake from STANDBY, not SHUTDOWN.
It might "appear" to work in debug due to partial power retention or debugger interference — but it's not reliable.
Always use backup register markers or the RTC time to infer wake source across SHUTDOWN.
Oh the joys of shutdown and wake on the STM32, why is it so difficult !
So there is no way around this ?
2025-08-10 1:58 AM - edited 2025-08-10 3:09 AM
See above