Skip to content

Commit b17bec1

Browse files
authored
Initial SAMD51 support (#104)
Volodymyr, thank you for the contribution. code looks good, it compiles for other boards. I can't check more. Merged.
1 parent 91471fa commit b17bec1

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

src/InternalStorage.cpp

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/OTAStorage.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
#if defined(ARDUINO_ARCH_SAMD)
44
static const uint32_t pageSizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024 };
55
static const uint32_t eepromSizes[] = { 16384, 8192, 4096, 2048, 1024, 512, 256, 0 };
6-
#define EEPROM_EMULATION_RESERVATION ((*(uint32_t*)(NVMCTRL_FUSES_EEPROM_SIZE_ADDR) & NVMCTRL_FUSES_EEPROM_SIZE_Msk) >> NVMCTRL_FUSES_EEPROM_SIZE_Pos)
6+
#if defined(__SAMD51__)
7+
# define EEPROM_EMULATION_RESERVATION 0
8+
#else
9+
# define EEPROM_EMULATION_RESERVATION ((*(uint32_t*)(NVMCTRL_FUSES_EEPROM_SIZE_ADDR) & NVMCTRL_FUSES_EEPROM_SIZE_Msk) >> NVMCTRL_FUSES_EEPROM_SIZE_Pos)
10+
#endif
711
extern "C" {
812
char * __text_start__(); // 0x2000, 0x0 without bootloader and 0x4000 for M0 original bootloader
913
}

0 commit comments

Comments
 (0)