Pre-clean DUE flash eeprom code

This commit is contained in:
Scott Lahteine 2020-04-30 20:09:51 -05:00
parent 306578d7be
commit 76bc7bf7b8
2 changed files with 78 additions and 90 deletions

View file

@ -19,6 +19,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#ifdef ARDUINO_ARCH_SAM
#include "../../inc/MarlinConfig.h"
#if ENABLED(FLASH_EEPROM_EMULATION)
#include "../shared/Marduino.h"
#include "../shared/eeprom_if.h"
#include "../shared/eeprom_api.h"
/* EEPROM emulation over flash with reduced wear /* EEPROM emulation over flash with reduced wear
* *
@ -50,15 +59,7 @@
* *
*/ */
#ifdef ARDUINO_ARCH_SAM //#define EE_EMU_DEBUG
#include "../../inc/MarlinConfig.h"
#if ENABLED(FLASH_EEPROM_EMULATION)
#include "../shared/Marduino.h"
#include "../shared/eeprom_if.h"
#include "../shared/eeprom_api.h"
#define EEPROMSize 4096 #define EEPROMSize 4096
#define PagesPerGroup 128 #define PagesPerGroup 128
@ -135,15 +136,18 @@ static uint8_t buffer[256] = {0}, // The RAM buffer to accumulate writes
curPage = 0, // Current FLASH page inside the group curPage = 0, // Current FLASH page inside the group
curGroup = 0xFF; // Current FLASH group curGroup = 0xFF; // Current FLASH group
//#define EE_EMU_DEBUG #define DEBUG_OUT ENABLED(EE_EMU_DEBUG)
#include "../../core/debug_out.h"
static void ee_Dump(const int page, const void* data) {
#ifdef EE_EMU_DEBUG #ifdef EE_EMU_DEBUG
static void ee_Dump(int page,const void* data) {
const uint8_t* c = (const uint8_t*) data; const uint8_t* c = (const uint8_t*) data;
char buffer[80]; char buffer[80];
sprintf_P(buffer, PSTR("Page: %d (0x%04x)\n"), page, page); sprintf_P(buffer, PSTR("Page: %d (0x%04x)\n"), page, page);
SERIAL_ECHO(buffer); DEBUG_ECHO(buffer);
char* p = &buffer[0]; char* p = &buffer[0];
for (int i = 0; i< PageSize; ++i) { for (int i = 0; i< PageSize; ++i) {
@ -153,12 +157,16 @@ static uint8_t buffer[256] = {0}, // The RAM buffer to accumulate writes
if ((i & 0xF) == 0xF) { if ((i & 0xF) == 0xF) {
*p++ = '\n'; *p++ = '\n';
*p = 0; *p = 0;
SERIAL_ECHO(buffer); DEBUG_ECHO(buffer);
p = &buffer[0]; p = &buffer[0];
} }
} }
}
#else
UNUSED(page);
UNUSED(data);
#endif #endif
}
/* Flash Writing Protection Key */ /* Flash Writing Protection Key */
#define FWP_KEY 0x5Au #define FWP_KEY 0x5Au
@ -171,7 +179,6 @@ static uint8_t buffer[256] = {0}, // The RAM buffer to accumulate writes
#define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE) #define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE)
#endif #endif
/** /**
* Writes the contents of the specified page (no previous erase) * Writes the contents of the specified page (no previous erase)
* @param page (page #) * @param page (page #)
@ -181,7 +188,7 @@ __attribute__ ((long_call, section (".ramfunc")))
static bool ee_PageWrite(uint16_t page, const void* data) { static bool ee_PageWrite(uint16_t page, const void* data) {
uint16_t i; uint16_t i;
uint32_t addrflash = ((uint32_t)getFlashStorage(page)); uint32_t addrflash = uint32_t(getFlashStorage(page));
// Read the flash contents // Read the flash contents
uint32_t pageContents[PageSize>>2]; uint32_t pageContents[PageSize>>2];
@ -196,13 +203,11 @@ static bool ee_PageWrite(uint16_t page,const void* data) {
for (i = 0; i <PageSize >> 2; i++) for (i = 0; i <PageSize >> 2; i++)
pageContents[i] = (((uint32_t*)data)[i]) | (~(pageContents[i] ^ ((uint32_t*)data)[i])); pageContents[i] = (((uint32_t*)data)[i]) | (~(pageContents[i] ^ ((uint32_t*)data)[i]));
#ifdef EE_EMU_DEBUG DEBUG_ECHO_START();
SERIAL_ECHO_START(); DEBUG_ECHOLNPAIR("EEPROM PageWrite ", page);
SERIAL_ECHOLNPAIR("EEPROM PageWrite ", page); DEBUG_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
SERIAL_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash); DEBUG_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
SERIAL_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0)); DEBUG_FLUSH();
SERIAL_FLUSH();
#endif
// Get the page relative to the start of the EFC controller, and the EFC controller to use // Get the page relative to the start of the EFC controller, and the EFC controller to use
Efc *efc; Efc *efc;
@ -244,10 +249,8 @@ static bool ee_PageWrite(uint16_t page,const void* data) {
// Reenable interrupts // Reenable interrupts
__enable_irq(); __enable_irq();
#ifdef EE_EMU_DEBUG DEBUG_ECHO_START();
SERIAL_ECHO_START(); DEBUG_ECHOLNPAIR("EEPROM Unlock failure for page ", page);
SERIAL_ECHOLNPAIR("EEPROM Unlock failure for page ", page);
#endif
return false; return false;
} }
@ -271,10 +274,9 @@ static bool ee_PageWrite(uint16_t page,const void* data) {
// Reenable interrupts // Reenable interrupts
__enable_irq(); __enable_irq();
#ifdef EE_EMU_DEBUG DEBUG_ECHO_START();
SERIAL_ECHO_START(); DEBUG_ECHOLNPAIR("EEPROM Write failure for page ", page);
SERIAL_ECHOLNPAIR("EEPROM Write failure for page ", page);
#endif
return false; return false;
} }
@ -288,8 +290,8 @@ static bool ee_PageWrite(uint16_t page,const void* data) {
if (memcmp(getFlashStorage(page),data,PageSize)) { if (memcmp(getFlashStorage(page),data,PageSize)) {
#ifdef EE_EMU_DEBUG #ifdef EE_EMU_DEBUG
SERIAL_ECHO_START(); DEBUG_ECHO_START();
SERIAL_ECHOLNPAIR("EEPROM Verify Write failure for page ", page); DEBUG_ECHOLNPAIR("EEPROM Verify Write failure for page ", page);
ee_Dump( page, (uint32_t *)addrflash); ee_Dump( page, (uint32_t *)addrflash);
ee_Dump(-page, data); ee_Dump(-page, data);
@ -308,7 +310,7 @@ static bool ee_PageWrite(uint16_t page,const void* data) {
} }
} }
} }
SERIAL_ECHOLNPAIR("--> Differing bits: ", count); DEBUG_ECHOLNPAIR("--> Differing bits: ", count);
#endif #endif
return false; return false;
@ -325,15 +327,13 @@ __attribute__ ((long_call, section (".ramfunc")))
static bool ee_PageErase(uint16_t page) { static bool ee_PageErase(uint16_t page) {
uint16_t i; uint16_t i;
uint32_t addrflash = ((uint32_t)getFlashStorage(page)); uint32_t addrflash = uint32_t(getFlashStorage(page));
#ifdef EE_EMU_DEBUG DEBUG_ECHO_START();
SERIAL_ECHO_START(); DEBUG_ECHOLNPAIR("EEPROM PageErase ", page);
SERIAL_ECHOLNPAIR("EEPROM PageErase ", page); DEBUG_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
SERIAL_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash); DEBUG_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
SERIAL_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0)); DEBUG_FLUSH();
SERIAL_FLUSH();
#endif
// Get the page relative to the start of the EFC controller, and the EFC controller to use // Get the page relative to the start of the EFC controller, and the EFC controller to use
Efc *efc; Efc *efc;
@ -374,10 +374,9 @@ static bool ee_PageErase(uint16_t page) {
// Reenable interrupts // Reenable interrupts
__enable_irq(); __enable_irq();
#ifdef EE_EMU_DEBUG DEBUG_ECHO_START();
SERIAL_ECHO_START(); DEBUG_ECHOLNPAIR("EEPROM Unlock failure for page ",page);
SERIAL_ECHOLNPAIR("EEPROM Unlock failure for page ",page);
#endif
return false; return false;
} }
@ -399,10 +398,9 @@ static bool ee_PageErase(uint16_t page) {
// Reenable interrupts // Reenable interrupts
__enable_irq(); __enable_irq();
#ifdef EE_EMU_DEBUG DEBUG_ECHO_START();
SERIAL_ECHO_START(); DEBUG_ECHOLNPAIR("EEPROM Erase failure for page ",page);
SERIAL_ECHOLNPAIR("EEPROM Erase failure for page ",page);
#endif
return false; return false;
} }
@ -416,19 +414,16 @@ static bool ee_PageErase(uint16_t page) {
uint32_t * aligned_src = (uint32_t *) addrflash; uint32_t * aligned_src = (uint32_t *) addrflash;
for (i = 0; i < PageSize >> 2; i++) { for (i = 0; i < PageSize >> 2; i++) {
if (*aligned_src++ != 0xFFFFFFFF) { if (*aligned_src++ != 0xFFFFFFFF) {
DEBUG_ECHO_START();
#ifdef EE_EMU_DEBUG DEBUG_ECHOLNPAIR("EEPROM Verify Erase failure for page ",page);
SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR("EEPROM Verify Erase failure for page ",page);
ee_Dump(page, (uint32_t *)addrflash); ee_Dump(page, (uint32_t *)addrflash);
#endif
return false; return false;
} }
} }
return true; return true;
} }
static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer=false) { static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer=false) {
uint32_t baddr; uint32_t baddr;
@ -930,11 +925,9 @@ static void ee_Init() {
// If all groups seem to be used, default to first group // If all groups seem to be used, default to first group
if (curGroup >= GroupCount) curGroup = 0; if (curGroup >= GroupCount) curGroup = 0;
#ifdef EE_EMU_DEBUG DEBUG_ECHO_START();
SERIAL_ECHO_START(); DEBUG_ECHOLNPAIR("EEPROM Current Group: ",curGroup);
SERIAL_ECHOLNPAIR("EEPROM Current Group: ",curGroup); DEBUG_FLUSH();
SERIAL_FLUSH();
#endif
// Now, validate that all the other group pages are empty // Now, validate that all the other group pages are empty
for (int grp = 0; grp < GroupCount; grp++) { for (int grp = 0; grp < GroupCount; grp++) {
@ -942,11 +935,9 @@ static void ee_Init() {
for (int page = 0; page < PagesPerGroup; page++) { for (int page = 0; page < PagesPerGroup; page++) {
if (!ee_IsPageClean(grp * PagesPerGroup + page)) { if (!ee_IsPageClean(grp * PagesPerGroup + page)) {
#ifdef EE_EMU_DEBUG DEBUG_ECHO_START();
SERIAL_ECHO_START(); DEBUG_ECHOLNPAIR("EEPROM Page ", page, " not clean on group ", grp);
SERIAL_ECHOLNPAIR("EEPROM Page ", page, " not clean on group ", grp); DEBUG_FLUSH();
SERIAL_FLUSH();
#endif
ee_PageErase(grp * PagesPerGroup + page); ee_PageErase(grp * PagesPerGroup + page);
} }
} }
@ -956,28 +947,22 @@ static void ee_Init() {
// and also validate that all the other ones are clean // and also validate that all the other ones are clean
for (curPage = 0; curPage < PagesPerGroup; curPage++) { for (curPage = 0; curPage < PagesPerGroup; curPage++) {
if (ee_IsPageClean(curGroup * PagesPerGroup + curPage)) { if (ee_IsPageClean(curGroup * PagesPerGroup + curPage)) {
#ifdef EE_EMU_DEBUG
ee_Dump(curGroup * PagesPerGroup + curPage, getFlashStorage(curGroup * PagesPerGroup + curPage)); ee_Dump(curGroup * PagesPerGroup + curPage, getFlashStorage(curGroup * PagesPerGroup + curPage));
#endif
break; break;
} }
} }
#ifdef EE_EMU_DEBUG DEBUG_ECHO_START();
SERIAL_ECHO_START(); DEBUG_ECHOLNPAIR("EEPROM Active page: ", curPage);
SERIAL_ECHOLNPAIR("EEPROM Active page: ", curPage); DEBUG_FLUSH();
SERIAL_FLUSH();
#endif
// Make sure the pages following the first clean one are also clean // Make sure the pages following the first clean one are also clean
for (int page = curPage + 1; page < PagesPerGroup; page++) { for (int page = curPage + 1; page < PagesPerGroup; page++) {
if (!ee_IsPageClean(curGroup * PagesPerGroup + page)) { if (!ee_IsPageClean(curGroup * PagesPerGroup + page)) {
#ifdef EE_EMU_DEBUG DEBUG_ECHO_START();
SERIAL_ECHO_START(); DEBUG_ECHOLNPAIR("EEPROM Page ", page, " not clean on active group ", curGroup);
SERIAL_ECHOLNPAIR("EEPROM Page ", page, " not clean on active group ", curGroup); DEBUG_FLUSH();
SERIAL_FLUSH();
ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page)); ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page));
#endif
ee_PageErase(curGroup * PagesPerGroup + page); ee_PageErase(curGroup * PagesPerGroup + page);
} }
} }
@ -1018,4 +1003,4 @@ void eeprom_flush() {
} }
#endif // FLASH_EEPROM_EMULATION #endif // FLASH_EEPROM_EMULATION
#endif // ARDUINO_ARCH_AVR #endif // ARDUINO_ARCH_SAM

View file

@ -46,6 +46,7 @@
#undef DEBUG_ECHO_MSG #undef DEBUG_ECHO_MSG
#undef DEBUG_ERROR_MSG #undef DEBUG_ERROR_MSG
#undef DEBUG_EOL #undef DEBUG_EOL
#undef DEBUG_FLUSH
#undef DEBUG_POS #undef DEBUG_POS
#undef DEBUG_XYZ #undef DEBUG_XYZ
#undef DEBUG_DELAY #undef DEBUG_DELAY
@ -71,6 +72,7 @@
#define DEBUG_ECHO_MSG SERIAL_ECHO_MSG #define DEBUG_ECHO_MSG SERIAL_ECHO_MSG
#define DEBUG_ERROR_MSG SERIAL_ERROR_MSG #define DEBUG_ERROR_MSG SERIAL_ERROR_MSG
#define DEBUG_EOL SERIAL_EOL #define DEBUG_EOL SERIAL_EOL
#define DEBUG_FLUSH SERIAL_FLUSH
#define DEBUG_POS SERIAL_POS #define DEBUG_POS SERIAL_POS
#define DEBUG_XYZ SERIAL_XYZ #define DEBUG_XYZ SERIAL_XYZ
#define DEBUG_DELAY(ms) serial_delay(ms) #define DEBUG_DELAY(ms) serial_delay(ms)
@ -95,6 +97,7 @@
#define DEBUG_ECHO_MSG(...) NOOP #define DEBUG_ECHO_MSG(...) NOOP
#define DEBUG_ERROR_MSG(...) NOOP #define DEBUG_ERROR_MSG(...) NOOP
#define DEBUG_EOL() NOOP #define DEBUG_EOL() NOOP
#define DEBUG_FLUSH() NOOP
#define DEBUG_POS(...) NOOP #define DEBUG_POS(...) NOOP
#define DEBUG_XYZ(...) NOOP #define DEBUG_XYZ(...) NOOP
#define DEBUG_DELAY(...) NOOP #define DEBUG_DELAY(...) NOOP