diff options
author | tmk <nobody@nowhere> | 2013-03-09 11:22:27 +0900 |
---|---|---|
committer | tmk <nobody@nowhere> | 2013-03-09 11:22:27 +0900 |
commit | 4d64fd8faa8b1a0ceb9019446ba6915aaf1812ea (patch) | |
tree | 25410ede4bbf7d5a8994bb385e6c7ee4ad2f4c0c /common/bootloader.c | |
parent | 359b68d35f0763ab0cafa2fb800e0a3497291f95 (diff) |
Add bootmagic.c and fix bootloader_jump
Diffstat (limited to 'common/bootloader.c')
-rw-r--r-- | common/bootloader.c | 100 |
1 files changed, 77 insertions, 23 deletions
diff --git a/common/bootloader.c b/common/bootloader.c index 6e04efbbda..77fa1b30a7 100644 --- a/common/bootloader.c +++ b/common/bootloader.c @@ -1,15 +1,16 @@ +#include <stdint.h> +#include <stdbool.h> #include <avr/io.h> #include <avr/interrupt.h> +#include <avr/wdt.h> #include <util/delay.h> #include "bootloader.h" -/* Start Bootloader from Application - * See - * http://www.pjrc.com/teensy/jump_to_bootloader.html - * http://www.fourwalledcubicle.com/files/LUFA/Doc/120219/html/_page__software_bootloader_start.html - */ +#ifdef PROTOCOL_LUFA +#include <LUFA/Drivers/USB/USB.h> +#endif + -// TODO: support usbasp /* Boot Section Size in bytes * Teensy halfKay 512 * Atmel DFU loader 4096 @@ -18,28 +19,82 @@ #ifndef BOOT_SIZE #define BOOT_SIZE 512 #endif - #define FLASH_SIZE (FLASHEND + 1) -#define BOOTLOADER_START (FLASHEND - BOOT_SIZE) +#define BOOTLOADER_START (FLASH_SIZE - BOOT_SIZE) + +/* + * 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"))); + +/* initialize MCU status by watchdog reset */ void bootloader_jump(void) { +#ifdef PROTOCOL_LUFA + USB_Disable(); cli(); + _delay_ms(2000); +#endif - // - //Teensy - // -#if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) - // disable watchdog, if enabled - // disable all peripherals +#ifdef PROTOCOL_PJRC + cli(); UDCON = 1; - USBCON = (1<<FRZCLK); // disable USB + USBCON = (1<<FRZCLK); UCSR1B = 0; _delay_ms(5); -#else - // This makes custom USBasploader come up. - MCUSR = 0; #endif + // watchdog reset + reset_key = BOOTLOADER_RESET_KEY; + wdt_enable(WDTO_250MS); + for (;;); +} + + +/* this runs before main() */ +void bootloader_jump_after_watchdog_reset(void) __attribute__ ((used, naked, section (".init3"))); +void bootloader_jump_after_watchdog_reset(void) +{ + if ((MCUSR & (1<<WDRF)) && reset_key == BOOTLOADER_RESET_KEY) { + + #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) + // This makes custom USBasploader come up. + MCUSR = 0; + #endif + + reset_key = 0; + ((void (*)(void))BOOTLOADER_START)(); + } +} + + +#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<<FRZCLK); + UCSR1B = 0; + _delay_ms(5); +#endif + + /* + * Initialize + */ #if defined(__AVR_AT90USB162__) EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0; @@ -62,10 +117,9 @@ void bootloader_jump(void) { PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; #endif - - // - //USBasp - // + /* + * USBaspLoader + */ #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) // This makes custom USBasploader come up. MCUSR = 0; @@ -81,7 +135,7 @@ void bootloader_jump(void) { ADCSRA = 0; TWCR = 0; UCSR0B = 0; #endif - // start Bootloader ((void (*)(void))BOOTLOADER_START)(); } +#endif |