Reputation: 1801
I using an STM32 (L0 5) HAL I need to disable IWDG or WWDG before entering in STOP mode. The below code is working fine until IWDG is resetting the MCU from STOP mode. For WWDG usage this is much faster and reset before HAL_PWR_EnterSTOPMode is called, despite HAL_WWDG_Refresh is called after each line. I tested also those scenarios also on Nucleo L05.
iwdgHandle.Instance = IWDG;
iwdgHandle.Init.Prescaler = IWDG_PRESCALER_64;
iwdgHandle.Init.Window = 4095;
iwdgHandle.Init.Reload = 4095;
if (HAL_IWDG_Init(&iwdgHandle) != HAL_OK) // almost 7secs until refresh has to be called
{
_Error_Handler(__FILE__, __LINE__);
}
HAL_PWR_EnableWakeUpPin(WakeSpi_Pin);
HAL_PWREx_EnableUltraLowPower(); // Enable Ultra low power mode
HAL_PWREx_EnableFastWakeUp(); // Enable the fast wake up from Ultra low power mode
HAL_SuspendTick();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
Upvotes: 5
Views: 22082
Reputation: 423
The only way to disable IWDG at runtime is:
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
// Initialize the Option Bytes structure
FLASH_OBProgramInitTypeDef OBInit;
HAL_FLASHEx_OBGetConfig(&OBInit);
// Set the IWDG_SW bit
OBInit.OptionType = OPTIONBYTE_USER;
OBInit.USERType = OB_USER_IWDG_STOP;
OBInit.USERConfig = OB_IWDG_STOP_FREEZE; //to enable, use OB_IWDG_STOP_RUN
// Write the Option Bytes
HAL_FLASHEx_OBProgram(&OBInit);
// Launch Option Bytes programming
HAL_FLASH_OB_Launch();
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
To disable/enable IWDG at standby, use OB_USER_IWDG_STDBY and OB_IWDG_STDBY_FREEZE / OB_IWDG_STDBY_RUN instead
Upvotes: 0
Reputation: 353
I have selected the suspend watchdog counters when halted in the debug options.
This code is in the first user section after init in main(). In the .ioc file I have set the pre scaler to 128 (at 168MHz gives about 3.12 mS per WD count) the window value at 120, and the free runner counter reset to 127
That means between 127 and 120 trying to refresh will cause a restart. Between 119 and 64 you can refresh the WWDG (this is a very wide window also the code I have is cheating in that its looking at the internal registers, i.e. its for debugging the thing; IRL you should use it to validate timing of task loops etc)
// code to put in main() user init
//
int i,old_i=0,cnt=0;
do {
//HAL_WWDG_MspInit(&hwwdg);
int i = hwwdg.Instance->CR;
if ( (i-128) < 120 ) HAL_WWDG_Refresh(&hwwdg);
asm("nop");
HAL_Delay(1);
cnt++;
}
while ( i == old_i && cnt );
This is the watchdog as I have it set for DEBUG (with a wide refresh window).
The hwwdg.Instance->CR register seems to hold the count+128. But using this code with 1mS delays etc I can refresh the WWDG . The cnt variable gives an indication of how many milli-seconds have passed before the watchdog has counted down sufficiently to allow a valid refresh.
For the last few hours I was simply getting mystery resets!
Solved for me! I;ll tighten the window and configure it for my tasking model.
Upvotes: 0
Reputation: 1
As previously mentioned, there is a solution involving option bytes. I utilized the STM32Cube Programmer application and disabled the IWDG_STOP option within the user options. This action freezes the watchdog timer when entering the stop mode.
Upvotes: 0
Reputation: 21
There's a flash option byte that you can clear that will prevent the IWDG or the WWDG timers from counting while in stop mode.
Upvotes: 2
Reputation: 783
I have the (somehow) same problem, so it's what I have done:
I use HAL library, and it firstly initializes HAL_Init();
, then calls SystemClock_Config();
, and after that it starts initializing peripherals, including iwdg
. (You can also do it without HAL).
So, when I want to go to stop mode, I restart the system using HAL_NVIC_SystemReset();
, and when micro restarts, just after SystemClock_Config();
I check for previous system restart reason (check this). If it's software reset, I go to stop mode and don't let IWDG to be initialized.
Simple, easy.
psudo code:
1. instead of directly going to STOP mode -> make a software restart using HAL_NVIC_SystemReset();
//After restart and configuring system clocks (before initializing other peripherals)
2. if(previous restart reason == software restart) {
goto stop mode /* we don't init iwdg */
} else {
continue initializing peripherals.
}
Upvotes: 1
Reputation: 920
The Independent watchdog can not be stopped in any processor mode. You have to wake up regularly to reload the watchdog. What you can do is change the prescaler to maximum so the watchdog is counting slowly.
IWDG will only be stopped if you disconnect the controller from the power supply.
Upvotes: 6