static bool writeSettingsToEEPROM(void) { config_streamer_t streamer; config_streamer_init(&streamer); config_streamer_start(&streamer, (uintptr_t)&__config_start, &__config_end - &__config_start); uint8_t chk = 0; configHeader_t header = { .eepromConfigVersion = EEPROM_CONF_VERSION, .boardIdentifier = TARGET_BOARD_IDENTIFIER, }; config_streamer_write(&streamer, (uint8_t *)&header, sizeof(header)); chk = updateChecksum(chk, (uint8_t *)&header, sizeof(header)); // write the transitional masterConfig record config_streamer_write(&streamer, (uint8_t *)&masterConfig, sizeof(masterConfig)); chk = updateChecksum(chk, (uint8_t *)&masterConfig, sizeof(masterConfig)); PG_FOREACH(reg) { const uint16_t regSize = pgSize(reg); configRecord_t record = { .size = sizeof(configRecord_t) + regSize, .pgn = pgN(reg), .version = pgVersion(reg), .flags = 0 }; if (pgIsSystem(reg)) { // write the only instance record.flags |= CR_CLASSICATION_SYSTEM; config_streamer_write(&streamer, (uint8_t *)&record, sizeof(record)); chk = updateChecksum(chk, (uint8_t *)&record, sizeof(record)); config_streamer_write(&streamer, reg->address, regSize); chk = updateChecksum(chk, reg->address, regSize); } else { // write one instance for each profile for (uint8_t profileIndex = 0; profileIndex < MAX_PROFILE_COUNT; profileIndex++) { record.flags = 0; record.flags |= ((profileIndex + 1) & CR_CLASSIFICATION_MASK); config_streamer_write(&streamer, (uint8_t *)&record, sizeof(record)); chk = updateChecksum(chk, (uint8_t *)&record, sizeof(record)); const uint8_t *address = reg->address + (regSize * profileIndex); config_streamer_write(&streamer, address, regSize); chk = updateChecksum(chk, address, regSize); } } } configFooter_t footer = { .terminator = 0, }; config_streamer_write(&streamer, (uint8_t *)&footer, sizeof(footer)); chk = updateChecksum(chk, (uint8_t *)&footer, sizeof(footer)); // append checksum now chk = ~chk; config_streamer_write(&streamer, &chk, sizeof(chk)); config_streamer_flush(&streamer); bool success = config_streamer_finish(&streamer) == 0; return success; } void writeConfigToEEPROM(void) { bool success = false; // write it for (int attempt = 0; attempt < 3 && !success; attempt++) { if (writeSettingsToEEPROM()) { success = true; } } if (success && isEEPROMContentValid()) { return; } // Flash write failed - just die now failureMode(FAILURE_FLASH_WRITE_FAILED); }
uint8_t pgMatcherForConfigRecord(const pgRegistry_t *candidate, const void *criteria) { const configRecord_t *record = (const configRecord_t *)criteria; return (pgN(candidate) == record->pgn && pgVersion(candidate) == record->version); }