cancel
Showing results for 
Search instead for 
Did you mean: 

Problem setting reload value for independent watchdog

danesh
Associate II
Posted on July 29, 2015 at 16:47

Hi all,

I am using a STM32F103 MCU and I want to set the reload value for independent watchdog (IWDG) so watchdog will reset the device (a timeout will occur) after ''t'' seconds. I am using the following code to initialize watchdog (for the moment I do not use LSI measurement and assume that the frequency of LSI clock is 40Khz, according to the reference manual):

void wd_init(uint32_t timeout) {

  IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);    // Enable write access to IWDG registers.

  IWDG_SetPrescaler(IWDG_Prescaler_32);            // IWDG timer clock will be (LSI / 32).

  IWDG_SetReload(timeout * LSIFreq / 32);

  IWDG_ReloadCounter();                            // Reload the IWDG counter (kick the dog for once!).

  IWDG_Enable();                                   // Enable IWDG (LSI will be enabled by hardware).

}

The unit of ''timeout'' is ''seconds''. The above code works fine only up to 4 seconds. I am turning on a LED whenever a reset due to the timeout happens, and up to 4 seconds, all resets are correctly happens each t seconds (t < 4s), but for values more that 4 seconds, the timeoout happens earlier and device keeps reseting however the timeout should not have happened. I have tested with LSI measurement using TIM5 CH4 (as stated in the example for IWDG) and the result is same. Is there anything that I am doing wrong?

Regards,

Dan.

7 REPLIES 7
danesh
Associate II
Posted on July 29, 2015 at 17:22

Some complementary info. I changed the prescaler from 32 to 256 and now the new code looks like below:

void wd_init(uint32_t timeout) {

  IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);    // Enable write access to IWDG registers.

  IWDG_SetPrescaler(IWDG_Prescaler_256);           // IWDG timer clock will be (LSI / 32).

  IWDG_SetReload(timeout * LSIFreq / 256);

  IWDG_ReloadCounter();                            // Reload the IWDG counter (kick the dog for once!).

  IWDG_Enable();                                   // Enable IWDG (LSI will be enabled by hardware).

}

The code now works fine for up to 20 seconds timeout and not for more than that which is still the problem.

Posted on July 29, 2015 at 18:13

The counter is only 12-bit, so you have to increase the prescaler so the math produces a number less than 4096.

For a 40 KHz source this equates to a maximum of around 26 seconds.

To extend it further you're going to have to start with a slower clock. 32.768 KHz would give you 32 seconds.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
danesh
Associate II
Posted on July 29, 2015 at 18:42

Is it possible to set the LSI frequency? AFAIK, LSI frequency can only be read for callibration, but here I have used a fixed value.

Posted on July 29, 2015 at 18:49

No, it is what it is, it's specified to be in the range of 30-60 KHz, nominally 40 KHz, my experience around 37 KHz, but haven't tested a statically meaningful number of them.

It's likely to be dependent to process, temperature and voltage.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
jpeacock
Associate II
Posted on July 29, 2015 at 19:57

The IWDG clock input is dedicated to the LSI oscillator so you can't change the clock source.

danesh
Associate II
Posted on July 29, 2015 at 22:06

Thanks! I thought that it should be like that.

danesh
Associate II
Posted on July 29, 2015 at 22:11

Thanks clive1! Helpful as usual! 🙂 I just wanted to know if there is any other way to define longer timeout than ~30 secs? I know that there can be watchdog with window. Would that be an alternative?

Thanks.