Prevent redundant writes and start implementing parser timeout
This commit is contained in:
@@ -3,21 +3,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static void Puts(const char *str)
|
||||
{
|
||||
while (*str != '\0') {
|
||||
USART_Putc(*str++);
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintArgs(const char *fmt, va_list ap)
|
||||
{
|
||||
char msg[256];
|
||||
|
||||
vsnprintf(msg, sizeof(msg), fmt, ap);
|
||||
|
||||
Puts(msg);
|
||||
}
|
||||
static void Puts(const char *str);
|
||||
static void PrintArgs(const char *fmt, va_list ap);
|
||||
|
||||
void Print(const char *fmt, ...)
|
||||
{
|
||||
@@ -51,3 +38,19 @@ void Error(const char *fmt, ...)
|
||||
|
||||
// XXX: Force reset?
|
||||
}
|
||||
|
||||
static void Puts(const char *str)
|
||||
{
|
||||
while (*str != '\0') {
|
||||
USART_Putc(*str++);
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintArgs(const char *fmt, va_list ap)
|
||||
{
|
||||
char msg[256];
|
||||
|
||||
vsnprintf(msg, sizeof(msg), fmt, ap);
|
||||
|
||||
Puts(msg);
|
||||
}
|
||||
|
||||
@@ -3,27 +3,44 @@
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
#define CMD_MAX_LEN 128
|
||||
|
||||
// TODO: Write documentation.
|
||||
// TODO: Implement start and stop commands.
|
||||
// TODO: Reset command buffer on timeout?
|
||||
// TODO: Reset command buffer on timeout.
|
||||
|
||||
static char cmdbuf[CMD_MAX_LEN + 1];
|
||||
static char *tail = cmdbuf + CMD_MAX_LEN - 1;
|
||||
static char *head = cmdbuf;
|
||||
|
||||
static bool ParseLine(cmd_t *out);
|
||||
static void StartTimer(void);
|
||||
static bool IsTimedOut(void);
|
||||
static void StopTimer(void);
|
||||
|
||||
bool CMD_Parse(char ch, cmd_t *out)
|
||||
{
|
||||
bool is_valid;
|
||||
|
||||
if (ch == '\n' || ch == '\r') {
|
||||
// FIXME: Reset command buffer on timeout:
|
||||
// No newline character is received if the serial
|
||||
// buffer is full and the ending is discarded. This
|
||||
// means that after a command that is too long, the
|
||||
// next command will not be parsed properly.
|
||||
|
||||
if (head == cmdbuf) {
|
||||
StartTimer();
|
||||
}
|
||||
|
||||
if (IsTimedOut() ||
|
||||
(ch == '\n' || ch == '\r')) {
|
||||
is_valid = ParseLine(out);
|
||||
tail = cmdbuf + CMD_MAX_LEN - 1;
|
||||
head = cmdbuf;
|
||||
StopTimer();
|
||||
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
@@ -70,3 +87,20 @@ static bool ParseLine(cmd_t *out)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void StartTimer(void)
|
||||
{
|
||||
TCNT0 = 0x00;
|
||||
TCCR0 = BIT(CS00) | BIT(CS02);
|
||||
}
|
||||
|
||||
static bool IsTimedOut(void)
|
||||
{
|
||||
return false; // TIFR & BIT(TOV0)
|
||||
}
|
||||
|
||||
static void StopTimer(void)
|
||||
{
|
||||
TCNT0 = 0x00;
|
||||
TIFR = BIT(TOV0);
|
||||
}
|
||||
|
||||
46
src/main.c
46
src/main.c
@@ -6,8 +6,8 @@
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
// TODO: Implement command parser timeout for large input.
|
||||
// TODO: Config header for chip specifics like EEPROM size.
|
||||
// TODO: Only update EEPROM if value differs from previous.
|
||||
// TODO: Check thermistor conversion results /w thermometer.
|
||||
// TODO: Implement primary state machine for update loop.
|
||||
// TODO: Migrate to ATMega 1284P-PU for 2nd 16-bit timer.
|
||||
@@ -31,7 +31,8 @@ static float relh;
|
||||
|
||||
static int Init(void);
|
||||
static void Update(void);
|
||||
static void UpdateSensors(void);
|
||||
static void SetTarget(float t, float td);
|
||||
static void GetSensorState(void);
|
||||
|
||||
static int Init(void)
|
||||
{
|
||||
@@ -85,7 +86,7 @@ static int Init(void)
|
||||
|
||||
if (MEM_Read(&mem) == 0) {
|
||||
Info("Found persistent configuration in EEPROM!");
|
||||
Info("Setting targets TEMP='%.2fC', DEWP='%.2fC'.",
|
||||
Info("Using targets TEMP='%.2fC', DEWP='%.2fC'.",
|
||||
mem.temp, mem.dewp);
|
||||
|
||||
temp_target = mem.temp;
|
||||
@@ -139,7 +140,6 @@ static void Update(void)
|
||||
{
|
||||
char ch;
|
||||
cmd_t cmd;
|
||||
mem_block_t mem;
|
||||
|
||||
// Parse serial commands
|
||||
while ((ch = USART_Getc()) >= 0) {
|
||||
@@ -148,18 +148,14 @@ static void Update(void)
|
||||
continue;
|
||||
}
|
||||
switch(cmd.type) {
|
||||
case T_SET: // Configure new persistent target
|
||||
Info("Setting new target TEMP='%.2fC'...", cmd.args[0]);
|
||||
Info("Setting new target DEWP='%.2fC'...", cmd.args[1]);
|
||||
mem.temp = temp_target = cmd.args[0];
|
||||
mem.dewp = dewp_target = cmd.args[1];
|
||||
MEM_Write(&mem);
|
||||
case T_SET: // Set new persistent target
|
||||
SetTarget(cmd.args[0], cmd.args[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Poll sensor values
|
||||
UpdateSensors();
|
||||
GetSensorState();
|
||||
|
||||
// Handle state
|
||||
switch (state) {
|
||||
@@ -174,7 +170,33 @@ static void Update(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateSensors(void)
|
||||
static void SetTarget(float t, float td)
|
||||
{
|
||||
mem_block_t mem;
|
||||
|
||||
Info("=======================================");
|
||||
Info("Setting temperature target to '%.2fC'.", t);
|
||||
Info("Setting dewpoint target to '%.2fC'.", td);
|
||||
Info("=======================================");
|
||||
|
||||
if (MEM_Read(&mem) == 0) {
|
||||
if (t == mem.temp && td == mem.dewp) {
|
||||
return; // Nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
mem.temp = t;
|
||||
mem.dewp = td;
|
||||
|
||||
// Keep in EEPROM
|
||||
MEM_Write(&mem);
|
||||
|
||||
// Update state
|
||||
temp_target = t;
|
||||
dewp_target = td;
|
||||
}
|
||||
|
||||
static void GetSensorState(void)
|
||||
{
|
||||
word raw;
|
||||
float t[6], rh[3], dp[3];
|
||||
|
||||
Reference in New Issue
Block a user