2025-06-08 11:35 PM - edited 2025-06-08 11:37 PM
Hi,
I have a situation where the configured watchdog on my STM32L031 does not trigger even though the MCU gets stuck in an I2C function. In my program flow, I first run through some initializations (as well as I2C_Init()) and then start the IWDG (Start_WDG()). I then try to establish an I2C connection to another device. In some cases this fails and I get stuck on line "while(!(I2C1->ISR & I2C_ISR_TXIS));". Surprisingly, in this situation the watchdog does not trigger as expected. I am of course aware that the code in this form is not properly programmed and error handling in this situation solves the problem (implemented a timeout which itself does a system reset). Nevertheless, it would be interesting to know why the IWDG in this version does not trigger.
Thanks in regard.
Greetings from Salzburg
2025-06-09 12:22 AM
Hi @Brigei !
Do you enable the clock LSI (disabled after reset) for the IWDG? The IWDG requires this clock source. Can be done in RCC->CSR register by enable bit LSION and wait until LSIRDY flag is set by hardware.
Greetings from Graz.
2025-06-09 12:25 AM
Don't see issues with your Start_IWDG() code, provided Update_IWDG does the right thing.
The first line will freeze IWDG when the debugger halts the MCU. Did you try without debugger attached? How did you then find out that the MCU "get stuck on line ..."
hth
KnarfB
PS: Better use the "insert code sample button" for inserting code here.
2025-06-09 12:44 AM
Yes LSI is enabled. When IWDG is enabled then, according to de reference manual, the LSI can't be disabled any more. So there shouldn't be a problem with that.
2025-06-09 12:48 AM
Welcome to the forum.
As @KnarfB mentioned, please see How to insert source code - not as images.
Please show your code for updating the Watchdog.
2025-06-09 12:56 AM
The "Update_IWDG" is a definition with "IWDG->KR = 0xAAAA".
When I analyze the whole thing with the debugger, I initially just let the program run. When I then press "pause," the program counter always points to the while loop.
If I try the whole thing without a debugger, the MCU also doesn't behave as expected. For example, it doesn't respond to a button press, which should trigger something else (the ISR is most likely executed correctly, but it has no effect because after the ISR, it jumps back to the while loop). If a reset were to be triggered by the IWDG, I would certainly detect it via the reset control bits.
So for me it's clear that the MCU gets stuck and the IWDG doesn't fire. I read somewhere that the I2C peripheral, when totally busy, could block the WDG. Could that really be?
2025-06-09 1:53 AM
But where do you do the Watchdog updates during the running program?
2025-06-09 2:15 AM
@Brigei wrote:Yes LSI is enabled. When IWDG is enabled then, according to de reference manual, the LSI can't be disabled any more. So there shouldn't be a problem with that.
Okay. Yes I know that the LSI can't be disabled.
About the LSI and the IWDG:
Tried it now on a STM32H745 and it's seems not necessary first to enable LSI before writing to the IWDG registers. Seems the IWDG enables the LSI automatically. Didn't know that before, because I never used the watchdogs.
But about your project:
Is it really necessary to use the watchdog when I2C hangs? Because the watchdog resets the whole system. Wouldn't it be better if you use a timeout in your while loop and return an error code? And maybe retry the I2C communication? And as @Andrew Neil mentioned where you refresh the watchdog periodically? I had a similar issue on AVR devices because I didn't refresh the watchdog. Therefore the MCU always resets.
2025-06-09 2:21 AM
@JohannesK wrote:
I had a similar issue on AVR devices because I didn't refresh the watchdog. Therefore the MCU always resets.
That sounds like the opposite problem!
It sounds like @Brigei's problem is that the WD is being refreshed where it shouldn't be.
@Brigei Hence the need to know how, exactly, you are refreshing the Watchdog.
2025-06-09 2:22 AM - edited 2025-06-09 2:35 AM
In my main loop (not in some ISR which potentially get triggered) - which generally works fine and exactly like expected (WDG fires when i set the counter just not long enouth). When debugging (setting a breakpoint right after the while loop) i can see that the while loop doesn‘t exit any more.