#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 boolean eeAvailable = false; const uint16_t startofConfigData = 16; const uint16_t startofPersistence = 16 + sizeof(startofConfigData) + (sizeof(startofConfigData) % 16); void InitEEPROM() { #ifdef SERIAL_DEBUG Serial.printf("connecting I2C EEPROM"); #endif ee.begin(); if (!ee.isConnected()) { MaintainDTC(DTC_NO_EEPROM_FOUND, true); } } void EEPROM_Process() { switch (globals.requestEEAction) { case EE_CFG_SAVE: StoreConfig_EEPROM(); globals.requestEEAction = EE_IDLE; break; case EE_CFG_LOAD: GetConfig_EEPROM(); globals.requestEEAction = EE_IDLE; break; case EE_PDS_SAVE: StorePersistence_EEPROM(); globals.requestEEAction = EE_IDLE; break; case EE_PDS_LOAD: GetPersistence_EEPROM(); globals.requestEEAction = EE_IDLE; break; case EE_IDLE: default: globals.requestEEAction = EE_IDLE; } } void StoreConfig_EEPROM() { ConfigData.checksum = 0; ConfigData.checksum = Checksum_EEPROM((uint8_t *)&ConfigData, sizeof(ConfigData)); if (!ee.isConnected()) return; ee.updateBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData)); } void GetConfig_EEPROM() { if (!ee.isConnected()) return; ee.readBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData)); uint32_t checksum = ConfigData.checksum; ConfigData.checksum = 0; if (Checksum_EEPROM((uint8_t *)&ConfigData, sizeof(ConfigData)) != checksum) { MaintainDTC(DTC_EEPROM_CFG_BAD, true); FormatConfig_EEPROM(); } ConfigData.checksum = checksum; } uint16_t getPersistanceAddress() { return startofPersistence + eePersistenceMarker; } 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 (!ee.isConnected()) return; ee.updateBlock(getPersistanceAddress(), (uint8_t *)&PersistenceData, sizeof(PersistenceData)); } void GetPersistence_EEPROM() { if (!ee.isConnected()) return; eePersistenceMarker = (ee.readByte(0) << 8) | ee.readByte(1); ee.readBlock(getPersistanceAddress(), (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); FormatPersistence_EEPROM(); } PersistenceData.checksum = checksum; } void FormatConfig_EEPROM() { configData_t defaults; ConfigData = defaults; StoreConfig_EEPROM(); } void FormatPersistence_EEPROM() { persistenceData_t defaults; PersistenceData = defaults; eePersistenceMarker = 0; StorePersistence_EEPROM(); } void MovePersistencePage_EEPROM(boolean reset) { eePersistenceMarker = reset ? sizeof(PersistenceData) : eePersistenceMarker + sizeof(PersistenceData); PersistenceData.writeCycleCounter = 0; if (!ee.isConnected()) return; ee.updateByte(0, (uint8_t)(eePersistenceMarker >> 8)); ee.updateByte(1, (uint8_t)(eePersistenceMarker & 0xFF)); } 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 (!ee.isConnected()) return; char ascii_buf[BLOCK_TO_LENGTH + 1]; sprintf(ascii_buf, "%*s", BLOCK_TO_LENGTH, "ASCII"); Serial.print(PSTR("\nAddress ")); for (int x = 0; x < BLOCK_TO_LENGTH; x++) Serial.printf("%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; Serial.printf(" %s", ascii_buf); Serial.printf("\n0x%05X:", memoryAddress); } ascii_buf[blockpoint] = ee.readByte(memoryAddress); Serial.printf(" %02X", ascii_buf[blockpoint]); if (ascii_buf[blockpoint] < 0x20 || ascii_buf[blockpoint] > 0x7E) ascii_buf[blockpoint] = '.'; memoryAddress++; } Serial.println(); }