Using a watchdog timer to restart an MKR 1010 WiFi

Hello all,

I am currently simply trying to figure out how it is possible to create some code that would allow me to execute a reset when the program gets stuck for too long.

I am using some AWS WiFi connectivity functions, and if connection is lost, upon reconnection the program has gotten stuck. So if a reconnection is not found for ~10 mins, then I would like to perform a reset.

I have not had any luck with the other post similar to this which was closed last year.

Best,
Anthony

Please read and use this topic: How to get the best out of this forum - Using Arduino / Project Guidance - Arduino Forum
It's not possible to give useful replies to Your wording.

1 Like

have a look at WDTZero library - it gives examples of using WDT - I have tested it on a MKRFOX 1200

1 Like

@horace thank you! I will test this out. I appreciate your quick response! I think I tried this and found that the program does not resume again. I think this does some sort of shut off? once the timer runs out it is done forever.

Hi @anthonylimon

The issue with the WDTZero library is that it doesn't take into account the time taken to synchronise registers on the SAMD21.

The SAMD21 has the advantage of a flexible clock system that allows practically any on-chip or external clock source to drive its peripheral modules, such as its TCC/TC timers, RTC, WDT etc... The disadvantage however is that certain registers have to be read and/or write synchronised between the peripheral and the CPU, this can take up to 5 to 6 clock source cycles.

The problem occurs if the clock source that's driving the peripheral is slow, such as the on-chip, low power 32.768kHz oscillator usually used to clock the watchdog. In this case, resetting the watchdog by writing CLEAR register requires a synchronisation time of 5 to 6 milliseconds.

The standard procedure for write synchronisation is to block and wait for the periperhal's register to synchronise:

WDT->CLEAR.reg = WDT_CLEAR_CLEAR_KEY;      // Reset the watchdog
while(WDT->STATUS.bit.SYNCBUSY);           // Wait for synchronisation

This works just fine if the peripheral is clocked at 48MHz like the CPU, but causes the program to block for 5 to 6 millisconds while writing to the watchdog's CLEAR register. This can be problematic if your program requires a fast loop time.

The solution is to use an if() statement in the loop(), to check whether register synchronisation is taking place, and only reset the watchdog if it isn't:

if (!WDT->STATUS.bit.SYNCBUSY)              // Check if the WDT register CLEAR register is not being synchronized
{
    WDT->CLEAR.reg = WDT_CLEAR_CLEAR_KEY;   // Reset the watchdog timer
}

This allows the watchdog to be reset without blocking. It might be worth modifying WDTZero library's clear() function, since others have raised a pull request for this change on Github, but the owner hasn't responded.

This issue was first described here:

1 Like

Wow. I really appreciate this in depth explanation. Exactly what I was looking for! I will try to implement this information. (As soon as I figure out how to reprogram my Arduino after getting it stuck in an infinitely resetting watchdog timer haha.. oops)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.