Update module 'watchdog' to run on atmega1284p hardware
This commit is contained in:
@@ -6,103 +6,111 @@ void WDT_Enable(void)
|
|||||||
{
|
{
|
||||||
Info("Enabling watchdog timer...");
|
Info("Enabling watchdog timer...");
|
||||||
|
|
||||||
// WDTCR: Watchdog Timer Control Register
|
// WDTCSR: Watchdog Timer Control Register
|
||||||
|
|
||||||
// 7 6 5 4 3 2 1 0
|
// 7 6 5 4 3 2 1 0
|
||||||
// – – - WDTOE WDE WDP2 WDP1 WDP0
|
// WDIF WDIE WDP3 WDCE WDE WDP2 WDP1 WDP0
|
||||||
|
|
||||||
// When the WDE is written to logic one, the
|
// WDP3:0: Watchdog Timer Prescaler
|
||||||
// Watchdog Timer is enabled, and if the WDE is
|
// The WDP3:0 bits determine the Watchdog Timer
|
||||||
// written to logic zero, the Watchdog Timer
|
// prescaling when the Watchdog Timer is running.
|
||||||
// function is disabled.
|
// The different prescaling values and their
|
||||||
|
// corresponding time-out periods are
|
||||||
|
|
||||||
// WDP2, WDP1, WDP0: Watchdog Timer Prescaler
|
// WDP3 WDP2 WDP1 WDP0 Cycles Timeout5V
|
||||||
// The WDP2, WDP1, and WDP0 bits determine the
|
// 0 0 0 0 2K 16ms
|
||||||
// Watchdog Timer prescaling when the Watchdog
|
// 0 0 0 1 4K 32ms
|
||||||
// Timer is enabled. The different prescaling
|
// 0 0 1 0 8K 64ms
|
||||||
// values and their corresponding Timeout
|
// 0 0 1 1 16K 125ms
|
||||||
// Periods are:
|
// 0 1 0 0 32K 250ms
|
||||||
|
// 0 1 0 1 64K 500ms
|
||||||
|
// 0 1 1 0 128K 1000ms
|
||||||
|
// 0 1 1 1 256K 2000ms
|
||||||
|
// 1 0 0 0 512K 4000ms
|
||||||
|
// 1 0 0 1 1024K 8000ms
|
||||||
|
|
||||||
// WDP2 WDP1 WDP0 Cycles Timeout3V Timeout5V
|
// WDCE: Watchdog Change Enable
|
||||||
// 0 0 0 16K 17.10ms 16.30ms
|
// This bit is used in timed sequences for changing
|
||||||
// 0 0 1 32K 34.30ms 32.50ms
|
// WDE and prescaler bits. To clear the WDE bit,
|
||||||
// 0 1 0 64K 68.50ms 65.00ms
|
// and/or change the prescaler bits, WDCE must be
|
||||||
// 0 1 1 128K 0.14s 0.13s
|
// set. Once written to one, hardware will clear
|
||||||
// 1 0 0 256K 0.27s 0.26s
|
// WDCE after four clock cycles.
|
||||||
// 1 0 1 512K 0.55s 0.52s
|
|
||||||
// 1 1 0 1,024K 1.10s 1.00s
|
|
||||||
// 1 1 1 2,048K 2.20s 2.10s
|
|
||||||
|
|
||||||
// WDTOE: Watchdog Turn-off Enable This bit must
|
|
||||||
// be set when the WDE bit is written to logic zero.
|
|
||||||
// Otherwise, the Watchdog will not be disabled.
|
|
||||||
// Once written to one, hardware will clear this
|
|
||||||
// bit after four clock cycles.
|
|
||||||
|
|
||||||
// 00001111: Watchdog enabled, 2sec timeout
|
// 00001111: Watchdog enabled, 2sec timeout
|
||||||
WDTCR = BIT(WDE) | BIT(WDP2) | BIT(WDP1) | BIT(WDP0);
|
WDTCSR = BIT(WDE) | BIT(WDP2) | BIT(WDP1) | BIT(WDP0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WDT_SetTimeoutFlag(byte flag)
|
void WDT_SetTimeoutFlag(byte flag)
|
||||||
{
|
{
|
||||||
|
// Currently only support for a maximum of 2 seconds
|
||||||
|
// timeout because there is no need for more and the
|
||||||
|
// bit location of WDP3 requires conditional logic.
|
||||||
|
|
||||||
|
// The sequence for clearing WDE and changing timeout
|
||||||
|
// configuration is as follows:
|
||||||
|
|
||||||
|
// 1. In the same operation, write a logic one to the
|
||||||
|
// Watchdog change enable bit (WDCE) and WDE. A logic
|
||||||
|
// one must be written to WDE regardless of the
|
||||||
|
// previous value of the WDE bit.
|
||||||
|
|
||||||
|
// 2. Within the next four clock cycles, write the WDE
|
||||||
|
// and Watchdog prescaler bits (WDP) as desired, but
|
||||||
|
// with the WDCE bit cleared. This must be done in one
|
||||||
|
// operation.
|
||||||
|
|
||||||
flag = CLAMP(flag, 7, 0);
|
flag = CLAMP(flag, 7, 0);
|
||||||
|
|
||||||
Info("Setting watchdog prescalar to %02X...", flag);
|
Info("Setting watchdog prescalar to %02X...", flag);
|
||||||
|
|
||||||
// Clear timer prescalar flags
|
// Disable interrupts
|
||||||
WDTCR &= 0xF8; // 11111000
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||||
|
WDTCSR = BIT(WDCE) | BIT(WDE);
|
||||||
WDTCR |= flag;
|
// Set new timer prescalar flag
|
||||||
|
WDTCSR = (WDTCSR & 0xC8) | flag; // C8=11001000
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX: COMMENTS UPDATED!
|
||||||
bool WDT_HasTriggered(void)
|
bool WDT_HasTriggered(void)
|
||||||
{
|
{
|
||||||
bool isreset;
|
bool isreset;
|
||||||
|
|
||||||
// To make use of the Reset Flags to identify a reset
|
// To make use of the Reset Flags to identify a reset
|
||||||
// condition, the user should read and then reset the
|
// condition, the user should read and then reset the
|
||||||
// MCUCSR as early as possible in the program. If the
|
// MCUSR as early as possible in the program. If the
|
||||||
// register is cleared before another reset occurs,
|
// register is cleared before another reset occurs,
|
||||||
// the source of the reset can be found by examining
|
// the source of the reset can be found by examining
|
||||||
// the Reset Flags.
|
// the Reset Flags.
|
||||||
|
|
||||||
// MCUCSR: MCU Control and Status Register
|
// MCUSR: MCU Status Register
|
||||||
// The MCU Control and Status Register provides
|
// The MCU Status Register provides information on
|
||||||
// information on which reset source caused an MCU
|
// which reset source caused an MCU reset.
|
||||||
// Reset.
|
|
||||||
|
|
||||||
// 7 6 5 4 3 2 1 0
|
// 7 6 5 4 3 2 1 0
|
||||||
// JTD ISC2 – JTRF WDRF BORF EXTRF PORF
|
// - - – JTRF WDRF BORF EXTRF PORF
|
||||||
|
|
||||||
// Is watchdog reset flag set?
|
// Is watchdog reset flag set?
|
||||||
isreset = ((MCUCSR & BIT(WDRF)) != 0);
|
isreset = ((MCUSR & BIT(WDRF)) != 0);
|
||||||
|
|
||||||
// XXX: Reset flag detection should be a separate
|
// XXX: Reset flag detection should be a separate
|
||||||
// module to handle the different types.
|
// module to handle the different types.
|
||||||
|
|
||||||
MCUCSR = 0;
|
MCUSR = 0;
|
||||||
|
|
||||||
return isreset;
|
return isreset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WDT_Disable(void)
|
void WDT_Disable(void)
|
||||||
{
|
{
|
||||||
// WDE can only be cleared if the WDTOE bit has
|
// See WDT_SetTimeoutFlag for an explanation of the
|
||||||
// logic level one. To disable an enabled watchdog
|
// necessary sequence for clearing WDE and changing
|
||||||
// timer, the following procedure must be followed:
|
// timeout configuration.
|
||||||
|
|
||||||
// 1. In the same operation, write a logic one to
|
// Disable interrupts
|
||||||
// WDTOE and WDE. A logic one must be written to WDE
|
|
||||||
// even though it is set to one before the disable
|
|
||||||
// operation starts.
|
|
||||||
|
|
||||||
// 2. Within the next four clock cycles, write a
|
|
||||||
// logic 0 to WDE. This disables the watchdog.
|
|
||||||
|
|
||||||
// No interrupts while we set WDTCR;
|
|
||||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||||
WDTCR = BIT(WDTOE) | BIT(WDE);
|
WDTCSR = BIT(WDCE) | BIT(WDE);
|
||||||
WDTCR = 0;
|
WDTCSR = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#define WDT1000 0x6 // 1000 ms
|
#define WDT1000 0x6 // 1000 ms
|
||||||
#define WDT500 0x5 // 500 ms
|
#define WDT500 0x5 // 500 ms
|
||||||
#define WDT250 0x4 // 250 ms
|
#define WDT250 0x4 // 250 ms
|
||||||
#define WDT100 0x3 // 100 ms
|
#define WDT125 0x3 // 125 ms
|
||||||
#define WDT64 0x2 // 64 ms
|
#define WDT64 0x2 // 64 ms
|
||||||
#define WDT32 0x1 // 32 ms
|
#define WDT32 0x1 // 32 ms
|
||||||
#define WDT16 0x0 // 16 ms
|
#define WDT16 0x0 // 16 ms
|
||||||
|
|||||||
Reference in New Issue
Block a user