From 3538955778c253e68779605cc67c27e15d195729 Mon Sep 17 00:00:00 2001 From: yiancar Date: Tue, 16 Jul 2019 03:11:59 +0100 Subject: 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 * Update docs/flashing.md Co-Authored-By: fauxpark * Update docs/flashing.md Co-Authored-By: fauxpark --- tmk_core/common/avr/bootloader.c | 77 ++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 34 deletions(-) (limited to 'tmk_core/common/avr/bootloader.c') diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c index 3cdcd2e426..29036f7c5a 100644 --- a/tmk_core/common/avr/bootloader.c +++ b/tmk_core/common/avr/bootloader.c @@ -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 @@ -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? @@ -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< Date: Fri, 30 Aug 2019 11:19:03 -0700 Subject: clang-format changes --- tmk_core/common/avr/bootloader.c | 365 +++++++++++++++++++++++---------------- 1 file changed, 212 insertions(+), 153 deletions(-) (limited to 'tmk_core/common/avr/bootloader.c') diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c index 29036f7c5a..5f9ecc5101 100644 --- a/tmk_core/common/avr/bootloader.c +++ b/tmk_core/common/avr/bootloader.c @@ -9,10 +9,9 @@ #include #ifdef PROTOCOL_LUFA -#include +# include #endif - /** \brief Bootloader Size in *bytes* * * AVR Boot section size are defined by setting BOOTSZ fuse in fact. Consult with your MCU datasheet. @@ -57,19 +56,19 @@ #define FLASH_SIZE (FLASHEND + 1L) #if !defined(BOOTLOADER_SIZE) - uint16_t bootloader_start; +uint16_t bootloader_start; #endif -#define BOOT_SIZE_256 0b110 -#define BOOT_SIZE_512 0b100 +#define BOOT_SIZE_256 0b110 +#define BOOT_SIZE_512 0b100 #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 +// compatibility between ATMega8 and ATMega88 +#if !defined(MCUCSR) +# if defined(MCUSR) +# define MCUCSR MCUSR +# endif #endif /** \brief Entering the Bootloader via Software @@ -77,163 +76,223 @@ * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html */ #define BOOTLOADER_RESET_KEY 0xB007B007 -uint32_t reset_key __attribute__ ((section (".noinit,\"aw\",@nobits;"))); +uint32_t reset_key __attribute__((section(".noinit,\"aw\",@nobits;"))); /** \brief initialize MCU status by watchdog reset * * FIXME: needs doc */ void bootloader_jump(void) { +#if !defined(BOOTLOADER_SIZE) + uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); - #if !defined(BOOTLOADER_SIZE) - uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); - - if (high_fuse & BOOT_SIZE_256) { - bootloader_start = (FLASH_SIZE - 512) >> 1; - } else if (high_fuse & BOOT_SIZE_512) { - bootloader_start = (FLASH_SIZE - 1024) >> 1; - } else if (high_fuse & BOOT_SIZE_1024) { - bootloader_start = (FLASH_SIZE - 2048) >> 1; - } else { - bootloader_start = (FLASH_SIZE - 4096) >> 1; - } - #endif + if (high_fuse & BOOT_SIZE_256) { + bootloader_start = (FLASH_SIZE - 512) >> 1; + } else if (high_fuse & BOOT_SIZE_512) { + bootloader_start = (FLASH_SIZE - 1024) >> 1; + } else if (high_fuse & BOOT_SIZE_1024) { + bootloader_start = (FLASH_SIZE - 2048) >> 1; + } else { + bootloader_start = (FLASH_SIZE - 4096) >> 1; + } +#endif // Something like this might work, but it compiled larger than the block above // bootloader_start = FLASH_SIZE - (256 << (~high_fuse & 0b110 >> 1)); +#if defined(BOOTLOADER_HALFKAY) + // http://www.pjrc.com/teensy/jump_to_bootloader.html + cli(); + // disable watchdog, if enabled (it's not) + // disable all peripherals + // a shutdown call might make sense here + UDCON = 1; + USBCON = (1 << FRZCLK); // disable USB + UCSR1B = 0; + _delay_ms(5); +# if defined(__AVR_AT90USB162__) // Teensy 1.0 + EIMSK = 0; + PCICR = 0; + SPCR = 0; + ACSR = 0; + EECR = 0; + TIMSK0 = 0; + TIMSK1 = 0; + UCSR1B = 0; + DDRB = 0; + DDRC = 0; + DDRD = 0; + PORTB = 0; + PORTC = 0; + PORTD = 0; + asm volatile("jmp 0x3E00"); +# elif defined(__AVR_ATmega32U4__) // Teensy 2.0 + EIMSK = 0; + PCICR = 0; + SPCR = 0; + ACSR = 0; + EECR = 0; + ADCSRA = 0; + TIMSK0 = 0; + TIMSK1 = 0; + TIMSK3 = 0; + TIMSK4 = 0; + UCSR1B = 0; + TWCR = 0; + DDRB = 0; + DDRC = 0; + DDRD = 0; + DDRE = 0; + DDRF = 0; + TWCR = 0; + PORTB = 0; + PORTC = 0; + PORTD = 0; + PORTE = 0; + PORTF = 0; + asm volatile("jmp 0x7E00"); +# elif defined(__AVR_AT90USB646__) // Teensy++ 1.0 + EIMSK = 0; + PCICR = 0; + SPCR = 0; + ACSR = 0; + EECR = 0; + ADCSRA = 0; + TIMSK0 = 0; + TIMSK1 = 0; + TIMSK2 = 0; + TIMSK3 = 0; + UCSR1B = 0; + TWCR = 0; + DDRA = 0; + DDRB = 0; + DDRC = 0; + DDRD = 0; + DDRE = 0; + DDRF = 0; + PORTA = 0; + PORTB = 0; + PORTC = 0; + PORTD = 0; + PORTE = 0; + PORTF = 0; + asm volatile("jmp 0xFC00"); +# elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0 + EIMSK = 0; + PCICR = 0; + SPCR = 0; + ACSR = 0; + EECR = 0; + ADCSRA = 0; + TIMSK0 = 0; + TIMSK1 = 0; + TIMSK2 = 0; + TIMSK3 = 0; + UCSR1B = 0; + TWCR = 0; + DDRA = 0; + DDRB = 0; + DDRC = 0; + DDRD = 0; + DDRE = 0; + DDRF = 0; + PORTA = 0; + PORTB = 0; + PORTC = 0; + PORTD = 0; + PORTE = 0; + PORTF = 0; + asm volatile("jmp 0x1FC00"); +# endif + +#elif defined(BOOTLOADER_CATERINA) + // this block may be optional + // TODO: figure it out + + uint16_t *const bootKeyPtr = (uint16_t *)0x0800; + + // Value used by Caterina bootloader use to determine whether to run the + // sketch or the bootloader programmer. + uint16_t bootKey = 0x7777; + + *bootKeyPtr = bootKey; + + // setup watchdog timeout + wdt_enable(WDTO_60MS); - #if defined(BOOTLOADER_HALFKAY) - // http://www.pjrc.com/teensy/jump_to_bootloader.html - cli(); - // disable watchdog, if enabled (it's not) - // disable all peripherals - // a shutdown call might make sense here - UDCON = 1; - USBCON = (1<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? - UDCON = 1; - USBCON = (1< 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? + UDCON = 1; + USBCON = (1 << FRZCLK); // disable USB + UCSR1B = 0; + _delay_ms(5); // 5 seems to work fine +# endif + +# ifdef BOOTLOADER_BOOTLOADHID + // force bootloadHID to stay in bootloader mode, so that it waits + // for a new firmware to be flashed + eeprom_write_byte((uint8_t *)1, 0x00); +# endif + + // watchdog reset + reset_key = BOOTLOADER_RESET_KEY; + wdt_enable(WDTO_250MS); + for (;;) + ; +#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 ((MCUCSR & (1<> 1))(); - #else - asm("ijmp" :: "z" (bootloader_start)); - #endif - } - #endif +void bootloader_jump_after_watchdog_reset(void) __attribute__((used, naked, section(".init3"))); +void bootloader_jump_after_watchdog_reset(void) { +#ifndef BOOTLOADER_HALFKAY + if ((MCUCSR & (1 << WDRF)) && reset_key == BOOTLOADER_RESET_KEY) { + reset_key = 0; + + // My custom USBasploader requires this to come up. + MCUCSR = 0; + + // Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog. + MCUCSR &= ~(1 << WDRF); + wdt_disable(); + +// This is compled into 'icall', address should be in word unit, not byte. +# ifdef BOOTLOADER_SIZE + ((void (*)(void))((FLASH_SIZE - BOOTLOADER_SIZE) >> 1))(); +# else + asm("ijmp" ::"z"(bootloader_start)); +# endif + } +#endif } -- cgit v1.2.3 From 91bd2117df4cc4d2be6c840103614f2245e54bd1 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Sun, 8 Sep 2019 01:12:46 +1000 Subject: Banish some more magic numbers (#6662) --- tmk_core/common/avr/bootloader.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'tmk_core/common/avr/bootloader.c') diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c index 5f9ecc5101..ca9746f327 100644 --- a/tmk_core/common/avr/bootloader.c +++ b/tmk_core/common/avr/bootloader.c @@ -59,11 +59,6 @@ uint16_t bootloader_start; #endif -#define BOOT_SIZE_256 0b110 -#define BOOT_SIZE_512 0b100 -#define BOOT_SIZE_1024 0b010 -#define BOOT_SIZE_2048 0b000 - // compatibility between ATMega8 and ATMega88 #if !defined(MCUCSR) # if defined(MCUSR) @@ -86,11 +81,11 @@ void bootloader_jump(void) { #if !defined(BOOTLOADER_SIZE) uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); - if (high_fuse & BOOT_SIZE_256) { + if (high_fuse & ~(FUSE_BOOTSZ0 & FUSE_BOOTSZ1)) { bootloader_start = (FLASH_SIZE - 512) >> 1; - } else if (high_fuse & BOOT_SIZE_512) { + } else if (high_fuse & ~(FUSE_BOOTSZ1)) { bootloader_start = (FLASH_SIZE - 1024) >> 1; - } else if (high_fuse & BOOT_SIZE_1024) { + } else if (high_fuse & ~(FUSE_BOOTSZ0)) { bootloader_start = (FLASH_SIZE - 2048) >> 1; } else { bootloader_start = (FLASH_SIZE - 4096) >> 1; -- cgit v1.2.3