Example #1
0
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);
}
Example #2
0
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);
}