+ #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
+
+ // 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);
+
+ while(1) {} // wait for watchdog timer to trigger
+
+ #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