diff --git a/Software/include/common.h b/Software/include/common.h index 70d627a..6f89f25 100644 --- a/Software/include/common.h +++ b/Software/include/common.h @@ -70,7 +70,4 @@ typedef enum batteryType_e extern const char *BatteryString[]; extern const size_t BatteryString_Elements; -#define STARTUP_DELAY 2500 -#define SHUTDOWN_DELAY_MS 2500 - #endif diff --git a/Software/include/debugger.h b/Software/include/debugger.h index 74020ef..d618de1 100644 --- a/Software/include/debugger.h +++ b/Software/include/debugger.h @@ -1,9 +1,9 @@ /** * @file debugger.h * - * @brief Header file for debugging functions and status in the DE-Timer application. + * @brief Header file for debugging functions and status in the ChainLube application. * - * This file declares functions and status definitions for debugging purposes in the DE-Timer project. + * This file declares functions and status definitions for debugging purposes in the ChainLube project. * It includes functions to print system information, WiFi information, format EEPROM data, * handle debug messages, and manage the status of different debug ports. * @@ -16,22 +16,6 @@ #include #include "webui.h" -const char PROGMEM helpCmd[] = "sysinfo - System Info\n" - "reboot - System Reboot\n" - "netinfo - WiFi Info\n" - "formatPDS - Format Persistence EEPROM Data\n" - "formatCFG - Format Configuration EEPROM Data\n" - "checkEE - Check EEPROM with checksum\n" - "dumpEE1k - dump the first 1kb of EEPROM to Serial\n" - "dumpEE - dump the whole EPPROM to Serial\n" - "killEE - kill the first 1024 byte of EEPROM\n" - "zeroEE - zero the first 1024 byte of EEPROM\n" - "resetPageEE - Reset the PersistenceData Page\n" - "dumpCFG - print Config struct\n" - "dumpPDS - print PersistanceStruct\n" - "saveEE - save EE-Data\n" - "showdtc - Show all DTCs\n" - "dumpGlobals - print globals\n"; typedef enum DebugStatus_e { @@ -52,8 +36,14 @@ const char sDebugPorts[dbg_cntElements][7] = { extern DebugStatus_t DebuggerStatus[dbg_cntElements]; +enum LogLevel +{ + LOG_INFO, + LOG_WARN, + LOG_ERROR +}; + void initDebugger(); -void pushCANDebug(uint32_t id, uint8_t dlc, uint8_t *data); void Debug_pushMessage(const char *format, ...); void SetDebugportStatus(DebugPorts_t port, DebugStatus_t status); void Debug_Process(); diff --git a/Software/include/globals.h b/Software/include/globals.h index 6abf70a..0f031b6 100644 --- a/Software/include/globals.h +++ b/Software/include/globals.h @@ -18,6 +18,7 @@ typedef struct Globals_s int loadvoltage_mV = 0; int battery_level = 0; bool timer_disabled = false; + bool toggle_wifi = false; } Globals_t; extern Globals_t globals; /**< Global variable struct */ diff --git a/Software/src/debugger.cpp b/Software/src/debugger.cpp index b7fe3e1..b87db80 100644 --- a/Software/src/debugger.cpp +++ b/Software/src/debugger.cpp @@ -12,22 +12,15 @@ */ #include "debugger.h" +#include +#include +#include #include "utilities.h" #include DebugStatus_t DebuggerStatus[dbg_cntElements]; -// Funktionszeiger -typedef void (*CommandFunction)(); - -// Struktur zur Zuordnung von Commands zu Funktionen -struct CommandMapping -{ - const char *command; - CommandFunction function; -}; - -void processCmdDebug(const char *command); +void processCmdDebug(String command); void Debug_formatCFG(); void Debug_formatPersistence(); void Debug_printSystemInfo(); @@ -39,93 +32,9 @@ void Debug_ShowDTCs(); void Debug_dumpGlobals(); void Debug_printHelp(); void Debug_Reboot(); +void Debug_setBatteryType(int batterytype); const char *uint32_to_binary_string(uint32_t num); -// Adapter-Functions for Debug-Commands -void adapterCheckEEPOM() { Debug_CheckEEPOM(false); } -void adapterCheckEEPOMFix() { Debug_CheckEEPOM(true); } -void adapterDumpEEPROM1k() { dumpEEPROM(0, 1024); } -void adapterDumpEEPROMAll() { dumpEEPROM(0, EEPROM_SIZE_BYTES); } -void adapterKillEEPROM() { writeSequentialToEEPROM(0, 1024); } -void adapterZeroEEPROM() { writeZeroToEEPROM(0, 1024); } -void adapterResetPageEEPROM() { MovePersistencePage_EEPROM(true); } -void adapterSaveEEPROM() { globals.requestEEAction = EE_ALL_SAVE; } -void adapterSetDebugPort() { SetDebugportStatus(dbg_Serial, enabled); } -void adapterCritDTC() { MaintainDTC(DTC_FAKE_DTC_CRIT, true, millis()); } -void adapterWarnDTC() { MaintainDTC(DTC_FAKE_DTC_WARN, true, millis()); } -void adapterInfoDTC() { MaintainDTC(DTC_FAKE_DTC_INFO, true, millis()); } -void adapterNotifyError() { Websocket_PushNotification("Debug Error Notification", error); } -void adapterNotifyWarning() { Websocket_PushNotification("Debug Warning Notification", warning); } -void adapterNotifySuccess() { Websocket_PushNotification("Debug Success Notification", success); } -void adapterNotifyInfo() { Websocket_PushNotification("Debug Info Notification", info); } - -// Definition der Command-Mapping-Tabelle -const CommandMapping commandMappings[] = { - {"help", Debug_printHelp}, - {"reboot", Debug_Reboot}, - {"sysinfo", Debug_printSystemInfo}, - {"netinfo", Debug_printWifiInfo}, - {"formatCFG", Debug_formatCFG}, - {"formatPDS", Debug_formatPersistence}, - {"checkEE", adapterCheckEEPOM}, - {"checkEEfix", adapterCheckEEPOMFix}, - {"dumpEE1k", adapterDumpEEPROM1k}, - {"dumpEE", adapterDumpEEPROMAll}, - {"killEE", adapterKillEEPROM}, - {"zeroEE", adapterZeroEEPROM}, - {"resetPageEE", adapterResetPageEEPROM}, - {"dumpCFG", Debug_dumpConfig}, - {"dumpPDS", Debug_dumpPersistance}, - {"saveEE", adapterSaveEEPROM}, - {"dumpGlobals", Debug_dumpGlobals}, - {"sdbg", adapterSetDebugPort}, - {"dtc_show", Debug_ShowDTCs}, - {"dtc_clear", ClearAllDTC}, - {"dtc_crit", adapterCritDTC}, - {"dtc_warn", adapterWarnDTC}, - {"dtc_info", adapterInfoDTC}, - {"notify_error", adapterNotifyError}, - {"notify_warning", adapterNotifyWarning}, - {"notify_success", adapterNotifySuccess}, - {"notify_info", adapterNotifyInfo}, -}; - -const size_t NUM_COMMANDS = sizeof(commandMappings) / sizeof(commandMappings[0]); - -const char helpText[][64] PROGMEM = { - "help - Print this help text", - "sysinfo - System Info", - "reboot - System Reboot", - "netinfo - WiFi Info", - "formatPDS - Format Persistence EEPROM Data", - "formatCFG - Format Configuration EEPROM Data", - "checkEE - Check EEPROM with checksum", - "checkEEfix - Check and fix EEPROM with checksum", - "dumpEE1k - Dump the first 1kb of EEPROM to Serial", - "dumpEE - Dump the whole EEPROM to Serial", - "killEE - Kill the first 1024 bytes of EEPROM", - "zeroEE - Zero the first 1024 bytes of EEPROM", - "resetPageEE - Reset the PersistenceData Page", - "dumpCFG - Print Config struct", - "dumpPDS - Print PersistenceStruct", - "saveEE - Save EE-Data", - "dumpGlobals - Print globals", - "sdbg - Set debug port status", - "dtc_show - Show all DTCs", - "dtc_clear - Clear all DTCs", - "dtc_crit - Maintain critical DTC", - "dtc_warn - Maintain warning DTC", - "dtc_info - Maintain info DTC", - "notify_error - Send error notification", - "notify_warning - Send warning notification", - "notify_success - Send success notification", - "notify_info - Send info notification"}; - -const size_t NUM_HELP_LINES = sizeof(helpText) / sizeof(helpText[0]); - -// Überprüfen, ob die Anzahl der Commands und Hilfetext-Zeilen übereinstimmen -static_assert(NUM_COMMANDS == NUM_HELP_LINES, "Number of commands and help text lines do not match!"); - /** * @brief Initializes the debugger by setting the initial status for different debug ports. * Serial debug output is turned off. @@ -180,7 +89,7 @@ void Debug_Process() InputProcessed = CMD_ABORT; break; - case 0x21 ... 0x7E: // it's a real letter or sign and not some control-chars + case 0x20 ... 0x7E: // it's a real letter or sign and not some control-chars inputBuffer[inputCnt] = inputChar; inputCnt++; Serial.write(inputChar); @@ -191,10 +100,10 @@ void Debug_Process() } // Check for input buffer overflow - if (inputCnt > sizeof(inputBuffer)) + if (inputCnt >= sizeof(inputBuffer) - 1) { + inputBuffer[sizeof(inputBuffer) - 1] = '\0'; inputCnt = 0; - inputBuffer[sizeof(inputBuffer) - 1] = 0; // terminate the String InputProcessed = CMD_OVERFLOW; } } @@ -207,7 +116,7 @@ void Debug_Process() break; case CMD_COMPLETE: - processCmdDebug(inputBuffer); + processCmdDebug(String(inputBuffer)); break; case CMD_OVERFLOW: @@ -244,6 +153,27 @@ void SetDebugportStatus(DebugPorts_t port, DebugStatus_t status) Debug_pushMessage("Enabled DebugPort %s\n", sDebugPorts[port]); } +void Debug_log(LogLevel level, const char *format, ...) +{ + if ((DebuggerStatus[dbg_Serial] == enabled) || (DebuggerStatus[dbg_Webui] == enabled)) + { + char buff[128]; + va_list arg; + va_start(arg, format); + vsnprintf(buff, sizeof(buff), format, arg); + va_end(arg); + + if (DebuggerStatus[dbg_Serial] == enabled) + { + Serial.print(buff); + } + if (DebuggerStatus[dbg_Webui] == enabled) + { + Websocket_PushLiveDebug(String(buff)); + } + } +} + /** * @brief Pushes a formatted debug message to the enabled debug ports (Serial or WebUI). * @@ -277,27 +207,134 @@ void Debug_pushMessage(const char *format, ...) } } -/** - * @brief Processes a debug command and performs corresponding actions. - * - * @param command The debug command to be processed. - */ -void processCmdDebug(const char *command) +// === splitArgs Helper === +std::vector splitArgs(const String &input) { - bool commandFound = false; - for (size_t i = 0; i < NUM_COMMANDS; ++i) + std::vector tokens; + int start = 0, end = 0; + while ((end = input.indexOf(' ', start)) != -1) { - if (strcmp(command, commandMappings[i].command) == 0) - { - commandMappings[i].function(); - commandFound = true; - break; - } - } - if (!commandFound) - { - Debug_pushMessage("unknown Command\n"); + tokens.push_back(input.substring(start, end)); + start = end + 1; } + if (start < input.length()) + tokens.push_back(input.substring(start)); + return tokens; +} + +// === getArg helper === +String getArg(const std::vector &args, size_t index, const String &defaultVal = "") +{ + if (index < args.size()) + return args[index]; + return defaultVal; +} + +// === Command Handler Map === +typedef std::function DebugCmdHandler; + +static const std::map &getCmdMap() +{ + static const std::map cmdMap = { + {"help", [](const String &) + { + Debug_log(LOG_INFO, "Available commands:\n"); + for (const auto &entry : getCmdMap()) + Debug_log(LOG_INFO, " - %s\n", entry.first.c_str()); + }}, + {"sysinfo", [](const String &) + { Debug_printSystemInfo(); }}, + {"netinfo", [](const String &) + { Debug_printWifiInfo(); }}, + {"formatCFG", [](const String &) + { Debug_formatCFG(); }}, + {"formatPDS", [](const String &) + { Debug_formatPersistence(); }}, + {"checkEE", [](const String &) + { Debug_CheckEEPOM(false); }}, + {"checkEEfix", [](const String &) + { Debug_CheckEEPOM(true); }}, + {"dumpEE1k", [](const String &) + { dumpEEPROM(0, 1024); }}, + {"dumpEE", [](const String &args) + { + int start = 0, len = EEPROM_SIZE_BYTES; + auto tokens = splitArgs(args); + if (tokens.size() >= 2) + { + start = tokens[0].toInt(); + len = tokens[1].toInt(); + } + dumpEEPROM(start, len); + }}, + {"resetPageEE", [](const String &) + { MovePersistencePage_EEPROM(true); }}, + {"dumpCFG", [](const String &) + { Debug_dumpConfig(); }}, + {"dumpPDS", [](const String &) + { Debug_dumpPersistance(); }}, + {"saveEE", [](const String &) + { globals.requestEEAction = EE_ALL_SAVE; }}, + {"dumpGlobals", [](const String &) + { Debug_dumpGlobals(); }}, + {"sdbg", [](const String &) + { SetDebugportStatus(dbg_Serial, enabled); }}, + {"dtc_show", [](const String &) + { Debug_ShowDTCs(); }}, + {"dtc_clear", [](const String &) + { ClearAllDTC(); }}, + {"dtc_crit", [](const String &) + { MaintainDTC(DTC_FAKE_DTC_CRIT, true, millis()); }}, + {"dtc_warn", [](const String &) + { MaintainDTC(DTC_FAKE_DTC_WARN, true, millis()); }}, + {"dtc_info", [](const String &) + { MaintainDTC(DTC_FAKE_DTC_INFO, true, millis()); }}, + {"notify_error", [](const String &) + { Websocket_PushNotification("Debug Error Notification", error); }}, + {"notify_warning", [](const String &) + { Websocket_PushNotification("Debug Warning Notification", warning); }}, + {"notify_success", [](const String &) + { Websocket_PushNotification("Debug Success Notification", success); }}, + {"notify_info", [](const String &) + { Websocket_PushNotification("Debug Info Notification", info); }}, + {"reboot", [](const String &) + { Debug_Reboot(); }}, + {"toggle_wifi", [](const String &) + { globals.toggle_wifi = true; }}, + {"dtc_add", [](const String &args) + { + auto tokens = splitArgs(args); + if (!tokens.empty()) + { + int code = tokens[0].toInt(); + MaintainDTC((DTCNum_t)code, true, millis()); + } + }}, + {"set_battery", [](const String &args) + { + auto tokens = splitArgs(args); + if (!tokens.empty()) + { + int batteryType = tokens[0].toInt(); + Debug_setBatteryType(batteryType); + } + }}}; + return cmdMap; +} + +void processCmdDebug(String input) +{ + input.trim(); + int splitIndex = input.indexOf(' '); + String command = splitIndex == -1 ? input : input.substring(0, splitIndex); + String args = splitIndex == -1 ? "" : input.substring(splitIndex + 1); + + auto &cmdMap = getCmdMap(); + auto it = cmdMap.find(command); + if (it != cmdMap.end()) + it->second(args); + else + Debug_log(LOG_WARN, "Unknown command: '%s'\n", command.c_str()); } /** @@ -409,11 +446,31 @@ void Debug_dumpPersistance() void Debug_printWifiInfo() { char buffer[33]; - GenerateDeviceSpecificPassword(QUOTE(WIFI_PASS_SEED), buffer, sizeof(buffer)); + GenerateDeviceSpecificPassword(QUOTE(WIFI_PASS_SEED), buffer, sizeof(buffer)); Debug_pushMessage("IP Adress: %s\n", WiFi.localIP().toString().c_str()); Debug_pushMessage("WiFi AP Pw: %s\n", buffer); } +void Debug_setBatteryType(int batterytype) +{ + + switch (batterytype) + { + case 2: + ConfigData.batteryType = BATTERY_LIPO_2S; + break; + case 3: + ConfigData.batteryType = BATTERY_LIPO_3S; + break; + default: + ConfigData.batteryType = BATTERY_UNDEFINED; + break; + } + + Debug_pushMessage("Set BatteryType to : %d\n", batterytype); + globals.requestEEAction = EE_CFG_SAVE; +} + /** * @brief Checks the EEPROM data integrity by calculating and comparing checksums. * Prints the result to the debug output. @@ -471,7 +528,7 @@ void Debug_ShowDTCs() char buff_active[9]; // Header for the DTC display - Debug_pushMessage("\n timestamp | DTC-Nr. | status | debugval\n"); + Debug_pushMessage("\n timestamp | DTC-Nr. | status | severity\n"); // Iterate through DTCStorage and display each entry for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++) @@ -495,25 +552,11 @@ void Debug_ShowDTCs() strcpy(buff_active, "none"); // Display DTC information - Debug_pushMessage("%s %7d %8s %8d\n", buff_timestamp, DTCStorage[i].Number, buff_active, DTCStorage[i].debugVal); + Debug_pushMessage("%s %7d %8s %8d\n", buff_timestamp, DTCStorage[i].Number, buff_active); } } } -/** - * @brief Prints the help information stored in PROGMEM. - */ -void Debug_printHelp() -{ - char buffer[64]; - for (size_t i = 0; i < NUM_HELP_LINES; ++i) - { - strncpy_P(buffer, helpText[i], sizeof(buffer)); - buffer[sizeof(buffer) - 1] = '\0'; // Sicherstellen, dass der String nullterminiert ist - Serial.println(buffer); - } -} - /** * @brief Initiates a system reboot by setting the system status to shutdown. * diff --git a/Software/src/globals.cpp b/Software/src/globals.cpp index 00d3d2d..7b51f47 100644 --- a/Software/src/globals.cpp +++ b/Software/src/globals.cpp @@ -7,4 +7,5 @@ void initGlobals() globals.systemStatus = sysStat_Startup; globals.requestEEAction = EE_IDLE; globals.systemStatustxt[0] = 0; + globals.toggle_wifi = false; } diff --git a/Software/src/main.cpp b/Software/src/main.cpp index 50866d6..aa9a894 100644 --- a/Software/src/main.cpp +++ b/Software/src/main.cpp @@ -247,6 +247,13 @@ void loop() DTC_Process(); Debug_Process(); + if (globals.toggle_wifi == true) + { + + globals.toggle_wifi = false; + toggleWiFiAP(); + } + #if defined(FEATURE_ENABLE_LORA) || defined(FEATURE_ENABLE_UARTLORA) LoRa_Process(); tmrStatusSender.update(); @@ -269,10 +276,11 @@ void loop() lastStatus = globals.systemStatus; } // Transition to Normal status after startup delay - if (millis() > STARTUP_DELAY) + if (millis() > STARTUP_DELAY_MS) { globals.systemStatus = sysStat_Normal; globals.resumeStatus = sysStat_Normal; + Debug_pushMessage("sysstat = Normal"); } break; @@ -713,7 +721,7 @@ void ProcessKeyCombos(bool *btnState) else if (keyCount_Fac2 == 4 && keyCount_Fac3 == 0) { Debug_pushMessage("KeyCombo: Reset Timer\n"); - if (globals.systemStatus == sysStat_Startup) + if (millis() < STARTUP_DELAY_MS) { OverrideDisplay(5000, "RST ", " ", " "); PersistenceData.faction_1_timer = 0;