diff --git a/Software/data_src/static/tt_dtc/dtc_13.json b/Software/data_src/static/tt_dtc/dtc_13.json new file mode 100644 index 0000000..a4bf6f4 --- /dev/null +++ b/Software/data_src/static/tt_dtc/dtc_13.json @@ -0,0 +1,4 @@ +{ + "title": "EEPROM-Migration failed", + "description": "Migration of EEPROM-Image from an other FW-Version failed - you need to reset everything manually!" +} \ No newline at end of file diff --git a/Software/include/dtc.h b/Software/include/dtc.h index 78ab1af..d86fbb1 100644 --- a/Software/include/dtc.h +++ b/Software/include/dtc.h @@ -19,6 +19,7 @@ typedef enum DTCNums_e DTC_NO_BATMNON_FOUND, DTC_BAT_LOW, DTC_BAT_CRITICAL, + DTC_EEPROM_MIGRATE_FAILED, DTC_LAST_DTC } DTCNums_t; diff --git a/Software/include/config.h b/Software/include/eeprom.h similarity index 61% rename from Software/include/config.h rename to Software/include/eeprom.h index eeb282a..5c99d5e 100644 --- a/Software/include/config.h +++ b/Software/include/eeprom.h @@ -1,5 +1,5 @@ -#ifndef _CONFIG_H_ -#define _CONFIG_H_ +#ifndef _EEPROM_H_ +#define _EEPROM_H_ #include <Arduino.h> #include <Wire.h> @@ -8,6 +8,7 @@ #include "globals.h" #include "dtc.h" #include "common.h" +#include "debugger.h" #define EEPROM_SIZE_BYTES I2C_DEVICESIZE_24LC64 #define EEPROM_ENDURANCE 1000000 @@ -38,25 +39,36 @@ typedef enum } batteryType_t; const char BatteryString[][10]{ - "Undefined", - "LiPo 2S", - "LiPo 3S" -}; + "Undefined", + "LiPo 2S", + "LiPo 3S"}; const size_t BatteryString_Elements = sizeof(BatteryString) / sizeof(BatteryString[0]); typedef struct { - uint8_t EEPROM_Version = 1; - batteryType_t batteryType = BATTERY_UNDEFINED; - bool active_faction_on_reboot = false; - uint32_t checksum = 0; + uint8_t EEPROM_Version; + batteryType_t batteryType; + bool active_faction_on_reboot; + char Faction_1_Name[32]; + char Faction_2_Name[32]; + char Faction_3_Name[32]; + uint32_t checksum; } configData_t; const configData_t ConfigData_defaults = { - 0, BATTERY_LIPO_3S, 0 + 2, // EEPROM_Version (incerease this if anything on Layout changes!) + BATTERY_LIPO_3S, // batteryType + false, // active_faction_on_reboot + "FACTION 1", // Faction_1_Name + "FACTION 2", // Faction_2_Name + "FACTION 3", // Faction_3_Name + 0 // checksum }; +const uint16_t startofConfigData = 16; +const uint16_t startofPersistence = 16 + sizeof(ConfigData) + (sizeof(ConfigData) % 16); + void InitEEPROM(); void EEPROM_Process(); void StoreConfig_EEPROM(); @@ -72,4 +84,5 @@ uint32_t ConfigSanityCheck(bool autocorrect = false); extern configData_t ConfigData; extern persistenceData_t PersistenceData; -#endif // _CONFIG_H_ \ No newline at end of file + +#endif // _EEPROM_H_ \ No newline at end of file diff --git a/Software/include/oled_display.h b/Software/include/oled_display.h index cacaf63..3e25d9a 100644 --- a/Software/include/oled_display.h +++ b/Software/include/oled_display.h @@ -6,7 +6,7 @@ #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include "globals.h" -#include "config.h" +#include "eeprom.h" #define OLED_SDA 4 #define OLED_SCL 15 diff --git a/Software/include/webui.h b/Software/include/webui.h index 41e52ec..5f1d83e 100644 --- a/Software/include/webui.h +++ b/Software/include/webui.h @@ -11,7 +11,7 @@ #include <AsyncJson.h> #include <ArduinoJson.h> -#include "config.h" +#include "eeprom.h" #include "globals.h" #include "dtc.h" #include "common.h" diff --git a/Software/src/config.cpp b/Software/src/eeprom.cpp similarity index 61% rename from Software/src/config.cpp rename to Software/src/eeprom.cpp index 9e3fe6d..14ea657 100644 --- a/Software/src/config.cpp +++ b/Software/src/eeprom.cpp @@ -1,25 +1,27 @@ -#include "config.h" +#include "eeprom.h" I2C_eeprom ee(0x50, EEPROM_SIZE_BYTES); configData_t ConfigData; persistenceData_t PersistenceData; -const uint16_t eeVersion = 1; // inc -boolean eeAvailable = false; +bool eeAvailable = false; -const uint16_t startofConfigData = 16; -const uint16_t startofPersistence = 16 + sizeof(ConfigData) + (sizeof(ConfigData) % 16); - -boolean checkEEPROMavailable(); +bool checkEEPROMavailable(); +bool ValidateEEPROM_Version(); +bool MigrateEEPROM(uint8_t fromVersion); void InitEEPROM() { ee.begin(); - checkEEPROMavailable(); + eeAvailable = checkEEPROMavailable(); + eeAvailable = ValidateEEPROM_Version(); } void EEPROM_Process() { + if (eeAvailable == false) + return; + switch (globals.requestEEAction) { case EE_CFG_SAVE: @@ -75,7 +77,8 @@ void StoreConfig_EEPROM() { ConfigData.checksum = 0; ConfigData.checksum = Checksum_EEPROM((uint8_t *)&ConfigData, sizeof(ConfigData)); - if (!checkEEPROMavailable()) + + if (eeAvailable == false) return; ee.updateBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData)); @@ -83,7 +86,7 @@ void StoreConfig_EEPROM() void GetConfig_EEPROM() { - if (!checkEEPROMavailable()) + if (eeAvailable == false) return; ee.readBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData)); @@ -108,23 +111,23 @@ void GetConfig_EEPROM() void StorePersistence_EEPROM() { + PersistenceData.checksum = 0; + PersistenceData.checksum = Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)); + + if (eeAvailable == false) + return; + if (PersistenceData.writeCycleCounter >= 0xFFF0) MovePersistencePage_EEPROM(false); else PersistenceData.writeCycleCounter++; - PersistenceData.checksum = 0; - PersistenceData.checksum = Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)); - - if (!checkEEPROMavailable()) - return; - ee.updateBlock(globals.eePersistanceAdress, (uint8_t *)&PersistenceData, sizeof(PersistenceData)); } void GetPersistence_EEPROM() { - if (!checkEEPROMavailable()) + if (eeAvailable == false) return; ee.readBlock(0, (uint8_t *)&globals.eePersistanceAdress, sizeof(globals.eePersistanceAdress)); @@ -153,14 +156,19 @@ void GetPersistence_EEPROM() void FormatConfig_EEPROM() { + if (eeAvailable == false) + return; + Serial.println("Formatting Config-Partition"); ConfigData = ConfigData_defaults; - ConfigData.EEPROM_Version = eeVersion; StoreConfig_EEPROM(); } void FormatPersistence_EEPROM() { + if (eeAvailable == false) + return; + Serial.println("Formatting Persistance-Partition"); memset(&PersistenceData, 0, sizeof(PersistenceData)); StorePersistence_EEPROM(); @@ -168,7 +176,7 @@ void FormatPersistence_EEPROM() void MovePersistencePage_EEPROM(boolean reset) { - if (!checkEEPROMavailable()) + if (eeAvailable == false) return; globals.eePersistanceAdress = +sizeof(PersistenceData); @@ -206,7 +214,7 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length) { #define BLOCK_TO_LENGTH 16 - if (!checkEEPROMavailable()) + if (eeAvailable == false) return; char ascii_buf[BLOCK_TO_LENGTH + 1]; @@ -236,15 +244,13 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length) Serial.println(); } -boolean checkEEPROMavailable() +bool checkEEPROMavailable() { if (!ee.isConnected()) { MaintainDTC(DTC_NO_EEPROM_FOUND, DTC_CRITICAL, true); - globals.systemStatus = sysStat_Error; return false; } - MaintainDTC(DTC_NO_EEPROM_FOUND, DTC_CRITICAL, false); return true; } @@ -260,4 +266,88 @@ uint32_t ConfigSanityCheck(bool autocorrect) } return setting_reset_bits; +} + +bool ValidateEEPROM_Version() +{ + if (eeAvailable == false) + return false; + + uint8_t EEPROMVersionOnChip = ee.readByte(startofConfigData); + + if (EEPROMVersionOnChip < ConfigData_defaults.EEPROM_Version) + { + Serial.printf("EEPROM Image Version is %d, but %d expected - trying to migrate\n"); + if (!MigrateEEPROM(EEPROMVersionOnChip)) + { + Serial.print("Error\n"); + MaintainDTC(DTC_EEPROM_MIGRATE_FAILED, DTC_CRITICAL, true, EEPROMVersionOnChip); + return false; + } + else + { + Serial.print("Success\n"); + } + } + return true; +} + +bool MigrateEEPROM(uint8_t fromVersion) +{ + uint16_t persistanceMarker_onChip; + + switch (fromVersion) + { + + // Version 1 EEPROM Layout: startAdress size (byte) + // const uint16_t startofConfigData = 16 16 + // const uint16_t startofPersistence = 32 24 + // + // typedef struct + // { + // uint8_t EEPROM_Version = 1; 16 1 + // batteryType_t batteryType = BATTERY_UNDEFINED; 17 4 + // bool active_faction_on_reboot = false; 21 1 + // uint32_t checksum = 0; 22 4 + // } configData_t; + // + // typedef struct offset + // { + // uint32_t writeCycleCounter = 0; 0 4 + // uint32_t faction_1_timer = 0; 4 4 + // uint32_t faction_2_timer = 0; 8 4 + // uint32_t faction_3_timer = 0; 12 4 + // factions_t activeFaction = NONE; 16 4 + // uint32_t checksum = 0; 20 4 + // } persistenceData_t; + + case 1: + // Migrate Config-Data and set defaults for Values which doesn't exists in this earlier Version + ConfigData.EEPROM_Version = ConfigData_defaults.EEPROM_Version; + strncpy(ConfigData.Faction_1_Name, ConfigData_defaults.Faction_1_Name, sizeof(ConfigData.Faction_1_Name)); + strncpy(ConfigData.Faction_2_Name, ConfigData_defaults.Faction_2_Name, sizeof(ConfigData.Faction_2_Name)); + strncpy(ConfigData.Faction_3_Name, ConfigData_defaults.Faction_3_Name, sizeof(ConfigData.Faction_3_Name)); + ee.readBlock(17, (uint8_t *)&ConfigData.batteryType, 4); + ee.readBlock(21, (uint8_t *)ConfigData.active_faction_on_reboot, 1); + + // Migrate Persistance-Data + ee.readBlock(0, (uint8_t *)&persistanceMarker_onChip, sizeof(uint16_t)); + if (persistanceMarker_onChip < startofPersistence) + { + ee.readBlock(persistanceMarker_onChip + 0, (uint8_t *)PersistenceData.writeCycleCounter, 4); + ee.readBlock(persistanceMarker_onChip + 4, (uint8_t *)PersistenceData.faction_1_timer, 4); + ee.readBlock(persistanceMarker_onChip + 8, (uint8_t *)PersistenceData.faction_2_timer, 4); + ee.readBlock(persistanceMarker_onChip + 12, (uint8_t *)PersistenceData.faction_3_timer, 4); + ee.readBlock(persistanceMarker_onChip + 16, (uint8_t *)PersistenceData.activeFaction, 4); + ee.readBlock(persistanceMarker_onChip + 20, (uint8_t *)PersistenceData.checksum, 4); + MovePersistencePage_EEPROM(true); + } + + return true; + break; + + default: + return false; + break; + } } \ No newline at end of file