Switch StaticAnalysisTest build test to use the new build system CPPCHECK module...
[pub/USBasp.git] / Bootloaders / CDC / BootloaderCDC.c
index a7fc883..ef68e14 100644 (file)
@@ -56,6 +56,34 @@ 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))
+       {
+               /* Turn off the watchdog */
+               MCUSR &= ~(1<<WDRF);
+               wdt_disable(); 
+
+               /* Clear the boot key and jump to the user application */
+               MagicBootKey = 0;
+
+               // cppcheck-suppress constStatement
+               ((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 +108,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);
@@ -421,7 +452,7 @@ static void CDC_Task(void)
        else if (Command == 'e')
        {
                /* Clear the application section of flash */
-               for (uint32_t CurrFlashAddress = 0; CurrFlashAddress < BOOT_START_ADDR; CurrFlashAddress += SPM_PAGESIZE)
+               for (uint32_t CurrFlashAddress = 0; CurrFlashAddress < (uint32_t)BOOT_START_ADDR; CurrFlashAddress += SPM_PAGESIZE)
                {
                        boot_page_erase(CurrFlashAddress);
                        boot_spm_busy_wait();