X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=tmk_core%2Fcommon%2Favr%2Fbootloader.c;h=29036f7c5a87ef518763402a2863cae47c2886e9;hb=3538955778c253e68779605cc67c27e15d195729;hp=34db8d0b0aa66c18538f978fac66e44f9938ed5c;hpb=79a823d8027d5795f04dc5faaed9172b43ab8203;p=qmk_firmware.git diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c index 34db8d0b0..29036f7c5 100644 --- a/tmk_core/common/avr/bootloader.c +++ b/tmk_core/common/avr/bootloader.c @@ -6,18 +6,18 @@ #include #include #include "bootloader.h" +#include #ifdef PROTOCOL_LUFA #include #endif -/* Bootloader Size in *bytes* +/** \brief Bootloader Size in *bytes* * * AVR Boot section size are defined by setting BOOTSZ fuse in fact. Consult with your MCU datasheet. * Note that 'Word'(2 bytes) size and address are used in datasheet while TMK uses 'Byte'. * - * * Size of Bootloaders in bytes: * Atmel DFU loader(ATmega32U4) 4096 * Atmel DFU loader(AT90USB128) 8192 @@ -27,10 +27,8 @@ * Teensy halfKay(ATmega32U4) 512 * Teensy++ halfKay(AT90USB128) 1024 * - * * AVR Boot section is located at the end of Flash memory like the followings. * - * * byte Atmel/LUFA(ATMega32u4) byte Atmel(AT90SUB128) * 0x0000 +---------------+ 0x00000 +---------------+ * | | | | @@ -56,52 +54,92 @@ * | Bootloader | 512B | Bootloader | 1KB * 0x7FFF +---------------+ 0x1FFFF +---------------+ */ -#ifndef BOOTLOADER_SIZE -#warning To use bootloader_jump() you need to define BOOTLOADER_SIZE in config.h. -#define BOOTLOADER_SIZE 4096 +#define FLASH_SIZE (FLASHEND + 1L) + +#if !defined(BOOTLOADER_SIZE) + uint16_t bootloader_start; #endif -#define FLASH_SIZE (FLASHEND + 1L) -#define BOOTLOADER_START (FLASH_SIZE - BOOTLOADER_SIZE) +#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 +#endif -/* - * 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 */ #define BOOTLOADER_RESET_KEY 0xB007B007 -uint32_t reset_key __attribute__ ((section (".noinit"))); +uint32_t reset_key __attribute__ ((section (".noinit,\"aw\",@nobits;"))); -/* initialize MCU status by watchdog reset */ +/** \brief initialize MCU status by watchdog reset + * + * FIXME: needs doc + */ void bootloader_jump(void) { - #ifndef CATERINA_BOOTLOADER - - #ifdef PROTOCOL_LUFA - USB_Disable(); - cli(); - _delay_ms(2000); - #endif - #ifdef PROTOCOL_PJRC - cli(); - UDCON = 1; - USBCON = (1<> 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 - #ifdef BOOTLOADHID_BOOTLOADER - // 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); + // 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<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<> 1))(); + #else + asm("ijmp" :: "z" (bootloader_start)); + #endif + } + #endif } -#endif