My Marlin configs for Fabrikator Mini and CTC i3 Pro B
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.

persistent_store_eeprom.cpp 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /**
  2. * Marlin 3D Printer Firmware
  3. *
  4. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  5. * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. */
  21. #ifdef __SAMD51__
  22. #include "../../inc/MarlinConfig.h"
  23. #if ENABLED(EEPROM_SETTINGS)
  24. #include "../shared/persistent_store_api.h"
  25. #if ENABLED(FLASH_EEPROM_EMULATION)
  26. #define NVMCTRL_CMD(c) do{ \
  27. SYNC(!NVMCTRL->STATUS.bit.READY); \
  28. NVMCTRL->INTFLAG.bit.DONE = true; \
  29. NVMCTRL->CTRLB.reg = c | NVMCTRL_CTRLB_CMDEX_KEY; \
  30. SYNC(NVMCTRL->INTFLAG.bit.DONE); \
  31. }while(0)
  32. #define NVMCTRL_FLUSH() do{ \
  33. if (NVMCTRL->SEESTAT.bit.LOAD) \
  34. NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_SEEFLUSH); \
  35. }while(0)
  36. #endif
  37. bool PersistentStore::access_start() {
  38. #if ENABLED(FLASH_EEPROM_EMULATION)
  39. NVMCTRL->SEECFG.reg = NVMCTRL_SEECFG_WMODE_BUFFERED; // Buffered mode and segment reallocation active
  40. #endif
  41. return true;
  42. }
  43. bool PersistentStore::access_finish() {
  44. #if ENABLED(FLASH_EEPROM_EMULATION)
  45. NVMCTRL_FLUSH();
  46. if (!NVMCTRL->SEESTAT.bit.LOCK)
  47. NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_LSEE); // Lock E2P data write access
  48. #endif
  49. return true;
  50. }
  51. bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
  52. #if ENABLED(FLASH_EEPROM_EMULATION)
  53. if (NVMCTRL->SEESTAT.bit.RLOCK)
  54. NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_USEE); // Unlock E2P data write access
  55. #endif
  56. while (size--) {
  57. const uint8_t v = *value;
  58. #if ENABLED(FLASH_EEPROM_EMULATION)
  59. SYNC(NVMCTRL->SEESTAT.bit.BUSY);
  60. if (NVMCTRL->INTFLAG.bit.SEESFULL)
  61. NVMCTRL_FLUSH(); // Next write will trigger a sector reallocation. I need to flush 'pagebuffer'
  62. ((volatile uint8_t *)SEEPROM_ADDR)[pos] = v;
  63. SYNC(!NVMCTRL->INTFLAG.bit.SEEWRC);
  64. #else
  65. uint8_t * const p = (uint8_t * const)pos;
  66. if (v != eeprom_read_byte(p)) {
  67. eeprom_write_byte(p, v);
  68. delay(2);
  69. if (eeprom_read_byte(p) != v) {
  70. SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
  71. return true;
  72. }
  73. }
  74. #endif
  75. crc16(crc, &v, 1);
  76. pos++;
  77. value++;
  78. }
  79. return false;
  80. }
  81. bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
  82. while (size--) {
  83. uint8_t c;
  84. #if ENABLED(FLASH_EEPROM_EMULATION)
  85. SYNC(NVMCTRL->SEESTAT.bit.BUSY);
  86. c = ((volatile uint8_t *)SEEPROM_ADDR)[pos];
  87. #else
  88. c = eeprom_read_byte((uint8_t*)pos);
  89. #endif
  90. if (writing) *value = c;
  91. crc16(crc, &c, 1);
  92. pos++;
  93. value++;
  94. }
  95. return false;
  96. }
  97. size_t PersistentStore::capacity() {
  98. #if ENABLED(FLASH_EEPROM_EMULATION)
  99. const uint8_t psz = NVMCTRL->SEESTAT.bit.PSZ,
  100. sblk = NVMCTRL->SEESTAT.bit.SBLK;
  101. if (!psz && !sblk) return 0;
  102. else if (psz <= 2) return (0x200 << psz);
  103. else if (sblk == 1 || psz == 3) return 4096;
  104. else if (sblk == 2 || psz == 4) return 8192;
  105. else if (sblk <= 4 || psz == 5) return 16384;
  106. else if (sblk >= 9 && psz == 7) return 65536;
  107. else return 32768;
  108. #else
  109. return E2END + 1;
  110. #endif
  111. }
  112. #endif // EEPROM_SETTINGS
  113. #endif // __SAMD51__