Add tsb bootloader support
This commit is contained in:
parent
04bcb76382
commit
07be559e94
46
fantemp/bootloader.cpp
Normal file
46
fantemp/bootloader.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#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>(0x7E00 / 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) == 0xF8)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Bootloader::call()
|
||||
{
|
||||
if (check())
|
||||
bootloader();
|
||||
else
|
||||
boot();
|
||||
}
|
24
fantemp/bootloader.hpp
Normal file
24
fantemp/bootloader.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
class Bootloader {
|
||||
public:
|
||||
template <typename Fn>
|
||||
static inline void init(Fn callback)
|
||||
{
|
||||
if (handleReset()) {
|
||||
callback();
|
||||
call();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void enter()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
private:
|
||||
static bool handleReset();
|
||||
static void reset();
|
||||
static bool check();
|
||||
static void call();
|
||||
};
|
@ -200,6 +200,12 @@
|
||||
<Compile Include="adc\hardware.hpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="bootloader.cpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="bootloader.hpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="clock.hpp">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
|
@ -5,11 +5,14 @@
|
||||
#define UART0_INT_VECTORS
|
||||
#include "uart/hardware0.hpp"
|
||||
|
||||
#include "bootloader.hpp"
|
||||
#include "controller.hpp"
|
||||
#include "terminal.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
Bootloader::init([]() {});
|
||||
|
||||
using serial = uart::Uart0<uart::Config<115200>>;
|
||||
Terminal<serial> terminal;
|
||||
terminal.init();
|
||||
|
@ -15,6 +15,7 @@ GF(HELP_CMD, "help");
|
||||
GF(SHOW_CMD, "show");
|
||||
GF(CURVE_CMD, "curve");
|
||||
GF(MONITOR_CMD, "monitor");
|
||||
GF(BOOTLOADER_CMD, "bootloader");
|
||||
|
||||
constexpr auto BACKSPACE = uint8_t{0x7f};
|
||||
constexpr auto CTRL_C = uint8_t{0x03};
|
||||
@ -109,6 +110,8 @@ class Terminal {
|
||||
printCurve();
|
||||
} else if (strncmp_P(m_inputBuffer, reinterpret_cast<const char *>(MONITOR_CMD), m_inputSize) == 0) {
|
||||
m_state = State::MONITOR;
|
||||
} else if (strncmp_P(m_inputBuffer, reinterpret_cast<const char *>(BOOTLOADER_CMD), m_inputSize) == 0) {
|
||||
handleBootloader();
|
||||
} else {
|
||||
printUnknown();
|
||||
}
|
||||
@ -124,10 +127,11 @@ class Terminal {
|
||||
static void printHelp()
|
||||
{
|
||||
m_serial << F("FanTemp command overview: ") << ENDL;
|
||||
m_serial << HELP_CMD << F(" ....: print this help message") << ENDL;
|
||||
m_serial << SHOW_CMD << F(" ....: shows current temperature and fan speed") << ENDL;
|
||||
m_serial << CURVE_CMD << F(" ...: shows the curve used to map temperature to fan speed") << ENDL;
|
||||
m_serial << MONITOR_CMD << F(" .: loops the show command until Ctrl + C is pressed") << ENDL;
|
||||
m_serial << HELP_CMD << F(" .......: print this help message") << ENDL;
|
||||
m_serial << SHOW_CMD << F(" .......: shows current temperature and fan speed") << ENDL;
|
||||
m_serial << CURVE_CMD << F(" ......: shows the curve used to map temperature to fan speed") << ENDL;
|
||||
m_serial << MONITOR_CMD << F(" ....: loops the show command until Ctrl + C is pressed") << ENDL;
|
||||
m_serial << BOOTLOADER_CMD << F(" .: enters the bootloader after 10 seconds") << ENDL;
|
||||
}
|
||||
|
||||
static void showState()
|
||||
@ -156,6 +160,21 @@ class Terminal {
|
||||
}
|
||||
}
|
||||
|
||||
static void handleBootloader()
|
||||
{
|
||||
for (int8_t i = 10; i >= 0; --i) {
|
||||
m_serial << i << ENDL;
|
||||
_delay_ms(1000);
|
||||
}
|
||||
|
||||
m_serial << F("Entering bootloader...") << ENDL;
|
||||
m_serial.flushTx();
|
||||
|
||||
_delay_ms(1000);
|
||||
|
||||
Bootloader::enter();
|
||||
}
|
||||
|
||||
static void printUnknown()
|
||||
{
|
||||
m_serial << F("Unknown command \"");
|
||||
|
Loading…
Reference in New Issue
Block a user