Skip to main content
Associate II
November 20, 2025
Solved

STM32WL31 fails to exit DEEPSTOP from RTC wakeup

  • November 20, 2025
  • 7 replies
  • 274 views

Good day,

I have a simple custom board with a STM32WL31 that needs to cyclically enter DEEPSTOP mode and then wake by means of RTC internal wakeup. It seems the device enters DEEPSTOP, but does not wake from it.

 

Basic setup:

  • Clocked from HSI, RTC clocked from LSE with 32kHz xtal.
  • SMPS not implemented.
  • Basic project generated with STM32CubeMX 6.16.0 with MCU Package for STM32WL3 Series 1.3.0 installed.
  • IWDT active
  • MR_SUBG radio not yet implemented

 

I can confirm RTC runs, RTC interrupt occurs every 1s, and HAL_PWR_EnterSLEEPMode() behaves correctly.

 

However, when I enter DEEPSTOP with the sequence below, then the code never gets to HAL_ResumeTick() (reset after a few seconds by IWDT):

 
PWR_DEEPSTOPTypeDef sConfigDEEPSTOP;
sConfigDEEPSTOP.deepStopMode = PWR_DEEPSTOP_WITH_SLOW_CLOCK_ON;
HAL_PWR_ConfigDEEPSTOP(&sConfigDEEPSTOP);
HAL_SuspendTick();
HAL_PWR_EnterDEEPSTOPMode();
HAL_ResumeTick();

 

Below is a reg dump of possible relevant registers just before calling SET_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk) in HAL_PWR_EnterDEEPSTOPMode().

 

PWR_CR1=0x00000114
PWR_CR2=0x00000120
PWR_IEWU=0x00000002
PWR_IWUP=0x00000002
PWR_IWUF=0x00000000
PWR_SR2=0x0000F3F0
PWR_CR5=0x00006514
PWR_DBGR=0x00000000
PWR_EXTSRR=0x00000000
RCC_CR=0x00001430
RCC_CFGR=0x00008000
RTC_CR=0x00005504
RTC_ISR=0x00000023
RTC_WUTR=0x00000001

 

Kindly advise any fixes or suggestions - thank you.

Best answer by xy3dg12

Check this : 

无标题.png

7 replies

Technical Moderator
November 21, 2025

hello @marvdm 
and welcome to ST community! 
are you using the RTC in internal wakeup mode? and can u try to implement these lines of code to your project ?

 HAL_PWREx_EnableInternalWakeUpLine(PWR_WAKEUP_RTC, PWR_WUP_RISIEDG);
 HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_RTC);
 HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x555, RTC_WAKEUPCLOCK_RTCCLK_DIV16);

Hope that helps
Gyessine 


 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
marvdmAuthor
Associate II
November 23, 2025

Hi Gyessine,

Thank you very much for your reply. Yes, I am using the RTC in internal wakeup mode.

I've implemented your lines, but unfortunately no change in behavior. My main code now is:

 HAL_PWREx_EnableInternalWakeUpLine(PWR_WAKEUP_RTC, PWR_WUP_RISIEDG);
 HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_RTC);
 // Setup to wake every 2s
 if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, (2-1), RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)
 {
 Error_Handler();
 }
 // Restart IWDT 8s timeout
 HAL_IWDG_Refresh(&hiwdg);
 PWR_DEEPSTOPTypeDef sConfigDEEPSTOP = {.deepStopMode = PWR_DEEPSTOP_WITH_SLOW_CLOCK_ON};
 HAL_PWR_ConfigDEEPSTOP(&sConfigDEEPSTOP);
 HAL_PWR_EnterDEEPSTOPMode();

The code executes into DEEPSTOP mode, but instead of waking after 2s, the IWDT triggers after about 8s.

I did see something interesting - when I program the board with STM32CubeProgrammer, then it works correctly (i.e. wake after 2s) for only the first cycle; after that the IWDT always triggers after 8s. When I power cycle the board, the IWDT always triggers after 8s. It is almost as if the STM32CubeProgrammer clears some flag/state so that it works correctly once.

Technical Moderator
November 24, 2025

hello @marvdm 
At this point, I suspect that the issue is related to your clock frequency. It appears to be operating at a quarter of the expected speed (0.25 Hz) instead of 1 Hz.
Can you verify the content of the RTC_WAKEUPCLOCK_CK_SPRE_16BITS register at the start of each cycle and double-check the RTC prescalers to ensure that the output is actually 1 Hz?
Hope that helps
Gyessine

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
marvdmAuthor
Associate II
November 25, 2025

Hi Gyessine,

Thank you for your feedback. I've checked the RTC, and I can confirm that it output frequency is correct.

I've taken a step back and setup a loop to test the RTC wakeup timer without DEEPSTOP:

while (1) {
 // Toggle LED
 HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin);
 HAL_PWREx_EnableInternalWakeUpLine(PWR_WAKEUP_RTC, PWR_WUP_RISIEDG);
 HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_RTC);
 // Setup wakeup after 3s: 32kHz/16 = 500us * 6000 = ~3s
 HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 6000, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
 // Wait for RTC wakeup flag
 while (!__HAL_PWR_GET_FLAG(PWR_FLAG_RTC));
}

For above code I observe the BLUE LED toggle every 3s, as expected. I also confirmed RTC_IRQHandler() fires correctly.

However, when I add the code to config & enter DEEPSTOP, I get the same problem.

I've profiled the current consumption (see picture below), and it seems as if the device exits DEEPSTOP correctly the first time after programming. However, it seems to not exit DEEPSTOP the second time - it goes into an unknown state indefinitely where it draws ~7mA, and no code is executed.

stm32wl31.png

I don't know if this is relevant, but the hardware platform does not implement the SMPS - there is no specific setup made in code for this, and I don't know if it is relevant to the behavior in DEEPSTOP.

Thank you,

Marius

marvdmAuthor
Associate II
November 26, 2025

Hi Gyessine,

Just as a quick follow-up to the above feedback. I'm wondering if my problem is not related to the power configuration. My hardware platform does not implement the SMPS (i.e. designed as per Fig 9 of the datasheet, "STM32WL31xx application circuit without SMPS"). I've now added the following lines:

MODIFY_REG(PWR->CR5, PWR_CR5_NOSMPS, (SMPS_OFF<<PWR_CR5_NOSMPS_Pos));
MODIFY_REG(PWR->CR5, PWR_CR5_SMPSLPOPEN, (SMPS_LOW_POWER_OPEN<<PWR_CR5_SMPSLPOPEN_Pos));

 Unfortunately I still get the same behavior (i.e. failure to exit DEEPSTOP). Is there perhaps any additional configuration I need to make in order to run & DEEPSTOP without SMPS?

xy3dg12Best answer
Visitor II
April 6, 2026

Check this : 

无标题.png

marvdmAuthor
Associate II
April 25, 2026

Thank you @xy3dg12, that did the trick.

For future reference, below is the working solution - the device successfully and repeatedly enters deepstop and then exits (after 2s) from RTC wakeup.

// ...

// Setup wakeup on RTC internal event
HAL_PWREx_EnableInternalWakeUpLine(PWR_WAKEUP_RTC, PWR_WUP_RISIEDG);
// Clear RTC internal wakeup flag
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_RTC);
// Setup RTC wakeup in 2s
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, (2-1), RTC_WAKEUPCLOCK_CK_SPRE_16BITS);

// Only RTC RAM is preserved through deepstop; write value to detect
// reset due to wake from deepstop
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, 0x1234);
	
// Setup deepstop with LSE clocking RTC
PWR_DEEPSTOPTypeDef sConfigDEEPSTOP;
sConfigDEEPSTOP.deepStopMode = PWR_DEEPSTOP_WITH_SLOW_CLOCK_ON;
HAL_PWR_ConfigDEEPSTOP(&sConfigDEEPSTOP);

// Setup application base (BL jumps here upon wakeup from deepstop)
*(uint32_t*)0x20000014 = 0x10040000;

// Enter deepstop
HAL_PWR_EnterDEEPSTOPMode();
	
// cpu resets upon wake from deepstop, never get here

 

Associate II
March 20, 2026

Hi all,

I have the same behaviour with STM32WL31 in deep stop and wakup from IO Pins. I tested succefully the project PWR_DEEPSTOP on the demoboard NUCLEO-WL33CC2 (this mount a different micro STM32WL33). When I write the code  PWR_DEEPSTOP on my board that use WL31 microcontroller I have the same behaviour as decribed from MARVDM; after programmed the micro it seam to enter in deep stop and when I perss the wakeup pin it exit from deep stop, execute the main and go back in deep stop. If I wakeup again by the IO pin it not exit from deep stop but look like in an udefined state. From this state, if I reset by the NRST pin it restart, execute the main enter in deep stop but if I wakenup by IO pin it go in undefined state again.

Any idea?

Associate II
April 7, 2026

Thank you xy3dg12,

your suggestion was correct: I added this line:

*(uint32_t*)0x20000014 = 0x10040000;

 and look like solved my problem.

But I do not undestend why this solved my problem. Why my firmware enter in bootloadr when wakeup from DeepStop? Why did the first wake-up after downloading the firmware work, but the others didn’t? Why the demoboard NUCLEO-WL33CC2 have not the same problem?

In my opinion all of this smells like a BUG and the added line of code is just a workaround!

 

Simone

 

Visitor II
April 8, 2026

I traced the bootloader and found that it jumps directly to the application after a power-on reset. Upon the first wake-up, it reads the RCC_CSR register and interprets it as a reset rather than a wake-up event, consequently entering the application. It only reads the AppBase variable on the second wake-up. Therefore, the device can only wake up successfully once.

Technical Moderator
April 7, 2026

Hello @sbelcatronic 
For moderation purposes:
Since the issue appears to be resolved, I will mark the reply that solved the issue as the solution, please post your new questions
into a new thread.
BR
Gyessine

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.