Add Leonardo compatibility to most bootloaders, run user application if BOOTRST fuse is set and the last reset cause was not the /RESET pin.

pull/1469/head
Dean Camera 11 years ago
parent fef991e28b
commit 4c637c93ba

@ -72,7 +72,17 @@ void Application_Jump_Check(void)
{ {
bool JumpToApplication = false; 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 */ /* Disable JTAG debugging */
JTAG_DISABLE(); JTAG_DISABLE();
@ -81,22 +91,27 @@ void Application_Jump_Check(void)
Delay_MS(10); Delay_MS(10);
/* If the TCK pin is not jumpered to ground, start the user application instead */ /* If the TCK pin is not jumpered to ground, start the user application instead */
JumpToApplication |= ((PINF & (1 << 4)) != 0); JumpToApplication = ((PINF & (1 << 4)) != 0);
/* Re-enable JTAG debugging */ /* Re-enable JTAG debugging */
JTAG_ENABLE(); JTAG_ENABLE();
#endif #else
/* Check if the device's BOOTRST fuse is set */
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))
JumpToApplication = true;
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */ MCUSR &= ~(1 << EXTRF);
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) }
JumpToApplication |= true; #endif
/* Don't run the user application if the reset vector is blank (no app loaded) */ /* Don't run the user application if the reset vector is blank (no app loaded) */
if (pgm_read_word_near(0) == 0xFFFF) bool ApplicationValid = (pgm_read_word_near(0) != 0xFFFF);
JumpToApplication = false;
/* If a request has been made to jump to the user application, honor it */ /* If a request has been made to jump to the user application, honor it */
if (JumpToApplication) if (JumpToApplication && ApplicationValid)
{ {
/* Turn off the watchdog */ /* Turn off the watchdog */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);

@ -59,9 +59,27 @@
* *
* \section Sec_Running Running the Bootloader * \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 * On the USB AVR8 devices, setting the \c HWBE device fuse will cause the bootloader to run if the \c HWB pin of
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST * the AVR is grounded when the device is reset.
* fuse is cleared. *
* 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 any time the system is not reset from
* the external reset pin, unless no valid user application has been loaded. To initiate the bootloader, the
* device's external reset pin should be grounded.
*
* <b>If the device's BOOTRST fuse is not set</b>, the bootloader will run only if initiated via a software
* jump, or if the \c HWB pin was low during the last device reset (if the \c HWBE fuse is 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. * For board specific exceptions to the above, see below.
* *

@ -108,7 +108,17 @@ void Application_Jump_Check(void)
{ {
bool JumpToApplication = false; 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 */ /* Disable JTAG debugging */
JTAG_DISABLE(); JTAG_DISABLE();
@ -117,22 +127,27 @@ void Application_Jump_Check(void)
Delay_MS(10); Delay_MS(10);
/* If the TCK pin is not jumpered to ground, start the user application instead */ /* If the TCK pin is not jumpered to ground, start the user application instead */
JumpToApplication |= ((PINF & (1 << 4)) != 0); JumpToApplication = ((PINF & (1 << 4)) != 0);
/* Re-enable JTAG debugging */ /* Re-enable JTAG debugging */
JTAG_ENABLE(); JTAG_ENABLE();
#endif #else
/* Check if the device's BOOTRST fuse is set */
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))
JumpToApplication = true;
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */ MCUSR &= ~(1 << EXTRF);
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) }
JumpToApplication |= true; #endif
/* Don't run the user application if the reset vector is blank (no app loaded) */ /* Don't run the user application if the reset vector is blank (no app loaded) */
bool ApplicationValid = (pgm_read_word_near(0) != 0xFFFF);
JumpToApplication = false;
/* If a request has been made to jump to the user application, honor it */ /* If a request has been made to jump to the user application, honor it */
if (JumpToApplication) if (JumpToApplication && ApplicationValid)
{ {
/* Turn off the watchdog */ /* Turn off the watchdog */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);

@ -57,9 +57,17 @@
* *
* \section Sec_Running Running the Bootloader * \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 * On the USB AVR8 devices, setting the \c HWBE device fuse will cause the bootloader to run if the \c HWB pin of
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST * the AVR is grounded when the device is reset.
* fuse is cleared. *
* 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 any time the system is not reset from
* the external reset pin, unless no valid user application has been loaded. To initiate the bootloader, the
* device's external reset pin should be grounded.
*
* <b>If the device's BOOTRST fuse is not set</b>, the bootloader will run only if initiated via a software
* jump, or if the \c HWB pin was low during the last device reset (if the \c HWBE fuse is set).
* *
* For board specific exceptions to the above, see below. * For board specific exceptions to the above, see below.
* *

@ -95,7 +95,7 @@ void Application_Jump_Check(void)
Delay_MS(10); Delay_MS(10);
/* If IO13 is not jumpered to ground, start the user application instead */ /* If IO13 is not jumpered to ground, start the user application instead */
JumpToApplication |= ((PINC & (1 << 7)) != 0); JumpToApplication = ((PINC & (1 << 7)) != 0);
/* Disable pull-up after the check has completed */ /* Disable pull-up after the check has completed */
PORTC &= ~(1 << 7); PORTC &= ~(1 << 7);
@ -108,22 +108,27 @@ void Application_Jump_Check(void)
Delay_MS(10); Delay_MS(10);
/* If the TCK pin is not jumpered to ground, start the user application instead */ /* If the TCK pin is not jumpered to ground, start the user application instead */
JumpToApplication |= ((PINF & (1 << 4)) != 0); JumpToApplication = ((PINF & (1 << 4)) != 0);
/* Re-enable JTAG debugging */ /* Re-enable JTAG debugging */
JTAG_ENABLE(); JTAG_ENABLE();
#endif #else
/* Check if the device's BOOTRST fuse is set */
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))
JumpToApplication = true;
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */ MCUSR &= ~(1 << EXTRF);
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) }
JumpToApplication |= true; #endif
/* Don't run the user application if the reset vector is blank (no app loaded) */ /* Don't run the user application if the reset vector is blank (no app loaded) */
if (pgm_read_word_near(0) == 0xFFFF) bool ApplicationValid = (pgm_read_word_near(0) != 0xFFFF);
JumpToApplication = false;
/* If a request has been made to jump to the user application, honor it */ /* If a request has been made to jump to the user application, honor it */
if (JumpToApplication) if (JumpToApplication && ApplicationValid)
{ {
/* Turn off the watchdog */ /* Turn off the watchdog */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);

@ -62,9 +62,17 @@
* *
* \section Sec_Running Running the Bootloader * \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 * On the USB AVR8 devices, setting the \c HWBE device fuse will cause the bootloader to run if the \c HWB pin of
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST * the AVR is grounded when the device is reset.
* fuse is cleared. *
* 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 any time the system is not reset from
* the external reset pin, unless no valid user application has been loaded. To initiate the bootloader, the
* device's external reset pin should be grounded.
*
* <b>If the device's BOOTRST fuse is not set</b>, the bootloader will run only if initiated via a software
* jump, or if the \c HWB pin was low during the last device reset (if the \c HWBE fuse is set).
* *
* For board specific exceptions to the above, see below. * For board specific exceptions to the above, see below.
* *

@ -127,7 +127,7 @@ void Application_Jump_Check(void)
Delay_MS(10); Delay_MS(10);
/* If IO13 is not jumpered to ground, start the user application instead */ /* If IO13 is not jumpered to ground, start the user application instead */
JumpToApplication |= ((PINC & (1 << 7)) != 0); JumpToApplication = ((PINC & (1 << 7)) != 0);
/* Disable pull-up after the check has completed */ /* Disable pull-up after the check has completed */
PORTC &= ~(1 << 7); PORTC &= ~(1 << 7);
@ -140,22 +140,27 @@ void Application_Jump_Check(void)
Delay_MS(10); Delay_MS(10);
/* If the TCK pin is not jumpered to ground, start the user application instead */ /* If the TCK pin is not jumpered to ground, start the user application instead */
JumpToApplication |= ((PINF & (1 << 4)) != 0); JumpToApplication = ((PINF & (1 << 4)) != 0);
/* Re-enable JTAG debugging */ /* Re-enable JTAG debugging */
JTAG_ENABLE(); JTAG_ENABLE();
#endif #else
/* Check if the device's BOOTRST fuse is set */
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))
JumpToApplication = true;
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */ MCUSR &= ~(1 << EXTRF);
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) }
JumpToApplication |= true; #endif
/* Don't run the user application if the reset vector is blank (no app loaded) */ /* Don't run the user application if the reset vector is blank (no app loaded) */
if (pgm_read_word_near(0) == 0xFFFF) bool ApplicationValid = (pgm_read_word_near(0) != 0xFFFF);
JumpToApplication = false;
/* If a request has been made to jump to the user application, honor it */ /* If a request has been made to jump to the user application, honor it */
if (JumpToApplication) if (JumpToApplication && ApplicationValid)
{ {
/* Turn off the watchdog */ /* Turn off the watchdog */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);

@ -56,9 +56,27 @@
* *
* \section Sec_Running Running the Bootloader * \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 * On the USB AVR8 devices, setting the \c HWBE device fuse will cause the bootloader to run if the \c HWB pin of
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST * the AVR is grounded when the device is reset.
* fuse is cleared. *
* 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 any time the system is not reset from
* the external reset pin, unless no valid user application has been loaded. To initiate the bootloader, the
* device's external reset pin should be grounded.
*
* <b>If the device's BOOTRST fuse is not set</b>, the bootloader will run only if initiated via a software
* jump, or if the \c HWB pin was low during the last device reset (if the \c HWBE fuse is 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 * \section Sec_Installation Driver Installation
* *

@ -14,7 +14,9 @@
* - Library Applications: * - Library Applications:
* - The CDC, DFU, Mass Storage and Printer class bootloaders will no longer run the user application if the application reset * - 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) * 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> * <b>Fixed:</b>
* - None. * - None.

Loading…
Cancel
Save