47 lines
716 B
C++
47 lines
716 B
C++
|
#include "bootloader.hpp"
|
||
|
|
||
|
#include <avr/io.h>
|
||
|
#include <avr/pgmspace.h>
|
||
|
#include <avr/wdt.h>
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
typedef void (*jmp_fn)() __attribute__((noreturn));
|
||
|
|
||
|
jmp_fn boot = reinterpret_cast<jmp_fn>(0x0000);
|
||
|
jmp_fn bootloader = reinterpret_cast<jmp_fn>(0x7800 / 2);
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
bool Bootloader::handleReset()
|
||
|
{
|
||
|
wdt_reset();
|
||
|
uint8_t mcuStatus = MCUSR;
|
||
|
MCUSR &= ~(1 << WDRF);
|
||
|
wdt_disable();
|
||
|
return (mcuStatus & (1 << WDRF));
|
||
|
}
|
||
|
|
||
|
void Bootloader::reset()
|
||
|
{
|
||
|
wdt_enable(WDTO_15MS);
|
||
|
while (true)
|
||
|
;
|
||
|
}
|
||
|
|
||
|
bool Bootloader::check()
|
||
|
{
|
||
|
if (pgm_read_byte(reinterpret_cast<uint16_t>(bootloader) * 2) != 0xFF)
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void Bootloader::call()
|
||
|
{
|
||
|
if (check())
|
||
|
bootloader();
|
||
|
else
|
||
|
boot();
|
||
|
}
|