364 lines
10 KiB
C++
364 lines
10 KiB
C++
#include "config.h"
|
|
#include "debugger.h"
|
|
|
|
I2C_eeprom ee(0x50, EEPROM_SIZE_BYTES);
|
|
|
|
LubeConfig_t LubeConfig;
|
|
persistenceData_t PersistenceData;
|
|
const uint16_t eeVersion = 2; // inc
|
|
boolean eeAvailable = false;
|
|
|
|
const uint16_t startofLubeConfig = 16;
|
|
const uint16_t startofPersistence = 16 + sizeof(LubeConfig) + (sizeof(LubeConfig) % 16);
|
|
|
|
boolean checkEEPROMavailable();
|
|
|
|
void InitEEPROM()
|
|
{
|
|
ee.begin();
|
|
checkEEPROMavailable();
|
|
}
|
|
|
|
void EEPROM_Process()
|
|
{
|
|
switch (globals.requestEEAction)
|
|
{
|
|
case EE_CFG_SAVE:
|
|
StoreConfig_EEPROM();
|
|
globals.requestEEAction = EE_IDLE;
|
|
Debug_pushMessage("Stored EEPROM CFG\n");
|
|
break;
|
|
case EE_CFG_LOAD:
|
|
GetConfig_EEPROM();
|
|
globals.requestEEAction = EE_IDLE;
|
|
Debug_pushMessage("Loaded EEPROM CFG\n");
|
|
break;
|
|
case EE_CFG_FORMAT:
|
|
FormatConfig_EEPROM();
|
|
globals.requestEEAction = EE_IDLE;
|
|
GetConfig_EEPROM();
|
|
Debug_pushMessage("Formated EEPROM CFG\n");
|
|
break;
|
|
case EE_PDS_SAVE:
|
|
StorePersistence_EEPROM();
|
|
globals.requestEEAction = EE_IDLE;
|
|
Debug_pushMessage("Stored EEPROM PDS\n");
|
|
break;
|
|
case EE_PDS_LOAD:
|
|
GetPersistence_EEPROM();
|
|
globals.requestEEAction = EE_IDLE;
|
|
Debug_pushMessage("Loaded EEPROM PDS\n");
|
|
break;
|
|
case EE_PDS_FORMAT:
|
|
FormatPersistence_EEPROM();
|
|
globals.requestEEAction = EE_IDLE;
|
|
GetPersistence_EEPROM();
|
|
Debug_pushMessage("Formated EEPROM PDS\n");
|
|
break;
|
|
case EE_FORMAT_ALL:
|
|
FormatConfig_EEPROM();
|
|
FormatPersistence_EEPROM();
|
|
GetConfig_EEPROM();
|
|
GetPersistence_EEPROM();
|
|
globals.requestEEAction = EE_IDLE;
|
|
Debug_pushMessage("Formated EEPROM ALL\n");
|
|
break;
|
|
case EE_ALL_SAVE:
|
|
StorePersistence_EEPROM();
|
|
StoreConfig_EEPROM();
|
|
globals.requestEEAction = EE_IDLE;
|
|
Debug_pushMessage("Stored EEPROM ALL\n");
|
|
break;
|
|
case EE_IDLE:
|
|
default:
|
|
globals.requestEEAction = EE_IDLE;
|
|
}
|
|
}
|
|
|
|
void StoreConfig_EEPROM()
|
|
{
|
|
LubeConfig.checksum = 0;
|
|
LubeConfig.checksum = Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig));
|
|
if (!checkEEPROMavailable())
|
|
return;
|
|
|
|
ee.updateBlock(startofLubeConfig, (uint8_t *)&LubeConfig, sizeof(LubeConfig));
|
|
|
|
uint32_t ConfigSanityCheckResult = ConfigSanityCheck(false);
|
|
if (ConfigSanityCheckResult > 0)
|
|
{
|
|
MaintainDTC(DTC_EEPROM_CFG_SANITY, true, ConfigSanityCheckResult);
|
|
}
|
|
}
|
|
|
|
void GetConfig_EEPROM()
|
|
{
|
|
if (!checkEEPROMavailable())
|
|
return;
|
|
|
|
ee.readBlock(startofLubeConfig, (uint8_t *)&LubeConfig, sizeof(LubeConfig));
|
|
|
|
uint32_t checksum = LubeConfig.checksum;
|
|
LubeConfig.checksum = 0;
|
|
|
|
if (Checksum_EEPROM((uint8_t *)&LubeConfig, sizeof(LubeConfig)) != checksum)
|
|
{
|
|
MaintainDTC(DTC_EEPROM_CFG_BAD, true);
|
|
}
|
|
LubeConfig.checksum = checksum;
|
|
|
|
uint32_t ConfigSanityCheckResult = ConfigSanityCheck(false);
|
|
if (ConfigSanityCheckResult > 0)
|
|
{
|
|
MaintainDTC(DTC_EEPROM_CFG_SANITY, true, ConfigSanityCheckResult);
|
|
}
|
|
}
|
|
|
|
void StorePersistence_EEPROM()
|
|
{
|
|
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())
|
|
return;
|
|
|
|
ee.readBlock(0, (uint8_t *)&globals.eePersistanceAdress, sizeof(globals.eePersistanceAdress));
|
|
// if we got the StartAdress of Persistance and it's out of Range - we Reset it and store defaults
|
|
// otherwise we Read from eeprom and check if everything is correct
|
|
if (globals.eePersistanceAdress < startofPersistence || globals.eePersistanceAdress > ee.getDeviceSize())
|
|
{
|
|
MovePersistencePage_EEPROM(true);
|
|
FormatPersistence_EEPROM();
|
|
MaintainDTC(DTC_EEPROM_PDSADRESS_BAD, true);
|
|
}
|
|
else
|
|
{
|
|
ee.readBlock(globals.eePersistanceAdress, (uint8_t *)&PersistenceData, sizeof(PersistenceData));
|
|
|
|
uint32_t checksum = PersistenceData.checksum;
|
|
PersistenceData.checksum = 0;
|
|
|
|
if (Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) != checksum)
|
|
{
|
|
MaintainDTC(DTC_EEPROM_PDS_BAD, true);
|
|
}
|
|
PersistenceData.checksum = checksum;
|
|
}
|
|
}
|
|
|
|
void FormatConfig_EEPROM()
|
|
{
|
|
Debug_pushMessage("Formatting Config-Partition\n");
|
|
LubeConfig = LubeConfig_defaults;
|
|
LubeConfig.EEPROM_Version = eeVersion;
|
|
StoreConfig_EEPROM();
|
|
}
|
|
|
|
void FormatPersistence_EEPROM()
|
|
{
|
|
Debug_pushMessage("Formatting Persistance-Partition\n");
|
|
PersistenceData = {0};
|
|
// memset(&PersistenceData, 0, sizeof(PersistenceData));
|
|
StorePersistence_EEPROM();
|
|
}
|
|
|
|
void MovePersistencePage_EEPROM(boolean reset)
|
|
{
|
|
if (!checkEEPROMavailable())
|
|
return;
|
|
|
|
globals.eePersistanceAdress += sizeof(PersistenceData);
|
|
PersistenceData.writeCycleCounter = 0;
|
|
|
|
// check if we reached the End of the EEPROM and Startover at the beginning
|
|
if ((globals.eePersistanceAdress + sizeof(PersistenceData)) > ee.getDeviceSize() || reset)
|
|
{
|
|
globals.eePersistanceAdress = startofPersistence;
|
|
}
|
|
|
|
ee.updateBlock(0, (uint8_t *)&globals.eePersistanceAdress, sizeof(globals.eePersistanceAdress));
|
|
}
|
|
|
|
uint32_t Checksum_EEPROM(uint8_t const *data, size_t len)
|
|
{
|
|
if (data == NULL)
|
|
return 0;
|
|
uint32_t crc, mask;
|
|
crc = 0xFFFFFFFF;
|
|
|
|
while (len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (uint8_t k = 0; k < 8; k++)
|
|
{
|
|
mask = -(crc & 1);
|
|
crc = (crc >> 1) ^ (0xEDB88320 & mask);
|
|
}
|
|
}
|
|
return ~crc;
|
|
}
|
|
|
|
void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
|
|
{
|
|
#define BLOCK_TO_LENGTH 16
|
|
|
|
if (!checkEEPROMavailable())
|
|
return;
|
|
|
|
char ascii_buf[BLOCK_TO_LENGTH + 1];
|
|
sprintf(ascii_buf, "%*s", BLOCK_TO_LENGTH, "ASCII");
|
|
Debug_pushMessage(PSTR("\nAddress "));
|
|
for (int x = 0; x < BLOCK_TO_LENGTH; x++)
|
|
Debug_pushMessage("%3d", x);
|
|
|
|
memoryAddress = memoryAddress / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
|
|
length = (length + BLOCK_TO_LENGTH - 1) / BLOCK_TO_LENGTH * BLOCK_TO_LENGTH;
|
|
|
|
for (unsigned int i = 0; i < length; i++)
|
|
{
|
|
int blockpoint = memoryAddress % BLOCK_TO_LENGTH;
|
|
if (blockpoint == 0)
|
|
{
|
|
ascii_buf[BLOCK_TO_LENGTH] = 0;
|
|
Debug_pushMessage(" %s", ascii_buf);
|
|
Debug_pushMessage("\n0x%05X:", memoryAddress);
|
|
}
|
|
ascii_buf[blockpoint] = ee.readByte(memoryAddress);
|
|
Debug_pushMessage(" %02X", ascii_buf[blockpoint]);
|
|
if (ascii_buf[blockpoint] < 0x20 || ascii_buf[blockpoint] > 0x7E)
|
|
ascii_buf[blockpoint] = '.';
|
|
memoryAddress++;
|
|
}
|
|
Debug_pushMessage("\n");
|
|
}
|
|
|
|
boolean checkEEPROMavailable()
|
|
{
|
|
if (!ee.isConnected())
|
|
{
|
|
MaintainDTC(DTC_NO_EEPROM_FOUND, true);
|
|
return false;
|
|
}
|
|
MaintainDTC(DTC_NO_EEPROM_FOUND, false);
|
|
return true;
|
|
}
|
|
|
|
uint32_t ConfigSanityCheck(bool autocorrect)
|
|
{
|
|
uint32_t setting_reset_bits = 0;
|
|
|
|
if (!(LubeConfig.DistancePerLube_Default > 0) || !(LubeConfig.DistancePerLube_Default < 50000))
|
|
{
|
|
SET_BIT(setting_reset_bits, 0);
|
|
if (autocorrect)
|
|
LubeConfig.DistancePerLube_Default = LubeConfig_defaults.DistancePerLube_Default;
|
|
}
|
|
|
|
if (!(LubeConfig.DistancePerLube_Rain > 0) || !(LubeConfig.DistancePerLube_Rain < 50000))
|
|
{
|
|
SET_BIT(setting_reset_bits, 1);
|
|
if (autocorrect)
|
|
LubeConfig.DistancePerLube_Rain = LubeConfig_defaults.DistancePerLube_Rain;
|
|
}
|
|
|
|
if (!(LubeConfig.tankCapacity_ml > 0) || !(LubeConfig.tankCapacity_ml < 5000))
|
|
{
|
|
SET_BIT(setting_reset_bits, 2);
|
|
if (autocorrect)
|
|
LubeConfig.tankCapacity_ml = LubeConfig_defaults.tankCapacity_ml;
|
|
}
|
|
|
|
if (!(LubeConfig.amountPerDose_microL > 0) || !(LubeConfig.amountPerDose_microL < 100))
|
|
{
|
|
SET_BIT(setting_reset_bits, 3);
|
|
if (autocorrect)
|
|
LubeConfig.amountPerDose_microL = LubeConfig_defaults.amountPerDose_microL;
|
|
}
|
|
|
|
if (!(LubeConfig.TankRemindAtPercentage >= 0) || !(LubeConfig.TankRemindAtPercentage <= 100))
|
|
{
|
|
SET_BIT(setting_reset_bits, 4);
|
|
if (autocorrect)
|
|
LubeConfig.TankRemindAtPercentage = LubeConfig_defaults.TankRemindAtPercentage;
|
|
}
|
|
|
|
if (LubeConfig.SpeedSource == SOURCE_IMPULSE)
|
|
{
|
|
if (!(LubeConfig.PulsePerRevolution > 0) || !(LubeConfig.PulsePerRevolution < 1000))
|
|
{
|
|
SET_BIT(setting_reset_bits, 5);
|
|
if (autocorrect)
|
|
LubeConfig.PulsePerRevolution = LubeConfig_defaults.PulsePerRevolution;
|
|
}
|
|
|
|
if (!(LubeConfig.TireWidth_mm > 0) || !(LubeConfig.TireWidth_mm < 500))
|
|
{
|
|
SET_BIT(setting_reset_bits, 6);
|
|
if (autocorrect)
|
|
LubeConfig.TireWidth_mm = LubeConfig_defaults.TireWidth_mm;
|
|
}
|
|
|
|
if (!(LubeConfig.TireWidthHeight_Ratio > 0) || !(LubeConfig.TireWidthHeight_Ratio < 150))
|
|
{
|
|
SET_BIT(setting_reset_bits, 7);
|
|
if (autocorrect)
|
|
LubeConfig.TireWidthHeight_Ratio = LubeConfig_defaults.TireWidthHeight_Ratio;
|
|
}
|
|
|
|
if (!(LubeConfig.RimDiameter_Inch > 0) || !(LubeConfig.RimDiameter_Inch < 30))
|
|
{
|
|
SET_BIT(setting_reset_bits, 8);
|
|
if (autocorrect)
|
|
LubeConfig.RimDiameter_Inch = LubeConfig_defaults.RimDiameter_Inch;
|
|
}
|
|
|
|
if (!(LubeConfig.DistancePerRevolution_mm > 0) || !(LubeConfig.DistancePerRevolution_mm < 10000))
|
|
{
|
|
SET_BIT(setting_reset_bits, 9);
|
|
if (autocorrect)
|
|
LubeConfig.DistancePerRevolution_mm = LubeConfig_defaults.DistancePerRevolution_mm;
|
|
}
|
|
}
|
|
|
|
if (!(LubeConfig.BleedingPulses > 0) || !(LubeConfig.BleedingPulses < 1001))
|
|
{
|
|
SET_BIT(setting_reset_bits, 10);
|
|
if (autocorrect)
|
|
LubeConfig.BleedingPulses = LubeConfig_defaults.BleedingPulses;
|
|
}
|
|
|
|
if (!(LubeConfig.SpeedSource >= 0) || !(LubeConfig.SpeedSource < SpeedSourceString_Elements))
|
|
{
|
|
SET_BIT(setting_reset_bits, 11);
|
|
if (autocorrect)
|
|
LubeConfig.SpeedSource = LubeConfig_defaults.SpeedSource;
|
|
}
|
|
|
|
if (!(LubeConfig.GPSBaudRate >= 0) || !(LubeConfig.GPSBaudRate < GPSBaudRateString_Elements))
|
|
{
|
|
SET_BIT(setting_reset_bits, 12);
|
|
if (autocorrect)
|
|
LubeConfig.GPSBaudRate = LubeConfig_defaults.GPSBaudRate;
|
|
}
|
|
|
|
if (!(LubeConfig.CANSource >= 0) || !(LubeConfig.CANSource < CANSourceString_Elements))
|
|
{
|
|
SET_BIT(setting_reset_bits, 13);
|
|
if (autocorrect)
|
|
LubeConfig.CANSource = LubeConfig_defaults.CANSource;
|
|
}
|
|
return setting_reset_bits;
|
|
} |