#include "parameters.h" #include #include #include static int32_t * const data_eeprom = (int32_t * const)0x08080000; typedef struct { int32_t *variable; char name[32]; } parameter_t; #define X(variable) {&variable, #variable}, static const parameter_t param_defs[] = { PARAMETERS }; #undef X #define NUM_PARAMETERS (sizeof(param_defs) / sizeof(param_defs[0])) static const int signature = 0x53504800 ^ PARAMETERS_VERSION; // Collect variable values to an array static void collect_data(int32_t *array) { *array++ = signature; *array++ = NUM_PARAMETERS; chSysLock(); for (int i = 0; i < NUM_PARAMETERS; i++) { *array++ = *param_defs[i].variable; } chSysUnlock(); } // Restore variable values from array to variables static bool restore_data(int32_t *array) { if (*array++ != signature) return false; int num_in_mem = *array++; if (num_in_mem > NUM_PARAMETERS) num_in_mem = NUM_PARAMETERS; chSysLock(); for (int i = 0; i < num_in_mem; i++) { *param_defs[i].variable = *array++; } chSysUnlock(); return true; } void parameters_save() { int32_t params[NUM_PARAMETERS + 2] = {}; collect_data(params); FLASH->PEKEYR = 0x89ABCDEF; FLASH->PEKEYR = 0x02030405; int32_t *dest = data_eeprom; int32_t *src = params; for (int i = 0; i < NUM_PARAMETERS + 2; i++) { while (FLASH->SR & FLASH_SR_BSY) chThdSleepMilliseconds(1); *dest++ = *src++; } FLASH->PECR |= FLASH_PECR_PELOCK; } bool parameters_load() { return restore_data(data_eeprom); } void parameters_print(BaseSequentialStream *chp, bool machine_readable) { int32_t *array = data_eeprom; if (*array++ != signature) { chprintf(chp, "EEPROM signature invalid\r\n"); } array++; for (int i = 0; i < NUM_PARAMETERS; i++) { if (machine_readable) chprintf(chp, "set %s %d\r\n",param_defs[i].name, *param_defs[i].variable); else chprintf(chp, "%32s current: %6d stored: %6d\r\n", param_defs[i].name, *param_defs[i].variable, *array++); } } bool parameter_set(const char *name, int32_t value) { for (int i = 0; i < NUM_PARAMETERS; i++) { if (strcasecmp(name, param_defs[i].name) == 0) { *param_defs[i].variable = value; return true; } } return false; } bool parameter_get(const char *name, int32_t *value) { for (int i = 0; i < NUM_PARAMETERS; i++) { if (strcasecmp(name, param_defs[i].name) == 0) { *value = *param_defs[i].variable; return true; } } return false; }