Skip to content

Commit

Permalink
Most bootloaders are now Leonardo compatible, and compatible woth the…
Browse files Browse the repository at this point in the history
… BOOTRST fuse (thanks to Alex Kazik).
  • Loading branch information
abcminiuser committed Oct 11, 2014
1 parent fef991e commit 4a7880e
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 45 deletions.
40 changes: 32 additions & 8 deletions Bootloaders/CDC/BootloaderCDC.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,17 @@ void Application_Jump_Check(void)
{
bool JumpToApplication = false;

#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
#if (BOARD == BOARD_LEONARDO)
/* Enable pull-up on the IO13 pin so we can use it to select the mode */
PORTC |= (1 << 7);
Delay_MS(10);

/* If IO13 is not jumpered to ground, start the user application instead */
JumpToApplication |= ((PINC & (1 << 7)) != 0);

/* Disable pull-up after the check has completed */
PORTC &= ~(1 << 7);
#elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
/* Disable JTAG debugging */
JTAG_DISABLE();

Expand All @@ -87,19 +97,33 @@ void Application_Jump_Check(void)
JTAG_ENABLE();
#endif

/* 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))
JumpToApplication |= true;
/* Check if the device's BOOTRST fuse is set (bootloader is run after a device reset) */
if (boot_lock_fuse_bits_get(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))
{
MCUSR &= ~(1 << EXTRF);
JumpToApplication |= true;
}
}
else
{
/* If the reset source was the watchdog and the key is correct, clear it and jump to the application */
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
{
MCUSR &= ~(1 << WDRF);
JumpToApplication |= true;
}
}

/* Don't run the user application if the reset vector is blank (no app loaded) */
if (pgm_read_word_near(0) == 0xFFFF)
JumpToApplication = false;
bool ApplicationValid = (pgm_read_word_near(0) != 0xFFFF);

/* If a request has been made to jump to the user application, honor it */
if (JumpToApplication)
if (JumpToApplication && ApplicationValid)
{
/* Turn off the watchdog */
MCUSR &= ~(1<<WDRF);
wdt_disable();

/* Clear the boot key and jump to the user application */
Expand Down
28 changes: 25 additions & 3 deletions Bootloaders/CDC/BootloaderCDC.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,31 @@
*
* \section Sec_Running Running the Bootloader
*
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
* fuse is cleared.
* On the USB AVR8 devices, setting the \c HWBE device fuse will cause the bootloader to run if the \c HWB pin of
* the AVR is grounded when the device is reset.
*
* The are two behaviours of this bootloader, depending on the device's fuses:
*
* <b>If the device's BOOTRST fuse is set</b>, the bootloader will run every time the device is reset from any source.
* The bootloader will immediately run the user application if:
* - An application has been loaded, and the last reset cause was <i>not</i> from the external reset pin
* - The bootloader has reset the device via the Watchdog, in order to start the user application
* - The user has not initiated the bootloader via software (see \ref Sec_API)
*
* <b>If the device's BOOTRST fuse is not set</b>, the bootloader will run only if requested.
* The bootloader will immediately run the user application if:
* - The user has not initiated the bootloader via software (see \ref Sec_API)
* - The HWBE pin was high on device reset, if the HWBE fuse was not set
*
* For board specific exceptions to the above, see below.
*
* \subsection SSec_XPLAIN Atmel Xplain Board
* Ground the USB AVR JTAG's \c TCK pin to ground when powering on the board to start the bootloader. This assumes the
* \c HWBE fuse is cleared and the \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
*
* \subsection SSec_Leonardo Arduino Leonardo Board
* Ground \c IO13 when powering the board to start the bootloader. This assumes the \c HWBE fuse is cleared and the
* \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
*
* For board specific exceptions to the above, see below.
*
Expand Down
40 changes: 32 additions & 8 deletions Bootloaders/DFU/BootloaderDFU.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,17 @@ void Application_Jump_Check(void)
{
bool JumpToApplication = false;

#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
#if (BOARD == BOARD_LEONARDO)
/* Enable pull-up on the IO13 pin so we can use it to select the mode */
PORTC |= (1 << 7);
Delay_MS(10);

/* If IO13 is not jumpered to ground, start the user application instead */
JumpToApplication |= ((PINC & (1 << 7)) != 0);

/* Disable pull-up after the check has completed */
PORTC &= ~(1 << 7);
#elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
/* Disable JTAG debugging */
JTAG_DISABLE();

Expand All @@ -123,19 +133,33 @@ void Application_Jump_Check(void)
JTAG_ENABLE();
#endif

/* 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))
JumpToApplication |= true;
/* Check if the device's BOOTRST fuse is set (bootloader is run after a device reset) */
if (boot_lock_fuse_bits_get(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))
{
MCUSR &= ~(1 << EXTRF);
JumpToApplication |= true;
}
}
else
{
/* If the reset source was the watchdog and the key is correct, clear it and jump to the application */
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
{
MCUSR &= ~(1 << WDRF);
JumpToApplication |= true;
}
}

/* Don't run the user application if the reset vector is blank (no app loaded) */

JumpToApplication = false;
bool ApplicationValid = (pgm_read_word_near(0) != 0xFFFF);

/* If a request has been made to jump to the user application, honor it */
if (JumpToApplication)
if (JumpToApplication && ApplicationValid)
{
/* Turn off the watchdog */
MCUSR &= ~(1<<WDRF);
wdt_disable();

/* Clear the boot key and jump to the user application */
Expand Down
18 changes: 15 additions & 3 deletions Bootloaders/DFU/BootloaderDFU.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,21 @@
*
* \section Sec_Running Running the Bootloader
*
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
* fuse is cleared.
* On the USB AVR8 devices, setting the \c HWBE device fuse will cause the bootloader to run if the \c HWB pin of
* the AVR is grounded when the device is reset.
*
* The are two behaviours of this bootloader, depending on the device's fuses:
*
* <b>If the device's BOOTRST fuse is set</b>, the bootloader will run every time the device is reset from any source.
* The bootloader will immediately run the user application if:
* - An application has been loaded, and the last reset cause was <i>not</i> from the external reset pin
* - The bootloader has reset the device via the Watchdog, in order to start the user application
* - The user has not initiated the bootloader via software (see \ref Sec_API)
*
* <b>If the device's BOOTRST fuse is not set</b>, the bootloader will run only if requested.
* The bootloader will immediately run the user application if:
* - The user has not initiated the bootloader via software (see \ref Sec_API)
* - The HWBE pin was high on device reset, if the HWBE fuse was not set
*
* For board specific exceptions to the above, see below.
*
Expand Down
30 changes: 22 additions & 8 deletions Bootloaders/MassStorage/BootloaderMassStorage.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void Application_Jump_Check(void)

#if (BOARD == BOARD_LEONARDO)
/* Enable pull-up on the IO13 pin so we can use it to select the mode */
PORTC |= (1 << 7);
PORTC |= (1 << 7);
Delay_MS(10);

/* If IO13 is not jumpered to ground, start the user application instead */
Expand All @@ -114,19 +114,33 @@ void Application_Jump_Check(void)
JTAG_ENABLE();
#endif

/* 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))
JumpToApplication |= true;
/* Check if the device's BOOTRST fuse is set (bootloader is run after a device reset) */
if (boot_lock_fuse_bits_get(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))
{
MCUSR &= ~(1 << EXTRF);
JumpToApplication |= true;
}
}
else
{
/* If the reset source was the watchdog and the key is correct, clear it and jump to the application */
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
{
MCUSR &= ~(1 << WDRF);
JumpToApplication |= true;
}
}

/* Don't run the user application if the reset vector is blank (no app loaded) */
if (pgm_read_word_near(0) == 0xFFFF)
JumpToApplication = false;
bool ApplicationValid = (pgm_read_word_near(0) != 0xFFFF);

/* If a request has been made to jump to the user application, honor it */
if (JumpToApplication)
if (JumpToApplication && ApplicationValid)
{
/* Turn off the watchdog */
MCUSR &= ~(1<<WDRF);
wdt_disable();

/* Clear the boot key and jump to the user application */
Expand Down
18 changes: 15 additions & 3 deletions Bootloaders/MassStorage/BootloaderMassStorage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,21 @@
*
* \section Sec_Running Running the Bootloader
*
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
* fuse is cleared.
* On the USB AVR8 devices, setting the \c HWBE device fuse will cause the bootloader to run if the \c HWB pin of
* the AVR is grounded when the device is reset.
*
* The are two behaviours of this bootloader, depending on the device's fuses:
*
* <b>If the device's BOOTRST fuse is set</b>, the bootloader will run every time the device is reset from any source.
* The bootloader will immediately run the user application if:
* - An application has been loaded, and the last reset cause was <i>not</i> from the external reset pin
* - The bootloader has reset the device via the Watchdog, in order to start the user application
* - The user has not initiated the bootloader via software (see \ref Sec_API)
*
* <b>If the device's BOOTRST fuse is not set</b>, the bootloader will run only if requested.
* The bootloader will immediately run the user application if:
* - The user has not initiated the bootloader via software (see \ref Sec_API)
* - The HWBE pin was high on device reset, if the HWBE fuse was not set
*
* For board specific exceptions to the above, see below.
*
Expand Down
30 changes: 22 additions & 8 deletions Bootloaders/Printer/BootloaderPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ void Application_Jump_Check(void)

#if (BOARD == BOARD_LEONARDO)
/* Enable pull-up on the IO13 pin so we can use it to select the mode */
PORTC |= (1 << 7);
PORTC |= (1 << 7);
Delay_MS(10);

/* If IO13 is not jumpered to ground, start the user application instead */
Expand All @@ -146,19 +146,33 @@ void Application_Jump_Check(void)
JTAG_ENABLE();
#endif

/* 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))
JumpToApplication |= true;
/* Check if the device's BOOTRST fuse is set (bootloader is run after a device reset) */
if (boot_lock_fuse_bits_get(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))
{
MCUSR &= ~(1 << EXTRF);
JumpToApplication |= true;
}
}
else
{
/* If the reset source was the watchdog and the key is correct, clear it and jump to the application */
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
{
MCUSR &= ~(1 << WDRF);
JumpToApplication |= true;
}
}

/* Don't run the user application if the reset vector is blank (no app loaded) */
if (pgm_read_word_near(0) == 0xFFFF)
JumpToApplication = false;
bool ApplicationValid = (pgm_read_word_near(0) != 0xFFFF);

/* If a request has been made to jump to the user application, honor it */
if (JumpToApplication)
if (JumpToApplication && ApplicationValid)
{
/* Turn off the watchdog */
MCUSR &= ~(1<<WDRF);
wdt_disable();

/* Clear the boot key and jump to the user application */
Expand Down
28 changes: 25 additions & 3 deletions Bootloaders/Printer/BootloaderPrinter.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,31 @@
*
* \section Sec_Running Running the Bootloader
*
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
* fuse is cleared.
* On the USB AVR8 devices, setting the \c HWBE device fuse will cause the bootloader to run if the \c HWB pin of
* the AVR is grounded when the device is reset.
*
* The are two behaviours of this bootloader, depending on the device's fuses:
*
* <b>If the device's BOOTRST fuse is set</b>, the bootloader will run every time the device is reset from any source.
* The bootloader will immediately run the user application if:
* - An application has been loaded, and the last reset cause was <i>not</i> from the external reset pin
* - The bootloader has reset the device via the Watchdog, in order to start the user application
* - The user has not initiated the bootloader via software (see \ref Sec_API)
*
* <b>If the device's BOOTRST fuse is not set</b>, the bootloader will run only if requested.
* The bootloader will immediately run the user application if:
* - The user has not initiated the bootloader via software (see \ref Sec_API)
* - The HWBE pin was high on device reset, if the HWBE fuse was not set
*
* For board specific exceptions to the above, see below.
*
* \subsection SSec_XPLAIN Atmel Xplain Board
* Ground the USB AVR JTAG's \c TCK pin to ground when powering on the board to start the bootloader. This assumes the
* \c HWBE fuse is cleared and the \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
*
* \subsection SSec_Leonardo Arduino Leonardo Board
* Ground \c IO13 when powering the board to start the bootloader. This assumes the \c HWBE fuse is cleared and the
* \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
*
* \section Sec_Installation Driver Installation
*
Expand Down
4 changes: 3 additions & 1 deletion LUFA/DoxygenPages/ChangeLog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
* - Library Applications:
* - The CDC, DFU, Mass Storage and Printer class bootloaders will no longer run the user application if the application reset
* vector is blank (thanks to Alex Kazik)
* - The Printer class bootloader is now compatible with the original Atmel XPLAIN and Arduino Leonardo boards.
* - The CDC, DFU and Printer class bootloaders are now compatible with the original Atmel XPLAIN and Arduino Leonardo boards.
* - The CDC, DFU, Mass Storage and Printer class bootloaders are not compatible with devices with the BOOTRST fuse set and will
* exit automatically unless an external reset was the last reset cause (thanks to Alex Kazik)
*
* <b>Fixed:</b>
* - None.
Expand Down

0 comments on commit 4a7880e

Please sign in to comment.