aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/avr/watchdog.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/avr/watchdog.c b/src/avr/watchdog.c
index f925a8d5..306f2cd8 100644
--- a/src/avr/watchdog.c
+++ b/src/avr/watchdog.c
@@ -7,6 +7,7 @@
#include <avr/interrupt.h> // WDT_vect
#include <avr/wdt.h> // wdt_enable
#include "command.h" // shutdown
+#include "irq.h" // irq_disable
#include "sched.h" // DECL_TASK
static uint8_t watchdog_shutdown;
@@ -22,7 +23,7 @@ watchdog_reset(void)
{
wdt_reset();
if (watchdog_shutdown) {
- WDTCSR |= 1<<WDIE;
+ WDTCSR = 1<<WDIE;
watchdog_shutdown = 0;
}
}
@@ -33,6 +34,25 @@ watchdog_init(void)
{
// 0.5s timeout, interrupt and system reset
wdt_enable(WDTO_500MS);
- WDTCSR |= 1<<WDIE;
+ WDTCSR = 1<<WDIE;
}
DECL_INIT(watchdog_init);
+
+// Very early reset of the watchdog
+void __attribute__((naked)) __visible __section(".init3")
+watchdog_early_init(void)
+{
+ MCUSR = 0;
+ wdt_disable();
+}
+
+// Support reset on AVR via the watchdog timer
+void
+command_reset(uint32_t *args)
+{
+ irq_disable();
+ wdt_enable(WDTO_15MS);
+ for (;;)
+ ;
+}
+DECL_COMMAND_FLAGS(command_reset, HF_IN_SHUTDOWN, "reset");