Stuck in Atmega328 reset loop?
Kill switch killing... but stuck in reset loop
I wanted to add a kill switch to my quadcopter project so that in the case of crash/emergency, a button might be pushed on the radio controller, the quadcopter motors stopped and the flight controller chip is reset. A good way of resetting an AVR is to invoke the watchdog timer and put the chip into an infinite loop - the watchdog times out and the chip is reset. This is fairly straightforward when the kill/reset signal is received:
#include <avr/wdt.h>
void kill_drone(void)
{
USART_Pputstring(PSTR("Kill drone!\n"));
wdt_reset();
wdt_enable(WDTO_15MS);
while(1){};
}
where the two watchdog handling functions are defined in avr/wdt.h.
The AVR is reset, but keeps on reseting, initialising and resetting in an infinite loop... Watchdog Groundhog day!
I wanted to add a kill switch to my quadcopter project so that in the case of crash/emergency, a button might be pushed on the radio controller, the quadcopter motors stopped and the flight controller chip is reset. A good way of resetting an AVR is to invoke the watchdog timer and put the chip into an infinite loop - the watchdog times out and the chip is reset. This is fairly straightforward when the kill/reset signal is received:
#include <avr/wdt.h>
void kill_drone(void)
{
USART_Pputstring(PSTR("Kill drone!\n"));
wdt_reset();
wdt_enable(WDTO_15MS);
while(1){};
}
where the two watchdog handling functions are defined in avr/wdt.h.
The AVR is reset, but keeps on reseting, initialising and resetting in an infinite loop... Watchdog Groundhog day!
It turns out that the watchdog register settings are enabled, even after a reset! To get around this, the watchdog must be turned off at the earliest opportunity of code execution by placing the necessary commands in the .init3 section of code:
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
void wdt_init(void)
{
MCUSR = 0;
wdt_disable();
return;
}
Finally we can exit this Groundhog day :)
Thhank you for this
ReplyDelete