DUE Watchdog usage

Thanks gogol!

I will do it as you suggest it. Much better.

Do you know why we can only change WDT status only once per boot ? Is it a design limitation of the SAM3X architecture ?

Thanks again,

gogol:
That exactly is the reason, why I am proposing this patch!
If you change variants.cpp by commenting out the WDT_disable(WDT); line, you break the core libraries for many other programs, as the watchdog is always active

If you do that, you have to edit variants.cpp for each program, depending if you need watchdog in your program or not.
The other way would be copying all the files to a second board, how it is done for the DigiX. But that needs twice the space on disk and constant sync of both directories for new versions of the IDE. VERY BAD!!

That exactly was the situation, where I came to the solution for my patch!

Read the entry post of that thread! I replace the line you are disabling with a line calling a new weak function WDT_Initialze(). This function does primarly the same, as the current line and is disabling WDT.

HOWEVER: A weak function can be redefined somewhere through a strong version. When the linker finds a function with the same name, this function will be used instead of the weak one.

That means: Once my patch is included in the CORE files nothing changes at all, as reset is still disabled. So we are backwards compatible.

But as soon, as you are creating a STRONG function WDT_Initialze() in your code, which will call WDT_Enable() instead of WDT_Disable() you can use WDT, where you need.

This workaround is needed, as the ARDUINO-architecture gives you no way, to influence main() before setup() is called.

Is it a design limitation of the SAM3X architecture ?

Yes, chapter 17.4 of the ATSAM3X8E datasheet says:

After a Processor Reset, the value of WDV is 0xFFF, corresponding to the maximum value of
the counter with the external reset generation enabled (field WDRSTEN at 1 after a Backup
Reset). This means that a default Watchdog is running at reset, i.e., at power-up. The user must
either disable it (by setting the WDDIS bit in WDT_MR) if he does not expect to use it or must
reprogram it to meet the maximum Watchdog period the application requires.
The Watchdog Mode Register (WDT_MR) can be written only once. Only a processor reset
resets it. Writing the WDT_MR register reloads the timer with the newly programmed mode
parameters.

Its always a good thing reading the datasheets of the controllers (even when you understand only 5%). but you might get an idea, what the controller is able to.

Thanks for this, i've created a diff file to apply these changes easy.
But somehow I get a warning if I compile a sketch without the WDT_Initialze function...

variant.cpp.o: In function `init':
C:\Program Files (x86)\Arduino\arduino-1.5.7\hardware\arduino\sam\variants\arduino_due_x/variant.cpp:378: warning: undefined reference to `WDT_Initialze'
--- arduino-1.5.8\hardware\arduino\sam\system\libsam\include\wdt.h	Thu Jan 8 17:33:06 2015 UTC
+++ arduino-1.5.8\hardware\arduino\sam\system\libsam\include\wdt.h	Thu Jan 8 17:33:06 2015 UTC
@@ -66,6 +66,8 @@
 
 extern uint32_t WDT_GetPeriod( uint32_t dwMs ) ;
 
+void WDT_Initialze();
+
 #ifdef __cplusplus
 }
 #endif
--- arduino-1.5.8\hardware\arduino\sam\system\libsam\source\wdt.c	Thu Jan 8 17:33:09 2015 UTC
+++ arduino-1.5.8\hardware\arduino\sam\system\libsam\source\wdt.c	Thu Jan 8 17:33:09 2015 UTC
@@ -130,3 +130,13 @@
     }
     return ((dwMs << 8) / 1000) ;
 }
+
+/**
+* \brief default arduino behaviour -> disable the watchdog.
+* watchdog can be enabled from a sketch
+*/
+#pragma weak WDT_Initialze
+void WDT_Initialze()
+{
+ WDT_Disable(WDT);
+}
--- arduino-1.5.8\hardware\arduino\sam\variants\arduino_due_x\variant.cpp	Thu Jan 8 17:33:14 2015 UTC
+++ arduino-1.5.8\hardware\arduino\sam\variants\arduino_due_x\variant.cpp	Thu Jan 8 17:33:14 2015 UTC
@@ -374,7 +374,8 @@
   }
 
   // Disable watchdog
-  WDT_Disable(WDT);
+  // WDT_Disable(WDT);
+  WDT_Initialze(); // instead of the line above to allow enabling the watchdog from a sketch
 
   // Initialize C library
   __libc_init_array();

I tried it now and the watchdog works perfectly!

gogol:
When trying to use the Watchdog on the DUE, you will come over short to one finding:
As variant.cpp contains the line WDT_Disable(WDT); in its init() function, the watchdog is disabled forever. So you need solutions, to prevent the disabling. I added now the following lines in variants.cpp before the init() function:

void WDT_Init();

#pragma weak WDT_Init
void WDT_Init()
{
  WDT_Disable(WDT);
}




And replaced <strong>*WDT_Disable(WDT);*</strong> with <strong>*WDT_Init(); *</strong> in the init() function.

That is now first hand a neutral solution, but gives you the ability to define a strong version of <strong>*WDT_Init(); *</strong> in your program. That can either be an empty-function, which leaves the Watchdog configured as from startup, or any other code, which changes the Watchdog to call the ISR WDT_Handler() or change any other settings.

Do I miss something in my thoughts or should this go into the main code?

A very nice solution to the problem!

Regards,
Ray L.

I like the idea of an easy call for the WatchDog. Have you considered creating a function

Watchdog.begin()

This would be in-keeping with the "arduino" way and makes it very clear in the code that you intend to start a watch dog timer.

I'd love to have this included so that I can make my µC projects more reliable and able to auto-restart. The ability to have a watchdog timer is quite crucial. Good proposal!

A while ago I created a pull request to get this type of functionality included in the core Add watchdog routines for Due. by bobc · Pull Request #2210 · arduino/Arduino · GitHub. I forget where it got to, I think there was some cosmetic changes required, but otherwise just needs a "push" to get into the core I think.

It's been kinda low on my list of priorities.

Allright, I have been digging for a few weeks so I will not post a stupid question in this topic.

I'm trying to modify a library written by some incompetents for a wireless networking shield - the FT1076M from futura electronics (open-electronics.org store). Those dudes just pretend the Sam3X controllers do not exist and in conclusion the library (MWifi) is written for the older avr architecture. The watchdog handling functions are included in avr/wdt.h. People pay money and are deceived because they lack the proper documentation so I wish to fix this problem.

As I wish to solve this for arduino due, first I would like to compile a sketch with some basic WDT functions.
Bur surprise - I cannot include the sam3x wdt.h because it is nowhere to be found in the include search path. And I am stuck in windows - in BSD it is easy to modify the include path.

Now, I respectfully ask you for help. A sketch has a setup() and a loop() but I see nothing on this post. What are you compiling and what are you including? There is nothing clear. Before the setup, the sketch can include stuff. #include <wdt.h> does not work (unable to locate wdt.h) and the avr/wdt.h is not acceptable because the controller is sam3x.

How can I include the wdt.h for sam3x? I'm using the arduino 1.5.8a framework.

The sketch should look like this:

#include <wdt.h> //unable to locate it unless I include the full path, but the dependencies in this case are not included

void setup() {
....
}

void loop() {
...
}

I thought it's fairly obvious from Bob's pull request. Just modify your own installation of Arduino.h, main.cpp etc. as per the files that he modified. Since it's not part of the core yet, this must be done manually on each computer you expect to use to compile sketches. (Teensyduino does exactly this in a slightly more automated way.)

It can't be done as a regular library that's #included in a sketch.

I may be overlooking something, but I can't find variant.cpp or variant.h for IDE 1.6.3. I can find it in my IDE 1.5.8 install.

For the 1.5.8 install, they are in: \Documents\Arduino\hardware\arduino\sam\variants\arduino_due_x

For the 1.6.3 install, I don't have don't have a path to sam\variants\arduino_due_x

I just have: C:\Program Files (x86)\Arduino\hardware\arduino\

And the only selection in the hardware\arduino directory is avr

Thanks,
-j

Unfortunately, after the sudden and badly thought out release of the board and library manager, I've no idea where these files are now. The location is likely to change until Arduino figure out the right place to put them, which is probably where they were in the first place.

In 1.6.3, they are probably under "My Documents" somewhere. Obviously you need to install support for the Due in the Board Manager first.

I had the same problem but i have it fixed

http://forum.arduino.cc/index.php?topic=314647.0

Hey Bob,

I did find out I needed to use the board manager to install Due support. I'm searching my drive for the files right now.

Kopples, I take a look at your suggestions.

Thanks,
-j

Ok found the files. Sheesh. That's an obscure location.

C:\Users\DUC\AppData\Roaming\Arduino15\packages\arduino\hardware\sam\1.6.3\variants\arduino_due_x

Now to get the WDT up and working.

Cheers,
-j

Hey Bob,

I made the file changes and additions as per your pull. As far as using it in setup() and loop(), what needs to be done?

Thanks,
-j

Here is one of the test cases I used which should illustrate it's use:

// Due Watchdog test case
// - enable the watchdog and demonstrate that wdt_reset() prevents timeout

void watchdogSetup(void)
{
  watchdogEnable(1000);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println ("start");
}

void loop() {
  // put your main code here, to run repeatedly:

  // this should not cause a watchdog timeout
  while (1){
    delay (100);
    Serial.println(millis());
    watchdogReset();
  }
  
}

Thank you sir. I'll give it a try.
-j

It works great. I tried a couple scenarios to force a system reset and to operate properly with the watchdog running in the background.

Thanks,
-j

koppels

I followed your instructions in Watchdog DUE - Arduino Due - Arduino Forum and your code to test the watchdog function works fine.

Can you supply code how to use to use regulary

Thanks