# \[ Electron \] : How can i use the hardware watchdog of the STM32F205?

**URL:** <https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823>\
**Category:** Firmware\
**Created:** [April 3, 2018, 12:22pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823 "2018-04-03T12:22:00Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![LucaM](https://avatars.discourse-cdn.com/v4/letter/l/2bfe46/32.png) [@LucaM](https://community.particle.io/u/LucaM)\
**Post date:** [April 3, 2018, 12:22pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/1 "2018-04-03T12:22:00Z")

</div>

Hi,

I’ve spent some time looking at the documentation and the Particle community, but i couldn’t find any reference on how to use the hardware watchdog of the Electron module.  
I’ve found something on [Photon](https://community.particle.io/t/watchdogs-on-the-photon/18254) and Core ( SparkIntervalTimer library) but nothing on electron.

I’m aware of the [apllication watchdog](https://docs.particle.io/reference/firmware/electron/#application-watchdog) but Im interested in a hardware level security, as example, something that can reset the uC if the code locks in a dead state because of bits flipped in RAM or because of erroneous jump of the program counter or in general because of a software or hardware fault.

Any clue on that?

thank you.

---

<div class="post-metadata">

**Author:** ![ScruffR](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/scruffr/32/6952_2.png) [@ScruffR](https://community.particle.io/u/ScruffR)\
**Post date:** [April 3, 2018, 12:22pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/2 "2018-04-03T12:22:56Z")

</div>

`SparkIntervalTimer` also works on the Electron (it uses the same µC as the Photon).

---

<div class="post-metadata">

**Author:** ![LucaM](https://avatars.discourse-cdn.com/v4/letter/l/2bfe46/32.png) [@LucaM](https://community.particle.io/u/LucaM)\
**Post date:** [April 3, 2018, 12:31pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/3 "2018-04-03T12:31:45Z")

</div>

oh, is it?  
I've not try to implement the library in my code, because i had a quick look to the [Source](https://github.com/pkourany/SparkIntervalTimer/blob/master/src/SparkIntervalTimer.cpp) and the Electron seems not supported.

Have you tested it before on Electron?

> 109 #else  
> 110 #error "\*\*\* PARTICLE device not supported by this library. PLATFORM should be Core or Photon \*\*\*"  
> 111 #endif

---

<div class="post-metadata">

**Author:** ![peekay123](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/peekay123/32/810_2.png) [@peekay123](https://community.particle.io/u/peekay123)\
**Post date:** [April 3, 2018, 12:37pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/4 "2018-04-03T12:37:39Z")

</div>

@LucaM, I just test compiled the SparkIntervalTimer on the web IDE with 0.6.0 and 0.7.0 firmware with an Electron as the target without any problems.

Using a hardware timer as a watchdog will ensure that it will fire if something stalls (vs the Application Watchdog) but doing a software reset is NOT the same as a hardware reset. This is where an external (hardware) watchdog may be a better choice.

---

<div class="post-metadata">

**Author:** ![ScruffR](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/scruffr/32/6952_2.png) [@ScruffR](https://community.particle.io/u/ScruffR)\
**Post date:** [April 3, 2018, 12:49pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/5 "2018-04-03T12:49:17Z")

</div>

The important bit in that code is _not_ the `#else` part but what it actually should contrast 😉

```cpp
#if defined(STM32F10X_MD) || !defined(PLATFORM_ID) //Core
...
#elif defined(STM32F2XX) && defined(PLATFORM_ID)	//Photon (ScruffR: and we also now know Electron too)
...
#else
  #error " ***PARTICLE device not supported by this library. PLATFORM should be Core or Photon***"
#endif

```

And since the Electron also runs a `STM32F2XX` it’s fine - the Electron was just not there at time of first contribution of the library.  
@peekay123, maybe the error message could be altered and the `|| !defined(PLATFORM_ID)` for Core may probably want changing as the Core does now have it declared too hence it may be confusing 😉  
However trying it despite the text would have revealed that it isn’t thrown anyway.

---

<div class="post-metadata">

**Author:** ![LucaM](https://avatars.discourse-cdn.com/v4/letter/l/2bfe46/32.png) [@LucaM](https://community.particle.io/u/LucaM)\
**Post date:** [April 3, 2018, 12:57pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/6 "2018-04-03T12:57:07Z")

</div>

Cool! I’m going to try it.

@peekay123  
Thankyou, however, I’m looking for a proper use of the watchdog timer, a piece of hardware that perform an hardware reset on the uC if the code stocks,(not a software routine that trigger a software reset).

Is SparkIntervalTimer the right library to use the built-in watchdog timer of the STM32F205?

(why should i use an external hardware when the STM32F205 has is built-in hardware watchdog?)

---

<div class="post-metadata">

**Author:** ![peekay123](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/peekay123/32/810_2.png) [@peekay123](https://community.particle.io/u/peekay123)\
**Post date:** [April 3, 2018, 1:00pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/7 "2018-04-03T13:00:54Z")

</div>

@LucaM, SparkIntervalTimer does not support the internal watchdog timer. The STM32F205 WDT or IDT is not currently supported and there are several firmware issues addressing this:

> <https://github.com/particle-iot/firmware/issues/1382>

> <https://github.com/particle-iot/firmware/issues/1503>

---

<div class="post-metadata">

**Author:** ![electronweather](https://avatars.discourse-cdn.com/v4/letter/e/e95f7d/32.png) [@electronweather](https://community.particle.io/u/electronweather)\
**Post date:** [April 7, 2018, 12:18pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/8 "2018-04-07T12:18:37Z")

</div>

Is it possible to use the internal watchdog timer with the Electron?

---

<div class="post-metadata">

**Author:** ![RWB](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/rwb/32/22599_2.png) [@RWB](https://community.particle.io/u/RWB)\
**Post date:** [April 7, 2018, 2:21pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/9 "2018-04-07T14:21:23Z")

</div>

Support for using the hardware watchdog is supposed to be coming in the 8.0 firmware version from what I have heard 🙂

---

<div class="post-metadata">

**Author:** ![tdasnoy](https://avatars.discourse-cdn.com/v4/letter/t/eb8c5e/32.png) [@tdasnoy](https://community.particle.io/u/tdasnoy)\
**Post date:** [October 9, 2018, 11:20am UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/10 "2018-10-09T11:20:05Z")

</div>

Hello everybody,

I’m also trying to use the IWDG. Looking into the firmware I found this file “stm32f2xx\_iwdg.h”

Using it in a simple example:

- after 30 sec config and enable WD
- with while(1){IWDG\_ReloadCounter();} no reset
- without while(1){IWDG\_ReloadCounter();} reset after ~1040ms
- using IWDG\_Prescaler\_256 or IWDG\_Prescaler\_4 does not change the reset period so I’m probably doing something wrong. I wanted to go for the maximum period between resets (~=32 sec) I also added the delays but do not know if it is needed?

```auto
#include "stm32f2xx_iwdg.h"

SYSTEM_THREAD(ENABLED);

void setup()
{
    Serial.begin(115200);
}

static unsigned long lastMillis = 0;
static unsigned long milPrev = 0;
static uint8_t t = 0;
static uint8_t once = 1;

void loop()
{
    if(!once)
    {
        unsigned long mil = millis() - lastMillis;
        if((mil-milPrev) > 1 ) // count 2ms untill WD reset
        {
            Serial.printlnf(" %lu",millis() - lastMillis);
            milPrev = mil;
        }
    }
    
    
    if(((millis() - lastMillis) > 1000) && once) 
    {
        t++;
        Serial.printlnf("t=%u",t);
        if(once && t==30)
        {
            once = 0;
            
            Serial.println("WD config");
            // 1. Enable write access to IWDG_PR and IWDG_RLR registers using
            // IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable) function*/
            IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
            
            // 2. Configure the IWDG prescaler using IWDG_SetPrescaler() function
            delay(500);
            IWDG_SetPrescaler(IWDG_Prescaler_256);
            delay(500);
            
            // 3. Configure the IWDG counter value using IWDG_SetReload() function.
            // This value will be loaded in the IWDG counter each time the counter
            // is reloaded, then the IWDG will start counting down from this value.
            delay(500);
            IWDG_SetReload(0xFFF);
            
            // 4. Start the IWDG using IWDG_Enable() function, when the IWDG is used
            // in software mode (no need to enable the LSI, it will be enabled by hardware)
            delay(500);
            
            uint8_t pvu = IWDG_GetFlagStatus(IWDG_FLAG_PVU) == SET;
            Serial.printlnf("pvu %u", pvu);
            uint8_t rvu = IWDG_GetFlagStatus(IWDG_FLAG_RVU) == SET;
            Serial.printlnf("rvu %u", rvu);
            delay(500);
            Serial.println("Reload");
            IWDG_ReloadCounter();
            
            delay(500);
            Serial.println("WD enable");
            IWDG_Enable();
            
            // 5. Then the application program must reload the IWDG counter at regular
            // intervals during normal operation to prevent an MCU reset, using
            // IWDG_ReloadCounter() function.

            //while(1){IWDG_ReloadCounter();}
        }
        
        lastMillis = millis();
    }
    
}

```

So it seems that the IWDG is working?  
Why is it officially not working? What am I missing?  
I do not plan to use Sleep in my application. Should I be careful with other things (OTA?)

---

<div class="post-metadata">

**Author:** ![thrmttnw](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/thrmttnw/32/13878_2.png) [@thrmttnw](https://community.particle.io/u/thrmttnw)\
**Post date:** [January 30, 2019, 8:23pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/11 "2019-01-30T20:23:05Z")

</div>

Thank you for listing this.

I am thinking that if it can be set to 32 seconds, and any blocking thing the system does can be over in less than 32 seconds, then it is usable. I am not sure the latter is always true when OTA software updating maybe with a 3-part OS upgrade for Electron.

Maybe possible to use System.disableUpdates(), and on a cloud signal restart without the watchdog, to allow an update within the next 15 minutes, then reverse when finished.

So I wonder what stops the watchdog (a reset is OK for this). And does anyone know how to get the pre-scaler setting to work? I could not find a working example online with the pre-scaler.

---

<div class="post-metadata">

**Author:** ![ScruffR](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/scruffr/32/6952_2.png) [@ScruffR](https://community.particle.io/u/ScruffR)\
**Post date:** [January 30, 2019, 9:12pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/12 "2019-01-30T21:12:58Z")

</div>

> [@tdasnoy](#):
>
> Why is it officially not working?

It is working - but it's working too good 😉  
Once started it can't be stopped any other way than with a reset but keeps running even in stop or standby mode and hence would reset your device while it's asleep, which is probably not desired.  
Additionally, as you already asserted, OTA updates would be interrupted by the IWDG since the update process wouldn't tickle the WDG.

However, there are ideas tossed around that may help out of these traps.  
e.g. for deep sleep (which would normally wake with a reset anyway) first reset the device with a retained deep sleep period. When this value is non-zero a STARTUP() macro should not start the IWDG again but copy that period, clear the retained version and engage the actual deep sleep phase with desired period. This way the IWDG won't interrupt deep sleep but on next sheduled wake the IWDG would again be enabled and the normal code can run.  
Rinse. Repeat.

Stop sleep (for more than the IWDG period) would be more tricky as the reset is inevitable to stop the IWDG.

---

<div class="post-metadata">

**Author:** ![thrmttnw](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/thrmttnw/32/13878_2.png) [@thrmttnw](https://community.particle.io/u/thrmttnw)\
**Post date:** [January 31, 2019, 6:23am UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/13 "2019-01-31T06:23:53Z")

</div>

Thanks, well a reset to stop is fine with me. Using retained sounds like a way to go.

OTA updates may be handled by announcing this to the device beforehand, to reset wo. restarting the dog for a period. A bit cumbersome to do manually when updating a large number of devices but should be well worth it.

> [@tdasnoy](#):
>
> using IWDG\_Prescaler\_256 or IWDG\_Prescaler\_4 does not change the reset period so I’m probably doing something wrong. I wanted to go for the maximum period between resets (~=32 sec) I also added the delays but do not know if it is needed?

Does anybody know how to get the pre-scaler to work?

---

<div class="post-metadata">

**Author:** ![tdasnoy](https://avatars.discourse-cdn.com/v4/letter/t/eb8c5e/32.png) [@tdasnoy](https://community.particle.io/u/tdasnoy)\
**Post date:** [February 1, 2019, 10:54am UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/14 "2019-02-01T10:54:27Z")

</div>

> [@ScruffR](#):
>
> It is working - but it’s working too good

No it is not. I've been using STM32 for a long time without Particle firmware and I haven't had any problems of this kind with the watchdog (enable, prescalers, reload,...).

It looks like the Hardware Watchdog timer is already used in the electron for another purpose hence the problem to modify prescaler. My guess is RTOS? Did not have the time or the motivation to dig further in the firmware code. Documentation is really lacking on this point. If someone could clarify this it would be great.

I ended up with an external Watchdog ~30 sec intervals, it's working perfectly (I'm not using any kind of sleep) even with OTA (In the unlikely case that the WD resets while flashing OTA, just retry).  
It was just a waste of time and money to get a feature that was already on the MCU...

---

<div class="post-metadata">

**Author:** ![peekay123](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/peekay123/32/810_2.png) [@peekay123](https://community.particle.io/u/peekay123)\
**Post date:** [February 1, 2019, 4:59pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/15 "2019-02-01T16:59:30Z")

</div>

@tdasnoy, the bootloader/OTA seems to use the IDWG:

> // Get the Bootloader Mode that will be used when IWDG reset occurs due to invalid firmware

---

<div class="post-metadata">

**Author:** ![thrmttnw](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/thrmttnw/32/13878_2.png) [@thrmttnw](https://community.particle.io/u/thrmttnw)\
**Post date:** [February 6, 2019, 4:05pm UTC](https://community.particle.io/t/electron-how-can-i-use-the-hardware-watchdog-of-the-stm32f205/40823/16 "2019-02-06T16:05:14Z")

</div>

Too bad. Got my hopes up there for a while. The existing ~1004ms is too tight.

For me an internal watchdog should be refreshed by the App, so an external watchdog it is then. Thank you for advising on the 30 seconds without sleeping. I will experiment with that together with sleeping.
