unsigned char _watchTheDog // how many milliseconds since we last reset the watchdog
void Setup()
{
Timer3.initialize(1000000 / 1000); // set to fire every millisecond. initialize takes microseconds as an argument.
Timer3.attachInterrupt(WatchTheDog ); // call WatchTheDog every millisecond
}
void WatchTheDog ()
{
_watchTheDog+= 1
}
void WatchdogReset()
{
if (_watchTheDog> 2){
// use the following 4 lines to kick the dog
noInterrupts();
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
interrupts();
_watchTheDog = 0
}
}
#ifdef __cplusplus
extern "C" {
#endif
void startup_early_hook() {
WDOG_TOVALL = 2000; // The next 2 lines sets the time-out value. This is the value that the watchdog timer compares itself to
WDOG_TOVALH = 0;
WDOG_PRESC = 0; // prescaler
WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN); // Enable WDG
}
#ifdef __cplusplus
}
#endif
void setup(){
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
WDOG_TOVALL = 10; // The next 2 lines sets the time-out value. This is the value that the watchdog timer compares itself to
WDOG_TOVALH = 0;
WDOG_PRESC = 0; // prescaler
WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN); // Enable WDG
}
void loop(){
WatchdogReset();
}
void WatchdogReset(){
static elapsedMillis watchdogTimer;
if (watchdogTimer > 5){
watchdogTimer = 0;
noInterrupts();
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
interrupts();
}
}
I haven't actually used the watchdog since posting that so I'll have to look at it again and get back to you.Hello duff
Great and working code, but where in Your code is definition of 6 second delay ?
Max
What are the units of these two values and how do they translate into time?
WDOG_TOVALL = 1000; // The next 2 lines sets the time-out value.
WDOG_TOVALH = 1;
I've implemented this and it is resetting about every 60 seconds with these values above. I want to set this to a value less than 1 second - actually in microseconds if possible.
Is there a minimum amount of elapsed time required between calls to kick the dog?
#ifdef __cplusplus
extern "C" {
#endif
void startup_early_hook() {
WDOG_TOVALL = 3000;
WDOG_TOVALH = 0;
WDOG_PRESC = 0;
WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN);
}
#ifdef __cplusplus
}
#endif
int led = 13;
void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
Serial.println("Setup");
}
void loop() {
WatchdogReset();
Serial.println("Begin");
delay(2608);
}
void WatchdogReset(){
static elapsedMillis watchdogTimer;
if (watchdogTimer > 5){
watchdogTimer = 0;
noInterrupts();
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
interrupts();
}
}
If your teensy 3* watchdog timer is configured to use the LPO, that internal oscillator is spec'd only at 10% accuracy (100,000 ppm). Using the LPTMR, i've measured the accuracy of LPO on various teensy's (anecdotal results at https://github.com/manitou48/crystals/blob/master/crystals.txt). I tested my T3.2 with LPO accuracy of 18934 ppm with the watchdog timer. I modified the BasicUsage example from https://github.com/adafruit/Adafruit_SleepyDog to adjust the delay before "kicking the watchdog" in loop().when the delay(2608); the sketch runs but when i use delay(2609); the watchdog kicks in. I expected a 3 sec reset time... But all and all this works for me .. I don't need accurate timing, just a reset if the code hangs
Thank you!
if (micros() -t > 3927000) {
Watchdog.reset();
t=micros();
Serial.println("running");
}
Here is more portable version of your watchdog code, no need to edit any core files but instead use the startup_early_hook. It also uses the interval timer to kick the dog.
Code:#define RCM_SRS0_WAKEUP 0x01 #define RCM_SRS0_LVD 0x02 #define RCM_SRS0_LOC 0x04 #define RCM_SRS0_LOL 0x08 #define RCM_SRS0_WDOG 0x20 #define RCM_SRS0_PIN 0x40 #define RCM_SRS0_POR 0x80 #define RCM_SRS1_LOCKUP 0x02 #define RCM_SRS1_SW 0x04 #define RCM_SRS1_MDM_AP 0x08 #define RCM_SRS1_SACKERR 0x20 IntervalTimer wdTimer; void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); // You have about 6 secs to open the serial monitor before a watchdog reset while(!Serial); delay(100); printResetType(); wdTimer.begin(KickDog, 500000); // kick the dog every 500msec } void loop() { Serial.println("doing loop things..."); delay(100); } void KickDog() { Serial.println("Kicking the dog!"); digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); noInterrupts(); WDOG_REFRESH = 0xA602; WDOG_REFRESH = 0xB480; interrupts(); } void printResetType() { if (RCM_SRS1 & RCM_SRS1_SACKERR) Serial.println("[RCM_SRS1] - Stop Mode Acknowledge Error Reset"); if (RCM_SRS1 & RCM_SRS1_MDM_AP) Serial.println("[RCM_SRS1] - MDM-AP Reset"); if (RCM_SRS1 & RCM_SRS1_SW) Serial.println("[RCM_SRS1] - Software Reset"); if (RCM_SRS1 & RCM_SRS1_LOCKUP) Serial.println("[RCM_SRS1] - Core Lockup Event Reset"); if (RCM_SRS0 & RCM_SRS0_POR) Serial.println("[RCM_SRS0] - Power-on Reset"); if (RCM_SRS0 & RCM_SRS0_PIN) Serial.println("[RCM_SRS0] - External Pin Reset"); if (RCM_SRS0 & RCM_SRS0_WDOG) Serial.println("[RCM_SRS0] - Watchdog(COP) Reset"); if (RCM_SRS0 & RCM_SRS0_LOC) Serial.println("[RCM_SRS0] - Loss of External Clock Reset"); if (RCM_SRS0 & RCM_SRS0_LOL) Serial.println("[RCM_SRS0] - Loss of Lock in PLL Reset"); if (RCM_SRS0 & RCM_SRS0_LVD) Serial.println("[RCM_SRS0] - Low-voltage Detect Reset"); } #ifdef __cplusplus extern "C" { #endif void startup_early_hook() { WDOG_TOVALL = (1000); // The next 2 lines sets the time-out value. This is the value that the watchdog timer compare itself to. WDOG_TOVALH = 0; WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN | WDOG_STCTRLH_WAITEN | WDOG_STCTRLH_STOPEN); // Enable WDG //WDOG_PRESC = 0; // prescaler } #ifdef __cplusplus } #endif
sketch_apr09a: In function 'void startup_early_hook()':
sketch_apr09a:58: error: previous declaration of 'void startup_early_hook()' with 'C++' linkage
void startup_early_hook() {
^
sketch_apr09a:58: error: conflicts with new declaration with 'C' linkage
void startup_early_hook() {
^
previous declaration of 'void startup_early_hook()' with 'C++' linkage
The Arduino preprocessor is a buggy piece of <CENSORED>. You need an explicit forward declaration:Re: startup_early_hook()
i get a compile error if i try to compile Duff's watchdog sketch in post #21 ?? what is proper way to override weak startup_early hook?
i'm using 1.8.1 with 1.35Code:sketch_apr09a: In function 'void startup_early_hook()': sketch_apr09a:58: error: previous declaration of 'void startup_early_hook()' with 'C++' linkage void startup_early_hook() { ^ sketch_apr09a:58: error: conflicts with new declaration with 'C' linkage void startup_early_hook() { ^ previous declaration of 'void startup_early_hook()' with 'C++' linkage
#ifdef __cplusplus
extern "C" { void startup_early_hook(); }
extern "C" {
#endif
void startup_early_hook() {
WDOG_TOVALL = (1000); // The next 2 lines sets the time-out value. This is the value that the watchdog timer compare itself to.
WDOG_TOVALH = 0;
WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN | WDOG_STCTRLH_WAITEN | WDOG_STCTRLH_STOPEN); // Enable WDG
//WDOG_PRESC = 0; // prescaler
}
#ifdef __cplusplus
}
The Arduino preprocessor is a buggy piece of <CENSORED>. You need an explicit forward declaration:
Hello, I have followed this thread and it is confusing. Is there a final answer on how to implement a watchdog on teensy 3.2 ?
Did you try the wdogduff.ino sketch in post #46 ?