From eb131bd02017e60d8f356450f92e6179623eb832 Mon Sep 17 00:00:00 2001 From: Kinchin Fong Date: Sat, 9 Sep 2023 22:34:57 +0800 Subject: [PATCH] Serial Communication Framework --- lib/ConfigManager/ConfigManager.cpp | 4 +- lib/ConfigManager/ConfigManager.h | 2 +- lib/InterSerial/InterSerial.cpp | 84 +++++++++++++++++++++++++++++ lib/InterSerial/InterSerial.h | 24 +++++++++ platformio.ini | 1 + src/main.cpp | 18 +++---- tools/init_fs.py | 5 ++ 7 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 lib/InterSerial/InterSerial.cpp create mode 100644 lib/InterSerial/InterSerial.h diff --git a/lib/ConfigManager/ConfigManager.cpp b/lib/ConfigManager/ConfigManager.cpp index 751b48a..b2aca6c 100644 --- a/lib/ConfigManager/ConfigManager.cpp +++ b/lib/ConfigManager/ConfigManager.cpp @@ -1,8 +1,8 @@ #include "ConfigManager.h" -void ConfigManager::Init(VFileSystem* fs) +int ConfigManager::Init(VFileSystem* fs) { - + return 0; } int ConfigManager::ReadId(char* id) diff --git a/lib/ConfigManager/ConfigManager.h b/lib/ConfigManager/ConfigManager.h index 766d277..727ba93 100644 --- a/lib/ConfigManager/ConfigManager.h +++ b/lib/ConfigManager/ConfigManager.h @@ -13,7 +13,7 @@ struct DeviceConfig class ConfigManager { public: - void Init(VFileSystem* fs); + int Init(VFileSystem* fs); int ReadId(char* id); int SetId(char* id); int ReadConfig(DeviceConfig& config); diff --git a/lib/InterSerial/InterSerial.cpp b/lib/InterSerial/InterSerial.cpp new file mode 100644 index 0000000..6a34847 --- /dev/null +++ b/lib/InterSerial/InterSerial.cpp @@ -0,0 +1,84 @@ +#include "InterSerial.h" + +#define MAX_CMD_LEN 200 + +void InterSerial::Init(DataRecorder* r, ConfigManager* c) +{ + Serial1.begin(115200); + cmdLine = ""; + rec = r; + cfg = c; +} + +void InterSerial::Process() +{ + while (Serial1.available()) { + ringBuffer.push(Serial1.read()); + } + + while (ringBuffer.size() > 0) { + if (cmdLine.endsWith("\r\n")) { + cmdLine.clear(); + } + + uint8_t readByte; + ringBuffer.pop(readByte); + if (cmdLine.isEmpty() && isspace(readByte)) { + continue; + } + cmdLine += (char)readByte; + + if (cmdLine.length() > MAX_CMD_LEN) { + Serial1.println("Command too long, max 200 bytes"); + cmdLine.clear(); + continue; + } + if (cmdLine.endsWith("\r\n")) { + if (cmdLine.startsWith("AT")) { + CmdHandler(cmdLine); + } else { + Serial1.println("Command should start with AT"); + cmdLine.clear(); + continue; + } + } + } +} + +void InterSerial::CmdHandler(String cmdLine) +{ + if (cmdLine == "AT\r\n") { + Serial1.println("OK"); + } else if (cmdLine.length() <= 5) { + Serial1.println("Bad Command"); + } else if (cmdLine[strlen("AT")] != '+') { + Serial1.println("Bad Command"); + } else { + String realCmd = cmdLine.substring(3, cmdLine.length() - 2); + ParseCmd(realCmd); + } +} + +void InterSerial::ParseCmd(String cmd) +{ + if (cmd == "DEVIDREAD") { + + } else if (cmd == "SYSCFGREAD") { + + } else if (cmd.startsWith("DEVIDSET") && cmd[strlen("DEVIDSET")] == '=') { + cmd.substring(strlen("DEVIDSET") + 1); + + } else if (cmd.startsWith("SYSCFGSET") && cmd[strlen("SYSCFGSET")] == '=') { + cmd.substring(strlen("SYSCFGSET") + 1); + + } else if (cmd.startsWith("MSGSTORE") && cmd[strlen("MSGSTORE")] == '=') { + cmd.substring(strlen("MSGSTORE") + 1); + + } else if (cmd == "MSGREAD=?") { + + } else if (cmd == "MSGDUMP") { + + } else { + Serial1.println("Bad Command"); + } +} diff --git a/lib/InterSerial/InterSerial.h b/lib/InterSerial/InterSerial.h new file mode 100644 index 0000000..367404a --- /dev/null +++ b/lib/InterSerial/InterSerial.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include "DataRecorder.h" +#include "ConfigManager.h" + + +class InterSerial +{ +public: + void Init(DataRecorder* rec, ConfigManager* cfg); + void Process(); + +private: + void CmdHandler(String cmdLine); + void ParseCmd(String cmd); + +private: + RingBuf ringBuffer; + String cmdLine; + DataRecorder* rec; + ConfigManager* cfg; +}; diff --git a/platformio.ini b/platformio.ini index 6909371..10be9c5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,3 +16,4 @@ board_upload.flash_size = 16MB board_build.partitions = partitions_12M_SPIFFS.csv framework = arduino upload_port = COM8 +lib_deps = locoduino/RingBuffer@^1.0.4 diff --git a/src/main.cpp b/src/main.cpp index 7467cac..c378088 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,31 +4,29 @@ #include "VFileSystem.h" #include "ConfigManager.h" #include "DataRecorder.h" +#include "InterSerial.h" VFileSystem fs; ConfigManager cfg; DataRecorder dataRec; +InterSerial interSerial; void setup() { - Serial1.begin(115200); - Serial1.println("Begin..."); - if (fs.Init()) { - Serial1.println("FS Init Failed."); return; } - - cfg.Init(&fs); + if (cfg.Init(&fs)) { + return; + } if (dataRec.Init(&fs)) { - Serial1.println("DataRecorder Init Failed."); return; } - - Serial1.println("End."); + interSerial.Init(&dataRec, &cfg); } void loop() { - + interSerial.Process(); + delay(10); } \ No newline at end of file diff --git a/tools/init_fs.py b/tools/init_fs.py index e8b99de..d783d99 100644 --- a/tools/init_fs.py +++ b/tools/init_fs.py @@ -1,3 +1,8 @@ +import os + +if not os.path.exists('../data'): + os.makedirs('../data') + for i in range(1024): with open(f"../data/rec-{str(i).zfill(4)}.dat", "wb") as f: data = b""