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">
|
<Compile Include="adc\hardware.hpp">
|
||||||
<SubType>compile</SubType>
|
<SubType>compile</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="bootloader.cpp">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="bootloader.hpp">
|
||||||
|
<SubType>compile</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="clock.hpp">
|
<Compile Include="clock.hpp">
|
||||||
<SubType>compile</SubType>
|
<SubType>compile</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -5,11 +5,14 @@
|
|||||||
#define UART0_INT_VECTORS
|
#define UART0_INT_VECTORS
|
||||||
#include "uart/hardware0.hpp"
|
#include "uart/hardware0.hpp"
|
||||||
|
|
||||||
|
#include "bootloader.hpp"
|
||||||
#include "controller.hpp"
|
#include "controller.hpp"
|
||||||
#include "terminal.hpp"
|
#include "terminal.hpp"
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
Bootloader::init([]() {});
|
||||||
|
|
||||||
using serial = uart::Uart0<uart::Config<115200>>;
|
using serial = uart::Uart0<uart::Config<115200>>;
|
||||||
Terminal<serial> terminal;
|
Terminal<serial> terminal;
|
||||||
terminal.init();
|
terminal.init();
|
||||||
|
@ -15,6 +15,7 @@ GF(HELP_CMD, "help");
|
|||||||
GF(SHOW_CMD, "show");
|
GF(SHOW_CMD, "show");
|
||||||
GF(CURVE_CMD, "curve");
|
GF(CURVE_CMD, "curve");
|
||||||
GF(MONITOR_CMD, "monitor");
|
GF(MONITOR_CMD, "monitor");
|
||||||
|
GF(BOOTLOADER_CMD, "bootloader");
|
||||||
|
|
||||||
constexpr auto BACKSPACE = uint8_t{0x7f};
|
constexpr auto BACKSPACE = uint8_t{0x7f};
|
||||||
constexpr auto CTRL_C = uint8_t{0x03};
|
constexpr auto CTRL_C = uint8_t{0x03};
|
||||||
@ -109,6 +110,8 @@ class Terminal {
|
|||||||
printCurve();
|
printCurve();
|
||||||
} else if (strncmp_P(m_inputBuffer, reinterpret_cast<const char *>(MONITOR_CMD), m_inputSize) == 0) {
|
} else if (strncmp_P(m_inputBuffer, reinterpret_cast<const char *>(MONITOR_CMD), m_inputSize) == 0) {
|
||||||
m_state = State::MONITOR;
|
m_state = State::MONITOR;
|
||||||
|
} else if (strncmp_P(m_inputBuffer, reinterpret_cast<const char *>(BOOTLOADER_CMD), m_inputSize) == 0) {
|
||||||
|
handleBootloader();
|
||||||
} else {
|
} else {
|
||||||
printUnknown();
|
printUnknown();
|
||||||
}
|
}
|
||||||
@ -124,10 +127,11 @@ class Terminal {
|
|||||||
static void printHelp()
|
static void printHelp()
|
||||||
{
|
{
|
||||||
m_serial << F("FanTemp command overview: ") << ENDL;
|
m_serial << F("FanTemp command overview: ") << ENDL;
|
||||||
m_serial << HELP_CMD << F(" ....: print this help message") << 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 << 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 << 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 << 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()
|
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()
|
static void printUnknown()
|
||||||
{
|
{
|
||||||
m_serial << F("Unknown command \"");
|
m_serial << F("Unknown command \"");
|
||||||
|
Loading…
Reference in New Issue
Block a user