Watchdog DUE

Hello users

I have a problem to enable the watchdog timer.

in mij main.cpp i have added this →

int main( void )
{
/*++*/	watchdogSetup();

	init();

	initVariant();

	delay(1);

then i have created the watchdog.cpp and the watchdog.h

this is watchdog.h

#ifndef _WATCHDOG_
#define _WATCHDOG_

#include <stdint.h>

// Watchdog functions

/*
 * \brief Enable the watchdog with the specified timeout. Should only be called once.
 *
 * \param timeount in milliseconds.
 */
void watchdogEnable (uint32_t timeout);

/*
 * \brief Disable the watchdog timer. Should only be called once.
 *
 */
void watchdogDisable (void);

/*
 * \brief Reset the watchdog counter.
 *
 */
void watchdogReset (void);

/*
 * \brief Watchdog initialize hook. This function is called from init(). If the user does not provide
 * this function, then the default action is to disable watchdog.
 */
void watchdogSetup (void);

#endif /* _WATCHDOG_ */

this is watchdog.cpp

#include <chip.h>

#include "watchdog.h"


void watchdogEnable (uint32_t timeout)
{
	/* this assumes the slow clock is running at 32.768 kHz
	   watchdog frequency is therefore 32768 / 128 = 256 Hz */
	timeout = timeout * 256 / 1000; 
	if (timeout == 0)
		timeout = 1;
	else if (timeout > 0xFFF)
		timeout = 0xFFF;
//	timeout = WDT_MR_WDRSTEN | WDT_MR_WDRPROC | WDT_MR_WDV(timeout) | WDT_MR_WDD(timeout);
	timeout = WDT_MR_WDRSTEN | WDT_MR_WDV(timeout) | WDT_MR_WDD(timeout);

	WDT_Enable (WDT, timeout);
}

void watchdogDisable(void)
{
	WDT_Disable (WDT);
}

void watchdogReset(void)
{
	WDT_Restart (WDT);
}


extern "C"
void _watchdogDefaultSetup (void)
{
	WDT_Disable (WDT);
	
}
void watchdogSetup (void) __attribute__ ((weak, alias("_watchdogDefaultSetup")));

and now last: my code->

void setup() {
   Serial.begin(9600);

}

void loop() {
    
Serial.println ("I need to see this more then ones so i know the the watchdog timer is enabled");
  
  while (1);
 
}

But the question is now how to enable the watchdog timer??
the antser is not just: put watchdogEnable(10); in it

can someone help me?

The answer is: you don't. The slightly longer but implausible answer is that you go back in time and slap whoever disabled the watchdog timer in the Arduino core library. The longer and actually viable answer is that you go into the Arduino core library and modify it so that it does not disable the watchdog timer. You see, you can only set the watchdog once on this microprocessor. After that it ignores all changes. So, once it is disabled you cannot enable it. Once you enable it at a certain speed I believe you cannot change the speed or disable it. This is presumably so that no programming mistake can mess up the watchdog but it's really annoying.

May be this can help you: http://forum.arduino.cc/index.php?topic=132986.0 Look at the entry #3 But note that I wrote it two years ago, for ide 1.5.2 In ide 1.6.0 the file variant.cpp is in the same place. But since ide 1.6.2 things are more complicate and you have to look in *%APPDATA%\Arduino15\hardware\arduino\sam\variants\arduino_due_x*

i have the solution you must forget what i say earlier. my english is bad i know.

all you have to do is this -->

\arduino\hardware\sam\1.6.3\system\libsam\source\wdt.c

extern void WDT_Enable( Wdt* pWDT, uint32_t dwMode )
{   
/*--*/  //pWDT->WDT_MR = dwMode ;
/*++*/  pWDT->REG_WDT_MR = dwMode ;
}

\arduino\hardware\sam\1.6.3\variants\arduino_due_x\variant.cpp

/*++*/
extern "C"
void _WDT_Setup (void)
{
    WDT_Disable (WDT);

}
void WDT_Setup (void) __attribute__ ((weak, alias("_WDT_Setup")));
/*++*/

#ifdef __cplusplus
extern "C" {
#endif

void __libc_init_array(void);

void init( void )
{
  SystemInit();

  // Set Systick to 1ms interval, common to all SAM3 variants
  if (SysTick_Config(SystemCoreClock / 1000))
  {
    // Capture error
    while (true);
  }

  // Disable watchdog
/*++*/  WDT_Setup();


/*--*/ //  WDT_Disable(WDT);

my code to test the watchdog function -->

// the setup routine runs once when you press reset:

int waittimer = 0;
double timeout = 6.5;  // 6,5 secondes
int timeout2 = 0;

void WDT_Setup (){ // my default time is 18 secondes

  timeout2 =(int)( timeout * 227); 
  
  timeout2 = 0x0fff2000 + timeout2; // 0xfff2000 is very inportant
  WDT_Enable(WDT,timeout2);  
  
  // number of loops:
  // 0x0fff2000 0
  // 0x0fff200f 231
  // 0x0fff2fff 2981
}        

void setup() 
{   
    Serial.begin(9600);
}

void loop() 
{
  waittimer++;
  Serial.println(waittimer); // numer of loops
}

and if you dont summon "void WDT_Setup(){}" then it will be disabled

koppels:

I tryied your solution with a small modification and works OK.

#define ledOnBoard     13

// the setup routine runs once when you press reset:

int waittimer = 0;
double timeout = 2.5;  // 2,5 secondes
int timeout2 = 0;

void WDT_Setup (){ // my default time is 18 secondes

 timeout2 =(int)( timeout * 227);

 timeout2 = 0x0fff2000 + timeout2; // 0xfff2000 is very inportant
 WDT_Enable(WDT,timeout2); 

 // number of loops:
 // 0x0fff2000 0
 // 0x0fff200f 231
 // 0x0fff2fff 2981
}       



void setup()
{   
  pinMode(ledOnBoard, OUTPUT); 
  Serial.begin(9600);
}

void loop()
{
 waittimer++;
 Serial.println(waittimer); // numer of loops
 if (waittimer > 10) 
 { //after 10 timer, we freeze the code into an infinite loop
     for(;;); //this is a deadlock
 }


}

When sketch is compiled started to run printing numbers 1 to 11 waiting time and starting again. I had running this sketch for many hours without problem. But if you disconnect board from PC and reconnect again program hangs, stay ON forever. If I press reset button or serial monitor button, sketch run again normally.

Can you help to understand what happens. Any idea

I means But if you disconnect board from PC and reconnect again program hangs, onboard LED stay ON forever. If I press reset button or serial monitor button, sketch run again normally.

I am sorry but I forget add line digitalWrite(ledOnBoard, LOW); on setup

#define ledOnBoard     13

// the setup routine runs once when you press reset:

int waittimer = 0;
double timeout = 2.5;  // 2,5 secondes
int timeout2 = 0;

void WDT_Setup (){ // my default time is 18 secondes

 timeout2 =(int)( timeout * 227);

 timeout2 = 0x0fff2000 + timeout2; // 0xfff2000 is very inportant
 WDT_Enable(WDT,timeout2);

 // number of loops:
 // 0x0fff2000 0
 // 0x0fff200f 231
 // 0x0fff2fff 2981
}      



void setup()
{  
  pinMode(ledOnBoard, OUTPUT);
digitalWrite(ledOnBoard, LOW);
  Serial.begin(9600);
}

void loop()
{
 waittimer++;
 Serial.println(waittimer); // numer of loops
 if (waittimer > 10)
 { //after 10 timer, we freeze the code into an infinite loop
     for(;;); //this is a deadlock
 }


}

Hello, there is no member called "REG_WDT_MR" in the Wdt-Struct. Could you please explain why you changed this entry in wdt.c?

Thanks!

koppels: i have the solution you must forget what i say earlier. my english is bad i know.

all you have to do is this -->

\arduino\hardware\sam\1.6.3\system\libsam\source\wdt.c

extern void WDT_Enable( Wdt* pWDT, uint32_t dwMode )
{ 
/*--*/ //pWDT->WDT_MR = dwMode ;
/*++*/ pWDT->REG_WDT_MR = dwMode ;
}

Has anyone successfully used the watchdog interrupt on the Due? There is a nice post for the Uno

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

but this does not work for the Due.

I am afraid that

void WDG_Handler()

is not defined for the Due.

My program stops when the interrupt is fired, probably because the interrupt routine ends in nirvana.

Any suggestion?

Edmund

Hi yxmnas Yes, it works.

Did you read my answer in post http://forum.arduino.cc/index.php?topic=132986.0 ? Look at the entry #3

And look at the entry #2 , where I specify the version of the IDE with witch I made the test.