Explorar o código

Usbasploader bootloader option addition (#6304)

* Added USBasp bootloader option for USBasploader

* author comment

* ifdef fix :)

* Add usbasp target

* Update docs/flashing.md

Co-Authored-By: fauxpark <fauxpark@gmail.com>

* Update docs/flashing.md

Co-Authored-By: fauxpark <fauxpark@gmail.com>

* Update docs/flashing.md

Co-Authored-By: fauxpark <fauxpark@gmail.com>
yiancar %!s(int64=5) %!d(string=hai) anos
pai
achega
3538955778
Modificáronse 6 ficheiros con 78 adicións e 37 borrados
  1. 4 0
      bootloader.mk
  2. 1 0
      docs/config_options.md
  3. 25 0
      docs/flashing.md
  4. 1 3
      keyboards/gingham/rules.mk
  5. 4 0
      tmk_core/avr.mk
  6. 43 34
      tmk_core/common/avr/bootloader.c

+ 4 - 0
bootloader.mk

@@ -76,6 +76,10 @@ ifeq ($(strip $(BOOTLOADER)), bootloadHID)
     OPT_DEFS += -DBOOTLOADER_BOOTLOADHID
     OPT_DEFS += -DBOOTLOADER_BOOTLOADHID
     BOOTLOADER_SIZE = 4096
     BOOTLOADER_SIZE = 4096
 endif
 endif
+ifeq ($(strip $(BOOTLOADER)), USBasp)
+    OPT_DEFS += -DBOOTLOADER_USBASP
+    BOOTLOADER_SIZE = 4096
+endif
 
 
 ifdef BOOTLOADER_SIZE
 ifdef BOOTLOADER_SIZE
     OPT_DEFS += -DBOOTLOADER_SIZE=$(strip $(BOOTLOADER_SIZE))
     OPT_DEFS += -DBOOTLOADER_SIZE=$(strip $(BOOTLOADER_SIZE))

+ 1 - 0
docs/config_options.md

@@ -289,6 +289,7 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
   * `halfkay`
   * `halfkay`
   * `caterina`
   * `caterina`
   * `bootloadHID`
   * `bootloadHID`
+  * `USBasp`
 
 
 ## Feature Options
 ## Feature Options
 
 

+ 25 - 0
docs/flashing.md

@@ -119,6 +119,31 @@ Flashing sequence:
 3. Flash a .hex file
 3. Flash a .hex file
 4. Reset the device into application mode (may be done automatically)
 4. Reset the device into application mode (may be done automatically)
 
 
+## USBasploader
+
+USBasploader is a bootloader developed by matrixstorm. It is used in some non-USB AVR chips such as the ATmega328P, which run V-USB.
+
+To ensure compatibility with the USBasploader bootloader, make sure this block is present in your `rules.mk`:
+
+    # Bootloader
+    #     This definition is optional, and if your keyboard supports multiple bootloaders of
+    #     different sizes, comment this out, and the correct address will be loaded
+    #     automatically (+60). See bootloader.mk for all options.
+    BOOTLOADER = USBasp
+
+Compatible flashers:
+
+* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI)
+* [avrdude](http://www.nongnu.org/avrdude/) with the `usbasp` programmer
+* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS)
+
+Flashing sequence:
+
+1. Press the `RESET` keycode, or keep the boot pin shorted to GND while quickly shorting RST to GND
+2. Wait for the OS to detect the device
+3. Flash a .hex file
+4. Reset the device into application mode (may be done automatically)
+
 ## STM32
 ## STM32
 
 
 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.
 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.

+ 1 - 3
keyboards/gingham/rules.mk

@@ -49,7 +49,7 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
 #   atmega32a    bootloadHID
 #   atmega32a    bootloadHID
 #
 #
 # This uses usbaspbootloader
 # This uses usbaspbootloader
-# BOOTLOADER = atmel-dfu
+BOOTLOADER = USBasp
 
 
 # If you don't know the bootloader type, then you can specify the
 # If you don't know the bootloader type, then you can specify the
 # Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line
 # Boot Section Size in *bytes* by uncommenting out the OPT_DEFS line
@@ -58,8 +58,6 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
 #   Atmel DFU loader    4096
 #   Atmel DFU loader    4096
 #   LUFA bootloader     4096
 #   LUFA bootloader     4096
 #   USBaspLoader        2048
 #   USBaspLoader        2048
-# OPT_DEFS += -DBOOTLOADER_SIZE=4096
-OPT_DEFS += -DBOOTLOADER_SIZE=2048
 
 
 # Flash program via avrdude, but default command is not suitable.
 # Flash program via avrdude, but default command is not suitable.
 # You can use plaid:default:program
 # You can use plaid:default:program

+ 4 - 0
tmk_core/avr.mk

@@ -245,6 +245,10 @@ avrdude-split-left: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware
 avrdude-split-right: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware
 avrdude-split-right: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware
 	$(call EXEC_AVRDUDE,eeprom-righthand.eep)
 	$(call EXEC_AVRDUDE,eeprom-righthand.eep)
 
 
+usbasp: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware
+	avrdude -p $(MCU) -c usbasp -U flash:w:$(BUILD_DIR)/$(TARGET).hex
+
+
 # Convert hex to bin.
 # Convert hex to bin.
 bin: $(BUILD_DIR)/$(TARGET).hex
 bin: $(BUILD_DIR)/$(TARGET).hex
 	$(OBJCOPY) -Iihex -Obinary $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
 	$(OBJCOPY) -Iihex -Obinary $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin

+ 43 - 34
tmk_core/common/avr/bootloader.c

@@ -65,6 +65,13 @@
 #define BOOT_SIZE_1024 0b010
 #define BOOT_SIZE_1024 0b010
 #define BOOT_SIZE_2048 0b000
 #define BOOT_SIZE_2048 0b000
 
 
+//compatibility between ATMega8 and ATMega88
+#if !defined (MCUCSR)
+    #if defined (MCUSR)
+        #define MCUCSR MCUSR
+    #endif
+#endif
+
 /** \brief Entering the Bootloader via Software
 /** \brief Entering the Bootloader via Software
  *
  *
  * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html
  * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html
@@ -149,6 +156,39 @@ void bootloader_jump(void) {
 
 
         while(1) {} // wait for watchdog timer to trigger
         while(1) {} // wait for watchdog timer to trigger
 
 
+    #elif defined(BOOTLOADER_USBASP)
+        // Taken with permission of Stephan Baerwolf from https://github.com/tinyusbboard/API/blob/master/apipage.c
+        wdt_enable(WDTO_15MS);
+        wdt_reset();
+        asm volatile (
+            "cli                    \n\t"
+            "ldi    r29 ,       %[ramendhi] \n\t"
+            "ldi    r28 ,       %[ramendlo] \n\t"
+            #if (FLASHEND>131071)
+                "ldi    r18 ,       %[bootaddrhi]   \n\t"
+                "st     Y+,         r18     \n\t"
+            #endif
+            "ldi    r18 ,       %[bootaddrme]   \n\t"
+            "st     Y+,     r18     \n\t"
+            "ldi    r18 ,       %[bootaddrlo]   \n\t"
+            "st     Y+,     r18     \n\t"
+            "out    %[mcucsrio],    __zero_reg__    \n\t"
+            "bootloader_startup_loop%=:         \n\t"
+            "rjmp bootloader_startup_loop%=     \n\t"
+            : 
+            : [mcucsrio]    "I" (_SFR_IO_ADDR(MCUCSR)),
+            #if (FLASHEND>131071)
+                [ramendhi]    "M" (((RAMEND - 2) >> 8) & 0xff),
+                [ramendlo]    "M" (((RAMEND - 2) >> 0) & 0xff),
+                [bootaddrhi]  "M" ((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >>16) & 0xff),
+            #else
+                [ramendhi]    "M" (((RAMEND - 1) >> 8) & 0xff),
+                [ramendlo]    "M" (((RAMEND - 1) >> 0) & 0xff),
+            #endif
+            [bootaddrme]  "M" ((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff),
+            [bootaddrlo]  "M" ((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff)
+        );
+
     #else // Assume remaining boards are DFU, even if the flag isn't set
     #else // Assume remaining boards are DFU, even if the flag isn't set
 
 
         #if !(defined(__AVR_ATmega32A__) || defined(__AVR_ATmega328P__)) // no USB - maybe BOOTLOADER_BOOTLOADHID instead though?
         #if !(defined(__AVR_ATmega32A__) || defined(__AVR_ATmega328P__)) // no USB - maybe BOOTLOADER_BOOTLOADHID instead though?
@@ -172,24 +212,19 @@ void bootloader_jump(void) {
 
 
 }
 }
 
 
-#ifdef __AVR_ATmega32A__
-    // MCUSR is actually called MCUCSR in ATmega32A
-    #define MCUSR MCUCSR
-#endif
-
 /* this runs before main() */
 /* this runs before main() */
 void bootloader_jump_after_watchdog_reset(void) __attribute__ ((used, naked, section (".init3")));
 void bootloader_jump_after_watchdog_reset(void) __attribute__ ((used, naked, section (".init3")));
 void bootloader_jump_after_watchdog_reset(void)
 void bootloader_jump_after_watchdog_reset(void)
 {
 {
     #ifndef BOOTLOADER_HALFKAY
     #ifndef BOOTLOADER_HALFKAY
-        if ((MCUSR & (1<<WDRF)) && reset_key == BOOTLOADER_RESET_KEY) {
+        if ((MCUCSR & (1<<WDRF)) && reset_key == BOOTLOADER_RESET_KEY) {
             reset_key = 0;
             reset_key = 0;
 
 
             // My custom USBasploader requires this to come up.
             // My custom USBasploader requires this to come up.
-            MCUSR = 0;
+            MCUCSR = 0;
 
 
             // Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog.
             // Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog.
-            MCUSR &= ~(1<<WDRF);
+            MCUCSR &= ~(1<<WDRF);
             wdt_disable();
             wdt_disable();
 
 
 
 
@@ -202,29 +237,3 @@ void bootloader_jump_after_watchdog_reset(void)
         }
         }
     #endif
     #endif
 }
 }
-
-
-#if 0
-    /*
-     * USBaspLoader - I'm not sure if this is used at all in any projects
-     *                would love to support it if it is -Jack
-     */
-#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
-    // This makes custom USBasploader come up.
-    MCUSR = 0;
-
-    // initialize ports
-    PORTB = 0; PORTC= 0; PORTD = 0;
-    DDRB = 0; DDRC= 0; DDRD = 0;
-
-    // disable interrupts
-    EIMSK = 0; EECR = 0; SPCR = 0;
-    ACSR = 0; SPMCSR = 0; WDTCSR = 0; PCICR = 0;
-    TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0;
-    ADCSRA = 0; TWCR = 0; UCSR0B = 0;
-#endif
-
-    // This is compled into 'icall', address should be in word unit, not byte.
-    ((void (*)(void))(BOOTLOADER_START/2))();
-}
-#endif