8cc0bb8a1e
Since avr-libc 1.8.0 MCUSR is marked as poison as it was replaced by the correct name MCUCSR. Thus code still using the old MCUSR name does not compile anymore. This commit replaces usages of former MCUSR by its new name MCUCSR and modifies the alias fallback accordingly.
106 lines
2.1 KiB
C
106 lines
2.1 KiB
C
#include "bootloader.h"
|
|
#include "dev/watchdog.h"
|
|
#include <util/delay.h>
|
|
#include <avr/wdt.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/pgmspace.h>
|
|
#include "dev/usb/usb_drv.h"
|
|
#include <avr/pgmspace.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/eeprom.h>
|
|
|
|
/* MCUSR is a deprecated name but older avr-libc versions may define it */
|
|
#if !defined (MCUCSR)
|
|
# if defined (MCUSR)
|
|
# warning *** MCUCSR not defined, using MCUSR instead ***
|
|
# define MCUCSR MCUSR
|
|
# endif
|
|
#endif
|
|
|
|
#ifndef EEPROM_MAGIC_BYTE_ADDR
|
|
#define EEPROM_MAGIC_BYTE_ADDR (uint8_t*)(E2END-3)
|
|
#endif
|
|
|
|
volatile uint32_t Boot_Key ATTR_NO_INIT;
|
|
|
|
extern void Bootloader_Jump_Check(void) ATTR_INIT_SECTION(3);
|
|
|
|
bool
|
|
bootloader_is_present(void)
|
|
{
|
|
#if defined(BOOTLOADER_START_ADDRESS)
|
|
return pgm_read_word_far(BOOTLOADER_START_ADDRESS) != 0xFFFF;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
void
|
|
Jump_To_Bootloader(void)
|
|
{
|
|
/* Disable all interrupts */
|
|
cli();
|
|
|
|
#ifdef UDCON
|
|
/* If USB is used, detach from the bus */
|
|
Usb_detach();
|
|
|
|
uint8_t i;
|
|
|
|
/* Wait two seconds for the USB detachment to register on the host */
|
|
for(i = 0; i < 200; i++) {
|
|
_delay_ms(10);
|
|
watchdog_periodic();
|
|
}
|
|
#endif
|
|
|
|
/* Set the bootloader key to the magic value and force a reset */
|
|
Boot_Key = MAGIC_BOOT_KEY;
|
|
|
|
eeprom_write_byte(EEPROM_MAGIC_BYTE_ADDR, 0xFF);
|
|
|
|
/* Enable interrupts */
|
|
sei();
|
|
|
|
watchdog_reboot();
|
|
}
|
|
|
|
void
|
|
Bootloader_Jump_Check(void)
|
|
{
|
|
/* If the reset source was the bootloader and the key is correct,
|
|
* clear it and jump to the bootloader
|
|
*/
|
|
if(MCUCSR & (1 << WDRF)) {
|
|
MCUCSR = 0;
|
|
if(Boot_Key == MAGIC_BOOT_KEY) {
|
|
Boot_Key = 0;
|
|
wdt_disable();
|
|
|
|
/* Disable all interrupts */
|
|
cli();
|
|
|
|
eeprom_write_byte(EEPROM_MAGIC_BYTE_ADDR, 0xFF);
|
|
|
|
/* Enable interrupts */
|
|
sei();
|
|
|
|
((void (*)(void))(BOOTLOADER_START_ADDRESS)) ();
|
|
} else {
|
|
/* The watchdog fired. Probably means we
|
|
* crashed. Wait two seconds before continuing.
|
|
*/
|
|
|
|
Boot_Key++;
|
|
uint8_t i;
|
|
|
|
for(i = 0; i < 200; i++) {
|
|
_delay_ms(10);
|
|
watchdog_periodic();
|
|
}
|
|
}
|
|
} else {
|
|
Boot_Key = MAGIC_BOOT_KEY - 4;
|
|
}
|
|
}
|