diff options
-rw-r--r-- | bootloader.mk | 4 | ||||
-rw-r--r-- | docs/config_options.md | 1 | ||||
-rw-r--r-- | docs/flashing.md | 25 | ||||
-rw-r--r-- | keyboards/gingham/rules.mk | 4 | ||||
-rw-r--r-- | tmk_core/avr.mk | 4 | ||||
-rw-r--r-- | tmk_core/common/avr/bootloader.c | 77 |
6 files changed, 78 insertions, 37 deletions
diff --git a/bootloader.mk b/bootloader.mk index 4bcf183fb..9d73063d0 100644 --- a/bootloader.mk +++ b/bootloader.mk | |||
@@ -76,6 +76,10 @@ ifeq ($(strip $(BOOTLOADER)), bootloadHID) | |||
76 | OPT_DEFS += -DBOOTLOADER_BOOTLOADHID | 76 | OPT_DEFS += -DBOOTLOADER_BOOTLOADHID |
77 | BOOTLOADER_SIZE = 4096 | 77 | BOOTLOADER_SIZE = 4096 |
78 | endif | 78 | endif |
79 | ifeq ($(strip $(BOOTLOADER)), USBasp) | ||
80 | OPT_DEFS += -DBOOTLOADER_USBASP | ||
81 | BOOTLOADER_SIZE = 4096 | ||
82 | endif | ||
79 | 83 | ||
80 | ifdef BOOTLOADER_SIZE | 84 | ifdef BOOTLOADER_SIZE |
81 | OPT_DEFS += -DBOOTLOADER_SIZE=$(strip $(BOOTLOADER_SIZE)) | 85 | OPT_DEFS += -DBOOTLOADER_SIZE=$(strip $(BOOTLOADER_SIZE)) |
diff --git a/docs/config_options.md b/docs/config_options.md index eb0a441cc..33cb8da9b 100644 --- a/docs/config_options.md +++ b/docs/config_options.md | |||
@@ -289,6 +289,7 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i | |||
289 | * `halfkay` | 289 | * `halfkay` |
290 | * `caterina` | 290 | * `caterina` |
291 | * `bootloadHID` | 291 | * `bootloadHID` |
292 | * `USBasp` | ||
292 | 293 | ||
293 | ## Feature Options | 294 | ## Feature Options |
294 | 295 | ||
diff --git a/docs/flashing.md b/docs/flashing.md index 3b4582f00..833b9dd62 100644 --- a/docs/flashing.md +++ b/docs/flashing.md | |||
@@ -119,6 +119,31 @@ Flashing sequence: | |||
119 | 3. Flash a .hex file | 119 | 3. Flash a .hex file |
120 | 4. Reset the device into application mode (may be done automatically) | 120 | 4. Reset the device into application mode (may be done automatically) |
121 | 121 | ||
122 | ## USBasploader | ||
123 | |||
124 | USBasploader is a bootloader developed by matrixstorm. It is used in some non-USB AVR chips such as the ATmega328P, which run V-USB. | ||
125 | |||
126 | To ensure compatibility with the USBasploader bootloader, make sure this block is present in your `rules.mk`: | ||
127 | |||
128 | # Bootloader | ||
129 | # This definition is optional, and if your keyboard supports multiple bootloaders of | ||
130 | # different sizes, comment this out, and the correct address will be loaded | ||
131 | # automatically (+60). See bootloader.mk for all options. | ||
132 | BOOTLOADER = USBasp | ||
133 | |||
134 | Compatible flashers: | ||
135 | |||
136 | * [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) | ||
137 | * [avrdude](http://www.nongnu.org/avrdude/) with the `usbasp` programmer | ||
138 | * [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) | ||
139 | |||
140 | Flashing sequence: | ||
141 | |||
142 | 1. Press the `RESET` keycode, or keep the boot pin shorted to GND while quickly shorting RST to GND | ||
143 | 2. Wait for the OS to detect the device | ||
144 | 3. Flash a .hex file | ||
145 | 4. Reset the device into application mode (may be done automatically) | ||
146 | |||
122 | ## STM32 | 147 | ## STM32 |
123 | 148 | ||
124 | All STM32 chips come preloaded with a factory bootloader that cannot be modified nor deleted. Some STM32 chips have bootloaders that do not come with USB programming (e.g. STM32F103) but the process is still the same. | 149 | All STM32 chips come preloaded with a factory bootloader that cannot be modified nor deleted. Some STM32 chips have bootloaders that do not come with USB programming (e.g. STM32F103) but the process is still the same. |
diff --git a/keyboards/gingham/rules.mk b/keyboards/gingham/rules.mk index b66b07129..83f424ba0 100644 --- a/keyboards/gingham/rules.mk +++ b/keyboards/gingham/rules.mk | |||
@@ -49,7 +49,7 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT | |||
49 | # atmega32a bootloadHID | 49 | # atmega32a bootloadHID |
50 | # | 50 | # |
51 | # This uses usbaspbootloader | 51 | # This uses usbaspbootloader |
52 | # BOOTLOADER = atmel-dfu | 52 | BOOTLOADER = USBasp |
53 | 53 | ||
54 | # If you don't know the bootloader type, then you can specify the | 54 | # If you don't know the bootloader type, then you can specify the |
55 | # Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line | 55 | # Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line |
@@ -58,8 +58,6 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT | |||
58 | # Atmel DFU loader 4096 | 58 | # Atmel DFU loader 4096 |
59 | # LUFA bootloader 4096 | 59 | # LUFA bootloader 4096 |
60 | # USBaspLoader 2048 | 60 | # USBaspLoader 2048 |
61 | # OPT_DEFS += -DBOOTLOADER_SIZE=4096 | ||
62 | OPT_DEFS += -DBOOTLOADER_SIZE=2048 | ||
63 | 61 | ||
64 | # Flash program via avrdude, but default command is not suitable. | 62 | # Flash program via avrdude, but default command is not suitable. |
65 | # You can use plaid:default:program | 63 | # You can use plaid:default:program |
diff --git a/tmk_core/avr.mk b/tmk_core/avr.mk index 6bf86d58a..670e141bf 100644 --- a/tmk_core/avr.mk +++ b/tmk_core/avr.mk | |||
@@ -245,6 +245,10 @@ avrdude-split-left: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware | |||
245 | avrdude-split-right: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware | 245 | avrdude-split-right: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware |
246 | $(call EXEC_AVRDUDE,eeprom-righthand.eep) | 246 | $(call EXEC_AVRDUDE,eeprom-righthand.eep) |
247 | 247 | ||
248 | usbasp: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware | ||
249 | avrdude -p $(MCU) -c usbasp -U flash:w:$(BUILD_DIR)/$(TARGET).hex | ||
250 | |||
251 | |||
248 | # Convert hex to bin. | 252 | # Convert hex to bin. |
249 | bin: $(BUILD_DIR)/$(TARGET).hex | 253 | bin: $(BUILD_DIR)/$(TARGET).hex |
250 | $(OBJCOPY) -Iihex -Obinary $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin | 254 | $(OBJCOPY) -Iihex -Obinary $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin |
diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c index 3cdcd2e42..29036f7c5 100644 --- a/tmk_core/common/avr/bootloader.c +++ b/tmk_core/common/avr/bootloader.c | |||
@@ -65,6 +65,13 @@ | |||
65 | #define BOOT_SIZE_1024 0b010 | 65 | #define BOOT_SIZE_1024 0b010 |
66 | #define BOOT_SIZE_2048 0b000 | 66 | #define BOOT_SIZE_2048 0b000 |
67 | 67 | ||
68 | //compatibility between ATMega8 and ATMega88 | ||
69 | #if !defined (MCUCSR) | ||
70 | #if defined (MCUSR) | ||
71 | #define MCUCSR MCUSR | ||
72 | #endif | ||
73 | #endif | ||
74 | |||
68 | /** \brief Entering the Bootloader via Software | 75 | /** \brief Entering the Bootloader via Software |
69 | * | 76 | * |
70 | * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html | 77 | * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html |
@@ -149,6 +156,39 @@ void bootloader_jump(void) { | |||
149 | 156 | ||
150 | while(1) {} // wait for watchdog timer to trigger | 157 | while(1) {} // wait for watchdog timer to trigger |
151 | 158 | ||
159 | #elif defined(BOOTLOADER_USBASP) | ||
160 | // Taken with permission of Stephan Baerwolf from https://github.com/tinyusbboard/API/blob/master/apipage.c | ||
161 | wdt_enable(WDTO_15MS); | ||
162 | wdt_reset(); | ||
163 | asm volatile ( | ||
164 | "cli \n\t" | ||
165 | "ldi r29 , %[ramendhi] \n\t" | ||
166 | "ldi r28 , %[ramendlo] \n\t" | ||
167 | #if (FLASHEND>131071) | ||
168 | "ldi r18 , %[bootaddrhi] \n\t" | ||
169 | "st Y+, r18 \n\t" | ||
170 | #endif | ||
171 | "ldi r18 , %[bootaddrme] \n\t" | ||
172 | "st Y+, r18 \n\t" | ||
173 | "ldi r18 , %[bootaddrlo] \n\t" | ||
174 | "st Y+, r18 \n\t" | ||
175 | "out %[mcucsrio], __zero_reg__ \n\t" | ||
176 | "bootloader_startup_loop%=: \n\t" | ||
177 | "rjmp bootloader_startup_loop%= \n\t" | ||
178 | : | ||
179 | : [mcucsrio] "I" (_SFR_IO_ADDR(MCUCSR)), | ||
180 | #if (FLASHEND>131071) | ||
181 | [ramendhi] "M" (((RAMEND - 2) >> 8) & 0xff), | ||
182 | [ramendlo] "M" (((RAMEND - 2) >> 0) & 0xff), | ||
183 | [bootaddrhi] "M" ((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >>16) & 0xff), | ||
184 | #else | ||
185 | [ramendhi] "M" (((RAMEND - 1) >> 8) & 0xff), | ||
186 | [ramendlo] "M" (((RAMEND - 1) >> 0) & 0xff), | ||
187 | #endif | ||
188 | [bootaddrme] "M" ((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), | ||
189 | [bootaddrlo] "M" ((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff) | ||
190 | ); | ||
191 | |||
152 | #else // Assume remaining boards are DFU, even if the flag isn't set | 192 | #else // Assume remaining boards are DFU, even if the flag isn't set |
153 | 193 | ||
154 | #if !(defined(__AVR_ATmega32A__) || defined(__AVR_ATmega328P__)) // no USB - maybe BOOTLOADER_BOOTLOADHID instead though? | 194 | #if !(defined(__AVR_ATmega32A__) || defined(__AVR_ATmega328P__)) // no USB - maybe BOOTLOADER_BOOTLOADHID instead though? |
@@ -172,24 +212,19 @@ void bootloader_jump(void) { | |||
172 | 212 | ||
173 | } | 213 | } |
174 | 214 | ||
175 | #ifdef __AVR_ATmega32A__ | ||
176 | // MCUSR is actually called MCUCSR in ATmega32A | ||
177 | #define MCUSR MCUCSR | ||
178 | #endif | ||
179 | |||
180 | /* this runs before main() */ | 215 | /* this runs before main() */ |
181 | void bootloader_jump_after_watchdog_reset(void) __attribute__ ((used, naked, section (".init3"))); | 216 | void bootloader_jump_after_watchdog_reset(void) __attribute__ ((used, naked, section (".init3"))); |
182 | void bootloader_jump_after_watchdog_reset(void) | 217 | void bootloader_jump_after_watchdog_reset(void) |
183 | { | 218 | { |
184 | #ifndef BOOTLOADER_HALFKAY | 219 | #ifndef BOOTLOADER_HALFKAY |
185 | if ((MCUSR & (1<<WDRF)) && reset_key == BOOTLOADER_RESET_KEY) { | 220 | if ((MCUCSR & (1<<WDRF)) && reset_key == BOOTLOADER_RESET_KEY) { |
186 | reset_key = 0; | 221 | reset_key = 0; |
187 | 222 | ||
188 | // My custom USBasploader requires this to come up. | 223 | // My custom USBasploader requires this to come up. |
189 | MCUSR = 0; | 224 | MCUCSR = 0; |
190 | 225 | ||
191 | // Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog. | 226 | // Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog. |
192 | MCUSR &= ~(1<<WDRF); | 227 | MCUCSR &= ~(1<<WDRF); |
193 | wdt_disable(); | 228 | wdt_disable(); |
194 | 229 | ||
195 | 230 | ||
@@ -202,29 +237,3 @@ void bootloader_jump_after_watchdog_reset(void) | |||
202 | } | 237 | } |
203 | #endif | 238 | #endif |
204 | } | 239 | } |
205 | |||
206 | |||
207 | #if 0 | ||
208 | /* | ||
209 | * USBaspLoader - I'm not sure if this is used at all in any projects | ||
210 | * would love to support it if it is -Jack | ||
211 | */ | ||
212 | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) | ||
213 | // This makes custom USBasploader come up. | ||
214 | MCUSR = 0; | ||
215 | |||
216 | // initialize ports | ||
217 | PORTB = 0; PORTC= 0; PORTD = 0; | ||
218 | DDRB = 0; DDRC= 0; DDRD = 0; | ||
219 | |||
220 | // disable interrupts | ||
221 | EIMSK = 0; EECR = 0; SPCR = 0; | ||
222 | ACSR = 0; SPMCSR = 0; WDTCSR = 0; PCICR = 0; | ||
223 | TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; | ||
224 | ADCSRA = 0; TWCR = 0; UCSR0B = 0; | ||
225 | #endif | ||
226 | |||
227 | // This is compled into 'icall', address should be in word unit, not byte. | ||
228 | ((void (*)(void))(BOOTLOADER_START/2))(); | ||
229 | } | ||
230 | #endif | ||