@@ -54,17 +54,41 @@ extern "C" {
54
54
55
55
__attribute__ ((long_call, noinline, section (" .data#" ))) //
56
56
void waitForReady() {
57
- #if defined(ARDUINO_ARCH_SAMD)
57
+ #if defined(__SAMD51__)
58
+ while (!NVMCTRL->STATUS .bit .READY );
59
+ #elif defined(ARDUINO_ARCH_SAMD)
58
60
while (!NVMCTRL->INTFLAG .bit .READY );
59
61
#elif defined(ARDUINO_ARCH_NRF5)
60
62
while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
61
63
#endif
62
64
}
65
+
66
+ #if defined(__SAMD51__)
67
+ // Invalidate all CMCC cache entries if CMCC cache is enabled.
68
+ __attribute__ ((long_call, noinline, section (" .data#" )))
69
+ static void invalidate_CMCC_cache()
70
+ {
71
+ if (CMCC->SR .bit .CSTS ) {
72
+ CMCC->CTRL .bit .CEN = 0 ;
73
+ while (CMCC->SR .bit .CSTS ) {}
74
+ CMCC->MAINT0 .bit .INVALL = 1 ;
75
+ CMCC->CTRL .bit .CEN = 1 ;
76
+ }
77
+ }
78
+ #endif
63
79
64
80
__attribute__ ((long_call, noinline, section (" .data#" )))
65
81
static void eraseFlash(int address, int length, int pageSize)
66
82
{
67
- #if defined(ARDUINO_ARCH_SAMD)
83
+ #if defined(__SAMD51__)
84
+ int rowSize = (pageSize * NVMCTRL->PARAM .bit .NVMP ) / 64 ;
85
+ for (int i = 0 ; i < length; i += rowSize) {
86
+ NVMCTRL->ADDR .reg = ((uint32_t )(address + i));
87
+ NVMCTRL->CTRLB .reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_EB;
88
+ waitForReady ();
89
+ invalidate_CMCC_cache ();
90
+ }
91
+ #elif defined(ARDUINO_ARCH_SAMD)
68
92
int rowSize = pageSize * 4 ;
69
93
for (int i = 0 ; i < length; i += rowSize) {
70
94
NVMCTRL->ADDR .reg = ((uint32_t )(address + i)) / 2 ;
@@ -94,7 +118,7 @@ extern "C" {
94
118
__attribute__ ((long_call, noinline, section (" .data#" )))
95
119
static void copyFlashAndReset(int dest, int src, int length, int pageSize)
96
120
{
97
- uint32_t * d = (uint32_t *)dest;
121
+ volatile uint32_t * d = (volatile uint32_t *)dest;
98
122
uint32_t * s = (uint32_t *)src;
99
123
100
124
eraseFlash (dest, length, pageSize);
@@ -115,8 +139,15 @@ int InternalStorageClass::open(int length)
115
139
_writeIndex = 0 ;
116
140
_writeAddress = (uint32_t *)STORAGE_START_ADDRESS;
117
141
118
- #ifdef ARDUINO_ARCH_SAMD
119
- // enable auto page writes
142
+ #if defined(__SAMD51__)
143
+ // Enable auto dword writes
144
+ NVMCTRL->CTRLA .bit .WMODE = NVMCTRL_CTRLA_WMODE_ADW_Val;
145
+ waitForReady ();
146
+ // Disable NVMCTRL cache while writing, per SAMD51 errata
147
+ NVMCTRL->CTRLA .bit .CACHEDIS0 = 1 ;
148
+ NVMCTRL->CTRLA .bit .CACHEDIS1 = 1 ;
149
+ #elif defined(ARDUINO_ARCH_SAMD)
150
+ // Enable auto page writes
120
151
NVMCTRL->CTRLB .bit .MANW = 0 ;
121
152
#endif
122
153
0 commit comments