aboutsummaryrefslogtreecommitdiffstats
path: root/src/avr/watchdog.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2017-04-02 23:16:51 -0400
committerKevin O'Connor <kevin@koconnor.net>2017-04-02 23:19:29 -0400
commite44678ceba9095637af477c3cc6e41c8724c01f4 (patch)
tree5c1f7809ad9ce13f5cae6e83df92b2489fd49b67 /src/avr/watchdog.c
parent85c0e9c574df15c47d9823e6dd74071bc87f2ab5 (diff)
downloadkutter-e44678ceba9095637af477c3cc6e41c8724c01f4.tar.gz
kutter-e44678ceba9095637af477c3cc6e41c8724c01f4.tar.xz
kutter-e44678ceba9095637af477c3cc6e41c8724c01f4.zip
avr: Implement reset command
Support restarting the mcu using the watchdog feature of AVR chips via a new reset command. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src/avr/watchdog.c')
-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");