Skip to content

Commit 4a7880e

Browse files
committed
Most bootloaders are now Leonardo compatible, and compatible woth the BOOTRST fuse (thanks to Alex Kazik).
1 parent fef991e commit 4a7880e

9 files changed

Lines changed: 191 additions & 45 deletions

File tree

Bootloaders/CDC/BootloaderCDC.c

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,17 @@ void Application_Jump_Check(void)
7272
{
7373
bool JumpToApplication = false;
7474

75-
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
75+
#if (BOARD == BOARD_LEONARDO)
76+
/* Enable pull-up on the IO13 pin so we can use it to select the mode */
77+
PORTC |= (1 << 7);
78+
Delay_MS(10);
79+
80+
/* If IO13 is not jumpered to ground, start the user application instead */
81+
JumpToApplication |= ((PINC & (1 << 7)) != 0);
82+
83+
/* Disable pull-up after the check has completed */
84+
PORTC &= ~(1 << 7);
85+
#elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
7686
/* Disable JTAG debugging */
7787
JTAG_DISABLE();
7888

@@ -87,19 +97,33 @@ void Application_Jump_Check(void)
8797
JTAG_ENABLE();
8898
#endif
8999

90-
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */
91-
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
92-
JumpToApplication |= true;
100+
/* Check if the device's BOOTRST fuse is set (bootloader is run after a device reset) */
101+
if (boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
102+
{
103+
/* If the reset source was not an external reset or the key is correct, clear it and jump to the application */
104+
if ((MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY))
105+
{
106+
MCUSR &= ~(1 << EXTRF);
107+
JumpToApplication |= true;
108+
}
109+
}
110+
else
111+
{
112+
/* If the reset source was the watchdog and the key is correct, clear it and jump to the application */
113+
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
114+
{
115+
MCUSR &= ~(1 << WDRF);
116+
JumpToApplication |= true;
117+
}
118+
}
93119

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

98123
/* If a request has been made to jump to the user application, honor it */
99-
if (JumpToApplication)
124+
if (JumpToApplication && ApplicationValid)
100125
{
101126
/* Turn off the watchdog */
102-
MCUSR &= ~(1<<WDRF);
103127
wdt_disable();
104128

105129
/* Clear the boot key and jump to the user application */

Bootloaders/CDC/BootloaderCDC.txt

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,31 @@
5959
*
6060
* \section Sec_Running Running the Bootloader
6161
*
62-
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
63-
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
64-
* fuse is cleared.
62+
* On the USB AVR8 devices, setting the \c HWBE device fuse will cause the bootloader to run if the \c HWB pin of
63+
* the AVR is grounded when the device is reset.
64+
*
65+
* The are two behaviours of this bootloader, depending on the device's fuses:
66+
*
67+
* <b>If the device's BOOTRST fuse is set</b>, the bootloader will run every time the device is reset from any source.
68+
* The bootloader will immediately run the user application if:
69+
* - An application has been loaded, and the last reset cause was <i>not</i> from the external reset pin
70+
* - The bootloader has reset the device via the Watchdog, in order to start the user application
71+
* - The user has not initiated the bootloader via software (see \ref Sec_API)
72+
*
73+
* <b>If the device's BOOTRST fuse is not set</b>, the bootloader will run only if requested.
74+
* The bootloader will immediately run the user application if:
75+
* - The user has not initiated the bootloader via software (see \ref Sec_API)
76+
* - The HWBE pin was high on device reset, if the HWBE fuse was not set
77+
*
78+
* For board specific exceptions to the above, see below.
79+
*
80+
* \subsection SSec_XPLAIN Atmel Xplain Board
81+
* Ground the USB AVR JTAG's \c TCK pin to ground when powering on the board to start the bootloader. This assumes the
82+
* \c HWBE fuse is cleared and the \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
83+
*
84+
* \subsection SSec_Leonardo Arduino Leonardo Board
85+
* Ground \c IO13 when powering the board to start the bootloader. This assumes the \c HWBE fuse is cleared and the
86+
* \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
6587
*
6688
* For board specific exceptions to the above, see below.
6789
*

Bootloaders/DFU/BootloaderDFU.c

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,17 @@ void Application_Jump_Check(void)
108108
{
109109
bool JumpToApplication = false;
110110

111-
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
111+
#if (BOARD == BOARD_LEONARDO)
112+
/* Enable pull-up on the IO13 pin so we can use it to select the mode */
113+
PORTC |= (1 << 7);
114+
Delay_MS(10);
115+
116+
/* If IO13 is not jumpered to ground, start the user application instead */
117+
JumpToApplication |= ((PINC & (1 << 7)) != 0);
118+
119+
/* Disable pull-up after the check has completed */
120+
PORTC &= ~(1 << 7);
121+
#elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
112122
/* Disable JTAG debugging */
113123
JTAG_DISABLE();
114124

@@ -123,19 +133,33 @@ void Application_Jump_Check(void)
123133
JTAG_ENABLE();
124134
#endif
125135

126-
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */
127-
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
128-
JumpToApplication |= true;
136+
/* Check if the device's BOOTRST fuse is set (bootloader is run after a device reset) */
137+
if (boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
138+
{
139+
/* If the reset source was not an external reset or the key is correct, clear it and jump to the application */
140+
if ((MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY))
141+
{
142+
MCUSR &= ~(1 << EXTRF);
143+
JumpToApplication |= true;
144+
}
145+
}
146+
else
147+
{
148+
/* If the reset source was the watchdog and the key is correct, clear it and jump to the application */
149+
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
150+
{
151+
MCUSR &= ~(1 << WDRF);
152+
JumpToApplication |= true;
153+
}
154+
}
129155

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

134159
/* If a request has been made to jump to the user application, honor it */
135-
if (JumpToApplication)
160+
if (JumpToApplication && ApplicationValid)
136161
{
137162
/* Turn off the watchdog */
138-
MCUSR &= ~(1<<WDRF);
139163
wdt_disable();
140164

141165
/* Clear the boot key and jump to the user application */

Bootloaders/DFU/BootloaderDFU.txt

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,21 @@
5757
*
5858
* \section Sec_Running Running the Bootloader
5959
*
60-
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
61-
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
62-
* fuse is cleared.
60+
* On the USB AVR8 devices, setting the \c HWBE device fuse will cause the bootloader to run if the \c HWB pin of
61+
* the AVR is grounded when the device is reset.
62+
*
63+
* The are two behaviours of this bootloader, depending on the device's fuses:
64+
*
65+
* <b>If the device's BOOTRST fuse is set</b>, the bootloader will run every time the device is reset from any source.
66+
* The bootloader will immediately run the user application if:
67+
* - An application has been loaded, and the last reset cause was <i>not</i> from the external reset pin
68+
* - The bootloader has reset the device via the Watchdog, in order to start the user application
69+
* - The user has not initiated the bootloader via software (see \ref Sec_API)
70+
*
71+
* <b>If the device's BOOTRST fuse is not set</b>, the bootloader will run only if requested.
72+
* The bootloader will immediately run the user application if:
73+
* - The user has not initiated the bootloader via software (see \ref Sec_API)
74+
* - The HWBE pin was high on device reset, if the HWBE fuse was not set
6375
*
6476
* For board specific exceptions to the above, see below.
6577
*

Bootloaders/MassStorage/BootloaderMassStorage.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ void Application_Jump_Check(void)
9191

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

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

117-
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */
118-
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
119-
JumpToApplication |= true;
117+
/* Check if the device's BOOTRST fuse is set (bootloader is run after a device reset) */
118+
if (boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
119+
{
120+
/* If the reset source was not an external reset or the key is correct, clear it and jump to the application */
121+
if ((MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY))
122+
{
123+
MCUSR &= ~(1 << EXTRF);
124+
JumpToApplication |= true;
125+
}
126+
}
127+
else
128+
{
129+
/* If the reset source was the watchdog and the key is correct, clear it and jump to the application */
130+
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
131+
{
132+
MCUSR &= ~(1 << WDRF);
133+
JumpToApplication |= true;
134+
}
135+
}
120136

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

125140
/* If a request has been made to jump to the user application, honor it */
126-
if (JumpToApplication)
141+
if (JumpToApplication && ApplicationValid)
127142
{
128143
/* Turn off the watchdog */
129-
MCUSR &= ~(1<<WDRF);
130144
wdt_disable();
131145

132146
/* Clear the boot key and jump to the user application */

Bootloaders/MassStorage/BootloaderMassStorage.txt

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,21 @@
6262
*
6363
* \section Sec_Running Running the Bootloader
6464
*
65-
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
66-
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
67-
* fuse is cleared.
65+
* On the USB AVR8 devices, setting the \c HWBE device fuse will cause the bootloader to run if the \c HWB pin of
66+
* the AVR is grounded when the device is reset.
67+
*
68+
* The are two behaviours of this bootloader, depending on the device's fuses:
69+
*
70+
* <b>If the device's BOOTRST fuse is set</b>, the bootloader will run every time the device is reset from any source.
71+
* The bootloader will immediately run the user application if:
72+
* - An application has been loaded, and the last reset cause was <i>not</i> from the external reset pin
73+
* - The bootloader has reset the device via the Watchdog, in order to start the user application
74+
* - The user has not initiated the bootloader via software (see \ref Sec_API)
75+
*
76+
* <b>If the device's BOOTRST fuse is not set</b>, the bootloader will run only if requested.
77+
* The bootloader will immediately run the user application if:
78+
* - The user has not initiated the bootloader via software (see \ref Sec_API)
79+
* - The HWBE pin was high on device reset, if the HWBE fuse was not set
6880
*
6981
* For board specific exceptions to the above, see below.
7082
*

Bootloaders/Printer/BootloaderPrinter.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ void Application_Jump_Check(void)
123123

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

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

149-
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */
150-
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
151-
JumpToApplication |= true;
149+
/* Check if the device's BOOTRST fuse is set (bootloader is run after a device reset) */
150+
if (boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) & FUSE_BOOTRST)
151+
{
152+
/* If the reset source was not an external reset or the key is correct, clear it and jump to the application */
153+
if ((MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY))
154+
{
155+
MCUSR &= ~(1 << EXTRF);
156+
JumpToApplication |= true;
157+
}
158+
}
159+
else
160+
{
161+
/* If the reset source was the watchdog and the key is correct, clear it and jump to the application */
162+
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
163+
{
164+
MCUSR &= ~(1 << WDRF);
165+
JumpToApplication |= true;
166+
}
167+
}
152168

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

157172
/* If a request has been made to jump to the user application, honor it */
158-
if (JumpToApplication)
173+
if (JumpToApplication && ApplicationValid)
159174
{
160175
/* Turn off the watchdog */
161-
MCUSR &= ~(1<<WDRF);
162176
wdt_disable();
163177

164178
/* Clear the boot key and jump to the user application */

Bootloaders/Printer/BootloaderPrinter.txt

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,31 @@
5656
*
5757
* \section Sec_Running Running the Bootloader
5858
*
59-
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
60-
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
61-
* fuse is cleared.
59+
* On the USB AVR8 devices, setting the \c HWBE device fuse will cause the bootloader to run if the \c HWB pin of
60+
* the AVR is grounded when the device is reset.
61+
*
62+
* The are two behaviours of this bootloader, depending on the device's fuses:
63+
*
64+
* <b>If the device's BOOTRST fuse is set</b>, the bootloader will run every time the device is reset from any source.
65+
* The bootloader will immediately run the user application if:
66+
* - An application has been loaded, and the last reset cause was <i>not</i> from the external reset pin
67+
* - The bootloader has reset the device via the Watchdog, in order to start the user application
68+
* - The user has not initiated the bootloader via software (see \ref Sec_API)
69+
*
70+
* <b>If the device's BOOTRST fuse is not set</b>, the bootloader will run only if requested.
71+
* The bootloader will immediately run the user application if:
72+
* - The user has not initiated the bootloader via software (see \ref Sec_API)
73+
* - The HWBE pin was high on device reset, if the HWBE fuse was not set
74+
*
75+
* For board specific exceptions to the above, see below.
76+
*
77+
* \subsection SSec_XPLAIN Atmel Xplain Board
78+
* Ground the USB AVR JTAG's \c TCK pin to ground when powering on the board to start the bootloader. This assumes the
79+
* \c HWBE fuse is cleared and the \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
80+
*
81+
* \subsection SSec_Leonardo Arduino Leonardo Board
82+
* Ground \c IO13 when powering the board to start the bootloader. This assumes the \c HWBE fuse is cleared and the
83+
* \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
6284
*
6385
* \section Sec_Installation Driver Installation
6486
*

LUFA/DoxygenPages/ChangeLog.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
* - Library Applications:
1515
* - The CDC, DFU, Mass Storage and Printer class bootloaders will no longer run the user application if the application reset
1616
* vector is blank (thanks to Alex Kazik)
17-
* - The Printer class bootloader is now compatible with the original Atmel XPLAIN and Arduino Leonardo boards.
17+
* - The CDC, DFU and Printer class bootloaders are now compatible with the original Atmel XPLAIN and Arduino Leonardo boards.
18+
* - The CDC, DFU, Mass Storage and Printer class bootloaders are not compatible with devices with the BOOTRST fuse set and will
19+
* exit automatically unless an external reset was the last reset cause (thanks to Alex Kazik)
1820
*
1921
* <b>Fixed:</b>
2022
* - None.

0 commit comments

Comments
 (0)