From 5a726f5d4859d27d3dd92233c3827f928cb50b67 Mon Sep 17 00:00:00 2001 From: Leon Krieg Date: Tue, 1 Oct 2024 15:47:31 +0200 Subject: [PATCH] Clear WDRF flag and set WDCE before enabling watchdog --- Makefile | 14 +++++++------- src/common/watchdog.c | 18 ++++++++++++++---- src/main.c | 8 -------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 247bd1b..488eee3 100644 --- a/Makefile +++ b/Makefile @@ -50,13 +50,8 @@ DEPENDS := $(FILES:%.c=$(TMPDIR)/%.d) # AUXILIARY TARGETS (AND FUSE SETTINGS) # ============================================================================== -# .PHONY: all -# all: flash - -.PHONY: run -run: $(TARGET) - $(E) "[SIM] $<" - $(Q) $(SIM) -m $(MCU) -f $(FREQ) $< +.PHONY: all +all: flash .PHONY: flash flash: $(TARGET) @@ -69,6 +64,11 @@ flash: $(TARGET) -U lock:w:0xFF:m \ -U flash:w:$< +.PHONY: run +run: $(TARGET) + $(E) "[SIM] $<" + $(Q) $(SIM) -m $(MCU) -f $(FREQ) $< + .PHONY: clean clean: $(E) "[REM] $(TARGET)" diff --git a/src/common/watchdog.c b/src/common/watchdog.c index fc610af..e3463d6 100644 --- a/src/common/watchdog.c +++ b/src/common/watchdog.c @@ -36,8 +36,17 @@ void WDT_Enable(void) // set. Once written to one, hardware will clear // WDCE after four clock cycles. - // 00001111: Watchdog enabled, 2sec timeout - WDTCSR = BIT(WDE) | BIT(WDP2) | BIT(WDP1) | BIT(WDP0); + // Setting WDCE before enabling the watchdog should + // not be necessary according to the data sheet but + // it does not seem to work otherwise. + + // Disable interrupts + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + MCUSR &= ~BIT(WDRF); + WDTCSR = BIT(WDCE) | BIT(WDE); + // 00001111: Watchdog enabled, 2sec timeout + WDTCSR = BIT(WDE) | BIT(WDP2) | BIT(WDP1) | BIT(WDP0); + } } void WDT_SetTimeoutFlag(byte flag) @@ -65,13 +74,13 @@ void WDT_SetTimeoutFlag(byte flag) // Disable interrupts ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + WDT_Reset(); WDTCSR = BIT(WDCE) | BIT(WDE); // Set new timer prescalar flag - WDTCSR = (WDTCSR & 0xC8) | flag; // C8=11001000 + WDTCSR = BIT(WDE) | flag; } } -// XXX: COMMENTS UPDATED! bool WDT_HasTriggered(void) { bool isreset; @@ -109,6 +118,7 @@ void WDT_Disable(void) // Disable interrupts ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + WDT_Reset(); WDTCSR = BIT(WDCE) | BIT(WDE); WDTCSR = 0; } diff --git a/src/main.c b/src/main.c index a12020f..a9a01d3 100644 --- a/src/main.c +++ b/src/main.c @@ -57,14 +57,6 @@ static int Init(void) Info("Initializing..."); - // FIXME: Something is wrong here: - // - AVRDUDE sometimes fails to verify flash. - // - UART sometimes stops working. - // - External crystal problems? - // - Power supply problems? - // - Wrong fuses? Unlikely. - // - Bootloader problems? - // The watchdog timer is clocked from a separate // on-chip oscillator which runs at 1 MHz. Eight // different clock cycle periods can be selected