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>
This commit is contained in:
Kevin O'Connor 2017-04-02 23:16:51 -04:00
parent 85c0e9c574
commit e44678ceba
1 changed files with 22 additions and 2 deletions

View File

@ -7,6 +7,7 @@
#include <avr/interrupt.h> // WDT_vect #include <avr/interrupt.h> // WDT_vect
#include <avr/wdt.h> // wdt_enable #include <avr/wdt.h> // wdt_enable
#include "command.h" // shutdown #include "command.h" // shutdown
#include "irq.h" // irq_disable
#include "sched.h" // DECL_TASK #include "sched.h" // DECL_TASK
static uint8_t watchdog_shutdown; static uint8_t watchdog_shutdown;
@ -22,7 +23,7 @@ watchdog_reset(void)
{ {
wdt_reset(); wdt_reset();
if (watchdog_shutdown) { if (watchdog_shutdown) {
WDTCSR |= 1<<WDIE; WDTCSR = 1<<WDIE;
watchdog_shutdown = 0; watchdog_shutdown = 0;
} }
} }
@ -33,6 +34,25 @@ watchdog_init(void)
{ {
// 0.5s timeout, interrupt and system reset // 0.5s timeout, interrupt and system reset
wdt_enable(WDTO_500MS); wdt_enable(WDTO_500MS);
WDTCSR |= 1<<WDIE; WDTCSR = 1<<WDIE;
} }
DECL_INIT(watchdog_init); 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");