eeprom.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. //! @file
  2. //! @date Jun 20, 2019
  3. //! @author Marek Běl
  4. #include "eeprom.h"
  5. #include "Marlin.h"
  6. #include <avr/eeprom.h>
  7. #include <stdint.h>
  8. #include "language.h"
  9. void eeprom_init()
  10. {
  11. eeprom_init_default_byte((uint8_t*)EEPROM_POWER_COUNT, 0);
  12. eeprom_init_default_byte((uint8_t*)EEPROM_CRASH_COUNT_X, 0);
  13. eeprom_init_default_byte((uint8_t*)EEPROM_CRASH_COUNT_Y, 0);
  14. eeprom_init_default_byte((uint8_t*)EEPROM_FERROR_COUNT, 0);
  15. eeprom_init_default_word((uint16_t*)EEPROM_POWER_COUNT_TOT, 0);
  16. eeprom_init_default_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT, 0);
  17. eeprom_init_default_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT, 0);
  18. eeprom_init_default_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, 0);
  19. eeprom_init_default_word((uint16_t*)EEPROM_MMU_FAIL_TOT, 0);
  20. eeprom_init_default_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT, 0);
  21. eeprom_init_default_byte((uint8_t*)EEPROM_MMU_FAIL, 0);
  22. eeprom_init_default_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL, 0);
  23. eeprom_init_default_dword((uint32_t*)EEPROM_TOTAL_TOOLCHANGE_COUNT, 0);
  24. if (eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)) == EEPROM_EMPTY_VALUE)
  25. {
  26. eeprom_update_byte(&(EEPROM_Sheets_base->active_sheet), 0);
  27. // When upgrading from version older version (before multiple sheets were implemented in v3.8.0)
  28. // Sheet 1 uses the previous Live adjust Z (@EEPROM_BABYSTEP_Z)
  29. int last_babystep = eeprom_read_word((uint16_t *)EEPROM_BABYSTEP_Z);
  30. eeprom_update_word(reinterpret_cast<uint16_t *>(&(EEPROM_Sheets_base->s[0].z_offset)), last_babystep);
  31. }
  32. // initialize the sheet names in eeprom
  33. for (uint_least8_t i = 0; i < (sizeof(Sheets::s)/sizeof(Sheets::s[0])); i++) {
  34. SheetName sheetName;
  35. eeprom_default_sheet_name(i, sheetName);
  36. eeprom_init_default_block(EEPROM_Sheets_base->s[i].name, (sizeof(Sheet::name)/sizeof(Sheet::name[0])), sheetName.c);
  37. }
  38. if(!eeprom_is_sheet_initialized(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet))))
  39. {
  40. eeprom_switch_to_next_sheet();
  41. }
  42. check_babystep();
  43. #ifdef PINDA_TEMP_COMP
  44. eeprom_init_default_byte((uint8_t*)EEPROM_PINDA_TEMP_COMPENSATION, 0);
  45. #endif //PINDA_TEMP_COMP
  46. eeprom_init_default_dword((uint32_t*)EEPROM_JOB_ID, 0);
  47. eeprom_init_default_dword((uint32_t*)EEPROM_TOTALTIME, 0);
  48. eeprom_init_default_dword((uint32_t*)EEPROM_FILAMENTUSED, 0);
  49. eeprom_init_default_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED, 0);
  50. }
  51. //! @brief Get default sheet name for index
  52. //!
  53. //! | index | sheetName |
  54. //! | ----- | --------- |
  55. //! | 0 | Smooth1 |
  56. //! | 1 | Smooth2 |
  57. //! | 2 | Textur1 |
  58. //! | 3 | Textur2 |
  59. //! | 4 | Satin |
  60. //! | 5 | NylonPA |
  61. //! | 6 | Custom1 |
  62. //! | 7 | Custom2 |
  63. //!
  64. //! @param[in] index
  65. //! @param[out] sheetName
  66. void eeprom_default_sheet_name(uint8_t index, SheetName &sheetName)
  67. {
  68. static_assert(8 == sizeof(SheetName),"Default sheet name needs to be adjusted.");
  69. if (index < 2)
  70. {
  71. strcpy_P(sheetName.c, PSTR("Smooth"));
  72. }
  73. else if (index < 4)
  74. {
  75. strcpy_P(sheetName.c, PSTR("Textur"));
  76. }
  77. else if (index < 5)
  78. {
  79. strcpy_P(sheetName.c, PSTR("Satin "));
  80. }
  81. else if (index < 6)
  82. {
  83. strcpy_P(sheetName.c, PSTR("NylonPA"));
  84. }
  85. else
  86. {
  87. strcpy_P(sheetName.c, PSTR("Custom"));
  88. }
  89. if (index <4 || index >5)
  90. {
  91. sheetName.c[6] = '0' + ((index % 2)+1);
  92. sheetName.c[7] = '\0';
  93. }
  94. }
  95. //! @brief Get next initialized sheet
  96. //!
  97. //! If current sheet is the only sheet initialized, current sheet is returned.
  98. //!
  99. //! @param sheet Current sheet
  100. //! @return next initialized sheet
  101. //! @retval -1 no sheet is initialized
  102. int8_t eeprom_next_initialized_sheet(int8_t sheet)
  103. {
  104. for (int8_t i = 0; i < static_cast<int8_t>(sizeof(Sheets::s)/sizeof(Sheet)); ++i)
  105. {
  106. ++sheet;
  107. if (sheet >= static_cast<int8_t>(sizeof(Sheets::s)/sizeof(Sheet))) sheet = 0;
  108. if (eeprom_is_sheet_initialized(sheet)) return sheet;
  109. }
  110. return -1;
  111. }
  112. void eeprom_switch_to_next_sheet()
  113. {
  114. int8_t sheet = eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet));
  115. sheet = eeprom_next_initialized_sheet(sheet);
  116. if (sheet >= 0) eeprom_update_byte(&(EEPROM_Sheets_base->active_sheet), sheet);
  117. }
  118. bool __attribute__((noinline)) eeprom_is_sheet_initialized(uint8_t sheet_num) {
  119. return (eeprom_read_word(reinterpret_cast<uint16_t*>(&(EEPROM_Sheets_base->s[sheet_num].z_offset))) != EEPROM_EMPTY_VALUE16);
  120. }
  121. bool __attribute__((noinline)) eeprom_is_initialized_block(const void *__p, size_t __n) {
  122. const uint8_t *p = (const uint8_t*)__p;
  123. while (__n--) {
  124. if (eeprom_read_byte(p++) != EEPROM_EMPTY_VALUE)
  125. return true;
  126. }
  127. return false;
  128. }
  129. void eeprom_update_block_P(const void *__src, void *__dst, size_t __n) {
  130. const uint8_t *src = (const uint8_t*)__src;
  131. uint8_t *dst = (uint8_t*)__dst;
  132. while (__n--) {
  133. eeprom_update_byte(dst++, pgm_read_byte(src++));
  134. }
  135. }
  136. void eeprom_toggle(uint8_t *__p) {
  137. eeprom_write_byte(__p, !eeprom_read_byte(__p));
  138. }
  139. void __attribute__((noinline)) eeprom_increment_byte(uint8_t *__p) {
  140. eeprom_write_byte(__p, eeprom_read_byte(__p) + 1);
  141. }
  142. void __attribute__((noinline)) eeprom_increment_word(uint16_t *__p) {
  143. eeprom_write_word(__p, eeprom_read_word(__p) + 1);
  144. }
  145. void __attribute__((noinline)) eeprom_increment_dword(uint32_t *__p) {
  146. eeprom_write_dword(__p, eeprom_read_dword(__p) + 1);
  147. }
  148. void __attribute__((noinline)) eeprom_add_byte(uint8_t *__p, uint8_t add) {
  149. eeprom_write_byte(__p, eeprom_read_byte(__p) + add);
  150. }
  151. void __attribute__((noinline)) eeprom_add_word(uint16_t *__p, uint16_t add) {
  152. eeprom_write_word(__p, eeprom_read_word(__p) + add);
  153. }
  154. void __attribute__((noinline)) eeprom_add_dword(uint32_t *__p, uint32_t add) {
  155. eeprom_write_dword(__p, eeprom_read_dword(__p) + add);
  156. }
  157. uint8_t __attribute__((noinline)) eeprom_init_default_byte(uint8_t *__p, uint8_t def) {
  158. uint8_t val = eeprom_read_byte(__p);
  159. if (val == EEPROM_EMPTY_VALUE) {
  160. eeprom_write_byte(__p, def);
  161. return def;
  162. }
  163. return val;
  164. }
  165. uint16_t __attribute__((noinline)) eeprom_init_default_word(uint16_t *__p, uint16_t def) {
  166. uint16_t val = eeprom_read_word(__p);
  167. if (val == EEPROM_EMPTY_VALUE16) {
  168. eeprom_write_word(__p, def);
  169. return def;
  170. }
  171. return val;
  172. }
  173. uint32_t __attribute__((noinline)) eeprom_init_default_dword(uint32_t *__p, uint32_t def) {
  174. uint32_t val = eeprom_read_dword(__p);
  175. if (val == EEPROM_EMPTY_VALUE32) {
  176. eeprom_write_dword(__p, def);
  177. return def;
  178. }
  179. return val;
  180. }
  181. void __attribute__((noinline)) eeprom_init_default_float(float *__p, float def) {
  182. if (eeprom_read_dword((uint32_t*)__p) == EEPROM_EMPTY_VALUE32)
  183. eeprom_write_float(__p, def);
  184. }
  185. void __attribute__((noinline)) eeprom_init_default_block(void *__p, size_t __n, const void *def) {
  186. if (!eeprom_is_initialized_block(__p, __n))
  187. eeprom_update_block(def, __p, __n);
  188. }
  189. void __attribute__((noinline)) eeprom_init_default_block_P(void *__p, size_t __n, const void *def) {
  190. if (!eeprom_is_initialized_block(__p, __n))
  191. eeprom_update_block_P(def, __p, __n);
  192. }