diff --git a/projects/rfdsatt/board.h b/projects/rfdsatt/board.h new file mode 100644 index 0000000..2707b1b --- /dev/null +++ b/projects/rfdsatt/board.h @@ -0,0 +1,4 @@ +#pragma once + +#define NUM_CHAN 4 +#define NUM_STAGE 2 diff --git a/projects/rfdsatt/board_rfdsatt_4ch.c b/projects/rfdsatt/board_rfdsatt_4ch.c index e0c6b97..e2e6d07 100644 --- a/projects/rfdsatt/board_rfdsatt_4ch.c +++ b/projects/rfdsatt/board_rfdsatt_4ch.c @@ -4,9 +4,7 @@ #include #include "attenuator.h" - -#define NUM_CHAN 4 -#define NUM_STAGE 2 +#include "board.h" static const struct attenuator_def attenuator_def_at1[NUM_STAGE] = { { { GPIOB, GPIO3 } }, { { GPIOA, GPIO15 } }, diff --git a/projects/rfdsatt/rfdsatt.c b/projects/rfdsatt/rfdsatt.c index 792f77a..e018988 100644 --- a/projects/rfdsatt/rfdsatt.c +++ b/projects/rfdsatt/rfdsatt.c @@ -159,6 +159,81 @@ static void gpio_setup(void) #endif } +/*********************************************************************** + * attenuator eeprom store + ***********************************************************************/ + +#include "board.h" + +struct eeprom_chan { + uint8_t stage_qdb[NUM_STAGE]; +}; + +struct eeprom_state { + uint8_t version; + uint8_t num_chan:4, + num_stage:4; + struct eeprom_chan chan[NUM_CHAN]; +} __attribute__ ((packed)); + +static int store_to_eeprom(void) +{ + struct eeprom_state est = { + .version = 1, + .num_chan = NUM_CHAN, + .num_stage = NUM_STAGE, + }; + const uint8_t *_est = (const uint8_t *) &est; + unsigned int i; + + for (i = 0; i < NUM_CHAN; i++) { + for (int s = 0; s < NUM_STAGE; s++) + est.chan[i].stage_qdb[s] = attenuator_stage_get(i+1, s+1, ATT_VAL_CURRENT); + } + /* write to EEPROM */ + for (i = 0; i < sizeof(est); i++) { + int rc = eeprom_write_byte(i, _est[i]); + if (rc < 1) { + printf("Error writing to EEPROM byte %u\r\n", i); + return rc; + } + } + + printf("Saved current settings to EEPROM\r\n"); + return 0; +} + +static int load_from_eeprom(void) +{ + struct eeprom_state est; + unsigned int i; + int rc; + + rc = eeprom_read((uint8_t *) &est, sizeof(est), 0); + if (rc < 0) { + printf("Failed to read from EEPROM: %d\r\n", rc); + return rc; + } + if (est.version != 1) { + if (est.version == 255) + printf("EEPROM empty, cannot restore settings\r\n"); + else + printf("Unknown EEPROM version: %d\r\n", est.version); + return -1; + } + if (est.num_chan != NUM_CHAN || est.num_stage != NUM_STAGE) { + printf("Unexpected EEPROM contents\r\n"); + return -1; + } + for (i = 0; i < est.num_chan; i++) { + for (int s = 0; s < est.num_stage; s++) + attenuator_stage_set(i+1, s+1, est.chan[i].stage_qdb[s]); + } + printf("EEPROM settings restored\r\n"); + return 0; +} + + /*********************************************************************** * uVTY interface ***********************************************************************/ @@ -229,6 +304,19 @@ DEFUN(att_set, att_set_cmd, "set", printf("Error setting attenuator %d: %d\r\n", channel, rc); } +DEFUN(save, save_cmd, "save", + "Save the current state to the EEPROM") +{ + store_to_eeprom(); +} + +DEFUN(load, load_cmd, "load", + "Load all settings from the EEPROM") +{ + load_from_eeprom(); +} + + DEFUN(interact, interact_cmd, "interact", "Enter interactive single-key mode") { @@ -426,6 +514,10 @@ int main(void) time_init(); attenuator_init(&board_att_cfg, board_att_st); + print_banner(); + + load_from_eeprom(); + microvty_init("rfdsat4ch> "); microvty_register(&reset_cmd); microvty_register(&uuid_cmd); @@ -436,8 +528,8 @@ int main(void) microvty_register(&test_cmd); microvty_register(&i2c_read_cmd); microvty_register(&i2c_write_cmd); - - print_banner(); + microvty_register(&load_cmd); + microvty_register(&save_cmd); microvty_print_prompt(); fibre_run(&led.fibre);