diff options
author | Dean Camera <dean@fourwalledcubicle.com> | 2012-04-29 17:15:06 +0000 |
---|---|---|
committer | Dean Camera <dean@fourwalledcubicle.com> | 2012-04-29 17:15:06 +0000 |
commit | 04740d680eb5f5bb665e87155e8d88023ef74214 (patch) | |
tree | ee469798b10ea1d021881d98103dea3cc8e08a99 /Bootloaders/CDC | |
parent | cc959c945b8002ece6c47e86af012112dd2535b3 (diff) | |
download | lufa-04740d680eb5f5bb665e87155e8d88023ef74214.tar.gz lufa-04740d680eb5f5bb665e87155e8d88023ef74214.tar.bz2 lufa-04740d680eb5f5bb665e87155e8d88023ef74214.zip |
The library bootloaders will now correctly start the user application after a watchdog-based application start, even if the /HWB line is held low externally during the reset phase.
Diffstat (limited to 'Bootloaders/CDC')
-rw-r--r-- | Bootloaders/CDC/BootloaderCDC.c | 24 | ||||
-rw-r--r-- | Bootloaders/CDC/BootloaderCDC.h | 5 |
2 files changed, 29 insertions, 0 deletions
diff --git a/Bootloaders/CDC/BootloaderCDC.c b/Bootloaders/CDC/BootloaderCDC.c index a7fc883cf..d057349c7 100644 --- a/Bootloaders/CDC/BootloaderCDC.c +++ b/Bootloaders/CDC/BootloaderCDC.c @@ -56,6 +56,27 @@ static uint32_t CurrAddress; */ static bool RunBootloader = true; +/** Magic lock for forced application start. If the HWBE fuse is programmed and BOOTRST is unprogrammed, the bootloader + * will start if the /HWB line of the AVR is held low and the system is reset. However, if the /HWB line is still held + * low when the application attempts to start via a watchdog reset, the bootloader will re-start. If set to the value + * \ref MAGIC_BOOT_KEY the special init function \ref Application_Jump_Check() will force the application to start. + */ +uint32_t MagicBootKey ATTR_NO_INIT; + + +/** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application + * start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid, + * this will force the user application to start via a software jump. + */ +void Application_Jump_Check(void) +{ + // If the reset source was the bootloader and the key is correct, clear it and jump to the application + if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) + { + MagicBootKey = 0; + ((void (*)(void))0x0000)(); + } +} /** Main program entry point. This routine configures the hardware required by the bootloader, then continuously * runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start @@ -80,6 +101,9 @@ int main(void) /* Disconnect from the host - USB interface will be reset later along with the AVR */ USB_Detach(); + + /* Unlock the forced application start mode of the bootloader if it is restarted */ + MagicBootKey = MAGIC_BOOT_KEY; /* Enable the watchdog and force a timeout to reset the AVR */ wdt_enable(WDTO_250MS); diff --git a/Bootloaders/CDC/BootloaderCDC.h b/Bootloaders/CDC/BootloaderCDC.h index 4b9e7d6d8..257e884e6 100644 --- a/Bootloaders/CDC/BootloaderCDC.h +++ b/Bootloaders/CDC/BootloaderCDC.h @@ -67,6 +67,9 @@ /** Eight character bootloader firmware identifier reported to the host when requested */ #define SOFTWARE_IDENTIFIER "LUFACDC" + /** Magic bootloader key to unlock forced application start mode. */ + #define MAGIC_BOOT_KEY 0xDC42CACA + /* Type Defines: */ /** Type define for a non-returning pointer to the start of the loaded application in flash memory. */ typedef void (*AppPtr_t)(void) ATTR_NO_RETURN; @@ -75,6 +78,8 @@ static void CDC_Task(void); static void SetupHardware(void); + void Application_Jump_Check(void) ATTR_INIT_SECTION(3); + void EVENT_USB_Device_ConfigurationChanged(void); #if defined(INCLUDE_FROM_BOOTLOADERCDC_C) || defined(__DOXYGEN__) |