Contiki 2.6

bootloader.c

00001 #include "bootloader.h"
00002 #include "dev/watchdog.h"
00003 #include <util/delay.h>
00004 #include <avr/wdt.h>
00005 #include <avr/interrupt.h>
00006 #include <avr/pgmspace.h>
00007 #include "dev/usb/usb_drv.h"
00008 
00009 //Not all AVR toolchains alias MCUSR to the older MSUSCR name
00010 //#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8515__) || defined (__AVR_ATmega16__)
00011 #if !defined (MCUSR) && defined (MCUCSR)
00012 #warning *** MCUSR not defined, using MCUCSR instead ***
00013 #define MCUSR MCUCSR
00014 #endif
00015 
00016 volatile uint32_t Boot_Key ATTR_NO_INIT;
00017 
00018 bool
00019 bootloader_is_present(void) {
00020 #if defined(RAMPZ) 
00021         return pgm_read_word_far(BOOTLOADER_START_ADDRESS)!=0xFFFF;
00022 #else
00023 /* Probably can just return false when < 64K flash */
00024 //      return pgm_read_word_near(BOOTLOADER_START_ADDRESS)!=0xFFFF;
00025         return false;
00026 #endif
00027 }
00028 void
00029 Jump_To_Bootloader(void)
00030 {
00031         uint8_t i;
00032         
00033 #ifdef UDCON
00034         // If USB is used, detach from the bus
00035         Usb_detach();
00036 #endif
00037 
00038         // Disable all interrupts
00039         cli();
00040 
00041         // Set the bootloader key to the magic value and force a reset
00042         Boot_Key = MAGIC_BOOT_KEY;
00043 
00044         // Wait two seconds for the USB detachment to register on the host
00045         for (i = 0; i < 128; i++)
00046                 _delay_ms(16);
00047 
00048         // Set the bootloader key to the magic value and force a reset
00049         Boot_Key = MAGIC_BOOT_KEY;
00050         
00051         watchdog_reboot();
00052 }
00053 
00054 extern void Bootloader_Jump_Check(void) ATTR_INIT_SECTION(3);
00055 
00056 void
00057 Bootloader_Jump_Check(void)
00058 {
00059         // If the reset source was the bootloader and the key is correct, clear it and jump to the bootloader
00060         if(MCUSR & (1<<WDRF)) {
00061                 MCUSR = 0;
00062                 if(Boot_Key == MAGIC_BOOT_KEY) {
00063                         Boot_Key = 0;
00064                         wdt_disable();
00065                         
00066                         ((void (*)(void))BOOTLOADER_START_ADDRESS)();
00067                 } else {
00068                         Boot_Key++;
00069                 }
00070         } else {
00071                 Boot_Key = MAGIC_BOOT_KEY-4;
00072         }
00073 }