EEPROM changes

This commit is contained in:
Marcel Peterkau 2022-05-15 16:37:34 +02:00
parent 7b2c853b0d
commit ba90e98565
8 changed files with 258 additions and 64 deletions

View File

@ -21,6 +21,28 @@
<meta name="msapplication-config" content="static/img/browserconfig.xml">
<meta name="theme-color" content="#111111">
<script type="text/javascript">
var opacity = 0;
var intervalID = 0;
window.onload = setTimeout(() => { fadeout(); }, 4000);
function fadeout() {
intervalID = setInterval(hide, 200);
}
function hide() {
var responseMessage = document.getElementById("responseMessage");
opacity =
Number(window.getComputedStyle(responseMessage).getPropertyValue("opacity"))
if (opacity > 0) {
opacity = opacity - 0.1;
responseMessage.style.opacity = opacity
}
else {
responseMessage.remove()
clearInterval(intervalID);
}
}
</script>
</head>
<body>
@ -61,8 +83,12 @@
</p>
<h3>%DEVICE_NAME%</h3>
</div>
<!-- AlertMessageBox-->
<div id="responseMessage" class="alert alert-%RESP_MESSAGE_TYPE%" %SHOW_RESP_MESSAGE%>
%RESP_MESSAGE%
</div>
<div class="container-fluid pb-5">
<h4>Akku</h4>
<h4>BATTERY: %BATTERY_TYPE%</h4>
<div class="progress">
<div class="progress-bar text-light" role="progressbar" aria-valuenow="%BAT_REMAIN_CAPACITY%"
aria-valuemin="0" aria-valuemax="100" style="width: %BAT_REMAIN_CAPACITY%&#37;">
@ -71,13 +97,13 @@
</div>
</div>
<div class="container-fluid pb-5">
<h4>Fraktionen</h4>
<h4>FACTIONS</h4>
<div class="table-responsive">
<table class="table text-light text-center">
<thead>
<tr>
<th scope="col">Fraktion</td>
<th scope="col">Zeit</td>
<th scope="col">Faction</td>
<th scope="col">Time</td>
</tr>
</thead>
<tbody>
@ -137,11 +163,12 @@
<div class="tab-pane fade" id="tab_settings" role="tabpanel">
<h3>Settings</h3>
<hr>
<form action="\post.htm" method="POST">
<form method="POST">
<div class="form-group row">
<label for="commandInput" class="col-sm-2 col-form-label">Command</label>
<div class="col-sm-10">
<input type="text" class="form-control bg-light" id="commandInput" placeholder="type command here...">
<input type="text" name="commandInput" class="form-control bg-light" id="commandInput"
placeholder="type command here...">
</div>
</div>
<div class="form-group row">

View File

@ -22,8 +22,10 @@ board_build.ldscript = eagle.flash.4m1m.ld
monitor_filters = esp8266_exception_decoder
monitor_speed = 115200
;upload_protocol = esptool
;upload_speed = 921600
upload_port = 10.0.1.49
upload_protocol = espota
upload_port = 10.0.1.34
upload_flags =
--auth=${wifi_cred.admin_password}

View File

@ -1,28 +1,46 @@
#include "config.h"
I2C_eeprom ee(0x50, EEPROM_SIZE_BYTES);
configData_t ConfigData;
persistenceData_t PersistenceData;
uint16_t eePersistenceMarker = 0;
uint16_t eeVersion = 0; // inc
const uint16_t eeVersion = 1; // inc
boolean eeAvailable = false;
const uint16_t startofConfigData = 16;
const uint16_t startofPersistence = 16 + sizeof(startofConfigData) + (sizeof(startofConfigData) % 16);
const uint16_t persistencemarker_Adress = 0; // sizeof 4
const uint16_t startofConfig_Adress = 16;
const uint16_t startofPersistence_Adress = startofConfig_Adress + sizeof(ConfigData) + (sizeof(ConfigData) % 16);
boolean checkEEPROMavailable();
void InitEEPROM()
{
#ifdef SERIAL_DEBUG
Serial.printf("connecting I2C EEPROM");
#endif
ee.begin();
if (!ee.isConnected())
if (!checkEEPROMavailable())
{
globals.systemStatus = sysStat_Error;
MaintainDTC(DTC_NO_EEPROM_FOUND, true);
return;
}
GetConfig_EEPROM();
if (ConfigData.EEPROM_Version != eeVersion)
{
FormatConfig_EEPROM();
globals.systemStatus = sysStat_Error;
MaintainDTC(DTC_EEPROM_VERSION_BAD, true);
return;
}
if (getPersistanceAddress() > ee.getDeviceSize())
{
FormatPersistence_EEPROM();
globals.systemStatus = sysStat_Error;
MaintainDTC(DTC_EEPROM_PDS_MARKER_INVALID, true);
return;
}
GetPersistence_EEPROM();
}
void EEPROM_Process()
{
@ -55,18 +73,18 @@ void StoreConfig_EEPROM()
{
ConfigData.checksum = 0;
ConfigData.checksum = Checksum_EEPROM((uint8_t *)&ConfigData, sizeof(ConfigData));
if (!ee.isConnected())
if (!checkEEPROMavailable())
return;
ee.updateBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData));
ee.updateBlock(startofConfig_Adress, (uint8_t *)&ConfigData, sizeof(ConfigData));
}
void GetConfig_EEPROM()
{
if (!ee.isConnected())
if (!checkEEPROMavailable())
return;
ee.readBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData));
ee.readBlock(startofConfig_Adress, (uint8_t *)&ConfigData, sizeof(ConfigData));
uint32_t checksum = ConfigData.checksum;
ConfigData.checksum = 0;
@ -79,14 +97,21 @@ void GetConfig_EEPROM()
ConfigData.checksum = checksum;
}
uint16_t getPersistanceAddress()
uint32_t getPersistanceAddress()
{
return startofPersistence + eePersistenceMarker;
uint32_t eePersistenceMarker;
ee.readBlock(persistencemarker_Adress, (uint8_t *)&eePersistenceMarker, sizeof(eePersistenceMarker));
return eePersistenceMarker;
}
void updatePersistanceAddress(uint32_t adress)
{
ee.updateBlock(persistencemarker_Adress, (uint8_t *)&adress, sizeof(adress));
}
void StorePersistence_EEPROM()
{
if (PersistenceData.writeCycleCounter >= 0xFFF0)
if (PersistenceData.writeCycleCounter >= EEPROM_ENDURANCE)
MovePersistencePage_EEPROM(false);
else
PersistenceData.writeCycleCounter++;
@ -94,17 +119,17 @@ void StorePersistence_EEPROM()
PersistenceData.checksum = 0;
PersistenceData.checksum = Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData));
if (!ee.isConnected())
if (!checkEEPROMavailable())
return;
ee.updateBlock(getPersistanceAddress(), (uint8_t *)&PersistenceData, sizeof(PersistenceData));
}
void GetPersistence_EEPROM()
{
if (!ee.isConnected())
if (!checkEEPROMavailable())
return;
eePersistenceMarker = (ee.readByte(0) << 8) | ee.readByte(1);
ee.readBlock(getPersistanceAddress(), (uint8_t *)&PersistenceData, sizeof(PersistenceData));
uint32_t checksum = PersistenceData.checksum;
@ -122,6 +147,7 @@ void FormatConfig_EEPROM()
{
configData_t defaults;
ConfigData = defaults;
ConfigData.EEPROM_Version = eeVersion;
StoreConfig_EEPROM();
}
@ -129,19 +155,40 @@ void FormatPersistence_EEPROM()
{
persistenceData_t defaults;
PersistenceData = defaults;
eePersistenceMarker = 0;
updatePersistanceAddress(startofPersistence_Adress);
StorePersistence_EEPROM();
}
void MovePersistencePage_EEPROM(boolean reset)
{
eePersistenceMarker = reset ? sizeof(PersistenceData) : eePersistenceMarker + sizeof(PersistenceData);
PersistenceData.writeCycleCounter = 0;
if (!ee.isConnected())
if (!checkEEPROMavailable())
return;
ee.updateByte(0, (uint8_t)(eePersistenceMarker >> 8));
ee.updateByte(1, (uint8_t)(eePersistenceMarker & 0xFF));
if (reset)
{
updatePersistanceAddress(startofPersistence_Adress);
}
else
{
uint32_t newPersistenceMarker = getPersistanceAddress() + sizeof(PersistenceData);
// check if we reached the End of the EEPROM and Startover at the beginning
if ((newPersistenceMarker + sizeof(PersistenceData)) > ee.getDeviceSize())
{
MaintainDTC(DTC_EEPROM_WORNOUT, true);
return;
}
else
{
updatePersistanceAddress(newPersistenceMarker);
PersistenceData.writeCycleCounter = 0;
}
}
}
uint32_t GetEESize()
{
return ee.getDeviceSize();
}
uint32_t Checksum_EEPROM(uint8_t const *data, size_t len)
@ -167,7 +214,13 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
{
#define BLOCK_TO_LENGTH 16
if (!ee.isConnected())
if (length > ee.getDeviceSize())
length = ee.getDeviceSize();
if (memoryAddress + length > ee.getDeviceSize())
return;
if (!checkEEPROMavailable())
return;
char ascii_buf[BLOCK_TO_LENGTH + 1];
@ -196,3 +249,13 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
}
Serial.println();
}
boolean checkEEPROMavailable()
{
if (!ee.isConnected())
{
MaintainDTC(DTC_NO_EEPROM_FOUND, true);
return false;
}
return true;
}

View File

@ -8,7 +8,8 @@
#include "globals.h"
#include "dtc.h"
#define EEPROM_SIZE_BYTES I2C_DEVICESIZE_24LC256
#define EEPROM_SIZE_BYTES I2C_DEVICESIZE_24LC01
#define EEPROM_ENDURANCE 1000000
typedef enum
{
@ -20,7 +21,7 @@ typedef enum
typedef struct
{
uint16_t writeCycleCounter = 0;
uint32_t writeCycleCounter = 0;
uint32_t faction_1_timer = 0;
uint32_t faction_2_timer = 0;
uint32_t faction_3_timer = 0;
@ -28,8 +29,23 @@ typedef struct
uint32_t checksum = 0;
} persistenceData_t;
typedef enum
{
BATTERY_UNDEFINED,
BATTERY_LIPO_2S,
BATTERY_LIPO_3S
} batteryType_t;
const char BatteryString[][10]{
"Undefined",
"LiPo 2S",
"LiPo 3S"
};
typedef struct
{
uint8_t EEPROM_Version = 1;
batteryType_t batteryType = BATTERY_UNDEFINED;
uint32_t checksum = 0;
} configData_t;
@ -44,9 +60,10 @@ void FormatPersistence_EEPROM();
uint32_t Checksum_EEPROM(uint8_t const *data, size_t len);
void dumpEEPROM(uint16_t memoryAddress, uint16_t length);
void MovePersistencePage_EEPROM(boolean reset);
uint16_t getPersistanceAddress();
uint32_t getPersistanceAddress();
void updatePersistanceAddress(uint32_t adress);
uint32_t GetEESize();
extern configData_t ConfigData;
extern persistenceData_t PersistenceData;
extern uint16_t eePersistenceMarker;
#endif // _CONFIG_H_

View File

@ -10,6 +10,9 @@ typedef enum DTCNums_e
DTC_NO_EEPROM_FOUND,
DTC_EEPROM_CFG_BAD,
DTC_EEPROM_PDS_BAD,
DTC_EEPROM_VERSION_BAD,
DTC_EEPROM_WORNOUT, // this will happen if the EEPROM-cells are all overwritten 1 million times!
DTC_EEPROM_PDS_MARKER_INVALID, // This happens if the Marker of the PersistanceData was pointing to an EE-Adress bigger than the used EEPROM-IC
DTC_LAST_DTC
} DTCNums_t;

View File

@ -44,6 +44,7 @@ void powerMonitorTicker_callback();
void EEPROMCyclicPDS_callback();
void toggleWiFiAP(boolean shutdown = false);
void SystemShutdown();
void SetBatteryType(batteryType_t type);
#ifdef REMOTE_DEBUG
RemoteDebug Debug;
@ -141,8 +142,6 @@ void setup()
#endif
InitEEPROM();
GetConfig_EEPROM();
GetPersistence_EEPROM();
ArduinoOTA.setPort(8266);
ArduinoOTA.setHostname(globals.DeviceName_ID);
@ -152,7 +151,7 @@ void setup()
{
const uint8_t seg_ota[] = {0x3F, 0x78, 0x77, 0x00};
const uint8_t seg_flsh[] = {0x71, 0x38, 0x6D, 0x76};
const uint8_t seg_fs[] = {0x71, 0x6D, 0x00, 0x00};
const uint8_t seg_file[] = {0x71, 0x30, 0x38, 0x79};
disp_FAC_1.setBrightness(7);
disp_FAC_2.setBrightness(7);
@ -166,7 +165,7 @@ void setup()
}
else
{
disp_FAC_2.setSegments(seg_fs);
disp_FAC_2.setSegments(seg_file);
LittleFS.end();
} });
@ -319,6 +318,11 @@ void powerMonitorTicker_callback()
{
// loadvoltage and percentage is global, because of battery Monitoring
const int bat_min_2s = 680;
const int bat_max_2s = 840;
const int bat_min_3s = 1020;
const int bat_max_3s = 1260;
float shuntvoltage = 0;
float current_mA = 0;
float busvoltage = 0;
@ -330,8 +334,20 @@ void powerMonitorTicker_callback()
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
globals.loadvoltage = busvoltage + (shuntvoltage / 1000);
battery_level = map(globals.loadvoltage * 100, 655, 840, 0, 100);
switch (ConfigData.batteryType)
{
case BATTERY_LIPO_2S:
battery_level = map(globals.loadvoltage * 100, bat_min_2s, bat_max_2s, 0, 100);
globals.battery_level = battery_level < 0 ? 0 : battery_level;
break;
case BATTERY_LIPO_3S:
battery_level = map(globals.loadvoltage * 100, bat_min_3s, bat_max_3s, 0, 100);
globals.battery_level = battery_level < 0 ? 0 : battery_level;
break;
default:
globals.battery_level = -1;
break;
}
debugV("Battery Level: %d %%", globals.battery_level);
debugV("Bus Voltage: %f V", busvoltage);
@ -421,6 +437,10 @@ void processCmdRemoteDebug()
StoreConfig_EEPROM();
else if (lastCmd == "showdtc")
RemoteDebug_ShowDTCs();
else if (lastCmd == "bat_3s")
SetBatteryType(BATTERY_LIPO_3S);
else if (lastCmd == "bat_2s")
SetBatteryType(BATTERY_LIPO_2S);
}
void RemoteDebug_formatCFG()
@ -455,10 +475,13 @@ void RemotDebug_printSystemInfo()
: "UNKNOWN"));
debugA("OTA-Pass: %s", QUOTE(ADMIN_PASSWORD));
debugA("Git-Revison: %s", GIT_REV);
debugA("I2C EEPROM Size: %d", GetEESize());
}
void RemoteDebug_dumpConfig()
{
debugA("EEPROM_Version: %d", ConfigData.EEPROM_Version);
debugA("BatteryType: %d", ConfigData.batteryType);
debugA("checksum: 0x%08X", ConfigData.checksum);
}
@ -535,3 +558,13 @@ void RemoteDebug_ShowDTCs()
}
}
#endif
void SetBatteryType(batteryType_t type)
{
if (ConfigData.batteryType != type)
{
ConfigData.batteryType = type;
globals.requestEEAction = EE_CFG_SAVE;
debugV("Set Batterytype to %s", type == BATTERY_LIPO_2S ? "2s Lipo" : "3s LiPo");
}
}

View File

@ -10,4 +10,7 @@ const char helpCmd[] = "sysinfo - System Info\r\n"
"resetPageEE - Reset the PersistenceData Page\r\n"
"dumpCFG - print Config struct\r\n"
"dumpPDS - print PersistanceStruct\r\n"
"saveEE - save EE-Data\r\n";
"saveEE - save EE-Data\r\n"
"bat_3s - set BatteryType to 3S LiPo\r\n"
"bat_2s - set BatteryType to 2S LiPo\r\n"
;

View File

@ -2,12 +2,22 @@
AsyncWebServer webServer(80);
const char *PARAM_MESSAGE = "message";
typedef enum
{
RESPMSG_HIDE,
RESPMSG_SUCCESS,
RESPMSG_INFO,
RESPMSG_WARNING,
RESPMSG_DANGER
} statusResponseMessage_Type_t;
char StatusResponseMessage[64];
statusResponseMessage_Type_t StatusResponseMessage_Type = RESPMSG_INFO;
String processor(const String &var);
void WebserverPOST_Callback(AsyncWebServerRequest *request);
void WebserverNotFound_Callback(AsyncWebServerRequest *request);
void Webserver_Callback(AsyncWebServerRequest *request);
void WebserverCommands_Callback(String input);
void initWebUI()
{
@ -22,7 +32,7 @@ void initWebUI()
{ request->redirect("/index.htm"); });
webServer.onNotFound(WebserverNotFound_Callback);
webServer.on("/index.htm", HTTP_GET, Webserver_Callback);
webServer.on("/post.htm", HTTP_POST, WebserverPOST_Callback);
webServer.on("/index.htm", HTTP_POST, WebserverPOST_Callback);
webServer.begin();
}
@ -32,6 +42,29 @@ String processor(const String &var)
if (var == "SHOW_DTC_TABLE")
return globals.systemStatus == sysStat_Error ? "" : "hidden";
if (var == "SHOW_RESP_MESSAGE")
return StatusResponseMessage_Type != RESPMSG_HIDE ? "" : "hidden";
if (var == "RESP_MESSAGE_TYPE")
{
switch (StatusResponseMessage_Type)
{
case RESPMSG_SUCCESS:
return "success";
case RESPMSG_INFO:
return "info";
case RESPMSG_WARNING:
return "warning";
case RESPMSG_DANGER:
return "danger";
default:
return "info";
}
}
if (var == "RESP_MESSAGE")
return String(StatusResponseMessage);
if (var == "BAT_REMAIN_CAPACITY")
return String(globals.battery_level);
@ -122,6 +155,10 @@ String processor(const String &var)
{
return String(globals.battery_level);
}
if (var == "BATTERY_TYPE")
{
return String(BatteryString[ConfigData.batteryType]);
}
if (var == "BATTERY_VOLTAGE")
{
return String(globals.loadvoltage);
@ -133,30 +170,39 @@ String processor(const String &var)
void Webserver_Callback(AsyncWebServerRequest *request)
{
request->send(LittleFS, "/index.htm", "text/html", false, processor);
StatusResponseMessage_Type = RESPMSG_HIDE;
}
void WebserverPOST_Callback(AsyncWebServerRequest *request)
{
request->send(LittleFS, "/post.htm", "text/html", false, processor);
Serial.print("POST:\n");
int paramsNr = request->params();
for (int i = 0; i < paramsNr; i++)
{
AsyncWebParameter *p = request->getParam(i);
Serial.printf("%s : %s\n", p->name().c_str(), p->value().c_str());
if (p->name() == "resetcount")
{
PersistenceData.faction_1_timer = 0;
PersistenceData.faction_2_timer = 0;
PersistenceData.faction_3_timer = 0;
globals.requestEEAction = EE_PDS_SAVE;
}
if (p->name() == "commandInput")
WebserverCommands_Callback(p->value());
}
request->send(LittleFS, "/index.htm", "text/html", false, processor);
}
void WebserverNotFound_Callback(AsyncWebServerRequest *request)
{
request->send(404, "text/html", "Not found");
}
void WebserverCommands_Callback(String input)
{
String command = input.substring(0, input.indexOf(' '));
StatusResponseMessage_Type = RESPMSG_HIDE;
if (command == "reset")
{
strcpy(StatusResponseMessage, "Counter Reset done");
StatusResponseMessage_Type = RESPMSG_SUCCESS;
PersistenceData.faction_1_timer = 0;
PersistenceData.faction_2_timer = 0;
PersistenceData.faction_3_timer = 0;
PersistenceData.activeFaction = NONE;
}
}