2017-10-25 00:55:23 +02:00
|
|
|
/**
|
|
|
|
* Marlin 3D Printer Firmware
|
|
|
|
* Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
|
|
*
|
|
|
|
* Based on Sprinter and grbl.
|
|
|
|
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
2017-08-01 18:19:23 +02:00
|
|
|
#ifdef TARGET_LPC1768
|
2017-06-17 23:19:42 +02:00
|
|
|
|
2017-09-06 13:28:32 +02:00
|
|
|
#include "../../inc/MarlinConfig.h"
|
2017-06-17 23:19:42 +02:00
|
|
|
|
2017-09-06 13:28:32 +02:00
|
|
|
#if ENABLED(EEPROM_SETTINGS)
|
2017-06-17 23:19:42 +02:00
|
|
|
|
2017-09-06 13:28:32 +02:00
|
|
|
#include "../persistent_store_api.h"
|
2017-08-01 18:19:23 +02:00
|
|
|
|
2018-08-14 00:30:26 +02:00
|
|
|
#include <chanfs/diskio.h>
|
|
|
|
#include <chanfs/ff.h>
|
2017-06-17 23:19:42 +02:00
|
|
|
|
2017-10-04 22:40:54 +02:00
|
|
|
extern uint32_t MSC_Aquire_Lock();
|
|
|
|
extern uint32_t MSC_Release_Lock();
|
|
|
|
|
2017-06-17 23:19:42 +02:00
|
|
|
FATFS fat_fs;
|
|
|
|
FIL eeprom_file;
|
2018-08-14 00:30:26 +02:00
|
|
|
bool eeprom_file_open = false;
|
2017-06-17 23:19:42 +02:00
|
|
|
|
2018-08-14 00:30:26 +02:00
|
|
|
bool PersistentStore::access_start() {
|
2017-10-19 17:44:45 +02:00
|
|
|
const char eeprom_erase_value = 0xFF;
|
2017-10-04 22:40:54 +02:00
|
|
|
MSC_Aquire_Lock();
|
Update LPC persistent store to initialize eeprom.dat with FF
This change initialize any data in eeprom.dat beyond the current file size to FF.
That way if eeprom.dat is deleted and created again, it doesn't take the old values or random ones, but rather starts with FF in all positions as a real brand new or erased eeprom.dat
Currently if you delete eeprom.dat and restart the board, the new file is created in the same sector with the same content, since FAT does not actually delete the data, just marks the sector as free. I tested by deleting the file, and then rebooting the board, and checking the file content.
The change can be tested in the same way, deleting, rebooting the board, and then the new content should be all FF.
If an eeprom file already exist with data on it, but smaller than E2END, it will be padded with FF on first access, so it will not have random or old content appended.
2017-09-28 03:43:43 +02:00
|
|
|
if (f_mount(&fat_fs, "", 1)) {
|
2017-10-04 22:40:54 +02:00
|
|
|
MSC_Release_Lock();
|
|
|
|
return false;
|
|
|
|
}
|
2017-06-17 23:19:42 +02:00
|
|
|
FRESULT res = f_open(&eeprom_file, "eeprom.dat", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
|
Update LPC persistent store to initialize eeprom.dat with FF
This change initialize any data in eeprom.dat beyond the current file size to FF.
That way if eeprom.dat is deleted and created again, it doesn't take the old values or random ones, but rather starts with FF in all positions as a real brand new or erased eeprom.dat
Currently if you delete eeprom.dat and restart the board, the new file is created in the same sector with the same content, since FAT does not actually delete the data, just marks the sector as free. I tested by deleting the file, and then rebooting the board, and checking the file content.
The change can be tested in the same way, deleting, rebooting the board, and then the new content should be all FF.
If an eeprom file already exist with data on it, but smaller than E2END, it will be padded with FF on first access, so it will not have random or old content appended.
2017-09-28 03:43:43 +02:00
|
|
|
if (res) MSC_Release_Lock();
|
|
|
|
|
|
|
|
if (res == FR_OK) {
|
2017-10-26 20:37:26 +02:00
|
|
|
UINT bytes_written;
|
|
|
|
FSIZE_t file_size = f_size(&eeprom_file);
|
Update LPC persistent store to initialize eeprom.dat with FF
This change initialize any data in eeprom.dat beyond the current file size to FF.
That way if eeprom.dat is deleted and created again, it doesn't take the old values or random ones, but rather starts with FF in all positions as a real brand new or erased eeprom.dat
Currently if you delete eeprom.dat and restart the board, the new file is created in the same sector with the same content, since FAT does not actually delete the data, just marks the sector as free. I tested by deleting the file, and then rebooting the board, and checking the file content.
The change can be tested in the same way, deleting, rebooting the board, and then the new content should be all FF.
If an eeprom file already exist with data on it, but smaller than E2END, it will be padded with FF on first access, so it will not have random or old content appended.
2017-09-28 03:43:43 +02:00
|
|
|
f_lseek(&eeprom_file, file_size);
|
2018-08-14 00:30:26 +02:00
|
|
|
while (file_size < capacity() && res == FR_OK) {
|
2017-10-19 17:44:45 +02:00
|
|
|
res = f_write(&eeprom_file, &eeprom_erase_value, 1, &bytes_written);
|
Update LPC persistent store to initialize eeprom.dat with FF
This change initialize any data in eeprom.dat beyond the current file size to FF.
That way if eeprom.dat is deleted and created again, it doesn't take the old values or random ones, but rather starts with FF in all positions as a real brand new or erased eeprom.dat
Currently if you delete eeprom.dat and restart the board, the new file is created in the same sector with the same content, since FAT does not actually delete the data, just marks the sector as free. I tested by deleting the file, and then rebooting the board, and checking the file content.
The change can be tested in the same way, deleting, rebooting the board, and then the new content should be all FF.
If an eeprom file already exist with data on it, but smaller than E2END, it will be padded with FF on first access, so it will not have random or old content appended.
2017-09-28 03:43:43 +02:00
|
|
|
file_size++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (res == FR_OK) {
|
|
|
|
f_lseek(&eeprom_file, 0);
|
|
|
|
f_sync(&eeprom_file);
|
2018-08-14 00:30:26 +02:00
|
|
|
eeprom_file_open = true;
|
Update LPC persistent store to initialize eeprom.dat with FF
This change initialize any data in eeprom.dat beyond the current file size to FF.
That way if eeprom.dat is deleted and created again, it doesn't take the old values or random ones, but rather starts with FF in all positions as a real brand new or erased eeprom.dat
Currently if you delete eeprom.dat and restart the board, the new file is created in the same sector with the same content, since FAT does not actually delete the data, just marks the sector as free. I tested by deleting the file, and then rebooting the board, and checking the file content.
The change can be tested in the same way, deleting, rebooting the board, and then the new content should be all FF.
If an eeprom file already exist with data on it, but smaller than E2END, it will be padded with FF on first access, so it will not have random or old content appended.
2017-09-28 03:43:43 +02:00
|
|
|
}
|
|
|
|
return res == FR_OK;
|
2017-06-17 23:19:42 +02:00
|
|
|
}
|
|
|
|
|
2018-08-14 00:30:26 +02:00
|
|
|
bool PersistentStore::access_finish() {
|
2017-06-17 23:19:42 +02:00
|
|
|
f_close(&eeprom_file);
|
|
|
|
f_unmount("");
|
2017-10-04 22:40:54 +02:00
|
|
|
MSC_Release_Lock();
|
2018-08-14 00:30:26 +02:00
|
|
|
eeprom_file_open = false;
|
2017-06-17 23:19:42 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-10-18 21:00:29 +02:00
|
|
|
// File function return codes for type FRESULT This goes away soon. But it is helpful right now to see
|
|
|
|
// the different errors the read_data() and write_data() functions are seeing.
|
|
|
|
//
|
2017-10-25 00:55:23 +02:00
|
|
|
// typedef enum {
|
|
|
|
// FR_OK = 0, /* (0) Succeeded */
|
|
|
|
// FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
|
|
|
// FR_INT_ERR, /* (2) Assertion failed */
|
|
|
|
// FR_NOT_READY, /* (3) The physical drive cannot work */
|
|
|
|
// FR_NO_FILE, /* (4) Could not find the file */
|
|
|
|
// FR_NO_PATH, /* (5) Could not find the path */
|
|
|
|
// FR_INVALID_NAME, /* (6) The path name format is invalid */
|
|
|
|
// FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
|
|
|
// FR_EXIST, /* (8) Access denied due to prohibited access */
|
|
|
|
// FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
|
|
|
// FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
|
|
|
// FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
|
|
|
// FR_NOT_ENABLED, /* (12) The volume has no work area */
|
|
|
|
// FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
|
|
|
// FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
|
|
|
// FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
|
|
|
// FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
|
|
|
// FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
|
|
|
// FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
|
|
|
// FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
|
|
|
// } FRESULT;
|
2017-10-18 21:00:29 +02:00
|
|
|
|
2018-08-14 00:30:26 +02:00
|
|
|
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
|
|
|
|
if(!eeprom_file_open) return true;
|
2017-10-18 21:00:29 +02:00
|
|
|
FRESULT s;
|
2017-10-26 20:37:26 +02:00
|
|
|
UINT bytes_written = 0;
|
2017-10-25 00:55:23 +02:00
|
|
|
|
2017-10-18 21:00:29 +02:00
|
|
|
s = f_lseek(&eeprom_file, pos);
|
2017-10-25 00:55:23 +02:00
|
|
|
if (s) {
|
2017-10-18 21:00:29 +02:00
|
|
|
SERIAL_PROTOCOLPAIR(" write_data(", pos); // This extra chit-chat goes away soon. But it is helpful
|
2017-10-25 00:55:23 +02:00
|
|
|
SERIAL_PROTOCOLPAIR(",", (int)value); // right now to see errors that are happening in the
|
|
|
|
SERIAL_PROTOCOLPAIR(",", (int)size); // read_data() and write_data() functions
|
2018-01-24 04:17:33 +01:00
|
|
|
SERIAL_PROTOCOLLNPGM("...)");
|
2017-10-25 00:55:23 +02:00
|
|
|
SERIAL_PROTOCOLLNPAIR(" f_lseek()=", (int)s);
|
2017-10-18 21:00:29 +02:00
|
|
|
return s;
|
|
|
|
}
|
2017-10-25 00:55:23 +02:00
|
|
|
|
2017-10-18 21:00:29 +02:00
|
|
|
s = f_write(&eeprom_file, (void *)value, size, &bytes_written);
|
2017-10-25 00:55:23 +02:00
|
|
|
if (s) {
|
2017-10-18 21:00:29 +02:00
|
|
|
SERIAL_PROTOCOLPAIR(" write_data(", pos); // This extra chit-chat goes away soon. But it is helpful
|
2017-10-25 00:55:23 +02:00
|
|
|
SERIAL_PROTOCOLPAIR(",", (int)value); // right now to see errors that are happening in the
|
|
|
|
SERIAL_PROTOCOLPAIR(",", size); // read_data() and write_data() functions
|
2018-01-24 04:17:33 +01:00
|
|
|
SERIAL_PROTOCOLLNPGM("...)");
|
2017-10-25 00:55:23 +02:00
|
|
|
SERIAL_PROTOCOLLNPAIR(" f_write()=", (int)s);
|
|
|
|
SERIAL_PROTOCOLPAIR(" size=", size);
|
|
|
|
SERIAL_PROTOCOLLNPAIR("\n bytes_written=", bytes_written);
|
2017-10-18 21:00:29 +02:00
|
|
|
return s;
|
|
|
|
}
|
2017-06-17 23:19:42 +02:00
|
|
|
crc16(crc, value, size);
|
|
|
|
pos = pos + size;
|
2017-10-18 21:00:29 +02:00
|
|
|
return (bytes_written != size); // return true for any error
|
2017-06-17 23:19:42 +02:00
|
|
|
}
|
|
|
|
|
2018-08-14 00:30:26 +02:00
|
|
|
bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
|
|
|
|
if(!eeprom_file_open) return true;
|
2017-10-26 20:37:26 +02:00
|
|
|
UINT bytes_read = 0;
|
2017-10-18 21:00:29 +02:00
|
|
|
FRESULT s;
|
|
|
|
s = f_lseek(&eeprom_file, pos);
|
2018-03-10 10:02:53 +01:00
|
|
|
if (s) {
|
2017-10-18 21:00:29 +02:00
|
|
|
SERIAL_PROTOCOLPAIR(" read_data(", pos); // This extra chit-chat goes away soon. But it is helpful
|
2017-10-25 00:55:23 +02:00
|
|
|
SERIAL_PROTOCOLPAIR(",", (int)value); // right now to see errors that are happening in the
|
|
|
|
SERIAL_PROTOCOLPAIR(",", size); // read_data() and write_data() functions
|
2018-01-24 04:17:33 +01:00
|
|
|
SERIAL_PROTOCOLLNPGM("...)");
|
2017-10-25 00:55:23 +02:00
|
|
|
SERIAL_PROTOCOLLNPAIR(" f_lseek()=", (int)s);
|
2017-10-18 21:00:29 +02:00
|
|
|
return true;
|
|
|
|
}
|
2018-01-05 02:51:18 +01:00
|
|
|
if (writing) {
|
|
|
|
s = f_read(&eeprom_file, (void *)value, size, &bytes_read);
|
|
|
|
crc16(crc, value, size);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
uint8_t temp[size];
|
|
|
|
s = f_read(&eeprom_file, (void *)temp, size, &bytes_read);
|
|
|
|
crc16(crc, temp, size);
|
|
|
|
}
|
2017-10-25 00:55:23 +02:00
|
|
|
if (s) {
|
2017-10-18 21:00:29 +02:00
|
|
|
SERIAL_PROTOCOLPAIR(" read_data(", pos); // This extra chit-chat goes away soon. But it is helpful
|
2017-10-25 00:55:23 +02:00
|
|
|
SERIAL_PROTOCOLPAIR(",", (int)value); // right now to see errors that are happening in the
|
|
|
|
SERIAL_PROTOCOLPAIR(",", size); // read_data() and write_data() functions
|
2018-01-24 04:17:33 +01:00
|
|
|
SERIAL_PROTOCOLLNPGM("...)");
|
2017-10-25 00:55:23 +02:00
|
|
|
SERIAL_PROTOCOLLNPAIR(" f_write()=", (int)s);
|
|
|
|
SERIAL_PROTOCOLPAIR(" size=", size);
|
|
|
|
SERIAL_PROTOCOLLNPAIR("\n bytes_read=", bytes_read);
|
2017-10-18 21:00:29 +02:00
|
|
|
return true;
|
|
|
|
}
|
2017-06-17 23:19:42 +02:00
|
|
|
pos = pos + size;
|
2017-10-18 21:00:29 +02:00
|
|
|
return bytes_read != size; // return true for any error
|
2017-06-17 23:19:42 +02:00
|
|
|
}
|
|
|
|
|
2018-08-14 00:30:26 +02:00
|
|
|
bool PersistentStore::write_data(const int pos, uint8_t* value, size_t size) {
|
|
|
|
int data_pos = pos;
|
|
|
|
uint16_t crc = 0;
|
|
|
|
return write_data(data_pos, value, size, &crc);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PersistentStore::read_data(const int pos, uint8_t* value, size_t size) {
|
|
|
|
int data_pos = pos;
|
|
|
|
uint16_t crc = 0;
|
|
|
|
return read_data(data_pos, value, size, &crc);
|
|
|
|
}
|
|
|
|
|
|
|
|
const size_t PersistentStore::capacity() {
|
|
|
|
return 4096; //4KiB of Emulated EEPROM
|
|
|
|
}
|
2017-06-17 23:19:42 +02:00
|
|
|
|
|
|
|
#endif // EEPROM_SETTINGS
|
2017-09-06 13:28:32 +02:00
|
|
|
#endif // TARGET_LPC1768
|