Program Listing for File config.c¶
↰ Return to documentation for file (mainboard/Src/config.c
)
#include "config.h"
#include "error.h"
#include "mainboard_config.h"
#include "spi.h"
#include <stdlib.h>
#include <string.h>
#define VERSION_TYPE uint32_t
#define VERSION_SIZE sizeof(VERSION_TYPE)
struct config {
VERSION_TYPE version;
uint16_t address;
bool dirty;
size_t size;
void *data;
};
static m95256_t eeprom = NULL;
bool config_init(config_t *config, uint16_t address, uint32_t version, void *default_data, size_t size) {
assert(size <= EEPROM_BUFFER_SIZE);
*config = (config_t)malloc(sizeof(struct config));
(*config)->data = malloc(size);
(*config)->address = address;
(*config)->version = version;
(*config)->size = size + VERSION_SIZE;
(*config)->dirty = false;
if (eeprom == NULL) {
m95256_init(&eeprom, &SPI_EEPROM, EEPROM_CS_GPIO_Port, EEPROM_CS_Pin);
}
if (config_read(*config)) {
return true;
} else {
// Data in eeprom is gibberish
config_set(*config, default_data);
}
return false;
}
void config_deinit(config_t config) {
free(config->data);
free(config);
}
bool config_read(config_t config) {
uint8_t buffer[EEPROM_BUFFER_SIZE] = {0};
if (m95256_ReadBuffer(eeprom, buffer, config->address, config->size) == EEPROM_STATUS_COMPLETE) {
error_reset(ERROR_EEPROM_COMM, 0);
// Check if EEPROM's version matches config's
if (*((VERSION_TYPE *)buffer) == config->version) {
memcpy(config->data, buffer, config->size);
config->dirty = false;
return true;
}
} else {
error_set(ERROR_EEPROM_COMM, 0, HAL_GetTick());
}
return false;
}
bool config_write(config_t config) {
if (config->dirty) {
if (m95256_WriteBuffer(eeprom, (uint8_t *)config->data, config->address, config->size) ==
EEPROM_STATUS_COMPLETE) {
error_reset(ERROR_EEPROM_COMM, 0);
// Read just-written data and compare for errors
uint8_t testbuf[EEPROM_BUFFER_SIZE] = {0};
if (m95256_ReadBuffer(eeprom, testbuf, config->address, config->size) == EEPROM_STATUS_COMPLETE) {
if (memcmp(config->data, testbuf, config->size) == 0) {
error_reset(ERROR_EEPROM_WRITE, 0);
config->dirty = false;
return true;
}
error_set(ERROR_EEPROM_WRITE, 0, HAL_GetTick());
return false;
}
} else {
error_set(ERROR_EEPROM_COMM, 0, HAL_GetTick());
return false;
}
}
return true;
}
void *config_get(config_t config) {
return ((VERSION_TYPE *)config->data) + VERSION_SIZE;
}
void config_set(config_t config, void *data) {
memcpy(config->data, &config->version, VERSION_SIZE); // Copy version
memcpy(config->data + VERSION_SIZE, data, config->size - VERSION_SIZE); // Copy data after version
config->dirty = true;
}