132 lines
3.0 KiB
C++
132 lines
3.0 KiB
C++
#pragma once
|
|
|
|
#include <ctype.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
#include <avr/pgmspace.h>
|
|
|
|
#include "flash/flash.hpp"
|
|
|
|
#include "controller.hpp"
|
|
|
|
GF(ENDL, "\r\n");
|
|
GF(HELP_CMD, "help");
|
|
GF(SHOW_CMD, "show");
|
|
|
|
template <class Uart>
|
|
class Terminal {
|
|
public:
|
|
static void init()
|
|
{
|
|
m_serial.init();
|
|
|
|
m_serial << ENDL << F("FanTemp Control Panel") << ENDL << ENDL << F("$ ");
|
|
}
|
|
|
|
static void callback()
|
|
{
|
|
uint8_t inputByte;
|
|
bool handleInput = false;
|
|
|
|
while (m_serial.rxByte(inputByte)) {
|
|
if (isprint(inputByte) || inputByte == 0x03) {
|
|
m_inputBuffer[m_inputSize++] = inputByte;
|
|
|
|
// Handle Ctrl + C
|
|
if (inputByte == 0x03) {
|
|
m_serial << F("^C") << ENDL;
|
|
handleInput = true;
|
|
break;
|
|
}
|
|
// Echo
|
|
else {
|
|
m_serial << static_cast<char>(inputByte);
|
|
}
|
|
}
|
|
|
|
// Handle backspace
|
|
if (inputByte == 0x7f && m_inputSize > 0) {
|
|
m_serial << static_cast<char>(0x7f);
|
|
--m_inputSize;
|
|
}
|
|
// Handle line terminator
|
|
else if (inputByte == '\r' || inputByte == '\n') {
|
|
// Consume possible second line terminator
|
|
if (m_serial.peek(inputByte) && (inputByte == '\r' || inputByte == '\n')) {
|
|
m_serial.rxByte(inputByte);
|
|
}
|
|
m_serial << ENDL;
|
|
handleInput = true;
|
|
break;
|
|
}
|
|
|
|
if (m_inputSize >= INPUT_BUFFER_SIZE) {
|
|
m_serial << ENDL << F("WARNING: Terminal input buffer overflow!") << ENDL;
|
|
handleInput = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (handleInput) {
|
|
parseInput();
|
|
m_inputSize = 0;
|
|
m_serial << F("$ ");
|
|
}
|
|
}
|
|
|
|
private:
|
|
static constexpr auto INPUT_BUFFER_SIZE = 128;
|
|
|
|
static Uart m_serial;
|
|
static char m_inputBuffer[INPUT_BUFFER_SIZE];
|
|
static uint16_t m_inputSize;
|
|
|
|
static void parseInput()
|
|
{
|
|
if (m_inputSize) {
|
|
if (strncmp_P(m_inputBuffer, reinterpret_cast<const char *>(HELP_CMD), m_inputSize) == 0) {
|
|
printHelp();
|
|
} else if (strncmp_P(m_inputBuffer, reinterpret_cast<const char *>(SHOW_CMD), m_inputSize) == 0) {
|
|
showState();
|
|
} else {
|
|
printUnknown();
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
static void showState()
|
|
{
|
|
char floatBuffer[16];
|
|
|
|
sprintf(floatBuffer, "%.2f", Controller::m_adcSample);
|
|
m_serial << F("Read ADC ....: ") << floatBuffer << ENDL;
|
|
sprintf(floatBuffer, "%.2f", Controller::m_resistance);
|
|
m_serial << F("Resistance ..: ") << floatBuffer << ENDL;
|
|
sprintf(floatBuffer, "%.2f", Controller::m_temperature);
|
|
m_serial << F("Temperature .: ") << floatBuffer << F(" C") << ENDL;
|
|
m_serial << F("Fan speed ...: ") << Controller::m_fanSpeed << F("%") << ENDL;
|
|
}
|
|
|
|
static void printUnknown()
|
|
{
|
|
m_serial << F("Unknown command \"");
|
|
for (uint16_t i = 0; i < m_inputSize; ++i)
|
|
m_serial << static_cast<char>(m_inputBuffer[i]);
|
|
m_serial << F("\"") << ENDL;
|
|
}
|
|
};
|
|
|
|
template <class Uart>
|
|
char Terminal<Uart>::m_inputBuffer[INPUT_BUFFER_SIZE];
|
|
|
|
template <class Uart>
|
|
uint16_t Terminal<Uart>::m_inputSize = 0;
|