iwdg_init() and iwdg_feed()

Post here first, or if you can't find a relevant section!
pico
Posts: 73
Joined: Thu May 07, 2015 4:33 pm

Re: iwdg_init() and iwdg_feed()

Postby pico » Fri May 22, 2015 8:07 am

One difference between the ARM wd timers and the AVR timers is that you can't disable the ARM timers once initialized. Usually no big deal, but a difference worth noting.

User avatar
RogerClark
Posts: 5467
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: iwdg_init() and iwdg_feed()

Postby RogerClark » Fri May 22, 2015 8:14 am

One difference between the ARM wd timers and the AVR timers is that you can't disable the ARM timers once initialized. Usually no big deal, but a difference worth noting.


OK.

Thats interesting.

I guess this is for safety, i.e in case some random code accidentally turned off the WDT

pico
Posts: 73
Joined: Thu May 07, 2015 4:33 pm

Re: iwdg_init() and iwdg_feed()

Postby pico » Fri May 22, 2015 5:31 pm

To make the initialisation step a bit more obvious, you could use a wrapper like this to specify the timeout in ms directly:

Code: Select all

#define iwdg_init_ms(N) iwdg_init(IWDG_PRE_256,((N)/5))


So like this:

Code: Select all

#include <libmaple/iwdg.h>

#define iwdg_init_ms(N) iwdg_init(IWDG_PRE_256,((N)/5))

int snacks = 5;

void setup() {
  Serial.begin(115200);
  delay(4000); // allow a few secs to establish serial connection and open serial window
  //iwdg_init(IWDG_PRE_256, 1600); // init an 8 second wd timer by prescaling the ~50KHz clock and then calculating resulting ticks in 8 secs...
  iwdg_init_ms(8000); // or init an 8s wd timer a bit more obviously using a wrapper
  Serial.println("\r\nhmm, thats a mean looking dog!");
}

void loop() {
  if (snacks > 0) {
    Serial.println("nice doggy, here's a snack");
    iwdg_feed();
    --snacks;
  }
  else {
    Serial.println("uh oh, I've run out of snacks...");
  }
  delay(1000);
}


Anyway, just an idea.
Last edited by pico on Thu Jun 04, 2015 1:24 pm, edited 4 times in total.

User avatar
RogerClark
Posts: 5467
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: iwdg_init() and iwdg_feed()

Postby RogerClark » Fri May 22, 2015 7:50 pm

Or wrap them and rename to WDT_enable() like AVR

User avatar
RogerClark
Posts: 5467
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: iwdg_init() and iwdg_feed()

Postby RogerClark » Fri May 22, 2015 11:10 pm

OK

How about we use the same command as the AVR
e.g.

Code: Select all

wdt_enable(WDTO_15MS);// calls iwdg_init()

wdt_reset ();// calls iwdg_feed()



We'd just need to write some wrapper code to work out the prescaler

we could also define the time periods that are defined for AVR

http://www.nongnu.org/avr-libc/user-man ... aa4abea51f

I don't know if its worth allowing individual WDT times. People could just call the internal functions if they want more control

I'm not sure about WDT_disable();

Perhaps have code for it but have #error "ARM Does not support disabling the WDT"

pico
Posts: 73
Joined: Thu May 07, 2015 4:33 pm

Re: iwdg_init() and iwdg_feed()

Postby pico » Thu Jun 04, 2015 1:50 pm

I was reading today about the IWDG clock, and interestingly, it isn't very precise. This needs to be taken into account to avoid the watchdog going off either earlier or later than one might assume.

From http://embedded-lab.com/blog/?p=9662:

The dedicated separate clock of the IWDG hardware comes from Low Speed Internal (LSI) clock. It is not an accurate one as one might expect. This inaccuracy is due to the fact that the LSI is a RC oscillator. It has an oscillation frequency of somewhat between 30 – 60 kHz. For most applications it is assumed to have a mean frequency of 45 kHz though it is supposed to be around 32 kHz.


30-60KHz is obviously a huge range! I've found on the Maple mini clones I was playing with today that the effective clock for those devices is indeed about 45K. To be conservative, however, I'm using a notional value of a clock running at 51.2KHz. This leads to a simple macro calculation to convert ms to timer ticks:

#define iwdg_init_ms(N) iwdg_init(IWDG_PRE_256, ((N)/5) )

On my Maple minis, this results in the actual timeout being ~10% longer than nominal, i.e., a timeout value of 8000 ms counts down in ~8800 ms. But generally speaking, I'd rather a watchdog timer go off a bit late than too early.

Also note the count down tick register is only 12 bits wide, so trying to load a value of > 4095 will lead to unexpected results. This means the longest possible timeout settings corresponds to 20.475 secs (assuming the 51.2KHz clock).

User avatar
RogerClark
Posts: 5467
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: iwdg_init() and iwdg_feed()

Postby RogerClark » Thu Jun 04, 2015 10:05 pm

Is there any way to calibrate this against millis()

Is the WDT running off its own separate internal clock, and is there any way to read the value of the clock register ?

I guess this would still vary depending on temperature

User avatar
mrburnette
Posts: 1769
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: iwdg_init() and iwdg_feed()

Postby mrburnette » Thu Jun 04, 2015 11:37 pm

RogerClark wrote:Is there any way to calibrate this against millis()

Is the WDT running off its own separate internal clock, and is there any way to read the value of the clock register ?

I guess this would still vary depending on temperature


The way I read the data sheet is that the LSI is only RC if a 32K crystal is not installed... therefore, if the battery backup power domain is running off a crystal, the WDT should be accurate.

Of course, I could be completely wrong.

Ray

pico
Posts: 73
Joined: Thu May 07, 2015 4:33 pm

Re: iwdg_init() and iwdg_feed()

Postby pico » Fri Jun 05, 2015 5:00 am

mrburnette wrote:The way I read the data sheet is that the LSI is only RC if a 32K crystal is not installed... therefore, if the battery backup power domain is running off a crystal, the WDT should be accurate.

Of course, I could be completely wrong.

Ray


Not sure that would fix it -- the IWDT clock is designed to be independent of all other clocks, hence the "independent" in the description.

If you look at the clock diagram below, you can see the IWDG clock looks to separate from the RTC clock xtal. The RTC clock may use the LSI RC as an source (obviously a poor choice if it can be avoided!), the other options being the LSE Osc (external 32.768KHz xtal), and the HSE Osc (divided by 128) -- at least that what it look like to me. But the IWDG clock only has the LSI RC as an available source:

Clock-Internal-1024x366.png
Clock-Internal-1024x366.png (147.21 KiB) Viewed 360 times
Last edited by pico on Fri Jun 05, 2015 2:33 pm, edited 1 time in total.

User avatar
mrburnette
Posts: 1769
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: iwdg_init() and iwdg_feed()

Postby mrburnette » Fri Jun 05, 2015 11:56 am

... but the IWDG clock only has the LSI RC as an available source:


Yes, I agree.

Ray


Return to “General discussion”

Who is online

Users browsing this forum: Bing [Bot], michael_l, uXe and 2 guests