Compare commits

..

2 Commits

Author SHA1 Message Date
34428b76dd Add uptime command 2020-04-06 22:12:11 +02:00
9ef4d2a737 Add millis timer for timekeeping 2020-04-06 21:36:47 +02:00
6 changed files with 96 additions and 8 deletions

37
fantemp/clock.cpp Normal file
View File

@@ -0,0 +1,37 @@
#include "clock.hpp"
#include <avr/interrupt.h>
#include <avr/io.h>
namespace clk {
namespace detail {
volatile uint64_t sm_millisCounter = 0;
ISR(TIMER2_COMPA_vect)
{
++sm_millisCounter;
}
} // namespace detail
void init()
{
TCCR2A |= (1 << WGM21);
TCCR2B |= (1 << CS22) | (1 << CS20);
OCR2A = 124;
TIMSK2 |= (1 << OCIE2A);
}
uint64_t millis()
{
const auto oldSreg = SREG;
cli();
const auto millisCounter = detail::sm_millisCounter;
SREG = oldSreg;
return millisCounter;
}
} // namespace clk

View File

@@ -2,3 +2,12 @@
#define F_CPU 16000000 #define F_CPU 16000000
#include <util/delay.h> #include <util/delay.h>
#include <stdint.h>
namespace clk {
void init();
uint64_t millis();
} // namespace clk

View File

@@ -68,6 +68,19 @@
<ToolNumber>J41800099437</ToolNumber> <ToolNumber>J41800099437</ToolNumber>
<ToolName>Atmel-ICE</ToolName> <ToolName>Atmel-ICE</ToolName>
</com_atmel_avrdbg_tool_atmelice> </com_atmel_avrdbg_tool_atmelice>
<custom>
<ToolOptions>
<InterfaceProperties>
<IspClock>125000</IspClock>
</InterfaceProperties>
<InterfaceName>
</InterfaceName>
</ToolOptions>
<ToolType>custom</ToolType>
<ToolNumber>
</ToolNumber>
<ToolName>Custom Programming Tool</ToolName>
</custom>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings> <ToolchainSettings>
@@ -206,6 +219,9 @@
<Compile Include="bootloader.hpp"> <Compile Include="bootloader.hpp">
<SubType>compile</SubType> <SubType>compile</SubType>
</Compile> </Compile>
<Compile Include="clock.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="clock.hpp"> <Compile Include="clock.hpp">
<SubType>compile</SubType> <SubType>compile</SubType>
</Compile> </Compile>

View File

@@ -20,6 +20,8 @@ int main()
Controller controller; Controller controller;
controller.init(); controller.init();
clk::init();
while (true) { while (true) {
controller.callback(); controller.callback();
terminal.callback(); terminal.callback();

View File

@@ -8,6 +8,7 @@
#include "flash/flash.hpp" #include "flash/flash.hpp"
#include "clock.hpp"
#include "controller.hpp" #include "controller.hpp"
namespace detail { namespace detail {
@@ -18,8 +19,10 @@ GF(SHOW_CMD, "show");
GF(CURVE_CMD, "curve"); GF(CURVE_CMD, "curve");
GF(MONITOR_CMD, "monitor"); GF(MONITOR_CMD, "monitor");
GF(BOOTLOADER_CMD, "bootloader"); GF(BOOTLOADER_CMD, "bootloader");
GF(UPTIME_CMD, "uptime");
GF(VERSION_CMD, "version"); GF(VERSION_CMD, "version");
GF(VERSION, "1.2"); GF(VERSION, "1.3");
static inline bool substringEquals(const char *str, const ::detail::FlashString *flashStr, const size_t &size) static inline bool substringEquals(const char *str, const ::detail::FlashString *flashStr, const size_t &size)
{ {
@@ -97,9 +100,9 @@ class Terminal {
parseInput(); parseInput();
} }
if (m_state == State::MONITOR && --m_monitorDelayCounter == 0) { if (m_state == State::MONITOR && clk::millis() >= m_monitorDelayLastUpdate + MONITOR_DELAY) {
showState(); showState();
m_monitorDelayCounter = MONITOR_DELAY; m_monitorDelayLastUpdate = clk::millis();
} }
} }
@@ -107,7 +110,7 @@ class Terminal {
static constexpr auto INPUT_BUFFER_SIZE = 128; static constexpr auto INPUT_BUFFER_SIZE = 128;
static constexpr auto BACKSPACE = uint8_t{0x7f}; static constexpr auto BACKSPACE = uint8_t{0x7f};
static constexpr auto CTRL_C = uint8_t{0x03}; static constexpr auto CTRL_C = uint8_t{0x03};
static constexpr auto MONITOR_DELAY = 60000; static constexpr auto MONITOR_DELAY = 500;
enum class State { enum class State {
NONE, NONE,
@@ -118,7 +121,7 @@ class Terminal {
static char m_inputBuffer[INPUT_BUFFER_SIZE]; static char m_inputBuffer[INPUT_BUFFER_SIZE];
static uint16_t m_inputSize; static uint16_t m_inputSize;
static State m_state; static State m_state;
static uint16_t m_monitorDelayCounter; static uint64_t m_monitorDelayLastUpdate;
static void parseInput() static void parseInput()
{ {
@@ -134,9 +137,10 @@ class Terminal {
printCurve(); printCurve();
} else if (substringEquals(m_inputBuffer, detail::MONITOR_CMD, m_inputSize)) { } else if (substringEquals(m_inputBuffer, detail::MONITOR_CMD, m_inputSize)) {
m_state = State::MONITOR; m_state = State::MONITOR;
m_monitorDelayCounter = MONITOR_DELAY;
} else if (substringEquals(m_inputBuffer, detail::BOOTLOADER_CMD, m_inputSize)) { } else if (substringEquals(m_inputBuffer, detail::BOOTLOADER_CMD, m_inputSize)) {
handleBootloader(); handleBootloader();
} else if (substringEquals(m_inputBuffer, detail::UPTIME_CMD, m_inputSize)) {
printUptime();
} else if (substringEquals(m_inputBuffer, detail::VERSION_CMD, m_inputSize)) { } else if (substringEquals(m_inputBuffer, detail::VERSION_CMD, m_inputSize)) {
printVersion(); printVersion();
} else { } else {
@@ -164,6 +168,7 @@ class Terminal {
m_serial << detail::CURVE_CMD << F(" ......: shows mapping from temperature to fan speed") << detail::ENDL; m_serial << detail::CURVE_CMD << F(" ......: shows mapping from temperature to fan speed") << detail::ENDL;
m_serial << detail::MONITOR_CMD << F(" ....: loops the show command until Ctrl + C is pressed") << detail::ENDL; m_serial << detail::MONITOR_CMD << F(" ....: loops the show command until Ctrl + C is pressed") << detail::ENDL;
m_serial << detail::BOOTLOADER_CMD << F(" .: enters the bootloader after 3 seconds") << detail::ENDL; m_serial << detail::BOOTLOADER_CMD << F(" .: enters the bootloader after 3 seconds") << detail::ENDL;
m_serial << detail::UPTIME_CMD << F(" .....: show system uptime") << detail::ENDL;
m_serial << detail::VERSION_CMD << F(" ....: displays firmware version") << detail::ENDL; m_serial << detail::VERSION_CMD << F(" ....: displays firmware version") << detail::ENDL;
} }
@@ -203,6 +208,25 @@ class Terminal {
Bootloader::enter(); Bootloader::enter();
} }
static void printUptime()
{
constexpr auto delimiter = ':';
const auto uptime = clk::millis();
const auto hours = static_cast<uint16_t>(uptime / 1000 / 60 / 60);
const auto minutes = static_cast<uint8_t>((uptime / 1000 / 60) % 60);
const auto seconds = static_cast<uint8_t>((uptime / 1000) % 60);
m_serial << F("System uptime: ");
m_serial.template txNumber<uint16_t, 10, 2>(hours);
m_serial << delimiter;
m_serial.template txNumber<uint8_t, 10, 2>(minutes);
m_serial << delimiter;
m_serial.template txNumber<uint8_t, 10, 2>(seconds);
m_serial << detail::ENDL;
}
static void printVersion() static void printVersion()
{ {
m_serial << F("FanTemp v") << detail::VERSION << detail::ENDL; m_serial << F("FanTemp v") << detail::VERSION << detail::ENDL;
@@ -227,4 +251,4 @@ template <class Uart>
typename Terminal<Uart>::State Terminal<Uart>::m_state = State::NONE; typename Terminal<Uart>::State Terminal<Uart>::m_state = State::NONE;
template <class Uart> template <class Uart>
uint16_t Terminal<Uart>::m_monitorDelayCounter; uint64_t Terminal<Uart>::m_monitorDelayLastUpdate = 0;