diff --git a/src/common/common.c b/src/common/common.c index cafc163..700242d 100644 --- a/src/common/common.c +++ b/src/common/common.c @@ -3,21 +3,8 @@ #include -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); +} diff --git a/src/common/parser.c b/src/common/parser.c index 42fa254..f2d75f4 100644 --- a/src/common/parser.c +++ b/src/common/parser.c @@ -3,27 +3,44 @@ #include #include #include +#include #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); +} diff --git a/src/main.c b/src/main.c index b542ef1..4a5bc56 100644 --- a/src/main.c +++ b/src/main.c @@ -6,8 +6,8 @@ #include +// 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];