diff --git a/src/bus/i2c.c b/src/bus/i2c.c index fdef653..a04a244 100644 --- a/src/bus/i2c.c +++ b/src/bus/i2c.c @@ -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); diff --git a/src/bus/mosfet.c b/src/bus/mosfet.c index e3bd4f7..260acfd 100644 --- a/src/bus/mosfet.c +++ b/src/bus/mosfet.c @@ -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 diff --git a/src/common/watchdog.c b/src/common/watchdog.c index 6e2735f..7334c1e 100644 --- a/src/common/watchdog.c +++ b/src/common/watchdog.c @@ -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"); } diff --git a/src/common/watchdog.h b/src/common/watchdog.h index 1329194..b6e336a 100644 --- a/src/common/watchdog.h +++ b/src/common/watchdog.h @@ -4,7 +4,7 @@ #include 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); diff --git a/src/main.c b/src/main.c index 0dd4494..3353d30 100644 --- a/src/main.c +++ b/src/main.c @@ -7,13 +7,14 @@ #include // 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); }