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 | ||
