From: Stephan Baerwolf Date: Sun, 31 Mar 2013 17:31:23 +0000 (+0200) Subject: BUGFIX: fix issue 6 to really disable watchdog timer X-Git-Tag: v0.96~7 X-Git-Url: http://git.linex4red.de/pub/USBaspLoader.git/commitdiff_plain/27f21b1464a7743393bb1ea88f70d687155bbe4b BUGFIX: fix issue 6 to really disable watchdog timer On "https://github.com/baerwolf/USBaspLoader/issues/6" coldtobi reported an issue of disabling the watchdog timer in a wrong way. (At least on some newer devices.) This can lead to unexpected reboots within bootloader mode, and result in data losses / broken firmwares. The original report: ==================== At least on the ATMega644, the MCUSR bit WDRF in the MCUSR needs to be cleared first, otherwise it is not possible to disable the watchdog. (See http://www.atmel.com/Images/doc2593.pdf, p.53) ? Bit 3 - WDE: Watchdog System Reset Enable WDE is overridden by WDRF in MCUSR. This means that WDE is always set when WDRF is set. To clear WDE, WDRF must be cleared first. This feature ensures multiple resets during conditions causing failure, and a safe start-up after the failure. Otherwise the software cannot disable the wdt. This line just before wdt_disable will fix this MCUCSR = ~(1< Signed-off-by: Stephan Baerwolf --- diff --git a/firmware/main.c b/firmware/main.c index 87f0641..bd36e06 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -644,6 +644,15 @@ int __attribute__((__noreturn__)) main(void) #endif if(bootLoaderCondition()){ #if NEED_WATCHDOG +# if (defined(MCUSR) && defined(WDRF)) + /* + * Fix issue 6: (special thanks to coldtobi) + * + * The WDRF bit in the MCUSR needs to be cleared first, + * otherwise it is not possible to disable the watchdog + */ + MCUSR &= ~(_BV(WDRF)); +# endif wdt_disable(); /* main app may have enabled watchdog */ #endif initForUsbConnectivity();