123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- #include <Arduino.h>
- #include <EEPROM.h>
-
- #include "config.h"
- #include "config_pins.h"
- #include "data.h"
-
- // TODO make defines platform specific
- #define EEPROM_SIZE 4096
- #define RAM_SIZE (8192 / 8)
-
- 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 const char *last_error = "";
-
- static unsigned int max_presets_eeprom(void) {
- unsigned int s = EEPROM_SIZE - sizeof(struct data_config) + sizeof(struct data_config_preset *);
- return s / sizeof(struct data_config_preset);
- }
-
- static unsigned int max_presets_ram(void) {
- unsigned int s = RAM_SIZE - sizeof(struct data_config) + sizeof(struct data_config_preset *);
- return s / sizeof(struct data_config_preset);
- }
-
- static unsigned int max_presets(void) {
- unsigned int eeprom = max_presets_eeprom();
- unsigned int ram = max_presets_ram();
- return (eeprom < ram) ? eeprom : ram;
- }
-
- static uint32_t data_checksum(struct data_config *data) {
- uint32_t temp_checksum = data->checksum;
- data->checksum = 0;
-
- struct data_config_preset *temp_presets = data->presets;
- data->presets = NULL;
-
- 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 *)(temp_presets + i);
- for (unsigned int j = 0; j < sizeof(struct data_config_preset); j++) {
- c ^= t[j];
- }
- }
-
- data->checksum = temp_checksum;
- data->presets = temp_presets;
-
- return c;
- }
-
- const char *data_eeprom_error(void) {
- return last_error;
- }
-
- 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) {
- if (config.preset_count > max_presets()) {
- last_error = "Preset";
- return false;
- }
-
- config.presets = (struct data_config_preset *)malloc(config.preset_count * sizeof(struct data_config_preset));
- if (config.presets == NULL) {
- last_error = "Alloc";
- 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 read_checksum = config.checksum;
- uint32_t checksum = data_checksum(&config);
- if (read_checksum == checksum) {
- // verify version
- if (config.data_schema_version == DATA_SCHEMA_VERSION) {
- if (d.presets != NULL) {
- free(d.presets);
- }
- d = config;
-
- last_error = "";
- return true;
- } else {
- last_error = "Version";
- return false;
- }
- } else {
- Serial.print(F("checksum read="));
- Serial.print(read_checksum);
- Serial.print(F(" calc="));
- Serial.println(checksum);
- last_error = "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.presets = NULL;
- data_clear();
-
- Serial.print(F("EEPROM max presets: "));
- Serial.println(max_presets());
-
- Serial.print(F("EEPROM read... "));
- if (!data_eeprom_read()) {
- Serial.print(last_error);
- Serial.println(F(" Error"));
- } else {
- Serial.println(F("Ok"));
- }
- }
-
- void data_clear(void) {
- if (d.presets != NULL) {
- free(d.presets);
- d.presets = NULL;
- }
-
- 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;
- }
-
- 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;
- }
-
- bool data_preset_add(struct data_config_preset preset) {
- if ((d.preset_count == 0) || (d.presets == NULL)) {
- d.preset_count = 1;
- d.presets = (struct data_config_preset *)malloc(d.preset_count * sizeof(struct data_config_preset));
- if (d.presets == NULL) {
- d.preset_count = 0;
- last_error = "Alloc";
- return false;
- } else {
- d.presets[d.preset_count - 1] = preset;
- return true;
- }
- } else if (d.preset_count < max_presets()) {
- d.preset_count += 1;
- struct data_config_preset *new_mem = (struct data_config_preset *)realloc(d.presets, d.preset_count * sizeof(struct data_config_preset));
- if (new_mem == NULL) {
- d.preset_count -= 1;
- last_error = "Realloc";
- return false;
- } else {
- d.presets = new_mem;
- d.presets[d.preset_count - 1] = preset;
- return true;
- }
- } else {
- return false;
- }
- }
-
- bool data_preset_remove(unsigned int i) {
- if (d.preset_count == 1) {
- d.preset_count = 0;
- free(d.presets);
- d.presets = NULL;
- return true;
- } else if (d.preset_count > 1) {
- for (int j = i; j < (d.preset_count - 1); j++) {
- d.presets[j] = d.presets[j + 1];
- }
- d.preset_count -= 1;
- struct data_config_preset *new_mem = (struct data_config_preset *)realloc(d.presets, d.preset_count * sizeof(struct data_config_preset));
- if (new_mem == NULL) {
- d.preset_count += 1;
- last_error = "Realloc";
- return false;
- } else {
- d.presets = new_mem;
- return true;
- }
- } else {
- return true; // nothing to delete
- }
- }
|