|
|
@ -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 |