Pages: [1]   Go Down
Author Topic: DUE Watchdog usage  (Read 167 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When trying to use the Watchdog on the DUE, you will come over short to one finding:
Quote from: SAM3X8E Docmentation chapter 17.4
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.

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:
Code:
void WDT_Init();

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

And replaced   WDT_Disable(WDT);  with  WDT_Init();  in the init() function.

That is now first hand a neutral solution, but gives you the ability to define a strong version of  WDT_Init();  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?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just thinking further: To have a much cleaner solution with the right namespaces
Code:
void WDT_Init();
should go to wdt.h

Code:
#pragma weak WDT_Init
void WDT_Init()
{
  WDT_Disable(WDT);
}
should go to wdt.c

And finally in variant.cpp:
Code:
// WDT_Disable(WDT);
WDT_Init(); // add this line instead of WDT_Disable(WDT);

As soon as the function WDT_Init() gets redefined in the application, this strong version will be used and you are free to configure WDT.

Anything I may have forgotten to think about?
« Last Edit: April 15, 2014, 02:44:47 am by gogol » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 24
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Still talking only to myself :-(
Comparing the Arduino  hardware/arduino/sam/system/libsam/[source|include]/wdt.[c|h]
with the Atmel Framework version of wdt.[c|h]
I see, that Atmel provides already an wdt_init(),
Code:
uint32_t wdt_get_timeout_value(uint32_t ul_us, uint32_t ul_sclk);
void wdt_init(Wdt *p_wdt, uint32_t ul_mode, uint16_t us_counter,
uint16_t us_delta);
void wdt_disable(Wdt *p_wdt);
void wdt_restart(Wdt *p_wdt);
uint32_t wdt_get_status(Wdt *p_wdt);
uint32_t wdt_get_us_timeout_period(Wdt *p_wdt, uint32_t ul_sclk);

whereas Arduino provides as counterpart WDT_Enable()
Code:
extern void WDT_Enable( Wdt* pWDT, uint32_t dwMode ) ;
extern void WDT_Disable( Wdt* pWDT ) ;
extern void WDT_Restart( Wdt* pWDT ) ;
extern uint32_t WDT_GetStatus( Wdt* pWDT ) ;
extern uint32_t WDT_GetPeriod( uint32_t dwMs ) ;

So I think, that the new weak function should be named WDT_Initialze(), to avoid confusion.

Are there any readers here, which work on the that layer of libraries? 
Logged

Pages: [1]   Go Up
Jump to: