X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=tmk_core%2Fcommon%2Favr%2Fbootloader.c;h=3cdcd2e426b6b68a774b955c900e18962a60d28a;hb=746058306b6c3b037fc560a13bb78d088c734401;hp=cda295b1811e92f90baea342084b37a07139bcc1;hpb=d9fee5571d7de08e76dff5ce75816faf522240f6;p=qmk_firmware.git diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c index cda295b18..3cdcd2e42 100644 --- a/tmk_core/common/avr/bootloader.c +++ b/tmk_core/common/avr/bootloader.c @@ -1,131 +1,213 @@ #include #include #include +#include #include #include #include #include "bootloader.h" +#include #ifdef PROTOCOL_LUFA #include #endif -/* Boot Section Size in *BYTEs* - * Teensy halfKay 512 - * Teensy++ halfKay 1024 - * Atmel DFU loader 4096 - * LUFA bootloader 4096 - * USBaspLoader 2048 +/** \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 + * LUFA bootloader(ATmega32U4) 4096 + * Arduino Caterina(ATmega32U4) 4096 + * USBaspLoader(ATmega***) 2048 + * 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 +---------------+ + * | | | | + * | | | | + * | Application | | Application | + * | | | | + * = = = = + * | | 32KB-4KB | | 128KB-8KB + * 0x7000 +---------------+ 0x1E000 +---------------+ + * | Bootloader | 4KB | Bootloader | 8KB + * 0x7FFF +---------------+ 0x1FFFF +---------------+ + * + * + * byte Teensy(ATMega32u4) byte Teensy++(AT90SUB128) + * 0x0000 +---------------+ 0x00000 +---------------+ + * | | | | + * | | | | + * | Application | | Application | + * | | | | + * = = = = + * | | 32KB-512B | | 128KB-1KB + * 0x7E00 +---------------+ 0x1FC00 +---------------+ + * | 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 -#endif +#define FLASH_SIZE (FLASHEND + 1L) -#define FLASH_SIZE (FLASHEND + 1L) -#define BOOTLOADER_START (FLASH_SIZE - BOOTLOADER_SIZE) +#if !defined(BOOTLOADER_SIZE) + 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 -/* - * 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) { -#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 + + // 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<> 1))(); + #else + asm("ijmp" :: "z" (bootloader_start)); + #endif + } + #endif } #if 0 -/* Jumping To The Bootloader - * http://www.pjrc.com/teensy/jump_to_bootloader.html - * - * This method doen't work when using LUFA. idk why. - * - needs to initialize more regisers or interrupt setting? - */ -void bootloader_jump(void) { -#ifdef PROTOCOL_LUFA - USB_Disable(); - cli(); - _delay_ms(2000); -#endif - -#ifdef PROTOCOL_PJRC - cli(); - UDCON = 1; - USBCON = (1<