Contiki 3.x
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 #include <avr/pgmspace.h>
9 #include <avr/interrupt.h>
10 #include <avr/eeprom.h>
11 
12 /* MCUSR is a deprecated name but older avr-libc versions may define it */
13 #if !defined (MCUCSR)
14 # if defined (MCUSR)
15 # define MCUCSR MCUSR
16 # endif
17 #endif
18 
19 #ifndef EEPROM_MAGIC_BYTE_ADDR
20 #define EEPROM_MAGIC_BYTE_ADDR (uint8_t*)(E2END-3)
21 #endif
22 
23 volatile uint32_t Boot_Key ATTR_NO_INIT;
24 
25 extern void Bootloader_Jump_Check(void) ATTR_INIT_SECTION(3);
26 
27 bool
28 bootloader_is_present(void)
29 {
30 #if defined(BOOTLOADER_START_ADDRESS)
31  return pgm_read_word_far(BOOTLOADER_START_ADDRESS) != 0xFFFF;
32 #else
33  return false;
34 #endif
35 }
36 
37 void
38 Jump_To_Bootloader(void)
39 {
40  /* Disable all interrupts */
41  cli();
42 
43 #ifdef UDCON
44  /* If USB is used, detach from the bus */
45  Usb_detach();
46 
47  uint8_t i;
48 
49  /* Wait two seconds for the USB detachment to register on the host */
50  for(i = 0; i < 200; i++) {
51  _delay_ms(10);
53  }
54 #endif
55 
56  /* Set the bootloader key to the magic value and force a reset */
57  Boot_Key = MAGIC_BOOT_KEY;
58 
59  eeprom_write_byte(EEPROM_MAGIC_BYTE_ADDR, 0xFF);
60 
61  /* Enable interrupts */
62  sei();
63 
65 }
66 
67 void
68 Bootloader_Jump_Check(void)
69 {
70  /* If the reset source was the bootloader and the key is correct,
71  * clear it and jump to the bootloader
72  */
73  if(MCUCSR & (1 << WDRF)) {
74  MCUCSR = 0;
75  if(Boot_Key == MAGIC_BOOT_KEY) {
76  Boot_Key = 0;
77  wdt_disable();
78 
79  /* Disable all interrupts */
80  cli();
81 
82  eeprom_write_byte(EEPROM_MAGIC_BYTE_ADDR, 0xFF);
83 
84  /* Enable interrupts */
85  sei();
86 
87  ((void (*)(void))(BOOTLOADER_START_ADDRESS)) ();
88  } else {
89  /* The watchdog fired. Probably means we
90  * crashed. Wait two seconds before continuing.
91  */
92 
93  Boot_Key++;
94  uint8_t i;
95 
96  for(i = 0; i < 200; i++) {
97  _delay_ms(10);
99  }
100  }
101  } else {
102  Boot_Key = MAGIC_BOOT_KEY - 4;
103  }
104 }
This file contains the USB driver routines.
#define Usb_detach()
detaches from USB bus
Definition: usb_drv.h:367
void watchdog_reboot(void)
Keeps control until the WDT throws a reset signal.
Definition: watchdog.c:43
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition: watchdog.c:64