#ifndef __BOOTLOADER_H__ #define __BOOTLOADER_H__ #define DDR(x) (*(&x - 1)) /* address of data direction register of port x */ #define PIN(x) (*(&x - 2)) /* address of input register of port x */ #ifdef HWB_PORT #define HWB_DDR DDR(HWB_PORT) #define HWB_PIN PIN(HWB_PORT) #else #define HWB_PORT PORTD #define HWB_DDR DDRD #define HWB_PIN PIND #define HWB_MASK (1 << 7) #endif #if FLASHEND == (0x7FFF) #define BOOT_SECTION_SIZE 4*1024 #elif FLASHEND == (0x3FFF) #define BOOT_SECTION_SIZE 4*1024 #elif FLASHEND == (0x1FFF) #define BOOT_SECTION_SIZE 2*1024 #endif #define BOOTLOADER_START_ADDRESS (FLASHEND+1) - (BOOT_SECTION_SIZE) #define BOOT_KEY 0xAA55AA55 uint32_t boot_key __attribute__ ((section (".noinit"))); #define STRINGIFY(x) #x #define EXPAND(x) STRINGIFY(x) static inline void enter_bootloader(void) { __asm__ __volatile__("jmp " EXPAND(BOOTLOADER_START_ADDRESS)); } static inline void hardware_reset(void) { cli(); #define Wdt_change_enable() (WDTCSR |= (1<<WDCE) | (1<<WDE)) #define Wdt_enable_16ms() (WDTCSR = (1<<WDE)) Wdt_change_enable(); Wdt_enable_16ms(); while(1); } static inline void boot_loader(void) { boot_key = BOOT_KEY; hardware_reset(); } #define is_wdt_reset() ((MCUSR&(1<<WDRF)) ? (1==1):(0==1)) static inline void check_bootloader(void) { if ((is_wdt_reset()) && (boot_key == BOOT_KEY)) { boot_key = 0; enter_bootloader(); } } static inline void check_hwb(void) { if ( !(HWB_PIN & HWB_MASK) ) enter_bootloader(); // low/zero = active } #endif