Added an exclusion zone in the EEPROM.

That zone is used by some boot loaders to save flags that control the flashing at boot process.

The exclusion zone should be defined in the **.INI** board environments that require it by:
```log
 -DEEPROM_EXCL_ZONE=100,200
```
or in the board pin file by:
```c++
#define EEPROM_EXCL_ZONE 100,200  // Test a range
or
#define EEPROM_EXCL_ZONE 333      // Test a single byte
```
For example, in the Ender-3S1 F4: Marlin\src\pins\stm32f4\pins_CREALITY_V24S1_301F4.h:
```c++
#define EEPROM_EXCL_ZONE 919,926  // Test a range
```

### Related Issues

In the Ender-3 S1 with the STM32F401 SoC the range of exclusion is from 919 to 926. Even if the zone is filled with 0xFF values, the boot loader changes it when the printer is rebooted:

```log
0370: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0380: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0390: FF FF FF FF 00 FF FF FF FF FF FF FF FF 66 FF FF
03A0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
03B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
```
If the zone is not excluded, the boot loader may not allow flashing new firmware and may also cause CRC EEPROM corruption.

Perhaps related to:
https://github.com/mriscoc/Ender3V2S1/issues/125
https://github.com/mriscoc/Ender3V2S1/issues/1180
https://github.com/MarlinFirmware/Marlin/issues/26144
F4-CRC-TEST
Miguel Risco-Castillo 4 months ago
parent ec573df5fc
commit ff35dc6d3f

@ -35,14 +35,14 @@
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE size_t(E2END + 1)
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { return true; }
bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
uint16_t written = 0;
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
uint8_t v = *value;
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
@ -61,7 +61,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -958,14 +958,14 @@ static void ee_Init() {
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE 0x1000 // 4KB
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { ee_Init(); return true; }
bool PersistentStore::access_finish() { ee_Flush(); return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
uint16_t written = 0;
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
uint8_t v = *value;
if (v != ee_Read(uint32_t(p))) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
ee_Write(uint32_t(p), v);
@ -984,7 +984,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = ee_Read(uint32_t(pos));
uint8_t c = ee_Read(uint32_t(REAL_EEPROM_ADDR(pos)));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -36,14 +36,14 @@
#ifndef MARLIN_EEPROM_SIZE
#error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM."
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { eeprom_init(); return true; }
bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
uint16_t written = 0;
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
uint8_t v = *value;
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
@ -62,7 +62,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -31,24 +31,28 @@
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE 0x1000 // 4KB
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { return EEPROM.begin(MARLIN_EEPROM_SIZE); }
bool PersistentStore::access_finish() { EEPROM.end(); return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
for (size_t i = 0; i < size; i++) {
EEPROM.write(pos++, value[i]);
const int p = REAL_EEPROM_ADDR(pos);
EEPROM.write(p, value[i]);
crc16(crc, &value[i], 1);
++pos;
}
return false;
}
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
for (size_t i = 0; i < size; i++) {
uint8_t c = EEPROM.read(pos++);
const int p = REAL_EEPROM_ADDR(pos);
uint8_t c = EEPROM.read(p);
if (writing) value[i] = c;
crc16(crc, &c, 1);
++pos;
}
return false;
}

@ -37,7 +37,7 @@
#error "MARLIN_EEPROM_SIZE is required for IIC_BL24CXX_EEPROM."
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() {
eeprom_init();
@ -49,7 +49,7 @@ bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
while (size--) {
uint8_t v = *value;
uint8_t *const p = (uint8_t *const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
// EEPROM has only ~100,000 write cycles,
// so only write bytes that have changed!
@ -70,16 +70,10 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size,
uint16_t *crc, const bool writing /*=true*/) {
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing /*=true*/) {
do {
uint8_t *const p = (uint8_t *const)pos;
uint8_t c = eeprom_read_byte(p);
if (writing)
{
*value = c;
}
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;
value++;

@ -38,9 +38,7 @@
#define MARLIN_EEPROM_SIZE 0x1000 // 4KB
#endif
size_t PersistentStore::capacity() {
return MARLIN_EEPROM_SIZE;
}
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
#define _ALIGN(x) __attribute__((aligned(x)))
static char _ALIGN(4) HAL_eeprom_data[MARLIN_EEPROM_SIZE];
@ -85,11 +83,10 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uint16_t *crc, const bool writing /*=true*/) {
for (size_t i = 0; i < size; i++) {
uint8_t c = HAL_eeprom_data[pos + i];
const uint8_t c = HAL_eeprom_data[pos + i];
if (writing) value[i] = c;
crc16(crc, &c, 1);
}
pos += size;
return false;
}

@ -35,7 +35,7 @@
#ifndef MARLIN_EEPROM_SIZE
#error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM."
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_finish() { return true; }
@ -56,7 +56,7 @@ bool PersistentStore::access_start() {
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
while (size--) {
uint8_t *const p = (uint8_t *const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
uint8_t v = *value;
// EEPROM has only ~100,000 write cycles,
// so only write bytes that have changed!
@ -77,10 +77,8 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing /*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t *)pos);
if (writing && value) {
*value = c;
}
const uint8_t c = eeprom_read_byte((uint8_t *)REAL_EEPROM_ADDR(pos));
if (writing && value) *value = c;
crc16(crc, &c, 1);
pos++;

@ -35,7 +35,7 @@
uint8_t buffer[MARLIN_EEPROM_SIZE];
char filename[] = "eeprom.dat";
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() {
const char eeprom_erase_value = 0xFF;

@ -61,7 +61,7 @@ static uint8_t ram_eeprom[MARLIN_EEPROM_SIZE] __attribute__((aligned(4))) = {0};
static bool eeprom_dirty = false;
static int current_slot = 0;
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() {
uint32_t first_nblank_loc, first_nblank_val;
@ -112,7 +112,8 @@ bool PersistentStore::access_finish() {
}
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
for (size_t i = 0; i < size; i++) ram_eeprom[pos + i] = value[i];
const int p = REAL_EEPROM_ADDR(pos);
for (size_t i = 0; i < size; i++) ram_eeprom[p + i] = value[i];
eeprom_dirty = true;
crc16(crc, value, size);
pos += size;
@ -120,8 +121,9 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
}
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
const int p = REAL_EEPROM_ADDR(pos);
const uint8_t * const buff = writing ? &value[0] : &ram_eeprom[pos];
if (writing) for (size_t i = 0; i < size; i++) value[i] = ram_eeprom[pos + i];
if (writing) for (size_t i = 0; i < size; i++) value[i] = ram_eeprom[p + i];
crc16(crc, buff, size);
pos += size;
return false; // return true for any error

@ -49,7 +49,7 @@ bool eeprom_file_open = false;
#define MARLIN_EEPROM_SIZE size_t(0x1000) // 4KiB of Emulated EEPROM
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() {
const char eeprom_erase_value = 0xFF;

@ -36,7 +36,7 @@
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE 0x8000 // 32K
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { eeprom_init(); return true; }
bool PersistentStore::access_finish() { return true; }
@ -45,7 +45,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
uint16_t written = 0;
while (size--) {
uint8_t v = *value;
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
@ -64,7 +64,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
// Read from external EEPROM
const uint8_t c = eeprom_read_byte((uint8_t*)pos);
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -37,19 +37,24 @@ static const uint8_t flashdata[TOTAL_FLASH_SIZE] __attribute__((__aligned__(256
#include "../shared/eeprom_api.h"
size_t PersistentStore::capacity() {
return MARLIN_EEPROM_SIZE;
/* const uint8_t psz = NVMCTRL->SEESTAT.bit.PSZ,
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
/*
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
const uint8_t psz = NVMCTRL->SEESTAT.bit.PSZ,
sblk = NVMCTRL->SEESTAT.bit.SBLK;
return (!psz && !sblk) ? 0
: (psz <= 2) ? (0x200 << psz)
: (sblk == 1 || psz == 3) ? 4096
: (sblk == 2 || psz == 4) ? 8192
: (sblk <= 4 || psz == 5) ? 16384
: (sblk >= 9 && psz == 7) ? 65536
: 32768;*/
return (
(!psz && !sblk) ? 0
: (psz <= 2) ? (0x200 << psz)
: (sblk == 1 || psz == 3) ? 4096
: (sblk == 2 || psz == 4) ? 8192
: (sblk <= 4 || psz == 5) ? 16384
: (sblk >= 9 && psz == 7) ? 65536
: 32768
) - eeprom_exclude_size;
}
*/
uint32_t PAGE_SIZE;
uint32_t ROW_SIZE;
@ -99,8 +104,7 @@ bool PersistentStore::access_finish() {
volatile uint32_t *dst_addr = (volatile uint32_t *) &flashdata;
uint32_t *pointer = (uint32_t *) buffer;
for (uint32_t i = 0; i < TOTAL_FLASH_SIZE; i+=4) {
for (uint32_t i = 0; i < TOTAL_FLASH_SIZE; i += 4) {
*dst_addr = (uint32_t) *pointer;
pointer++;
dst_addr ++;
@ -120,19 +124,19 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
if (!hasWritten) {
// init temp buffer
buffer = (uint8_t *) malloc(MARLIN_EEPROM_SIZE);
hasWritten=true;
hasWritten = true;
}
memcpy(buffer+pos,value,size);
memcpy(buffer + REAL_EEPROM_ADDR(pos), value, size);
pos += size;
return false;
}
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
volatile uint8_t *dst_addr = (volatile uint8_t *) &flashdata;
dst_addr += pos;
volatile uint8_t *dst_addr = (volatile uint8_t *) &flashdata;
dst_addr += REAL_EEPROM_ADDR(pos);
memcpy(value,(const void *) dst_addr,size);
memcpy(value, (const void *)dst_addr, size);
pos += size;
return false;
}

@ -38,7 +38,7 @@
static bool initialized;
size_t PersistentStore::capacity() { return qspi.size(); }
size_t PersistentStore::capacity() { return qspi.size() - eeprom_exclude_size; }
bool PersistentStore::access_start() {
if (!initialized) {
@ -56,7 +56,7 @@ bool PersistentStore::access_finish() {
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
while (size--) {
const uint8_t v = *value;
qspi.writeByte(pos, v);
qspi.writeByte(REAL_EEPROM_ADDR(pos), v);
crc16(crc, &v, 1);
pos++;
value++;
@ -66,7 +66,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
while (size--) {
uint8_t c = qspi.readByte(pos);
const uint8_t c = qspi.readByte(REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -42,7 +42,7 @@
#ifndef MARLIN_EEPROM_SIZE
#error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM."
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { eeprom_init(); return true; }
bool PersistentStore::access_finish() { return true; }
@ -51,7 +51,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
uint16_t written = 0;
while (size--) {
const uint8_t v = *value;
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
@ -69,7 +69,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
while (size--) {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -35,7 +35,7 @@
static bool initialized;
size_t PersistentStore::capacity() { return qspi.size(); }
size_t PersistentStore::capacity() { return qspi.size() - eeprom_exclude_size; }
bool PersistentStore::access_start() {
if (!initialized) {
@ -53,7 +53,7 @@ bool PersistentStore::access_finish() {
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
while (size--) {
const uint8_t v = *value;
qspi.writeByte(pos, v);
qspi.writeByte(REAL_EEPROM_ADDR(pos), v);
crc16(crc, &v, 1);
pos++;
value++;
@ -63,7 +63,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
while (size--) {
uint8_t c = qspi.readByte(pos);
const uint8_t c = qspi.readByte(REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -40,7 +40,7 @@
#ifndef MARLIN_EEPROM_SIZE
#error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM."
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { eeprom_init(); return true; }
bool PersistentStore::access_finish() { return true; }
@ -49,7 +49,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
uint16_t written = 0;
while (size--) {
const uint8_t v = *value;
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
@ -67,7 +67,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
while (size--) {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -44,7 +44,7 @@
#error "MARLIN_EEPROM_SIZE is required for IIC_BL24CXX_EEPROM."
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { eeprom_init(); return true; }
bool PersistentStore::access_finish() { return true; }
@ -53,7 +53,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
uint16_t written = 0;
while (size--) {
uint8_t v = *value;
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
@ -71,8 +71,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t * const p = (uint8_t * const)pos;
uint8_t c = eeprom_read_byte(p);
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -101,7 +101,7 @@ static bool eeprom_data_written = false;
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE size_t(E2END + 1)
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() {
@ -245,14 +245,15 @@ bool PersistentStore::access_finish() {
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
while (size--) {
uint8_t v = *value;
const int p = REAL_EEPROM_ADDR(pos);
#if ENABLED(FLASH_EEPROM_LEVELING)
if (v != ram_eeprom[pos]) {
ram_eeprom[pos] = v;
if (v != ram_eeprom[p]) {
ram_eeprom[p] = v;
eeprom_data_written = true;
}
#else
if (v != eeprom_buffered_read_byte(pos)) {
eeprom_buffered_write_byte(pos, v);
if (v != eeprom_buffered_read_byte(p)) {
eeprom_buffered_write_byte(p, v);
eeprom_data_written = true;
}
#endif
@ -265,7 +266,8 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
const uint8_t c = TERN(FLASH_EEPROM_LEVELING, ram_eeprom[pos], eeprom_buffered_read_byte(pos));
const int p = REAL_EEPROM_ADDR(pos);
const uint8_t c = TERN(FLASH_EEPROM_LEVELING, ram_eeprom[p], eeprom_buffered_read_byte(p));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -40,7 +40,7 @@
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE 0x1000 // 4KB
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
#define _ALIGN(x) __attribute__ ((aligned(x)))
static char _ALIGN(4) HAL_eeprom_data[MARLIN_EEPROM_SIZE];

@ -33,7 +33,7 @@
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE 0x1000 // 4KB
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { return true; }
bool PersistentStore::access_finish() { return true; }

@ -38,7 +38,7 @@
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE size_t(E2END + 1)
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { eeprom_init(); return true; }
bool PersistentStore::access_finish() { return true; }
@ -47,7 +47,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
uint16_t written = 0;
while (size--) {
uint8_t v = *value;
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
@ -66,7 +66,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
// Read from either external EEPROM, program flash or Backup SRAM
const uint8_t c = eeprom_read_byte((uint8_t*)pos);
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -41,7 +41,7 @@
#error "MARLIN_EEPROM_SIZE is required for IIC_BL24CXX_EEPROM."
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { eeprom_init(); return true; }
bool PersistentStore::access_finish() { return true; }
@ -50,7 +50,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
uint16_t written = 0;
while (size--) {
uint8_t v = *value;
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
@ -68,8 +68,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t * const p = (uint8_t * const)pos;
uint8_t c = eeprom_read_byte(p);
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -41,7 +41,7 @@
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE ((EEPROM_PAGE_SIZE) * 2)
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
static uint8_t ram_eeprom[MARLIN_EEPROM_SIZE] __attribute__((aligned(4))) = {0};
static bool eeprom_dirty = false;

@ -39,7 +39,7 @@
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE 0x1000 // 4KB
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
#define _ALIGN(x) __attribute__ ((aligned(x))) // SDIO uint32_t* compat.
static char _ALIGN(4) HAL_eeprom_data[MARLIN_EEPROM_SIZE];

@ -36,7 +36,7 @@
#ifndef MARLIN_EEPROM_SIZE
#error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM."
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_finish() { return true; }
@ -57,7 +57,7 @@ bool PersistentStore::access_start() {
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
uint16_t written = 0;
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
uint8_t v = *value;
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
@ -76,7 +76,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing && value) *value = c;
crc16(crc, &c, 1);
pos++;

@ -36,7 +36,7 @@
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE size_t(E2END + 1)
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { return true; }
bool PersistentStore::access_finish() { return true; }
@ -44,7 +44,7 @@ bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
uint16_t written = 0;
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
uint8_t v = *value;
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
@ -63,7 +63,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -35,7 +35,7 @@
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE size_t(E2END + 1)
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { return true; }
bool PersistentStore::access_finish() { return true; }
@ -43,7 +43,7 @@ bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
uint16_t written = 0;
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
uint8_t v = *value;
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
@ -62,7 +62,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -35,7 +35,7 @@
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE size_t(E2END + 1)
#endif
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE - eeprom_exclude_size; }
bool PersistentStore::access_start() { return true; }
bool PersistentStore::access_finish() { return true; }
@ -43,7 +43,7 @@ bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
uint16_t written = 0;
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t * const p = (uint8_t * const)REAL_EEPROM_ADDR(pos);
uint8_t v = *value;
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
@ -62,7 +62,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
const uint8_t c = eeprom_read_byte((uint8_t*)REAL_EEPROM_ADDR(pos));
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;

@ -26,6 +26,19 @@
#include "../../libs/crc16.h"
// For testing. Define with -DEEPROM_EXCL_ZONE=919,926 in INI files.
//#define EEPROM_EXCL_ZONE 919,926 // Test a range
//#define EEPROM_EXCL_ZONE 333 // Test a single byte
#ifdef EEPROM_EXCL_ZONE
static constexpr int eeprom_exclude_zone[] = { EEPROM_EXCL_ZONE },
eeprom_exclude_size = eeprom_exclude_zone[COUNT(eeprom_exclude_zone) - 1] - eeprom_exclude_zone[0] + 1;
#define REAL_EEPROM_ADDR(A) (A < eeprom_exclude_zone[0] ? (A) : (A) + eeprom_exclude_size)
#else
#define REAL_EEPROM_ADDR(A) (A)
static constexpr int eeprom_exclude_size = 0;
#endif
class PersistentStore {
public:

@ -1841,7 +1841,8 @@ bool unified_bed_leveling::smart_fill_one(const uint8_t x, const uint8_t y, cons
print_hex_word(i);
SERIAL_ECHOPGM(": ");
for (uint16_t j = 0; j < 16; j++) {
persistentStore.read_data(i + j, &cccc, sizeof(uint8_t));
int pos = i + j;
persistentStore.read_data(pos, &cccc, sizeof(uint8_t));
print_hex_byte(cccc);
SERIAL_CHAR(' ');
}

@ -712,7 +712,7 @@ static_assert(settingsdata_size <= MARLIN_EEPROM_SIZE, "EEPROM too small to cont
MarlinSettings settings;
uint16_t MarlinSettings::datasize() { return settingsdata_size; }
uint16_t MarlinSettings::datasize() { return sizeof(SettingsData); }
/**
* Post-process after Retrieve or Reset
@ -797,7 +797,8 @@ void MarlinSettings::postprocess() {
bool MarlinSettings::sd_update_status() {
uint8_t val;
persistentStore.read_data(SD_FIRMWARE_UPDATE_EEPROM_ADDR, &val);
int pos = SD_FIRMWARE_UPDATE_EEPROM_ADDR;
persistentStore.read_data(pos, &val);
return (val == SD_FIRMWARE_UPDATE_ACTIVE_VALUE);
}
@ -850,9 +851,6 @@ void MarlinSettings::postprocess() {
#define EEPROM_READ(V...) do{ SERIAL_ECHOPGM("READ: ", F(STRINGIFY(FIRST(V)))); EEPROM_READ_(V); SERIAL_ECHOLNPGM(" CRC: ", working_crc); }while(0)
#define EEPROM_READ_ALWAYS(V...) do{ SERIAL_ECHOPGM("READ: ", F(STRINGIFY(FIRST(V)))); EEPROM_READ_ALWAYS_(V); SERIAL_ECHOLNPGM(" CRC: ", working_crc); }while(0)
#define EEPROM_WRITE(V...) do{ SERIAL_ECHOPGM("WRITE: ", F(STRINGIFY(FIRST(V)))); EEPROM_WRITE_(V); SERIAL_ECHOLNPGM(" CRC: ", working_crc); }while(0)
// #define EEPROM_READ(V...) do{ SERIAL_ECHOLNPGM("READ: ", F(STRINGIFY(FIRST(V)))); EEPROM_READ_(V); }while(0)
// #define EEPROM_READ_ALWAYS(V...) do{ SERIAL_ECHOLNPGM("READ: ", F(STRINGIFY(FIRST(V)))); EEPROM_READ_ALWAYS_(V); }while(0)
// #define EEPROM_WRITE(V...) do{ SERIAL_ECHOLNPGM("WRITE: ", F(STRINGIFY(FIRST(V)))); EEPROM_WRITE_(V); }while(0)
#else
#define EEPROM_READ(V...) EEPROM_READ_(V)
#define EEPROM_READ_ALWAYS(V...) EEPROM_READ_ALWAYS_(V)

@ -35,4 +35,6 @@
#define DISABLE_DEBUG false // DISABLE_(DEBUG|JTAG) is not supported for STM32F4.
#define ALLOW_STM32F4
#define EEPROM_EXCL_ZONE 919,926 // Exclude EEPROM area used as bootloader flag zone
#include "../stm32f1/pins_CREALITY_V24S1_301.h"

Loading…
Cancel
Save