nes-proj/cpu/avr/bootloader.c
Enrico Joerns 8cc0bb8a1e [avr] Removed usage of deprecated MCUSR
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.
2014-08-30 01:58:18 +02:00

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;
}
}