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.

eeprom_sdcard.cpp 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /**
  23. * Implementation of EEPROM settings in SD Card
  24. */
  25. #ifdef TARGET_LPC1768
  26. #include "../../inc/MarlinConfig.h"
  27. #if ENABLED(SDCARD_EEPROM_EMULATION)
  28. //#define DEBUG_SD_EEPROM_EMULATION
  29. #include "../shared/eeprom_api.h"
  30. #include <chanfs/diskio.h>
  31. #include <chanfs/ff.h>
  32. extern uint32_t MSC_Aquire_Lock();
  33. extern uint32_t MSC_Release_Lock();
  34. FATFS fat_fs;
  35. FIL eeprom_file;
  36. bool eeprom_file_open = false;
  37. #define EEPROM_FILENAME "eeprom.dat"
  38. #ifndef MARLIN_EEPROM_SIZE
  39. #define MARLIN_EEPROM_SIZE size_t(0x1000) // 4KiB of Emulated EEPROM
  40. #endif
  41. size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
  42. bool PersistentStore::access_start() {
  43. const char eeprom_erase_value = 0xFF;
  44. MSC_Aquire_Lock();
  45. if (f_mount(&fat_fs, "", 1)) {
  46. MSC_Release_Lock();
  47. return false;
  48. }
  49. FRESULT res = f_open(&eeprom_file, EEPROM_FILENAME, FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
  50. if (res) MSC_Release_Lock();
  51. if (res == FR_OK) {
  52. UINT bytes_written;
  53. FSIZE_t file_size = f_size(&eeprom_file);
  54. f_lseek(&eeprom_file, file_size);
  55. while (file_size < capacity() && res == FR_OK) {
  56. res = f_write(&eeprom_file, &eeprom_erase_value, 1, &bytes_written);
  57. file_size++;
  58. }
  59. }
  60. if (res == FR_OK) {
  61. f_lseek(&eeprom_file, 0);
  62. f_sync(&eeprom_file);
  63. eeprom_file_open = true;
  64. }
  65. return res == FR_OK;
  66. }
  67. bool PersistentStore::access_finish() {
  68. f_close(&eeprom_file);
  69. f_unmount("");
  70. MSC_Release_Lock();
  71. eeprom_file_open = false;
  72. return true;
  73. }
  74. // This extra chit-chat goes away soon, but is helpful for now
  75. // to see errors that are happening in read_data / write_data
  76. static void debug_rw(const bool write, int &pos, const uint8_t *value, const size_t size, const FRESULT s, const size_t total=0) {
  77. #if ENABLED(DEBUG_SD_EEPROM_EMULATION)
  78. FSTR_P const rw_str = write ? F("write") : F("read");
  79. SERIAL_CHAR(' ');
  80. SERIAL_ECHOF(rw_str);
  81. SERIAL_ECHOLNPGM("_data(", pos, ",", *value, ",", size, ", ...)");
  82. if (total) {
  83. SERIAL_ECHOPGM(" f_");
  84. SERIAL_ECHOF(rw_str);
  85. SERIAL_ECHOPGM("()=", s, "\n size=", size, "\n bytes_");
  86. SERIAL_ECHOLNF(write ? F("written=") : F("read="), total);
  87. }
  88. else
  89. SERIAL_ECHOLNPGM(" f_lseek()=", s);
  90. #endif
  91. }
  92. // File function return codes for type FRESULT. This goes away soon, but
  93. // is helpful right now to see any errors in read_data and write_data.
  94. //
  95. // typedef enum {
  96. // FR_OK = 0, /* (0) Succeeded */
  97. // FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
  98. // FR_INT_ERR, /* (2) Assertion failed */
  99. // FR_NOT_READY, /* (3) The physical drive cannot work */
  100. // FR_NO_FILE, /* (4) Could not find the file */
  101. // FR_NO_PATH, /* (5) Could not find the path */
  102. // FR_INVALID_NAME, /* (6) The path name format is invalid */
  103. // FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
  104. // FR_EXIST, /* (8) Access denied due to prohibited access */
  105. // FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
  106. // FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
  107. // FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
  108. // FR_NOT_ENABLED, /* (12) The volume has no work area */
  109. // FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
  110. // FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
  111. // FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
  112. // FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
  113. // FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
  114. // FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
  115. // FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
  116. // } FRESULT;
  117. bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
  118. if (!eeprom_file_open) return true;
  119. FRESULT s;
  120. UINT bytes_written = 0;
  121. s = f_lseek(&eeprom_file, pos);
  122. if (s) {
  123. debug_rw(true, pos, value, size, s);
  124. return s;
  125. }
  126. s = f_write(&eeprom_file, (void*)value, size, &bytes_written);
  127. if (s) {
  128. debug_rw(true, pos, value, size, s, bytes_written);
  129. return s;
  130. }
  131. crc16(crc, value, size);
  132. pos += size;
  133. return bytes_written != size; // return true for any error
  134. }
  135. bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
  136. if (!eeprom_file_open) return true;
  137. UINT bytes_read = 0;
  138. FRESULT s;
  139. s = f_lseek(&eeprom_file, pos);
  140. if (s) {
  141. debug_rw(false, pos, value, size, s);
  142. return true;
  143. }
  144. if (writing) {
  145. s = f_read(&eeprom_file, (void*)value, size, &bytes_read);
  146. crc16(crc, value, size);
  147. }
  148. else {
  149. uint8_t temp[size];
  150. s = f_read(&eeprom_file, (void*)temp, size, &bytes_read);
  151. crc16(crc, temp, size);
  152. }
  153. if (s) {
  154. debug_rw(false, pos, value, size, s, bytes_read);
  155. return true;
  156. }
  157. pos += size;
  158. return bytes_read != size; // return true for any error
  159. }
  160. #endif // SDCARD_EEPROM_EMULATION
  161. #endif // TARGET_LPC1768