I have repeatedly observed that changing the watchdog prescaler on a running watchdog from 16 down to 4 usually causes the watchdog counter to eventually stop decrementing. I assume this happens due to something like decreasing the prescaler value below the internal prescaler counters value. Sometimes it can be decreased and keeps running.
Anyways, I cant find any notes in the reference manual to say not to change the prescaler. IT is also a workaround to intentionally (or accidentally) stop a watchdog from running!
My code is set up correctly, window watchdog works exactly as expected. Only when reducing the prescaler to slow the watchdog down does it become and issue. The down counter stops decrementing as seen in the debugger and in my debug print output. No watchdog interrupt ever occurs if the down counter is stopped.
Solved! Go to Solution.
I'm not necessarily proposing a "Bug" in the silicon. But, it may be that there are usage limitations that are not documented. If someone can tell me how it is possible to reliably see the watchdog stop counting down, when it is meant to be impossible to stop it, then that would be great too. Maybe I had brain failure and messed up setting the prescaler. Maybe I made it so slow it appeared to not be counting down!
ANSWERED - While preparing an example that demonstrates this problem happening I stumbled upon what was going on and it makes sense. The watchdog counter does indeed cease to count down when its prescaler is changed, but not forever. Most likely long enough to cause a timing problem and watchdog reset if you are using the window feature.
Imaging the prescaler is a down counter that decrements the watchdog timer each time it reaches zero, then resets itself to the prescaler value (-1). So for a prescaler factor of 16, it decrements the watchdog counter every 16 clock counts. Now, say this prescalers counter is at 15 and you reduce the prescaler value to 4. You are expecting the watchdog counter to now decrement every four counts. But, for the first period the prescaler has to count all the way down to zero so it will take 15 clocks before the first time the watchdog counter is decremented. During this time the watchdog counter remains at a constant value. Kind of obvious really after you think about it, standard timer behavior without shadow registers.
In my case, this additional 11 counts equates to 5.5ms. This would not really be an issue if not using the window function. A risk that an expected watchdog reset could take longer but. If using the window function then you rely on another timer (tick count based maybe) to let you know if it has been long enough since the last kick to be allowed to kick again. So, you kick the dog, and think you are not allowed to kick it again for say 10ms, but it got stalled for 5.5ms by the prescaler change. So, when you go to kick it after 10ms, it has not counted down enough and you kick it inside the window and BOOM!
I have attached a minimal example (STM32H753ZITx and STM32CubeIDE) showing this happening for future reference. If you place a breakpoint on the line wdogslowed = 1, then after it is hit, place a breakpoint on the line 155 lastWDogKickTime = now then you can watch the WWDG CR counter not decrementing in the SFRs view. Eventually you will see it start to decrement again.