/* Re-enable JTAG debugging */
JTAG_ENABLE();
+ #elif ((BOARD == BOARD_PROMICRO) || (BOARD == BOARD_MICRO))
+ /* Pro-Micro and Arduino Micro board use power-on reset, but no external reset. Both boards have
+ * the hardware bootloader pin HWBE enabled. Unfortunately only the external reset allows together
+ * with an enabled HWBE that the CPU start at the bootloader address independent of the FUSE_BOOTRST.
+ * That means the power-on reset will start just controlled by the FUSE_BOOTRST the bootloader or
+ * direct in the application and cannot be overridden by HWBE signal. Therfore FUSE_BOOTRST shall
+ * be enabled, otherwise the bootloader will not be reached for these boards.
+ * The bootloader checks FUSE_HWBE as *unprogammed* instead of FUSE_BOOTRST as programmed on other
+ * board variants to decide fast application start, without waiting the dedicted bootloader timeout
+ * in case of a USB, watchdog, brown-out or JTAG reset. If the watchdog reset was initiated from
+ * the bootloader marked with the MAGIC_BOOT_KEY this reset flag is reset. All other reset flags
+ * are left untouched to allow the application code checking the reset signals, especially in case
+ * of application fast start.
+ * The bootloader is entered always for external reset and power-on reset. But the bootloader is
+ * anyway exited after that dedicted timeout, if a reset-vector to the application is programmed.
+ * Once a DFU program interacts this the bootloader during this dedicted timeout, the timer stops
+ * and the application needs to be started by DFU bootloader command manually or using a reset.
+ */
+
+ /* Check if the device's forced Bootloader via Hardware Bootenable is unprogrammed */
+ if (BootloaderAPI_ReadFuse(GET_EXTENDED_FUSE_BITS) & ~FUSE_HWBE)
+ {
+ /* If the reset source was not an external or power-on reset jump to the application */
+ if (!(MCUSR & ((1 << EXTRF) || (1 << PORF))))
+ JumpToApplication = true;
+ }
+ /* If the reset source was the bootloader and the key is correct, clear it and jump to the application;
+ * this can happen in the HWBE fuse is set, and the HBE pin is low during the watchdog reset */
+ if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
+ {
+ JumpToApplication = true;
+
+ /* Clear reset source */
+ MCUSR &= ~(1 << WDRF);
+ }
#else
+ /* Check if the device's BOOTRST fuse is set */
+ if (!(BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS) & ~FUSE_BOOTRST))
+ {
+ /* If the reset source was not an external reset or the key is correct, clear it and jump to the application */
+ if (!(MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY))
+ JumpToApplication = true;
+
+ /* Clear reset source */
+ MCUSR &= ~(1 << EXTRF);
+ }
+ else
{
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application;
* this can happen in the HWBE fuse is set, and the HBE pin is low during the watchdog reset */
}
#endif
+ /* Clear the boot key in any case */
+ MagicBootKey = 0;
+
/* Don't run the user application if the reset vector is blank (no app loaded) */
bool ApplicationValid = (pgm_read_word_near(0) != 0xFFFF);
if (JumpToApplication && ApplicationValid)
{
/* 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)();
}