iwdg_init() and iwdg_feed()

pico
Thu May 21, 2015 4:23 pm
Has anyone yet tested these libmaple independent watchdog functions as working for sketches built with IDE 1.6.x?

RogerClark
Thu May 21, 2015 8:44 pm
I don’t recall anyone ever mentioning either of these

Can you elaborate on their function ?


mrburnette
Thu May 21, 2015 11:38 pm
RogerClark wrote:I don’t recall anyone ever mentioning either of these

Can you elaborate on their function ?


RogerClark
Thu May 21, 2015 11:52 pm
Ray

Thanks for that.

I don’t recall anyone every testing those functions.


pico
Fri May 22, 2015 5:18 am
RogerClark wrote:Ray

Thanks for that.

I don’t recall anyone every testing those functions.


RogerClark
Fri May 22, 2015 5:34 am
@pico

Looking in the source code, those are the only two functions in iwdg.c, which is described as “Independent watchdog (IWDG) support”

So I suspect thats it, in terms of what was implemented by LeafLabs. That doesnt mean to say the STM32 doesn’t have more funky stuff it can do,
We are really just scratching the surface of its functionality in a lot of places ;-)


pico
Fri May 22, 2015 6:25 am
Fair enough — I suppose there’s a good chance it would all “just work” then. They were the wdt functions I was familiar with back in the old Maple 0.18 days… I was just wondering if people were still using these after the maplelib port.

Perhaps using a wdt less common than I assume? I tend to think of it as fairly basic functionality (although I know in the Arduino world for a long time wdt were considered too “dangerous” for beginners, and early bootloaders didn’t support it.)

And even the Due to this day doesn’t support wdt without a bit of hacking of the core files! (although I believe Bob Cousins has had a pull request accepted that should make it possible “out of the box” starting with IDE 1.6.5).

Here’s a little test sketch that should test whether it’s been implemented… unfortunately I don’t have convenient access to a Maple clone to test it right now (but I have some mini clones on order). But if someone wants to run it and see whether it resets after 8 seconds, I would appreciate it!

#include <libmaple/iwdg.h>

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, 1250); // init an 8 second wd timer
Serial.println("\r\nhmm, that's 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);
}


RogerClark
Fri May 22, 2015 6:52 am
Yes

It resets after 8 secs on a maple mini

nice doggy, here’s a snack
nice doggy, here’s a snack
uh oh, I’ve run out of snacks…
uh oh, I’ve run out of snacks…
uh oh, I’ve run out of snacks…
uh oh, I’ve run out of snacks…
uh oh, I’ve run out of snacks…
uh oh, I’ve run out of snacks…
uh oh, I’ve run out of snacks…

I’m not sure I’m seeing things from the start, as its hard to get to the serial monitor in time

PS. Should work on any STM32 won’t it ???

PPS.

I guess we should include that header in the core headers or perhaps wrap those core functions in some nice name??


pico
Fri May 22, 2015 7:32 am
Thanks Roger… that looks like it’s resetting after 8s of “no snacks”. 8-) (Probably should have put a delay in the setup before the first message to give it time to reestablish the serial connection and to open the window.)

I can’t remember if it used to be that you had to include the iwdg.h header explicity in your sketch or not, but I seem to think that may have been the case. Probably no downside in including it automatically, however, given the guard #ifdefs in iwdg.h.

Not sure if it will work on any stm32 device, but it wouldn’t surprise me if it did. The iwdg with a 40KHz timer is pretty standard across a range of devices, I believe, so I would expect all the registers would be accessible by the same name across devices.


RogerClark
Fri May 22, 2015 8:01 am
I just tested it

And it needs the include

I’ll include it in Arduino.h or similar do that you wont need to include it


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.

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
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:

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


RogerClark
Fri May 22, 2015 7:50 pm
Or wrap them and rename to WDT_enable() like AVR

RogerClark
Fri May 22, 2015 11:10 pm
OK

How about we use the same command as the AVR
e.g.
wdt_enable(WDTO_15MS);// calls iwdg_init()

wdt_reset ();// calls iwdg_feed()


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).


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


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


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


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


smithy
Mon Aug 29, 2016 12:48 am
Since no one posted what came out of this i´m asking if there is a more precise way of using the WD timer ?

#include <libmaple/iwdg.h>
#define iwdg_init_ms(N) iwdg_init(IWDG_PRE_256,((N)/5))

unsigned long temp;
void setup() {
Serial.begin(19200);
delay(4000); // allow a few secs to establish serial connection and open serial window
Serial.println("Begin");
//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(200); // or init an 8s wd timer a bit more obviously using a wrapper
temp = millis();
}

void loop() {
Serial.println(millis()-temp);
delay(10);
}


RogerClark
Mon Aug 29, 2016 1:21 am
The problem is that the watch dog clock is not crystal controlled , its an internal RC clock whose frequency will vary with temperature and can be different for different batches of chips.

The clock frequency is around 40 kHz (between 30 kHz and 60 kHz). For more details, refer to
the electrical characteristics section of the datasheets.

You would need to calibrate the WDT value based on the external crystal

To do this you would need to select the RTCCLOCK to run from the LSI, (as this is the same oscillator that the WDT uses).

Work out what speed its running at, and calculate the divider and preload values needed for the actual time you need.

You would need to re calibrate periodically, to ensure that value gets updated as the oscillator frequency changes as the device heats up (as it will when its in use)

A lot of systems do this not just for the WDT but often for the RTC.

I’m also a bit curious about why you need this to be so accurate, in my experience the WDT is not expected to be a precise timeout


smithy
Mon Aug 29, 2016 1:39 am
I need a watchdog because i´m developing an ebike computer which regulates throttle output. If something goes wrong i need to ensure that the throttle goes low. As long as its always longer than the period i set it will be ok i guess (depending on the spread). Since there are a lot of devices i interface with at the same time i don´t know yet how long a usual loop will take but the wdt should be as small as it can be (around 50-100ms)

RogerClark
Mon Aug 29, 2016 2:02 am
Hi Smithy

Thats interesting, I’m building a eBike project as well. Mine doesn’t effect the throttle so I hadn’t considered using a WDT, but I think I will now implement it with WDT

Is yours for a Bosch eBike ?

Definitely just look at calibrating via the RTCCLOCK value, it should not be too hard to do.


smithy
Mon Aug 29, 2016 2:31 am
Its more for universal usage like the CA (http://www.ebikes.ca/product-info/cycle-analyst-3.html) did. Maybe it can work with bosh interfaces aswell don´t have one to test :( There are quite some controllers which support the CA plug right now i´m using it aswell. Some controllers can even vary the ampere drawn and so on, the possibilities are unlimited in such a project (dual drive etc.). Thats why we switched from the little nano (used 2 units before which were interfacing via i2c) to the stm32. Optionally we thought supporting the smartbms OZ890 for even more customizing on the fly :) I´ll pm you when i have a vid of my lcdmenu.

RogerClark
Mon Aug 29, 2016 2:47 am
From what I’ve read the Bosch system is quite locked down.

I don’t have an eBike, my dad as a Bocsh, hence why I have an interest.

The 8Fun system looks the best as its hackable via RS232 to reconfigure loads of settings ;-)


GrumpyOldPizza
Wed Feb 22, 2017 3:11 pm
Quick question. If LSI feeds IWDG, could IWDG be disabled by turning off LSI ? Do anybody try ?

bluesystems
Sun Mar 12, 2017 8:02 pm
I found this PDF file in ST micro’s documents on the STM32 micro.
http://www.st.com/resource/en/product_t … s_iwdg.pdf

This documents provides a good description of the STM32 hardware watchdog that iwdg is using.

The processor has a dedicated 32Khz clock for the watchdog hardware with a 8 bit pre-scaler and a 12 bit count down counter.
So with the 256 pre-scaler that would make each dog tick 32,000/256 = 125Hz or 8mS long.
Using 256 in the first field makes the second field 8mS ticks in decimal numbers.

The second field controls the STM32 count down counter that is 12 bits or 2^12 = 4096.
So the maximum watchdog timeout can be 4096 @ 8mS per tick making for 32.768 seconds as the longest time out possible.
I personally have not tried that long.

This example gives about a 16 second timeout and seems to work fine.
The first field is a 256 perscaller on the 32Khz clock and the second filed is then 2000 ticks at 8mS each.
iwdg_init(IWDG_PRE_256, 2000);

And remember once the dog is turned on there is no way to turn it off except for a power off reset.
So be careful to make sure you feed the dog in all your code once it is turned on or it will bite back!

Bob


bluesystems
Sun Mar 12, 2017 8:14 pm
I just noted the data sheet shows the watchdog timer between 30Khz to 60Khz with the typical of 40Khz.
Odd as the app note uses 32Khz in the examples.

So the 256 pre-scale typically gives 40,000/256 or 6.4mS ticks in the second field.
Can be as short as 60,000/256 or 4.2667mS per tick or a total time out of 17.476seconds

Bob


Leave a Reply

Your email address will not be published. Required fields are marked *