2024-04-04 08:30 AM
- STM32G0B0RE
Our controller was running fairly well but on occasion we were seeing the windowed watchdog trip(The IWDDGRSTF flag set on reboot.) We were not sure whether this was a too short or too long trip so decided to extend the window wider(set the Reload counter from 1800 to 2500.) The kick logic runs from the system clock and is set to reload the every 1.0 second or greater.
The original window should be running between ~781msec and 1.77 sec +/- the 32kHz clock inaccuracy. What is odd is that this work very well but on occasion would trip. But simply expanding the end of the window to 2.44 sec (~781msec to 2.44 sec) the watchdog trips frequently.
Is there some relationship between the two times that we did not understand from RM0454? Is there something wrong with the setup code below?
Thanks
void IWDG_Config(void)
{
// Source clock is the LSI(independent internal 32 kHz RC.)
// Enable IWDG (the LSI oscillator will be enabled by hardware)
LL_IWDG_Enable(IWDG);
// Enable write access to IWDG_PR and IWDG_RLR registers
LL_IWDG_EnableWriteAccess(IWDG);
// Set IWDG Prescaler value to 32. The clock is now
// 32kHz/32 = 1024Hz
LL_IWDG_SetPrescaler(IWDG, LL_IWDG_PRESCALER_32);
// Set IWDG Reload value to 1800.
// 1024 hHz has a period of 1/1024 = 0.9765msec
// // 0.9765msec * 1800 = 1.7577sec watchdog timeout
// LL_IWDG_SetReloadCounter(IWDG, 1800);
// 0.9765msec * 2500 = 2.44125sec watchdog timeout
LL_IWDG_SetReloadCounter(IWDG, 2500);
// Wait until RVU flag is reset to be sure that the reload value
// update operation is completed.
while(LL_IWDG_IsActiveFlag_RVU(IWDG) != RESET);
// Set the IWDG window value to 800.
// (0.9765msec * 800) = 781.25msec start window.
LL_IWDG_SetWindow(IWDG, 800);
// The watchdog window starts at 781msec and goes to 1.757seconds so the watchdog
// kick must happen in between these times.
// Kicked it after every 781msec but before every 1.757sec
// The WATCHDOG_KICK_COUNT is currently set to 900msec, so any changes in this function
// must be checked against this value as the main loop uses it to know when to kick the
// watchdog.
}
2024-04-04 10:05 AM
2024-04-04 01:02 PM
From RM0454:
If the reload operation is performed while the counter is greater than the value stored in the IWDG window register (IWDG_WINR), then a reset is provided.
We needed to use a higher number for the Window value as if you want to kick the window watchdog every second, the window value needs to be one second below the timeout value.
void IWDG_Config(void)
{
// Source clock is the LSI(independent internal 32 kHz RC.)
// Enable IWDG (the LSI oscillator will be enabled by hardware)
LL_IWDG_Enable(IWDG);
// Enable write access to IWDG_PR and IWDG_RLR registers
LL_IWDG_EnableWriteAccess(IWDG);
// Set IWDG Prescaler value to 32. The clock is now
// 32kHz/32 = 1024Hz
LL_IWDG_SetPrescaler(IWDG, LL_IWDG_PRESCALER_32);
// Set IWDG Reload value to 4000.
// 1024 hHz has a period of 1/1024 = 0.9765msec
// 0.9765msec * 4000 = 3.906sec watchdog timeout
LL_IWDG_SetReloadCounter(IWDG, 4000);
// Wait until RVU flag is reset to be sure that the reload value
// update operation is completed.
while(LL_IWDG_IsActiveFlag_RVU(IWDG) != RESET);
// From RM0454
// If the reload operation is performed while the counter is greater than the value stored
// in the IWDG window register (IWDG_WINR), then a reset is provided.
// If we want to kick the watchdog every second, then the window value needs to be 1 second
// below the watchdog timeout value. If it is a lower number, then when we kick the
// watchdog, the counter value will be Above the window value and we will trip the too
// early time. We need to insure that when we kick the watchdog, the countdown value is
// not zero AND also greater than the window value(this seems weird.)
// Set the IWDG window value to 3000.
// (0.9765msec * 3000) = 2.9295 sec.
LL_IWDG_SetWindow(IWDG, 3000);
// The watchdog timeout starts at 3.906sec and counts down to zero. As it is counting down
// we can not kick the watchdog until the counter falls below the window value of 2.9295 sec.
// The kick must occur after 3.906 - 2.9295 = 0.9767 seconds but before 3.906 sec.
// The WATCHDOG_KICK_COUNT is currently set to 2 seconds, so any changes in this function
// must be checked against this value as the main loop uses it to know when to kick the
// watchdog.
}