Skip to content

Commit

Permalink
Usbasploader bootloader option addition (qmk#6304)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
2 people authored and drashna committed Jul 16, 2019
1 parent 7d557a0 commit 3538955
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 37 deletions.
4 changes: 4 additions & 0 deletions bootloader.mk
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ ifeq ($(strip $(BOOTLOADER)), bootloadHID)
OPT_DEFS += -DBOOTLOADER_BOOTLOADHID
BOOTLOADER_SIZE = 4096
endif
ifeq ($(strip $(BOOTLOADER)), USBasp)
OPT_DEFS += -DBOOTLOADER_USBASP
BOOTLOADER_SIZE = 4096
endif

ifdef BOOTLOADER_SIZE
OPT_DEFS += -DBOOTLOADER_SIZE=$(strip $(BOOTLOADER_SIZE))
Expand Down
1 change: 1 addition & 0 deletions docs/config_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
* `halfkay`
* `caterina`
* `bootloadHID`
* `USBasp`

## Feature Options

Expand Down
25 changes: 25 additions & 0 deletions docs/flashing.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,31 @@ Flashing sequence:
3. Flash a .hex file
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

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.
Expand Down
4 changes: 1 addition & 3 deletions keyboards/gingham/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# atmega32a bootloadHID
#
# This uses usbaspbootloader
# BOOTLOADER = atmel-dfu
BOOTLOADER = USBasp

# 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
Expand All @@ -58,8 +58,6 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
# OPT_DEFS += -DBOOTLOADER_SIZE=4096
OPT_DEFS += -DBOOTLOADER_SIZE=2048

# Flash program via avrdude, but default command is not suitable.
# You can use plaid:default:program
Expand Down
4 changes: 4 additions & 0 deletions tmk_core/avr.mk
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ avrdude-split-left: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware
avrdude-split-right: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware
$(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.
bin: $(BUILD_DIR)/$(TARGET).hex
$(OBJCOPY) -Iihex -Obinary $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
Expand Down
77 changes: 43 additions & 34 deletions tmk_core/common/avr/bootloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@
#define BOOT_SIZE_1024 0b010
#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
*
* http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html
Expand Down Expand Up @@ -149,6 +156,39 @@ void bootloader_jump(void) {

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

#if !(defined(__AVR_ATmega32A__) || defined(__AVR_ATmega328P__)) // no USB - maybe BOOTLOADER_BOOTLOADHID instead though?
Expand All @@ -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() */
void bootloader_jump_after_watchdog_reset(void) __attribute__ ((used, naked, section (".init3")));
void bootloader_jump_after_watchdog_reset(void)
{
#ifndef BOOTLOADER_HALFKAY
if ((MCUSR & (1<<WDRF)) && reset_key == BOOTLOADER_RESET_KEY) {
if ((MCUCSR & (1<<WDRF)) && reset_key == BOOTLOADER_RESET_KEY) {
reset_key = 0;

// My custom USBasploader requires this to come up.
MCUSR = 0;
MCUCSR = 0;

// Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog.
MCUSR &= ~(1<<WDRF);
MCUCSR &= ~(1<<WDRF);
wdt_disable();


Expand All @@ -202,29 +237,3 @@ void bootloader_jump_after_watchdog_reset(void)
}
#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

0 comments on commit 3538955

Please sign in to comment.