Contiki 2.5
bootloader.c
1 #include "bootloader.h"
2 #include "dev/watchdog.h"
3 #include <util/delay.h>
4 #include <avr/wdt.h>
5 #include <avr/interrupt.h>
6 #include <avr/pgmspace.h>
7 #include "dev/usb/usb_drv.h"
8 
9 //Not all AVR toolchains alias MCUSR to the older MSUSCR name
10 //#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8515__) || defined (__AVR_ATmega16__)
11 #if !defined (MCUSR) && defined (MCUCSR)
12 #warning *** MCUSR not defined, using MCUCSR instead ***
13 #define MCUSR MCUCSR
14 #endif
15 
16 volatile uint32_t Boot_Key ATTR_NO_INIT;
17 
18 bool
19 bootloader_is_present(void) {
20 #if defined(RAMPZ)
21  return pgm_read_word_far(BOOTLOADER_START_ADDRESS)!=0xFFFF;
22 #else
23 /* Probably can just return false when < 64K flash */
24 // return pgm_read_word_near(BOOTLOADER_START_ADDRESS)!=0xFFFF;
25  return false;
26 #endif
27 }
28 void
29 Jump_To_Bootloader(void)
30 {
31  uint8_t i;
32 
33 #ifdef UDCON
34  // If USB is used, detach from the bus
35  Usb_detach();
36 #endif
37 
38  // Disable all interrupts
39  cli();
40 
41  // Set the bootloader key to the magic value and force a reset
42  Boot_Key = MAGIC_BOOT_KEY;
43 
44  // Wait two seconds for the USB detachment to register on the host
45  for (i = 0; i < 128; i++)
46  _delay_ms(16);
47 
48  // Set the bootloader key to the magic value and force a reset
49  Boot_Key = MAGIC_BOOT_KEY;
50 
51  watchdog_reboot();
52 }
53 
54 extern void Bootloader_Jump_Check(void) ATTR_INIT_SECTION(3);
55 
56 void
57 Bootloader_Jump_Check(void)
58 {
59  // If the reset source was the bootloader and the key is correct, clear it and jump to the bootloader
60  if(MCUSR & (1<<WDRF)) {
61  MCUSR = 0;
62  if(Boot_Key == MAGIC_BOOT_KEY) {
63  Boot_Key = 0;
64  wdt_disable();
65 
66  ((void (*)(void))BOOTLOADER_START_ADDRESS)();
67  } else {
68  Boot_Key++;
69  }
70  } else {
71  Boot_Key = MAGIC_BOOT_KEY-4;
72  }
73 }