#include #include #include #include "parameters.h" #include #include #include static int32_t * const data_eeprom = (int32_t * const)0x08080000; parameters_t params = { #define X(type, name, default) default, PARAMETERS #undef X }; typedef enum {T_int, T_fix16_t} param_type_t; typedef struct { param_type_t type; int32_t *variable; char name[32]; } parameter_def_t; #define X(type, name, default) {T_ ## type, (int32_t*)¶ms.name, #name}, static const parameter_def_t param_defs[] = { PARAMETERS }; #undef X #define NUM_PARAMETERS (sizeof(param_defs) / sizeof(param_defs[0])) static const int signature = 0x53504800 ^ PARAMETERS_VERSION; void parameters_save() { FLASH->PEKEYR = 0x89ABCDEF; FLASH->PEKEYR = 0x02030405; int32_t *dest = data_eeprom; *dest++ = signature; *dest++ = NUM_PARAMETERS; for (int i = 0; i < NUM_PARAMETERS; i++) { while (FLASH->SR & FLASH_SR_BSY) chThdSleepMilliseconds(1); *dest++ = *(int32_t*)param_defs[i].variable; } FLASH->PECR |= FLASH_PECR_PELOCK; } bool parameters_load() { int32_t *array = data_eeprom; if (*array++ != signature) return false; int count = *array++; if (count > NUM_PARAMETERS) count = NUM_PARAMETERS; for (int i = 0; i < count; i++) { *param_defs[i].variable = *array++; } return true; } static void format(param_type_t type, int32_t value, char buf[13]) { if (type == T_int) snprintf(buf, 13, "%ld", value); else fix16_to_str(value, buf, 4); } static int32_t parse(param_type_t type, const char *buf) { if (type == T_int) return atoi(buf); else return fix16_from_str(buf); } void parameters_print(BaseChannel *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++) { char current[13]; format(param_defs[i].type, *param_defs[i].variable, current); char stored[13]; format(param_defs[i].type, *array++, stored); if (machine_readable) chprintf(chp, "set %s %s\r\n",param_defs[i].name, current); else chprintf(chp, "%32s current: %8s stored: %8s\r\n", param_defs[i].name, current, stored); } } bool parameter_set(const char *name, const char *value) { for (int i = 0; i < NUM_PARAMETERS; i++) { if (strcasecmp(name, param_defs[i].name) == 0) { *param_defs[i].variable = parse(param_defs[i].type, value); return true; } } return false; } bool parameter_get(const char *name, char value[13]) { for (int i = 0; i < NUM_PARAMETERS; i++) { if (strcasecmp(name, param_defs[i].name) == 0) { format(param_defs[i].type, *param_defs[i].variable, value); return true; } } return false; }