2025-03-19 5:28 AM
1. [Part Number] STM32WL33CC1
2. [Environment] Windows OS, STM32CubeIDE version 1.18.0, Firmware package STM32Cube FW_WL3 V1.1.0
3. [Schematics] STM32 Nucleo-64 development board
4. [Details] See below.
5. [Expected behavior] When the device is woken up from deep sleep the LD2 turns on
6. [How to reproduce] Run ST PWR_DEEPSTOP example
7. [Occurrence] Consistent
8. [Sanity checks] I have tried reading various registers to see if I can see a difference in behaviour.
The following code is based on the ST PWR_DEEPSTOP example, with minor modifications, as indicated in the comments. However, it does not behave as expected.
Ideally, after a power-on reset, the device should blink LD1 for 5 seconds before entering deep sleep. It appears to do so, as the debugger disconnects likely due to various peripherals shutting down to conserve power.
The issue arises when the device is woken up by pressing the B1 button on the Nucleo-WL33 board. While the device does wake up as expected, it never reaches the section of code intended to check if it was woken from deep sleep.
Since debugging is not possible after waking up, I added code to turn on LD2 upon entering this block and turn it off afterward. However, this behavior is never observed, indicating that the block is never executed.
if (__HAL_PWR_GET_FLAG(PWR_FLAG_DEEPSTOPF) != RESET)
{
BSP_LED_Off(LD2);
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_DEEPSTOPF);
}
When program is ran, the LD2 comes on as expected but never gets turned off even though I am assuming that I am waking-up from a deep-sleep.
Question is what am I missing?
See full code below. I have slightly modified the standard ST example but adding the LD2 as explain alread.
#include "main.h"
#define LED_TOGGLE_DELAY 100UL
PWR_DEEPSTOPTypeDef sConfigDEEPSTOP;
static uint32_t TimingDelay = LED_TOGGLE_DELAY;
void SystemClock_Config(void);
void PeriphCommonClock_Config(void);
static void MX_GPIO_Init(void);
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* Uncomment to be able to debug after wake-up from Deepstop. Consumption will be increased */
//HAL_DBGMCU_EnableDBGDeepstopMode();
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* Configure LD1 */
BSP_LED_Init(LD1);
/* Configure LD2 */
BSP_LED_Init(LD2);
BSP_LED_On(LD2);
/* Configure LD3 for error handler */
BSP_LED_Init(LD3);
/* Check if the system was resumed from Deepstop mode */
if (__HAL_PWR_GET_FLAG(PWR_FLAG_DEEPSTOPF) != RESET)
{
/* Turn off LD2 */
BSP_LED_Off(LD2);
/* Clear Deepstop flag */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_DEEPSTOPF);
/* Check and Clear the Wakeup flag */
if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUFA12) != RESET)
{
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUFA12);
}
/* Wait that user release the USER push-button */
BSP_PB_Init(B1, BUTTON_MODE_GPIO);
while (BSP_PB_GetState(B1) == GPIO_PIN_RESET) {}
}
/* Initialize the USER push-button to generate external interrupts */
BSP_PB_Init(B1, BUTTON_MODE_EXTI);
/* Turn on LD1 */
BSP_LED_On(LD1);
/* Insert 5 seconds delay */
HAL_Delay(5000);
/* The Following Wakeup sequence is highly recommended prior to Deepstop mode entry
- Enable wakeup
- Clear wake up pin flag depending in edge detection & pin level.
- Enter the Deepstop mode.
*/
/* Enable WakeUp Pin PWR_WAKEUP_PIN0 connected to */
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PORTA, PWR_WAKEUP_PIN0, PWR_WUP_RISIEDG);
/* Clear all related wakeup flags*/
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUFA12);
sConfigDEEPSTOP.deepStopMode = PWR_DEEPSTOP_WITH_SLOW_CLOCK_ON;
/* Enter the Deepstop mode */
HAL_PWR_ConfigDEEPSTOP(&sConfigDEEPSTOP);
HAL_PWR_EnterDEEPSTOPMode();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
Many thanks in advance.
Ola
2025-03-30 12:44 PM - edited 2025-03-30 12:44 PM
no answer unfortunately, but me having the same issues and maybe some more details.
I am observing the same problem when testing with the Nucleo-WL33CC1 board for both the PWR_DEEPSTOP and the PWR_DEEPSTOP_RTC example.
I could keep the debugger connected by switching to Deepstop2 mode via
MODIFY_REG_FIELD(PWR->DBGR, PWR_DBGR_DEEPSTOP2, 1);
When waking up the DEEPSTOPF flag as well as the WAKEUP_ISC flag and the whole CSR register are 0. The memory address 0x2000 000C which based on the reference manual indicates whether the system has been woken up from Deepstop mode is 0x01000000. I didn't find any information how to interpret this though.
Was anyone more successful in detecting a wakeup from Deepstop?
2025-04-14 6:10 AM
I have same problem with Wb09KE.... any soluitons?
2025-04-28 4:35 AM
I've escalated this behavior internally (under internal ticket number 208687) and I will be back to you with news ASAP.
Best Regards.
STTwo-32
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.
2025-06-12 4:06 AM
Hello folks,
any thoughts about that?
have a nice day!
2025-07-02 8:39 AM
I too am experiencing a problem when waking up from DEEPSTOP - the line
__HAL_PWR_GET_FLAG(PWR_FLAG_DEEPSTOPF)
Doesn't ever return a non-zero value after waking up with either of my wakeup sources configured by:
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PORTA, PWR_WAKEUP_PIN0, PWR_WUP_FALLEDG);
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PORTA, PWR_WAKEUP_PIN11, PWR_WUP_FALLEDG);
on a custom PCB. Wakeup has been verified, current has been verified, it's just that the PWR->EXTSRR
register doesn't show the DEEPSTOPF bit set upon wakeup.
Any resolution?
2025-08-28 11:14 AM
This seems like a big problem, as there has been no response so far.
2025-08-29 2:21 AM
Hi All,
The following code provides a workaround for an issue with the deepStopMode feature of the WL33, originally reported in March 2025. The main problem identified was that the macro
__HAL_PWR_GET_FLAG(PWR_FLAG_WUFA11)
did not return the expected status of the wakeup pins or the deepStopMode state.
Although the initial report focused on testing with the macro __HAL_PWR_GET_FLAG(PWR_FLAG_DEEPSTOPF), the original intent was to configure the wakeup pins to properly resume the WL33 microcontroller from deepStopMode.
The root cause appears to be that the flag states are only valid during a portion of system startup and do not persist until execution reaches main(). To address this, the weak function CPUcontextRestore() can be overridden by the user to preserve variables that must remain consistent across deepStopMode cycles.
The workaround introduces a variable placed in the noinit section of RAM, ensuring that it is not reset during a typical deepStopMode restart. The CPUcontextRestore() function is then used to check the wakeup reasons and update the relevant bit fields in the ramSavedContext data structure.
It is important to ensure that no other tasks or interrupts are running before attempting to enter deepStopMode; otherwise, the transition will fail.
Example scenario
In this example, GPIO pin PA11 of the STM32WL33X is connected to a sensor’s interrupt pin, allowing the sensor to wake the microcontroller from deepStopMode. Additionally, while the device is in sleep mode, the RTC generates a periodic interrupt every 15 seconds, enabling the system to wake up and perform housekeeping tasks.
Caveat
This code has not been fully tested on its own; it was assembled from portions of a working project. The intent is simply to provide a starting point for others who may be struggling with the same deepStopMode issue.
typedef struct
{
unsigned char WakeupCount;
struct
{
unsigned char pa11:1;
unsigned char :7;
};
} RamSavedContext_t;
/*
This variable is defined in system_stm32wl3x.c so we need to expoose it to our
main module by using the keyword extern. The data field WakeupFromSleepFlag
in RAM_VR structure is set depending on whether a POR or not
*/
extern RAM_VR_TypeDef RAM_VR;
/*
This is our custom variable in must be placed in a noinit section which
wiped during deepstop restarts.
obviously because it is in ram if power is removed contents is lost
*/
RamSavedContext_t ramSavedContext __attribute__((section(".noinit")));
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_RTC_Init();
/* USER CODE BEGIN 2 */
if (RAM_VR.WakeupFromSleepFlag != 1)
{
// We should only enter this block on POR so we
// simply reset our custom variable and then enter
// deep stop mode.
memset(&ramSavedContext, 0, sizeof ramSavedContext);
enterDeepstopMode();
}
/* USER CODE END 2 */
while (1)
{
if (ramSavedContext.pa11)
{
ramSavedContext.pa11 = 0;
// If we get into this block it means that we were
// woken up from deep stop mode because of the configured
// wakeup pin which in this case is PA11
}
else if (ramSavedContext.other_wakeup_pin)
{
// if other pin configured.
// (1) Add pin to RamSavedContext_t struct
// (2) Add to configure pin in deepStopMode() function
// (3) Test and set flag in CPUcontextRestore() function
// (4) Clear flag when entering.
}
else
{
// if get here it means that the rtc is responsible for wakeup
// from deepStopMode so simply handle whatever you want
}
ramSavedContext.WakeupCount++; // Keep track how many times woken up
enterDeepstopMode();
}
}
/* USER CODE BEGIN 4 */
*/
void enterDeepstopMode()
{
const int WakeUpCounter = 15; // rtc wakeup every seconds
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
/* Clear Deepstop flag */
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_DEEPSTOPF);
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF_ALL);
/* Enable wakeup for RTC */
HAL_PWREx_EnableInternalWakeUpLine(PWR_WAKEUP_RTC, PWR_WUP_RISIEDG);
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, WakeUpCounter - 1, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PORTA, PWR_WAKEUP_PIN11, PWR_WUP_RISIEDG);
MODIFY_REG_FIELD(PWR->DBGR, PWR_DBGR_DEEPSTOP2, 1);
PWR_DEEPSTOPTypeDef sConfigDEEPSTOP = {.deepStopMode = PWR_DEEPSTOP_WITH_SLOW_CLOCK_ON};
HAL_PWR_ConfigDEEPSTOP(&sConfigDEEPSTOP);
/* Enter the Deepstop mode */
HAL_PWR_EnterDEEPSTOPMode();
__NOP(); // You must never get here if deep stop mode entered correctly
}
/*
* Override the __WEAK void CPUcontextRestore(void) function defined
* and called from system_stm32wl3x.c
*/
void CPUcontextRestore(void)
{
if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUFA11))
{
ramSavedContext.pa11 = 1;
}
}
/* USER CODE END 4 */