#include #include #include "config.h" #include "config_pins.h" #include "data.h" #define EEPROM_SIZE 4096 struct data_config { uint8_t data_schema_version; uint8_t preset_count; uint32_t checksum; struct data_config_options options; struct data_config_preset *presets; }; static struct data_config d; static unsigned int max_presets(void) { unsigned int s = EEPROM_SIZE - sizeof(struct data_config) + sizeof(struct data_config_preset *); return s / sizeof(struct data_config_preset); } static uint32_t data_checksum(struct data_config *data) { uint32_t c = 0; uint8_t *t = (uint8_t *)data; for (unsigned int i = 0; i < sizeof(struct data_config); i++) { c ^= t[i]; } for (unsigned int i = 0; i < data->preset_count; i++) { t = (uint8_t *)(&data->presets[i]); for (unsigned int j = 0; j < sizeof(struct data_config_preset); j++) { c ^= t[j]; } } return c; } static bool data_eeprom_read(void) { struct data_config config; uint8_t *data = (uint8_t *)&config; // read meta-data and settings unsigned int s = sizeof(struct data_config); for (unsigned int i = 0; i < s; i++) { data[i] = EEPROM.read(i); } if (config.preset_count > 0) { config.presets = (struct data_config_preset *)malloc(config.preset_count * sizeof(struct data_config_preset)); if (config.presets == NULL) { Serial.print(F("Alloc ")); return false; } if (config.preset_count > max_presets()) { Serial.print(F("Preset ")); return false; } // read presets for (unsigned int i = 0; i < config.preset_count; i++) { data = (uint8_t *)(&config.presets[i]); for (unsigned int j = 0; j < sizeof(struct data_config_preset); j++) { data[j] = EEPROM.read(s + j); s += sizeof(struct data_config_preset); } } } else { config.presets = NULL; } // verify checksum uint32_t checksum = data_checksum(&config); if (config.checksum == checksum) { // verify version if (config.data_schema_version == DATA_SCHEMA_VERSION) { if (d.presets != NULL) { free(d.presets); } d = config; return true; } else { Serial.print(F("Version ")); return false; } } else { Serial.print(F("Checksum ")); return false; } } void data_eeprom_write(void) { d.checksum = data_checksum(&d); // write meta-data and settings uint8_t *data = (uint8_t *)&d; unsigned int s = sizeof(struct data_config); for (unsigned int i = 0; i < s; i++) { EEPROM.update(i, data[i]); } // write presets for (unsigned int i = 0; i < d.preset_count; i++) { data = (uint8_t *)(&d.presets[i]); for (unsigned int j = 0; j < sizeof(struct data_config_preset); j++) { EEPROM.update(s + j, data[j]); s += sizeof(struct data_config_preset); } } } void data_init(void) { d.data_schema_version = DATA_SCHEMA_VERSION; d.preset_count = 0; d.checksum = 0; d.options.speed_x = XY_MAX_SPEED; d.options.speed_y = XY_MAX_SPEED; d.options.speed_z = Z_MAX_SPEED; d.options.speed_e = E_MAX_SPEED; d.options.accel_x = XY_MAX_ACCEL; d.options.accel_y = XY_MAX_ACCEL; d.options.accel_z = Z_MAX_ACCEL; d.options.accel_e = E_MAX_ACCEL; d.presets = NULL; Serial.print(F("EEPROM read... ")); if (!data_eeprom_read()) { Serial.println(F("Error")); } else { Serial.println(F("Ok")); } } struct data_config_options *data_options(void) { return &d.options; } unsigned int data_preset_count(void) { return d.preset_count; } struct data_config_preset *data_preset(unsigned int i) { if (i < d.preset_count) { return &d.presets[i]; } return NULL; } void data_preset_add(struct data_config_preset preset) { } void data_preset_remove(unsigned int i) { }