No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

data.cpp 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #include <Arduino.h>
  2. #include <EEPROM.h>
  3. #include "config.h"
  4. #include "config_pins.h"
  5. #include "data.h"
  6. // TODO make defines platform specific
  7. #define EEPROM_SIZE 4096
  8. #define RAM_SIZE (8192 / 8)
  9. struct data_config {
  10. uint8_t data_schema_version;
  11. uint8_t preset_count;
  12. uint32_t checksum;
  13. struct data_config_options options;
  14. struct data_config_preset *presets;
  15. };
  16. static struct data_config d;
  17. static const char *last_error = "";
  18. static unsigned int max_presets_eeprom(void) {
  19. unsigned int s = EEPROM_SIZE - sizeof(struct data_config) + sizeof(struct data_config_preset *);
  20. return s / sizeof(struct data_config_preset);
  21. }
  22. static unsigned int max_presets_ram(void) {
  23. unsigned int s = RAM_SIZE - sizeof(struct data_config) + sizeof(struct data_config_preset *);
  24. return s / sizeof(struct data_config_preset);
  25. }
  26. static unsigned int max_presets(void) {
  27. unsigned int eeprom = max_presets_eeprom();
  28. unsigned int ram = max_presets_ram();
  29. return (eeprom < ram) ? eeprom : ram;
  30. }
  31. static uint32_t data_checksum(struct data_config *data) {
  32. uint32_t temp_checksum = data->checksum;
  33. data->checksum = 0;
  34. struct data_config_preset *temp_presets = data->presets;
  35. data->presets = NULL;
  36. uint32_t c = 0;
  37. uint8_t *t = (uint8_t *)data;
  38. for (unsigned int i = 0; i < sizeof(struct data_config); i++) {
  39. c ^= t[i];
  40. }
  41. for (unsigned int i = 0; i < data->preset_count; i++) {
  42. t = (uint8_t *)(temp_presets + i);
  43. for (unsigned int j = 0; j < sizeof(struct data_config_preset); j++) {
  44. c ^= t[j];
  45. }
  46. }
  47. data->checksum = temp_checksum;
  48. data->presets = temp_presets;
  49. return c;
  50. }
  51. const char *data_eeprom_error(void) {
  52. return last_error;
  53. }
  54. bool data_eeprom_read(void) {
  55. struct data_config config;
  56. uint8_t *data = (uint8_t *)&config;
  57. // read meta-data and settings
  58. unsigned int s = sizeof(struct data_config);
  59. for (unsigned int i = 0; i < s; i++) {
  60. data[i] = EEPROM.read(i);
  61. }
  62. if (config.preset_count > 0) {
  63. if (config.preset_count > max_presets()) {
  64. last_error = "Preset";
  65. return false;
  66. }
  67. config.presets = (struct data_config_preset *)malloc(config.preset_count * sizeof(struct data_config_preset));
  68. if (config.presets == NULL) {
  69. last_error = "Alloc";
  70. return false;
  71. }
  72. // read presets
  73. for (unsigned int i = 0; i < config.preset_count; i++) {
  74. data = (uint8_t *)(&config.presets[i]);
  75. for (unsigned int j = 0; j < sizeof(struct data_config_preset); j++) {
  76. data[j] = EEPROM.read(s + j);
  77. s += sizeof(struct data_config_preset);
  78. }
  79. }
  80. } else {
  81. config.presets = NULL;
  82. }
  83. // verify checksum
  84. uint32_t read_checksum = config.checksum;
  85. uint32_t checksum = data_checksum(&config);
  86. if (read_checksum == checksum) {
  87. // verify version
  88. if (config.data_schema_version == DATA_SCHEMA_VERSION) {
  89. if (d.presets != NULL) {
  90. free(d.presets);
  91. }
  92. d = config;
  93. last_error = "";
  94. return true;
  95. } else {
  96. last_error = "Version";
  97. return false;
  98. }
  99. } else {
  100. Serial.print(F("checksum read="));
  101. Serial.print(read_checksum);
  102. Serial.print(F(" calc="));
  103. Serial.println(checksum);
  104. last_error = "Checksum";
  105. return false;
  106. }
  107. }
  108. void data_eeprom_write(void) {
  109. d.checksum = data_checksum(&d);
  110. // write meta-data and settings
  111. uint8_t *data = (uint8_t *)&d;
  112. unsigned int s = sizeof(struct data_config);
  113. for (unsigned int i = 0; i < s; i++) {
  114. EEPROM.update(i, data[i]);
  115. }
  116. // write presets
  117. for (unsigned int i = 0; i < d.preset_count; i++) {
  118. data = (uint8_t *)(&d.presets[i]);
  119. for (unsigned int j = 0; j < sizeof(struct data_config_preset); j++) {
  120. EEPROM.update(s + j, data[j]);
  121. s += sizeof(struct data_config_preset);
  122. }
  123. }
  124. }
  125. void data_init(void) {
  126. d.presets = NULL;
  127. data_clear();
  128. Serial.print(F("EEPROM max presets: "));
  129. Serial.println(max_presets());
  130. Serial.print(F("EEPROM read... "));
  131. if (!data_eeprom_read()) {
  132. Serial.print(last_error);
  133. Serial.println(F(" Error"));
  134. } else {
  135. Serial.println(F("Ok"));
  136. }
  137. }
  138. void data_clear(void) {
  139. if (d.presets != NULL) {
  140. free(d.presets);
  141. d.presets = NULL;
  142. }
  143. d.data_schema_version = DATA_SCHEMA_VERSION;
  144. d.preset_count = 0;
  145. d.checksum = 0;
  146. d.options.speed_x = XY_MAX_SPEED;
  147. d.options.speed_y = XY_MAX_SPEED;
  148. d.options.speed_z = Z_MAX_SPEED;
  149. d.options.speed_e = E_MAX_SPEED;
  150. d.options.accel_x = XY_MAX_ACCEL;
  151. d.options.accel_y = XY_MAX_ACCEL;
  152. d.options.accel_z = Z_MAX_ACCEL;
  153. d.options.accel_e = E_MAX_ACCEL;
  154. }
  155. struct data_config_options *data_options(void) {
  156. return &d.options;
  157. }
  158. unsigned int data_preset_count(void) {
  159. return d.preset_count;
  160. }
  161. struct data_config_preset *data_preset(unsigned int i) {
  162. if (i < d.preset_count) {
  163. return &d.presets[i];
  164. }
  165. return NULL;
  166. }
  167. bool data_preset_add(struct data_config_preset preset) {
  168. if ((d.preset_count == 0) || (d.presets == NULL)) {
  169. d.preset_count = 1;
  170. d.presets = (struct data_config_preset *)malloc(d.preset_count * sizeof(struct data_config_preset));
  171. if (d.presets == NULL) {
  172. d.preset_count = 0;
  173. last_error = "Alloc";
  174. return false;
  175. } else {
  176. d.presets[d.preset_count - 1] = preset;
  177. return true;
  178. }
  179. } else if (d.preset_count < max_presets()) {
  180. d.preset_count += 1;
  181. struct data_config_preset *new_mem = (struct data_config_preset *)realloc(d.presets, d.preset_count * sizeof(struct data_config_preset));
  182. if (new_mem == NULL) {
  183. d.preset_count -= 1;
  184. last_error = "Realloc";
  185. return false;
  186. } else {
  187. d.presets = new_mem;
  188. d.presets[d.preset_count - 1] = preset;
  189. return true;
  190. }
  191. } else {
  192. return false;
  193. }
  194. }
  195. bool data_preset_remove(unsigned int i) {
  196. if (d.preset_count == 1) {
  197. d.preset_count = 0;
  198. free(d.presets);
  199. d.presets = NULL;
  200. return true;
  201. } else if (d.preset_count > 1) {
  202. for (int j = i; j < (d.preset_count - 1); j++) {
  203. d.presets[j] = d.presets[j + 1];
  204. }
  205. d.preset_count -= 1;
  206. struct data_config_preset *new_mem = (struct data_config_preset *)realloc(d.presets, d.preset_count * sizeof(struct data_config_preset));
  207. if (new_mem == NULL) {
  208. d.preset_count += 1;
  209. last_error = "Realloc";
  210. return false;
  211. } else {
  212. d.presets = new_mem;
  213. return true;
  214. }
  215. } else {
  216. return true; // nothing to delete
  217. }
  218. }