@@ -54,17 +54,41 @@ extern "C" {
5454
5555 __attribute__ ((long_call, noinline, section (" .data#" ))) //
5656 void waitForReady() {
57- #if defined(ARDUINO_ARCH_SAMD)
57+ #if defined(__SAMD51__)
58+ while (!NVMCTRL->STATUS .bit .READY );
59+ #elif defined(ARDUINO_ARCH_SAMD)
5860 while (!NVMCTRL->INTFLAG .bit .READY );
5961#elif defined(ARDUINO_ARCH_NRF5)
6062 while (NRF_NVMC->READY == NVMC_READY_READY_Busy);
6163#endif
6264 }
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
6379
6480 __attribute__ ((long_call, noinline, section (" .data#" )))
6581 static void eraseFlash(int address, int length, int pageSize)
6682 {
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)
6892 int rowSize = pageSize * 4 ;
6993 for (int i = 0 ; i < length; i += rowSize) {
7094 NVMCTRL->ADDR .reg = ((uint32_t )(address + i)) / 2 ;
@@ -94,7 +118,7 @@ extern "C" {
94118 __attribute__ ((long_call, noinline, section (" .data#" )))
95119 static void copyFlashAndReset(int dest, int src, int length, int pageSize)
96120 {
97- uint32_t * d = (uint32_t *)dest;
121+ volatile uint32_t * d = (volatile uint32_t *)dest;
98122 uint32_t * s = (uint32_t *)src;
99123
100124 eraseFlash (dest, length, pageSize);
@@ -115,8 +139,15 @@ int InternalStorageClass::open(int length)
115139 _writeIndex = 0 ;
116140 _writeAddress = (uint32_t *)STORAGE_START_ADDRESS;
117141
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
120151 NVMCTRL->CTRLB .bit .MANW = 0 ;
121152#endif
122153
0 commit comments