Jump to reset vector when program exceeds specified watchdog timeout
This commit is contained in:
@@ -12,8 +12,9 @@
|
||||
#define TW_MR_SLA_NACK 0x48
|
||||
#define TW_MR_DATA_ACK 0x50
|
||||
|
||||
// XXX: Handle interrupts in I2C_vect ISR? This may not
|
||||
// actually be much better than the blocking approach
|
||||
// XXX: Error handling and recovery without watchdog timer.
|
||||
// XXX: Implement I2C_vect ISR? This may not actually be
|
||||
// much better than the blocking approach.
|
||||
|
||||
static void I2C_AHT20_Reset(void);
|
||||
static bool I2C_AHT20_IsCalibrated(void);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include "common.h"
|
||||
#include "bus/mosfet.h"
|
||||
|
||||
// XXX: This might be too much specificity for something where
|
||||
// a generic digital output implementation would be adequate.
|
||||
|
||||
int MOS_Init(void)
|
||||
{
|
||||
// PB0: MOSFET #1 Peltier
|
||||
|
||||
@@ -43,16 +43,16 @@ void WDT_Enable(void)
|
||||
WDTCR = BIT(WDE) | BIT(WDP2) | BIT(WDP1) | BIT(WDP0);
|
||||
}
|
||||
|
||||
void WDT_SetTimeout(unsigned char time)
|
||||
void WDT_SetTimeoutFlag(unsigned char flag)
|
||||
{
|
||||
time = CLAMP(time, 7, 0);
|
||||
flag = CLAMP(flag, 7, 0);
|
||||
|
||||
Info("Setting watchdog prescalar to %d...", time);
|
||||
Info("Setting watchdog prescalar to %02X...", flag);
|
||||
|
||||
// Clear timer prescalar flags
|
||||
WDTCR &= 0xF8; // 11111000
|
||||
|
||||
WDTCR |= time;
|
||||
WDTCR |= flag;
|
||||
}
|
||||
|
||||
bool WDT_HasTriggered(void)
|
||||
@@ -88,8 +88,8 @@ bool WDT_HasTriggered(void)
|
||||
void WDT_Disable(void)
|
||||
{
|
||||
// WDE can only be cleared if the WDTOE bit has
|
||||
// logic level one. To disable an enabled Watchdog
|
||||
// Timer, the following procedure must be followed:
|
||||
// logic level one. To disable an enabled watchdog
|
||||
// timer, the following procedure must be followed:
|
||||
|
||||
// 1. In the same operation, write a logic one to
|
||||
// WDTOE and WDE. A logic one must be written to WDE
|
||||
@@ -97,7 +97,7 @@ void WDT_Disable(void)
|
||||
// operation starts.
|
||||
|
||||
// 2. Within the next four clock cycles, write a
|
||||
// logic 0 to WDE. This disables the Watchdog
|
||||
// logic 0 to WDE. This disables the watchdog.
|
||||
|
||||
// No interrupts while we set WDTCR;
|
||||
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
||||
@@ -108,5 +108,13 @@ void WDT_Disable(void)
|
||||
|
||||
void WDT_Reset(void)
|
||||
{
|
||||
// TODO: Reset watchdog timer
|
||||
// The WDR – Watchdog Reset – instruction resets the
|
||||
// watchdog timer. The Watchdog Timer is also reset
|
||||
// when it is disabled and when a chip reset occurs.
|
||||
|
||||
// If the reset period expires without another
|
||||
// watchdog reset, the chip resets and executes from
|
||||
// the Reset Vector.
|
||||
|
||||
__asm__("WDR");
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
void WDT_Enable(void);
|
||||
void WDT_SetTimeout(unsigned char time);
|
||||
void WDT_SetTimeoutFlag(unsigned char flag);
|
||||
bool WDT_HasTriggered(void);
|
||||
void WDT_Disable(void);
|
||||
void WDT_Reset(void);
|
||||
|
||||
15
src/main.c
15
src/main.c
@@ -7,13 +7,14 @@
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
// TODO: Convert raw data from ADS1115 to usable values.
|
||||
// TODO: Implement optional sensor value check with CRC8.
|
||||
// TODO: Set timeouts for polling based things like I2C.
|
||||
// TODO: Write an improved serial parser (low priority).
|
||||
// TODO: Implement optional CRC8 sensor measurement check.
|
||||
// TODO: Either implement software PWM for the FAN03 timer
|
||||
// (which will be quite complicated) or pick a chip with
|
||||
// more than two 16-bit PWM outputs like the ATmega328PB.
|
||||
// https://www.mikrocontroller.net/articles/Soft-PWM
|
||||
// TODO: Check if FAN02 is receiving the right frequency.
|
||||
// TODO: Write an improved command parser (low priority).
|
||||
// TODO: Proper error handling and recovery (after testing).
|
||||
|
||||
int Init(void)
|
||||
{
|
||||
@@ -48,8 +49,8 @@ int Init(void)
|
||||
if (WDT_HasTriggered())
|
||||
Info("Unexpected system reset.");
|
||||
|
||||
// WDT_Enable();
|
||||
// WDT_SetTimeout(7);
|
||||
WDT_Enable();
|
||||
WDT_SetTimeoutFlag(0x7); // 2 seconds
|
||||
|
||||
// There is a possiblity to use interrupt signals
|
||||
// for I2C communication but only as one large
|
||||
@@ -98,8 +99,6 @@ void Update(void)
|
||||
float temp[3], rhum[3];
|
||||
short raw[4];
|
||||
|
||||
WDT_Reset(); // Reset watchdog
|
||||
|
||||
Info("Reading sensor values...");
|
||||
|
||||
I2C_SetChannel(AHT01);
|
||||
@@ -128,7 +127,9 @@ int main(void)
|
||||
Init();
|
||||
|
||||
for (;;) {
|
||||
WDT_Reset();
|
||||
Update();
|
||||
WDT_Reset();
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user