2025-10-23 8:43 AM
Hi Everyone,
I am facing an issue with my MCU entering low-power mode.
My code works fine when tested separately. I can successfully put the MCU into STOP 0 mode and wake it up through an EXTI line interrupt, but only when the Window Watchdog (WWDG) is disabled.
However, when I enable the WWDG, the MCU seems to get stuck at the WFI instruction when trying to enter STOP mode. It doesn’t proceed further or wake up through the EXTI line Interrupt. The only recovery option is a power cycle.
Has anyone faced a similar issue, or know what might cause this behaviour when WWDG is active?
I am open to sharing the source code.
Any suggestions or pointers would be appreciated!
Solved! Go to Solution.
2025-10-24 6:20 AM
After investigating, it appears that it is not possible to disable the WWDG without a hardware reset on STM32U0 microcontrollers. This limitation is by design to ensure system safety and reliability. Since WWDG is not supported in standby or stop mode, I don’t think it will be suitable for your use case.
2025-10-23 9:59 AM
> seems to get stuck at the WFI instruction
What makes you think this?
Could the WWDG be firing and resetting the chip?
2025-10-23 10:14 AM
Hello @suresh kumar1,
The issue arises because the WWDG is not operational in STOP mode due to the absence of the APB clock. To resolve this, you can either disable the WWDG before entering STOP mode and re-enable it upon waking up, or use an alternative low-power mode like Sleep mode where the WWDG can function.
Best regards,
2025-10-23 9:08 PM
No WWDG not resetting the chip.
Nothing happens after initiating STOP mode, I checked this by going into DEBUG mode, and the MCU was waiting at the WFI instruction inside the function: HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI); .
2025-10-23 11:24 PM
Hi @STackPointer64 ,
I don’t see any option to disable the Window Watchdog (WWDG) before entering STOP mode. Could you please guide me on how to disable it?
The issue is that the EXTI line interrupt does not wake up the MCU when the Window Watchdog is enabled.
Below is my currently implemented code:
static void SleepWakeUpMode(PowerManagerRunState_te PowerState)
{
WWDG__Clear();
HAL_SuspendTick(); // Stop SysTick interrupt
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON , PWR_STOPENTRY_WFI);
SystemClock_Config();
HAL_ResumeTick();
WWDG__Clear();
WriteRtcSram((uint32_t)GetSystemWakeupSource());
Wakeupsrc=ReadRtcSram();
CurrentPowerRunState = POWER_STATE_ACTIVE;
}*********Init*************
bool WWDG_Initialize(void)
{
#if(WATCHDOG_ENABLE)
if( WWDG_OK != WWDG_Init(&hwwdg))
{
return false;
}
return true;
#endif
}
WWDG_StatusTypeDef_te WWDG_Init(WWDG_HandleTypeDef *hwwdg)
{
/* Check validity of handler */
if (hwwdg == NULL || hwwdg->Instance == NULL) {
return WWDG_ERROR;
}
/* Validate Init parameters */
if (hwwdg->Init.Counter < COUNTER_MIN_VAL || hwwdg->Init.Counter > COUNTER_MAX_VAL) {
/* Counter must be in [0x40, 0x7F] range */
return WWDG_ERROR;
}
if (hwwdg->Init.Window > COUNTER_MAX_VAL || hwwdg->Init.Window > hwwdg->Init.Counter) {
return WWDG_ERROR;
}
if (hwwdg->Init.Prescaler > 7U) {
return WWDG_ERROR;
}
/* 1. Configure CFR: prescaler, window, and optionally EWI */
uint32_t cfr = 0U;
/* Set prescaler (WDGTB[2:0] at bits [13:11]) */
cfr |= ((hwwdg->Init.Prescaler << WWDG_CFR_WDGTB_POS) & WWDG_CFR_WDGTB_MASK);
/* Set window value (W[6:0] at bits [6:0]) */
cfr |= (hwwdg->Init.Window & WWDG_CFR_W_MASK);
/* Enable Early Wakeup Interrupt if requested */
if (hwwdg->Init.EWI_Enable) {
cfr |= WWDG_CFR_EWI;
}
/* Write configuration to CFR register */
hwwdg->Instance->CFR = cfr;
/* 2. Activate WWDG and set initial counter (CR register) */
uint32_t cr = (hwwdg->Init.Counter & WWDG_CR_T_MASK) | WWDG_CR_WDGA;
hwwdg->Instance->CR = cr;
return WWDG_OK;
}
*****************clear***************
bool WWDG__Clear(void)
{
#if(WATCHDOG_ENABLE)
if( WWDG_OK != WWDG_Clear(&hwwdg))
{
return false;
}
return true;
#endif
}
WWDG_StatusTypeDef_te WWDG_Clear(WWDG_HandleTypeDef *hwwdg)
{
/* Check handler validity */
if (hwwdg == NULL || hwwdg->Instance == NULL) {
return WWDG_ERROR;
}
/* Read current counter value */
uint32_t current_cnt = hwwdg->Instance->CR & WWDG_CR_T_MASK;
/* Check for early refresh */
if (current_cnt > hwwdg->Init.Window) {
return WWDG_ERROR;
}
/* Check for late refresh (counter expired or invalid) */
if (current_cnt < COUNTER_MIN_VAL) {
return WWDG_ERROR;
}
/* Valid refresh — reload counter */
uint32_t cr = (hwwdg->Init.Counter & WWDG_CR_T_MASK) | WWDG_CR_WDGA;
hwwdg->Instance->CR = cr;
return WWDG_OK;
}Please let me know if you need any further information.
2025-10-24 6:16 AM
You can't stop WWDG once enabled except through a system reset.
Perhaps switch to IWDG which works in stop mode.
2025-10-24 6:20 AM
After investigating, it appears that it is not possible to disable the WWDG without a hardware reset on STM32U0 microcontrollers. This limitation is by design to ensure system safety and reliability. Since WWDG is not supported in standby or stop mode, I don’t think it will be suitable for your use case.
2025-10-24 7:31 AM
Hi @STackPointer64 ,
Thanks for the detailed analysis.
Can I use the IWDG in STOP mode? I see that bit 17 of the FLASH_OPTR register is used to stop the IWDG counter in STOP mode.
If this is possible, could you suggest the necessary steps? Watchdog and low-power functionality are essential for my product.
2025-10-24 8:29 AM
Hello @suresh kumar1,
Yes IWDG can be used in STOP mode in STM32U0 according to the reference manual. But same as WWDG, once started cant be stopped unless by power cycle.
Best regards,
2025-10-24 2:34 PM
Hi @STackPointer64 ,
My idea is to freeze the Independent Watchdog (IWDG) counter in STOP mode so that the MCU will not reset due to the IWDG counter elapsing.
From my understanding, this can be achieved by clearing bit 17 (IWDG_STOP) of the FLASH_OPTR register, if I am right.
As per the reference manual, in STOP mode, the IWDG can be automatically frozen depending on the configuration of the IWDG_STOP bit in the FLASH_OPTR register.
So, the IWDG should not reset the MCU during STOP (sleep) mode, correct?
If both assumptions are correct, could you please share the steps or example code to:
Configure the IWDG to operate (or be frozen) in STOP mode, and
Set up the FLASH_OPTR register appropriately for this behaviour?