From b90545b148cdc002bd388efeaf331aa31691640b Mon Sep 17 00:00:00 2001 From: Leon Krieg Date: Wed, 28 Aug 2024 00:26:45 +0200 Subject: [PATCH] Handle numeric arguments for TEMP/DEWP commands --- README | 9 ++-- src/common.h | 5 ++ src/main.c | 49 +++++++++++++++-- src/parser.c | 149 ++++++++++++++++++++++++++++++++++----------------- 4 files changed, 155 insertions(+), 57 deletions(-) diff --git a/README b/README index 53f02e3..4918a5d 100644 --- a/README +++ b/README @@ -15,11 +15,12 @@ - RUN - STOP - - TEMP - - DEWP + - TEMP + - DEWP - Decimal point for numbers is optional. Make sure you - have disabled hardware flow control on the client side. + Decimal point for numbers is currently not supported. + Make sure you have disabled hardware flow control on + the client side. TODO: Do we need to handle backspaces for interactive serial consoles?! Overkill?! diff --git a/src/common.h b/src/common.h index c6764e4..be3c756 100644 --- a/src/common.h +++ b/src/common.h @@ -9,4 +9,9 @@ #include #define Sleep(ms) _delay_ms(ms) +void Enable(void); +void Disable(void); +void SetTemp(long val); +void SetDewp(long val); + #endif // MAD_COMMON_H diff --git a/src/main.c b/src/main.c index 77facbc..299e2fb 100644 --- a/src/main.c +++ b/src/main.c @@ -2,22 +2,63 @@ #include "serial.h" #include "parser.h" +bool running; + int main(void) { - unsigned long i; char ch; + unsigned long i = 1; + running = true; USART_Init(); - for (i = 1;; i++) { - if (i >= 99999) i = 1; - USART_Printf("[CORE] Fetching sensors #%05lu...\r\n", i); + for (;;) { + // Process rx ring buffer while ((ch = USART_GetChar())) { CMD_Parse(ch); } Sleep(3000); + + if (!running) + continue; + + // TODO: Main program + if (i >= 99999) i = 1; + USART_Printf("[CORE] Fetching sensors #%05lu...\r\n", i++); } return 0; } + +void Enable(void) +{ + USART_Printf("[CORE] Parsed 'CMD_RUN' token.\r\n"); + running = true; +} + +void Disable(void) +{ + USART_Printf("[CORE] Parsed 'CMD_STOP' token.\r\n"); + running = false; +} + +void SetTemp(long val) +{ + USART_Printf("[CORE] Parsed 'CMD_SET_TEMP', VAL='%ld'.\r\n", val); + if (val < 10) { + USART_Printf("[CORE] Error: Given temperature is too low.\r\n"); + } else if (val > 40) { + USART_Printf("[CORE] Error: Given temperature is too high.\r\n"); + } +} + +void SetDewp(long val) +{ + USART_Printf("[CORE] Parsed 'CMD_SET_DEWP', VAL='%ld'.\r\n", val); + if (val < 10) { + USART_Printf("[CORE] Error: Given dew point is too low.\r\n"); + } else if (val > 80) { + USART_Printf("[CORE] Error: Given dew point is too high.\r\n"); + } +} diff --git a/src/parser.c b/src/parser.c index 606d4f9..bbd2ee8 100644 --- a/src/parser.c +++ b/src/parser.c @@ -4,15 +4,16 @@ /* * # Supported Commands - * (Optional decimal point for numbers) * * - RUN * - STOP - * - TEMP 20 - * - DEWP 60.0 + * - TEMP + * - DEWP */ static int state; +static char numbuf[8]; +static size_t numlen; #define PARSE_IDLE 0 #define PARSE_CMD_RUN 1 @@ -22,6 +23,8 @@ static int state; void CMD_Parse(char ch) { + long num; + #if 0 switch (state) { case PARSE_IDLE: @@ -52,11 +55,11 @@ void CMD_Parse(char ch) if (ch == 'T') // TEMP state = 1; if (ch == 'D') // DEWP - state = 5; + state = 6; if (ch == 'R') // RUN - state = 9; + state = 11; if (ch == 'S') // STOP - state = 12; + state = 14; break; // Parse 'TEMP' @@ -80,85 +83,133 @@ void CMD_Parse(char ch) break; case 4: if (ch == ' ') { - // XXX: Just so the web server can show something... - USART_Printf("[CORE] Parsed 'CMD_SET_TEMP' token.\r\n"); + numlen = 0; + state = 5; + } else { + state = 0; + } + break; + case 5: + // Error: Number too long + if (numlen >= sizeof(numbuf) - 1) { + state = 0; + } + + // Parse numeric string + else if ((ch >= '0' && ch <= '9') || (!numlen && ch == '-')) { + numbuf[numlen++] = ch; + } + + // Parse terminator and strip decimal + else if (ch == '\n' || ch == '.' || ch == ',') { + numbuf[numlen] = '\0'; + num = strtol(numbuf, NULL, 10); + SetTemp(num); + state = 0; + } + + // Unexpected character + else { + USART_Printf("[CORE] Error: Unexpected character '%c'.\r\n", ch); + state = 0; } - // TODO: Parse float value - state = 0; break; // Parse 'DEWP' - case 5: - if (ch == 'E') - state = 6; - else - state = 0; - break; case 6: - if (ch == 'W') + if (ch == 'E') state = 7; else state = 0; break; case 7: - if (ch == 'P') + if (ch == 'W') state = 8; else state = 0; break; case 8: + if (ch == 'P') + state = 9; + else + state = 0; + break; + case 9: if (ch == ' ') { - // XXX: Just so the web server can show something... - USART_Printf("[CORE] Parsed 'CMD_SET_DEWP' token.\r\n"); + numlen = 0; + state = 10; + } else { + state = 0; + } + break; + case 10: + // Error: Number too long + if (numlen >= sizeof(numbuf) - 1) { + state = 0; + } + + // Parse numeric string + else if ((ch >= '0' && ch <= '9') || (!numlen && ch == '-')) { + numbuf[numlen++] = ch; + } + + // Parse terminator and strip decimal + else if (ch == '\n' || ch == '.' || ch == ',') { + numbuf[numlen] = '\0'; + num = strtol(numbuf, NULL, 10); + SetDewp(num); + state = 0; + } + + // Unexpected character + else { + USART_Printf("[CORE] Error: Unexpected character '%c'.\r\n", ch); + state = 0; } - // TODO: Parse float value - state = 0; break; // Parse 'RUN' - case 9: - if (ch == 'U') - state = 10; - else - state = 0; - break; - case 10: - if (ch == 'N') - state = 11; - else - state = 0; - break; case 11: - if (ch == '\n') { - // XXX: Just so the web server can show something... - USART_Printf("[CORE] Parsed 'CMD_RUN' token.\r\n"); - } - state = 0; + if (ch == 'U') + state = 12; + else + state = 0; break; - - // Parse 'STOP' case 12: - if (ch == 'T') + if (ch == 'N') state = 13; else state = 0; break; case 13: - if (ch == 'O') - state = 14; - else - state = 0; + if (ch == '\n') { + Enable(); + } + state = 0; break; + + // Parse 'STOP' case 14: - if (ch == 'P') + if (ch == 'T') state = 15; else state = 0; break; case 15: + if (ch == 'O') + state = 16; + else + state = 0; + break; + case 16: + if (ch == 'P') + state = 17; + else + state = 0; + break; + case 17: if (ch == '\n') { - // XXX: Just so the web server can show something... - USART_Printf("[CORE] Parsed 'CMD_STOP' token.\r\n"); + Disable(); } state = 0; break;