diff --git a/src/base/task.h b/src/base/task.h index 9266661..94f78d5 100644 --- a/src/base/task.h +++ b/src/base/task.h @@ -39,6 +39,7 @@ enum Type : uint8_t { DisplayMsgLapCounterStart, DisplayMsgLapCounterLapTime, DisplayMsgCorruptedConfig, + DisplayMsgCorruptedTrack, ConfigTrackDetect, ConfigWriteTempTrack, ConfigTrackDelete, diff --git a/src/modules/cmd/cmd.cpp b/src/modules/cmd/cmd.cpp index 669f7e4..6acbbc0 100644 --- a/src/modules/cmd/cmd.cpp +++ b/src/modules/cmd/cmd.cpp @@ -10,6 +10,7 @@ #include "data/config_store.h" #include "data/general_store.h" #include "base/router.h" +#include "data/eeprom_layout.h" char *Cmd::trimArg(char *input) { if (input == nullptr) { @@ -149,6 +150,14 @@ Cmd::CommandId Cmd::parseCommandName(const char *input) { return DbgSendBlankLap; } + if (strcmp(input, "DBG_CORRUPT_CONFIG") == 0) { + return DbgCorruptConfig; + } + + if (strcmp(input, "DBG_CORRUPT_TRACK") == 0) { + return DbgCorruptTrack; + } + if (strcmp(input, "HELP") == 0) { return HelpGlobal; } @@ -676,6 +685,72 @@ int Cmd::handleDbgSendBlankLap(unsigned short argc) { #endif } } + + +int Cmd::handleDbgCorruptConfig(unsigned short argc) { + if (argc != 1) { +#ifdef ERROR + if (logger_ != nullptr) { + logger_->error("DBG_CORRUPT_CONFIG expects no arguments"); + } +#endif + return 1; + } + if (!debug_locked_) { + #ifdef INFO + if (logger_ != nullptr) { + logger_->info("Corrupting config"); + } + #endif + uint16_t corrupted = 0xFFFF; + EEPROM.put(eeprom_layout::configCRCAddr(), corrupted); + } else { + #ifdef INFO + if (logger_ != nullptr) { + logger_->info("Unable to run debug commands when not in God Mode"); + } + #endif + } +} + + +int Cmd::handleDbgCorruptTrack(unsigned short argc, char* argv[]) { + if (argc != 2) { +#ifdef ERROR + if (logger_ != nullptr) { + logger_->error("DBG_CORRUPT_TRACK expects 1 argument"); + } +#endif + return 1; + } + + + if (!debug_locked_) { + unsigned short id; + + if (parseTrackSlotId(argv[1], id) != 0) { +#ifdef ERROR + if (logger_ != nullptr) { + logger_->error(String("ID out of range: ") + String(argv[1])); + } +#endif + return 1; + } + #ifdef INFO + if (logger_ != nullptr) { + logger_->info("Corrupting track"); + } + #endif + uint16_t corrupted = 0xFFFF; + EEPROM.put(eeprom_layout::trackCRCAddr(id), corrupted); + } else { + #ifdef INFO + if (logger_ != nullptr) { + logger_->info("Unable to run debug commands when not in God Mode"); + } + #endif + } +} int Cmd::handleUnknownCommand(unsigned short argc, char *argv[]) { #ifdef ERROR @@ -745,6 +820,12 @@ int Cmd::dispatchCommand(CommandId command, unsigned short argc, char *argv[]) { case DbgSendBlankLap: return this->handleDbgSendBlankLap(argc); + + case DbgCorruptConfig: + return this->handleDbgCorruptConfig(argc); + + case DbgCorruptTrack: + return this->handleDbgCorruptTrack(argc, argv); case HelpGlobal: return this->handleHelpGlobal(argc); diff --git a/src/modules/cmd/cmd.h b/src/modules/cmd/cmd.h index d039c6b..b30b61d 100644 --- a/src/modules/cmd/cmd.h +++ b/src/modules/cmd/cmd.h @@ -34,6 +34,8 @@ private: DebugUnlock, DebugLock, DbgSendBlankLap, + DbgCorruptConfig, + DbgCorruptTrack, HelpGlobal, }; @@ -74,6 +76,8 @@ private: int handleDebugUnlock(unsigned short argc); int handleDebugLock(unsigned short argc); int handleDbgSendBlankLap(unsigned short argc); + int handleDbgCorruptConfig(unsigned short argc); + int handleDbgCorruptTrack(unsigned short argc, char *argv[]); public: int push(const Task &task) override; diff --git a/src/modules/cmd/help.h b/src/modules/cmd/help.h index f427da3..c810da9 100644 --- a/src/modules/cmd/help.h +++ b/src/modules/cmd/help.h @@ -21,7 +21,10 @@ static constexpr char kGlobalHelpText[] = " BATTERY_SET_LOW,\n" " THERMO_SET_LOW,\n" " THERMO_SET_HIGH,\n" + " THERMO_SET_OFFSET,\n" " DEBUG_UNLOCK\n" " DEBUG_LOCK\n" - " DBG_SEND_BLANK_LAP\n"; + " DBG_SEND_BLANK_LAP\n" + " DBG_CORRUPT_CONFIG\n" + " DBG_CORRUPT_TRACK,\n"; } // namespace cmd_help diff --git a/src/modules/config/config.cpp b/src/modules/config/config.cpp index 550045f..3c2a474 100644 --- a/src/modules/config/config.cpp +++ b/src/modules/config/config.cpp @@ -29,6 +29,8 @@ int Config::writeTrack(const TrackData &track_data) { return 1; } EEPROM.put(eeprom_layout::trackSlotAddr(track_copy.id_), track_copy); + uint16_t crc = crc16_ccitt((uint8_t*)&track_copy, sizeof(track_copy)); + EEPROM.put(eeprom_layout::trackCRCAddr(track_copy.id_), crc); config_.track_slot_occupied_[track_copy.id_ - 1] = true; this->writeConfig(); #ifdef INFO @@ -153,6 +155,26 @@ int Config::readConfig() { } configGlobalWrite(config_); router::sendAll(module::Config, task::AllConfigUpdated); + uint8_t i = 1; + for (bool status : config_.track_slot_occupied_) { + TrackData track; + int res = getTrack(i, track); + if (res == 0) { + uint16_t track_crc; + EEPROM.get(eeprom_layout::trackCRCAddr(i), track_crc); + int crc_res = crc16_ccitt_check((uint8_t*)&track, sizeof(track), track_crc); + if (crc_res != 0) { + #ifdef ERROR + if (logger_ != nullptr) { + logger_->error("Corrupted track slot: " + String(track.id_)); + } + #endif + router::send(module::Lcd, task::DisplayMsgCorruptedTrack, 5000); + return 1; + } + } + i++; + } return 0; } diff --git a/src/modules/lcd/lcd.cpp b/src/modules/lcd/lcd.cpp index 946410d..0fef997 100644 --- a/src/modules/lcd/lcd.cpp +++ b/src/modules/lcd/lcd.cpp @@ -390,6 +390,20 @@ int Lcd::renderMsgCorruptedConfig() { return 0; } +int Lcd::renderMsgCorruptedTrack() { + if (!base_rendered_) { + this->clear(); + display_->setCursor(3, 1); + this->print("CRITICAL ERROR"); + display_->setCursor(2, 2); + this->print("CORRUPTED TRACK"); + display_->setCursor(0, 3); + this->print("Serial for more info"); + base_rendered_ = true; + } + return 0; +} + int Lcd::push(const Task &task) { return queue_.push(task); } Lcd::Lcd() @@ -609,6 +623,10 @@ int Lcd::loop(unsigned long timeout_ms) { case task::DisplayMsgCorruptedConfig: base_rendered_ = false; activateMessage(screen::MsgCorruptedConfig, next_task.data_); + + case task::DisplayMsgCorruptedTrack: + base_rendered_ = false; + activateMessage(screen::MsgCorruptedTrack, next_task.data_); default: break; @@ -687,6 +705,10 @@ int Lcd::loop(unsigned long timeout_ms) { case screen::MsgCorruptedConfig: this->renderMsgCorruptedConfig(); break; + + case screen::MsgCorruptedTrack: + this->renderMsgCorruptedTrack(); + break; default: break; diff --git a/src/modules/lcd/lcd.h b/src/modules/lcd/lcd.h index 62c2594..c240c3b 100644 --- a/src/modules/lcd/lcd.h +++ b/src/modules/lcd/lcd.h @@ -32,6 +32,7 @@ enum LcdScreen : uint8_t { MsgLapCounterStart, MsgLapCounterLapTime, MsgCorruptedConfig, + MsgCorruptedTrack, }; } // namespace screen @@ -81,6 +82,7 @@ private: int renderMsgLapCounterStart(); int renderMsgLapCounterLapTime(); int renderMsgCorruptedConfig(); + int renderMsgCorruptedTrack(); public: int push(const Task &task) override;