Protocol rework
This commit is contained in:
parent
3e77d34ccc
commit
2b713a3e3a
15 changed files with 1347 additions and 1155 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* @file eeprom.cpp
|
||||
* @brief EEPROM management implementation
|
||||
* @brief EEPROM management with dual-partition wear leveling.
|
||||
*
|
||||
* Created: 21.09.2025
|
||||
* Author: ThePetrovich
|
||||
|
|
@ -18,35 +18,127 @@
|
|||
|
||||
config_t config;
|
||||
|
||||
/*
|
||||
* Each partition occupies sizeof(config_t)+1 bytes:
|
||||
* [0 .. sizeof(config_t)-1] config_t struct
|
||||
* [sizeof(config_t)] generation counter (uint8_t)
|
||||
*/
|
||||
#define PARTITION_SIZE ((uint16_t)(sizeof(config_t) + 1))
|
||||
#define PARTITION_A_ADDR 0
|
||||
#define PARTITION_B_ADDR PARTITION_SIZE
|
||||
#define GEN_OFFSET ((uint16_t)sizeof(config_t))
|
||||
|
||||
/**
|
||||
* @brief Track which partition was last written so saves alternate.
|
||||
* 0 = partition A is current, 1 = partition B is current.
|
||||
*/
|
||||
static uint8_t g_active_partition = 0;
|
||||
|
||||
/**
|
||||
* @brief Check whether the partition at @p base contains a valid magic pair.
|
||||
*/
|
||||
static bool partition_valid(uint16_t base)
|
||||
{
|
||||
uint8_t m1 = EEPROM.read(base + offsetof(config_t, magic1));
|
||||
uint8_t m2 = EEPROM.read(base + offsetof(config_t, magic2));
|
||||
return (m1 == 0xA5 && m2 == 0x5A);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a config_t struct from the partition at @p base into @p dst.
|
||||
*/
|
||||
static void read_partition(uint16_t base, config_t *dst)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)dst;
|
||||
for (uint16_t i = 0; i < sizeof(config_t); i++) {
|
||||
p[i] = EEPROM.read(base + i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write @p src and a generation byte to the partition at @p base.
|
||||
* Uses EEPROM.update() so unchanged cells incur no wear.
|
||||
*/
|
||||
static void write_partition(uint16_t base, const config_t *src, uint8_t generation)
|
||||
{
|
||||
const uint8_t *p = (const uint8_t *)src;
|
||||
for (uint16_t i = 0; i < sizeof(config_t); i++) {
|
||||
EEPROM.update(base + i, p[i]);
|
||||
}
|
||||
EEPROM.update(base + GEN_OFFSET, generation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Populate @p cfg with safe factory defaults.
|
||||
* Used on first boot or when both partitions are corrupt.
|
||||
*/
|
||||
static void set_defaults(config_t *cfg)
|
||||
{
|
||||
cfg->magic1 = 0xA5;
|
||||
cfg->magic2 = 0x5A;
|
||||
cfg->pots.pot_hv = DEFAULT_POT_VALUE;
|
||||
cfg->pots.pot_amp = DEFAULT_POT_VALUE;
|
||||
cfg->pots.pot_det = DEFAULT_POT_VALUE;
|
||||
cfg->calibration.adccal0 = 0xFFFF;
|
||||
cfg->calibration.adccal3 = 0xFFFF;
|
||||
cfg->calibration.tempcal = 0;
|
||||
cfg->flags.value = 0;
|
||||
/* pot_low == pot_high disables drift compensation per channel. */
|
||||
cfg->temp_drift_compensation.temp_drift = 0;
|
||||
cfg->temp_drift_compensation.vbias_drift = 0;
|
||||
cfg->temp_drift_compensation.gain_drift = 0;
|
||||
cfg->temp_drift_compensation.threshold_drift = 0;
|
||||
cfg->temp_drift_compensation.drift_period_ms = 5000;
|
||||
cfg->temp_drift_compensation.pot_hv_low = DEFAULT_POT_VALUE;
|
||||
cfg->temp_drift_compensation.pot_hv_high = DEFAULT_POT_VALUE;
|
||||
cfg->temp_drift_compensation.pot_amp_low = DEFAULT_POT_VALUE;
|
||||
cfg->temp_drift_compensation.pot_amp_high = DEFAULT_POT_VALUE;
|
||||
cfg->temp_drift_compensation.pot_det_low = DEFAULT_POT_VALUE;
|
||||
cfg->temp_drift_compensation.pot_det_high = DEFAULT_POT_VALUE;
|
||||
}
|
||||
|
||||
void eeprom_init(void)
|
||||
{
|
||||
if (EEPROM.read(EEPROM_MAGIC_ADDR) != EEPROM_MAGIC_VALUE) {
|
||||
potentiometer_settings_t default_settings = {
|
||||
.hv_pot = DEFAULT_POT_VALUE, .amp_pot = DEFAULT_POT_VALUE, .det_pot = DEFAULT_POT_VALUE};
|
||||
bool a_valid = partition_valid(PARTITION_A_ADDR);
|
||||
bool b_valid = partition_valid(PARTITION_B_ADDR);
|
||||
|
||||
eeprom_save_pot_settings(&default_settings);
|
||||
EEPROM.write(EEPROM_MAGIC_ADDR, EEPROM_MAGIC_VALUE);
|
||||
if (a_valid && b_valid) {
|
||||
uint8_t gen_a = EEPROM.read(PARTITION_A_ADDR + GEN_OFFSET);
|
||||
uint8_t gen_b = EEPROM.read(PARTITION_B_ADDR + GEN_OFFSET);
|
||||
/* Signed delta handles wrap-around: B is newer if (gen_b - gen_a) > 0 mod 256. */
|
||||
if ((int8_t)(gen_b - gen_a) > 0) {
|
||||
read_partition(PARTITION_B_ADDR, &config);
|
||||
g_active_partition = 1;
|
||||
} else {
|
||||
read_partition(PARTITION_A_ADDR, &config);
|
||||
g_active_partition = 0;
|
||||
}
|
||||
} else if (a_valid) {
|
||||
read_partition(PARTITION_A_ADDR, &config);
|
||||
g_active_partition = 0;
|
||||
} else if (b_valid) {
|
||||
read_partition(PARTITION_B_ADDR, &config);
|
||||
g_active_partition = 1;
|
||||
} else {
|
||||
set_defaults(&config);
|
||||
write_partition(PARTITION_A_ADDR, &config, 0);
|
||||
g_active_partition = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void eeprom_load_pot_settings(potentiometer_settings_t *settings)
|
||||
void eeprom_save_config(void)
|
||||
{
|
||||
if (settings == nullptr) {
|
||||
return;
|
||||
}
|
||||
/* Write to whichever partition is NOT currently active. */
|
||||
uint8_t target_partition = (g_active_partition == 0) ? 1 : 0;
|
||||
uint16_t target_base = (target_partition == 0) ? PARTITION_A_ADDR : PARTITION_B_ADDR;
|
||||
uint16_t active_base = (g_active_partition == 0) ? PARTITION_A_ADDR : PARTITION_B_ADDR;
|
||||
|
||||
settings->hv_pot = EEPROM.read(EEPROM_POT_HV_ADDR);
|
||||
settings->amp_pot = EEPROM.read(EEPROM_POT_AMP_ADDR);
|
||||
settings->det_pot = EEPROM.read(EEPROM_POT_DET_ADDR);
|
||||
}
|
||||
|
||||
void eeprom_save_pot_settings(const potentiometer_settings_t *settings)
|
||||
{
|
||||
if (settings == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
EEPROM.write(EEPROM_POT_HV_ADDR, settings->hv_pot);
|
||||
EEPROM.write(EEPROM_POT_AMP_ADDR, settings->amp_pot);
|
||||
EEPROM.write(EEPROM_POT_DET_ADDR, settings->det_pot);
|
||||
uint8_t old_gen = EEPROM.read(active_base + GEN_OFFSET);
|
||||
uint8_t new_gen = old_gen + 1;
|
||||
|
||||
config.magic1 = 0xA5;
|
||||
config.magic2 = 0x5A;
|
||||
|
||||
write_partition(target_base, &config, new_gen);
|
||||
g_active_partition = target_partition;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue