|
@@ -19,6 +19,15 @@
|
19
|
19
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
20
|
*
|
21
|
21
|
*/
|
|
22
|
+#ifdef ARDUINO_ARCH_SAM
|
|
23
|
+
|
|
24
|
+#include "../../inc/MarlinConfig.h"
|
|
25
|
+
|
|
26
|
+#if ENABLED(FLASH_EEPROM_EMULATION)
|
|
27
|
+
|
|
28
|
+#include "../shared/Marduino.h"
|
|
29
|
+#include "../shared/eeprom_if.h"
|
|
30
|
+#include "../shared/eeprom_api.h"
|
22
|
31
|
|
23
|
32
|
/* EEPROM emulation over flash with reduced wear
|
24
|
33
|
*
|
|
@@ -50,15 +59,7 @@
|
50
|
59
|
*
|
51
|
60
|
*/
|
52
|
61
|
|
53
|
|
-#ifdef ARDUINO_ARCH_SAM
|
54
|
|
-
|
55
|
|
-#include "../../inc/MarlinConfig.h"
|
56
|
|
-
|
57
|
|
-#if ENABLED(FLASH_EEPROM_EMULATION)
|
58
|
|
-
|
59
|
|
-#include "../shared/Marduino.h"
|
60
|
|
-#include "../shared/eeprom_if.h"
|
61
|
|
-#include "../shared/eeprom_api.h"
|
|
62
|
+//#define EE_EMU_DEBUG
|
62
|
63
|
|
63
|
64
|
#define EEPROMSize 4096
|
64
|
65
|
#define PagesPerGroup 128
|
|
@@ -135,15 +136,18 @@ static uint8_t buffer[256] = {0}, // The RAM buffer to accumulate writes
|
135
|
136
|
curPage = 0, // Current FLASH page inside the group
|
136
|
137
|
curGroup = 0xFF; // Current FLASH group
|
137
|
138
|
|
138
|
|
-//#define EE_EMU_DEBUG
|
139
|
|
-#ifdef EE_EMU_DEBUG
|
140
|
|
- static void ee_Dump(int page,const void* data) {
|
|
139
|
+#define DEBUG_OUT ENABLED(EE_EMU_DEBUG)
|
|
140
|
+#include "../../core/debug_out.h"
|
|
141
|
+
|
|
142
|
+static void ee_Dump(const int page, const void* data) {
|
|
143
|
+
|
|
144
|
+ #ifdef EE_EMU_DEBUG
|
141
|
145
|
|
142
|
146
|
const uint8_t* c = (const uint8_t*) data;
|
143
|
147
|
char buffer[80];
|
144
|
148
|
|
145
|
149
|
sprintf_P(buffer, PSTR("Page: %d (0x%04x)\n"), page, page);
|
146
|
|
- SERIAL_ECHO(buffer);
|
|
150
|
+ DEBUG_ECHO(buffer);
|
147
|
151
|
|
148
|
152
|
char* p = &buffer[0];
|
149
|
153
|
for (int i = 0; i< PageSize; ++i) {
|
|
@@ -153,12 +157,16 @@ static uint8_t buffer[256] = {0}, // The RAM buffer to accumulate writes
|
153
|
157
|
if ((i & 0xF) == 0xF) {
|
154
|
158
|
*p++ = '\n';
|
155
|
159
|
*p = 0;
|
156
|
|
- SERIAL_ECHO(buffer);
|
|
160
|
+ DEBUG_ECHO(buffer);
|
157
|
161
|
p = &buffer[0];
|
158
|
162
|
}
|
159
|
163
|
}
|
160
|
|
- }
|
161
|
|
-#endif
|
|
164
|
+
|
|
165
|
+ #else
|
|
166
|
+ UNUSED(page);
|
|
167
|
+ UNUSED(data);
|
|
168
|
+ #endif
|
|
169
|
+}
|
162
|
170
|
|
163
|
171
|
/* Flash Writing Protection Key */
|
164
|
172
|
#define FWP_KEY 0x5Au
|
|
@@ -171,17 +179,16 @@ static uint8_t buffer[256] = {0}, // The RAM buffer to accumulate writes
|
171
|
179
|
#define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE)
|
172
|
180
|
#endif
|
173
|
181
|
|
174
|
|
-
|
175
|
182
|
/**
|
176
|
183
|
* Writes the contents of the specified page (no previous erase)
|
177
|
184
|
* @param page (page #)
|
178
|
185
|
* @param data (pointer to the data buffer)
|
179
|
186
|
*/
|
180
|
187
|
__attribute__ ((long_call, section (".ramfunc")))
|
181
|
|
-static bool ee_PageWrite(uint16_t page,const void* data) {
|
|
188
|
+static bool ee_PageWrite(uint16_t page, const void* data) {
|
182
|
189
|
|
183
|
190
|
uint16_t i;
|
184
|
|
- uint32_t addrflash = ((uint32_t)getFlashStorage(page));
|
|
191
|
+ uint32_t addrflash = uint32_t(getFlashStorage(page));
|
185
|
192
|
|
186
|
193
|
// Read the flash contents
|
187
|
194
|
uint32_t pageContents[PageSize>>2];
|
|
@@ -196,13 +203,11 @@ static bool ee_PageWrite(uint16_t page,const void* data) {
|
196
|
203
|
for (i = 0; i <PageSize >> 2; i++)
|
197
|
204
|
pageContents[i] = (((uint32_t*)data)[i]) | (~(pageContents[i] ^ ((uint32_t*)data)[i]));
|
198
|
205
|
|
199
|
|
- #ifdef EE_EMU_DEBUG
|
200
|
|
- SERIAL_ECHO_START();
|
201
|
|
- SERIAL_ECHOLNPAIR("EEPROM PageWrite ", page);
|
202
|
|
- SERIAL_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
|
203
|
|
- SERIAL_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
|
204
|
|
- SERIAL_FLUSH();
|
205
|
|
- #endif
|
|
206
|
+ DEBUG_ECHO_START();
|
|
207
|
+ DEBUG_ECHOLNPAIR("EEPROM PageWrite ", page);
|
|
208
|
+ DEBUG_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
|
|
209
|
+ DEBUG_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
|
|
210
|
+ DEBUG_FLUSH();
|
206
|
211
|
|
207
|
212
|
// Get the page relative to the start of the EFC controller, and the EFC controller to use
|
208
|
213
|
Efc *efc;
|
|
@@ -244,10 +249,8 @@ static bool ee_PageWrite(uint16_t page,const void* data) {
|
244
|
249
|
// Reenable interrupts
|
245
|
250
|
__enable_irq();
|
246
|
251
|
|
247
|
|
- #ifdef EE_EMU_DEBUG
|
248
|
|
- SERIAL_ECHO_START();
|
249
|
|
- SERIAL_ECHOLNPAIR("EEPROM Unlock failure for page ", page);
|
250
|
|
- #endif
|
|
252
|
+ DEBUG_ECHO_START();
|
|
253
|
+ DEBUG_ECHOLNPAIR("EEPROM Unlock failure for page ", page);
|
251
|
254
|
return false;
|
252
|
255
|
}
|
253
|
256
|
|
|
@@ -271,10 +274,9 @@ static bool ee_PageWrite(uint16_t page,const void* data) {
|
271
|
274
|
// Reenable interrupts
|
272
|
275
|
__enable_irq();
|
273
|
276
|
|
274
|
|
- #ifdef EE_EMU_DEBUG
|
275
|
|
- SERIAL_ECHO_START();
|
276
|
|
- SERIAL_ECHOLNPAIR("EEPROM Write failure for page ", page);
|
277
|
|
- #endif
|
|
277
|
+ DEBUG_ECHO_START();
|
|
278
|
+ DEBUG_ECHOLNPAIR("EEPROM Write failure for page ", page);
|
|
279
|
+
|
278
|
280
|
return false;
|
279
|
281
|
}
|
280
|
282
|
|
|
@@ -288,11 +290,11 @@ static bool ee_PageWrite(uint16_t page,const void* data) {
|
288
|
290
|
if (memcmp(getFlashStorage(page),data,PageSize)) {
|
289
|
291
|
|
290
|
292
|
#ifdef EE_EMU_DEBUG
|
291
|
|
- SERIAL_ECHO_START();
|
292
|
|
- SERIAL_ECHOLNPAIR("EEPROM Verify Write failure for page ", page);
|
|
293
|
+ DEBUG_ECHO_START();
|
|
294
|
+ DEBUG_ECHOLNPAIR("EEPROM Verify Write failure for page ", page);
|
293
|
295
|
|
294
|
|
- ee_Dump( page,(uint32_t *) addrflash);
|
295
|
|
- ee_Dump(-page,data);
|
|
296
|
+ ee_Dump( page, (uint32_t *)addrflash);
|
|
297
|
+ ee_Dump(-page, data);
|
296
|
298
|
|
297
|
299
|
// Calculate count of changed bits
|
298
|
300
|
uint32_t* p1 = (uint32_t*)addrflash;
|
|
@@ -308,7 +310,7 @@ static bool ee_PageWrite(uint16_t page,const void* data) {
|
308
|
310
|
}
|
309
|
311
|
}
|
310
|
312
|
}
|
311
|
|
- SERIAL_ECHOLNPAIR("--> Differing bits: ", count);
|
|
313
|
+ DEBUG_ECHOLNPAIR("--> Differing bits: ", count);
|
312
|
314
|
#endif
|
313
|
315
|
|
314
|
316
|
return false;
|
|
@@ -325,15 +327,13 @@ __attribute__ ((long_call, section (".ramfunc")))
|
325
|
327
|
static bool ee_PageErase(uint16_t page) {
|
326
|
328
|
|
327
|
329
|
uint16_t i;
|
328
|
|
- uint32_t addrflash = ((uint32_t)getFlashStorage(page));
|
|
330
|
+ uint32_t addrflash = uint32_t(getFlashStorage(page));
|
329
|
331
|
|
330
|
|
- #ifdef EE_EMU_DEBUG
|
331
|
|
- SERIAL_ECHO_START();
|
332
|
|
- SERIAL_ECHOLNPAIR("EEPROM PageErase ", page);
|
333
|
|
- SERIAL_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
|
334
|
|
- SERIAL_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
|
335
|
|
- SERIAL_FLUSH();
|
336
|
|
- #endif
|
|
332
|
+ DEBUG_ECHO_START();
|
|
333
|
+ DEBUG_ECHOLNPAIR("EEPROM PageErase ", page);
|
|
334
|
+ DEBUG_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
|
|
335
|
+ DEBUG_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
|
|
336
|
+ DEBUG_FLUSH();
|
337
|
337
|
|
338
|
338
|
// Get the page relative to the start of the EFC controller, and the EFC controller to use
|
339
|
339
|
Efc *efc;
|
|
@@ -374,10 +374,9 @@ static bool ee_PageErase(uint16_t page) {
|
374
|
374
|
// Reenable interrupts
|
375
|
375
|
__enable_irq();
|
376
|
376
|
|
377
|
|
- #ifdef EE_EMU_DEBUG
|
378
|
|
- SERIAL_ECHO_START();
|
379
|
|
- SERIAL_ECHOLNPAIR("EEPROM Unlock failure for page ",page);
|
380
|
|
- #endif
|
|
377
|
+ DEBUG_ECHO_START();
|
|
378
|
+ DEBUG_ECHOLNPAIR("EEPROM Unlock failure for page ",page);
|
|
379
|
+
|
381
|
380
|
return false;
|
382
|
381
|
}
|
383
|
382
|
|
|
@@ -399,10 +398,9 @@ static bool ee_PageErase(uint16_t page) {
|
399
|
398
|
// Reenable interrupts
|
400
|
399
|
__enable_irq();
|
401
|
400
|
|
402
|
|
- #ifdef EE_EMU_DEBUG
|
403
|
|
- SERIAL_ECHO_START();
|
404
|
|
- SERIAL_ECHOLNPAIR("EEPROM Erase failure for page ",page);
|
405
|
|
- #endif
|
|
401
|
+ DEBUG_ECHO_START();
|
|
402
|
+ DEBUG_ECHOLNPAIR("EEPROM Erase failure for page ",page);
|
|
403
|
+
|
406
|
404
|
return false;
|
407
|
405
|
}
|
408
|
406
|
|
|
@@ -416,20 +414,17 @@ static bool ee_PageErase(uint16_t page) {
|
416
|
414
|
uint32_t * aligned_src = (uint32_t *) addrflash;
|
417
|
415
|
for (i = 0; i < PageSize >> 2; i++) {
|
418
|
416
|
if (*aligned_src++ != 0xFFFFFFFF) {
|
419
|
|
-
|
420
|
|
- #ifdef EE_EMU_DEBUG
|
421
|
|
- SERIAL_ECHO_START();
|
422
|
|
- SERIAL_ECHOLNPAIR("EEPROM Verify Erase failure for page ",page);
|
423
|
|
-
|
424
|
|
- ee_Dump( page,(uint32_t *) addrflash);
|
425
|
|
- #endif
|
|
417
|
+ DEBUG_ECHO_START();
|
|
418
|
+ DEBUG_ECHOLNPAIR("EEPROM Verify Erase failure for page ",page);
|
|
419
|
+ ee_Dump(page, (uint32_t *)addrflash);
|
426
|
420
|
return false;
|
427
|
421
|
}
|
428
|
422
|
}
|
429
|
423
|
|
430
|
424
|
return true;
|
431
|
425
|
}
|
432
|
|
-static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer = false) {
|
|
426
|
+
|
|
427
|
+static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer=false) {
|
433
|
428
|
|
434
|
429
|
uint32_t baddr;
|
435
|
430
|
uint32_t blen;
|
|
@@ -512,7 +507,7 @@ static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer = false) {
|
512
|
507
|
return 0xFF;
|
513
|
508
|
}
|
514
|
509
|
|
515
|
|
-static uint32_t ee_GetAddrRange(uint32_t address, bool excludeRAMBuffer = false) {
|
|
510
|
+static uint32_t ee_GetAddrRange(uint32_t address, bool excludeRAMBuffer=false) {
|
516
|
511
|
uint32_t baddr,
|
517
|
512
|
blen,
|
518
|
513
|
nextAddr = 0xFFFF,
|
|
@@ -604,7 +599,7 @@ static bool ee_IsPageClean(int page) {
|
604
|
599
|
return true;
|
605
|
600
|
}
|
606
|
601
|
|
607
|
|
-static bool ee_Flush(uint32_t overrideAddress = 0xFFFFFFFF, uint8_t overrideData = 0xFF) {
|
|
602
|
+static bool ee_Flush(uint32_t overrideAddress = 0xFFFFFFFF, uint8_t overrideData=0xFF) {
|
608
|
603
|
|
609
|
604
|
// Check if RAM buffer has something to be written
|
610
|
605
|
bool isEmpty = true;
|
|
@@ -930,11 +925,9 @@ static void ee_Init() {
|
930
|
925
|
// If all groups seem to be used, default to first group
|
931
|
926
|
if (curGroup >= GroupCount) curGroup = 0;
|
932
|
927
|
|
933
|
|
- #ifdef EE_EMU_DEBUG
|
934
|
|
- SERIAL_ECHO_START();
|
935
|
|
- SERIAL_ECHOLNPAIR("EEPROM Current Group: ",curGroup);
|
936
|
|
- SERIAL_FLUSH();
|
937
|
|
- #endif
|
|
928
|
+ DEBUG_ECHO_START();
|
|
929
|
+ DEBUG_ECHOLNPAIR("EEPROM Current Group: ",curGroup);
|
|
930
|
+ DEBUG_FLUSH();
|
938
|
931
|
|
939
|
932
|
// Now, validate that all the other group pages are empty
|
940
|
933
|
for (int grp = 0; grp < GroupCount; grp++) {
|
|
@@ -942,11 +935,9 @@ static void ee_Init() {
|
942
|
935
|
|
943
|
936
|
for (int page = 0; page < PagesPerGroup; page++) {
|
944
|
937
|
if (!ee_IsPageClean(grp * PagesPerGroup + page)) {
|
945
|
|
- #ifdef EE_EMU_DEBUG
|
946
|
|
- SERIAL_ECHO_START();
|
947
|
|
- SERIAL_ECHOLNPAIR("EEPROM Page ", page, " not clean on group ", grp);
|
948
|
|
- SERIAL_FLUSH();
|
949
|
|
- #endif
|
|
938
|
+ DEBUG_ECHO_START();
|
|
939
|
+ DEBUG_ECHOLNPAIR("EEPROM Page ", page, " not clean on group ", grp);
|
|
940
|
+ DEBUG_FLUSH();
|
950
|
941
|
ee_PageErase(grp * PagesPerGroup + page);
|
951
|
942
|
}
|
952
|
943
|
}
|
|
@@ -956,28 +947,22 @@ static void ee_Init() {
|
956
|
947
|
// and also validate that all the other ones are clean
|
957
|
948
|
for (curPage = 0; curPage < PagesPerGroup; curPage++) {
|
958
|
949
|
if (ee_IsPageClean(curGroup * PagesPerGroup + curPage)) {
|
959
|
|
- #ifdef EE_EMU_DEBUG
|
960
|
|
- ee_Dump(curGroup * PagesPerGroup + curPage, getFlashStorage(curGroup * PagesPerGroup + curPage));
|
961
|
|
- #endif
|
|
950
|
+ ee_Dump(curGroup * PagesPerGroup + curPage, getFlashStorage(curGroup * PagesPerGroup + curPage));
|
962
|
951
|
break;
|
963
|
952
|
}
|
964
|
953
|
}
|
965
|
954
|
|
966
|
|
- #ifdef EE_EMU_DEBUG
|
967
|
|
- SERIAL_ECHO_START();
|
968
|
|
- SERIAL_ECHOLNPAIR("EEPROM Active page: ", curPage);
|
969
|
|
- SERIAL_FLUSH();
|
970
|
|
- #endif
|
|
955
|
+ DEBUG_ECHO_START();
|
|
956
|
+ DEBUG_ECHOLNPAIR("EEPROM Active page: ", curPage);
|
|
957
|
+ DEBUG_FLUSH();
|
971
|
958
|
|
972
|
959
|
// Make sure the pages following the first clean one are also clean
|
973
|
960
|
for (int page = curPage + 1; page < PagesPerGroup; page++) {
|
974
|
961
|
if (!ee_IsPageClean(curGroup * PagesPerGroup + page)) {
|
975
|
|
- #ifdef EE_EMU_DEBUG
|
976
|
|
- SERIAL_ECHO_START();
|
977
|
|
- SERIAL_ECHOLNPAIR("EEPROM Page ", page, " not clean on active group ", curGroup);
|
978
|
|
- SERIAL_FLUSH();
|
979
|
|
- ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page));
|
980
|
|
- #endif
|
|
962
|
+ DEBUG_ECHO_START();
|
|
963
|
+ DEBUG_ECHOLNPAIR("EEPROM Page ", page, " not clean on active group ", curGroup);
|
|
964
|
+ DEBUG_FLUSH();
|
|
965
|
+ ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page));
|
981
|
966
|
ee_PageErase(curGroup * PagesPerGroup + page);
|
982
|
967
|
}
|
983
|
968
|
}
|
|
@@ -1018,4 +1003,4 @@ void eeprom_flush() {
|
1018
|
1003
|
}
|
1019
|
1004
|
|
1020
|
1005
|
#endif // FLASH_EEPROM_EMULATION
|
1021
|
|
-#endif // ARDUINO_ARCH_AVR
|
|
1006
|
+#endif // ARDUINO_ARCH_SAM
|