Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions utility/WatchdogAVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,49 @@
#include <avr/sleep.h>
#include <avr/wdt.h>

#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include "WatchdogAVR.h"

void(* resetFunc) (void) = 0;

// Define watchdog timer interrupt.
ISR(WDT_vect) {
// Nothing needs to be done, however interrupt handler must be defined to
// prevent a reset.

if (_sleepy != _MAGIC_SLEEPY) {
// Disable watchdog and soft reset
MCUSR = 0;
wdt_disable();
resetFunc();
}
_sleepy=0; // Terminate sleep mode
}

int WatchdogAVR::enable(int maxPeriodMS) {
// Pick the closest appropriate watchdog timer value.
int actualMS;
_setPeriod(maxPeriodMS, _wdto, actualMS);
int actualMS;
_setPeriod(abs(maxPeriodMS), _wdto, actualMS);
// Enable the watchdog and return the actual countdown value.
wdt_enable(_wdto);
if (maxPeriodMS<0) WDTCSR |= (1<<WDIE); // Enable only watchdog interrupts.
_sleepy=0;
return actualMS;
}

void WatchdogAVR::reset() {
// Reset the watchdog.
wdt_reset();
_sleepy=0;
}

void WatchdogAVR::disable() {
// Disable the watchdog and clear any saved watchdog timer value.
wdt_disable();
_sleepy=0;
_wdto = -1;
}

Expand Down Expand Up @@ -70,6 +88,7 @@ int WatchdogAVR::sleep(int maxPeriodMS) {

// Set full power-down sleep mode and go to sleep.
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
_sleepy=_MAGIC_SLEEPY; // The only place where it should get this value
sleep_mode();

// Chip is now asleep!
Expand All @@ -86,7 +105,7 @@ int WatchdogAVR::sleep(int maxPeriodMS) {
}

void WatchdogAVR::_setPeriod(int maxMS, int &wdto, int &actualMS) {
// Note the order of these if statements from highest to lowest is
// Note the order of these if statements from highest to lowest is
// important so that control flow cascades down to the right value based
// on its position in the range of discrete timeouts.
if((maxMS >= 8000) || (maxMS == 0)) {
Expand Down
15 changes: 15 additions & 0 deletions utility/WatchdogAVR.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
#ifndef WATCHDOGAVR_H
#define WATCHDOGAVR_H


// Allows the WDT ISR to know if it's called from the sleep function or if
// a reset is to be performed.
// The 16 bits holds a "magic value" to prevent reset. This is safer than
// using a boolean in case the memory gets trashed.
// This is defined as global to allow access by the ISR

#include <stdint.h>

static uint16_t _sleepy;
#define _MAGIC_SLEEPY ~0xDEAD

class WatchdogAVR {
public:
WatchdogAVR():
Expand Down Expand Up @@ -44,4 +56,7 @@ class WatchdogAVR {
int _wdto;
};




#endif