Skip to content

Commit 2bd7378

Browse files
committed
Implement Auxiliary Flash writes
1 parent d21c9af commit 2bd7378

File tree

2 files changed

+50
-25
lines changed

2 files changed

+50
-25
lines changed

core/arm/armmem.c

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -88,31 +88,48 @@ static bool arm_nvm_region_lock_check(arm_t *arm) {
8888
return false;
8989
}
9090

91+
static bool arm_nvm_aux_region_check(arm_t *arm) {
92+
return (arm->mem.nvmctrl.ADDR.bit.ADDR << 1 & -FLASH_USER_PAGE_SIZE) == NVMCTRL_USER - NVMCTRL_USER_PAGE_ADDRESS;
93+
}
94+
9195
static void arm_nvm_clear_page_buffer(arm_mem_t *mem) {
9296
memset(mem->pb, ~0, FLASH_PAGE_SIZE);
9397
}
9498

95-
static void arm_nvm_erase_row(arm_t *arm, bool aux) {
96-
assert(!aux && "Not implemented");
99+
static void arm_nvm_erase_row(arm_t *arm) {
97100
if (likely(arm_nvm_region_lock_check(arm))) {
98101
memset(&arm->mem.nvm[(arm->mem.nvmctrl.ADDR.bit.ADDR << 1 &
99102
(FLASH_SIZE - 1) & -FLASH_ROW_SIZE) >> 2],
100103
~0, FLASH_ROW_SIZE);
101104
}
102105
}
103106

104-
static void arm_nvm_write_page(arm_t *arm, bool aux) {
105-
uint32_t idx = (arm->mem.nvmctrl.ADDR.bit.ADDR << 1 &
106-
(FLASH_SIZE - 1) & -FLASH_PAGE_SIZE) >> 2;
107-
assert(!aux && "Not implemented");
107+
static void arm_nvm_erase_aux_row(arm_t *arm) {
108+
if (likely(arm_nvm_aux_region_check(arm))) {
109+
memset(arm->mem.aux, ~0, FLASH_USER_PAGE_SIZE);
110+
}
111+
}
112+
113+
static void arm_nvm_write_page(arm_t *arm) {
108114
if (likely(arm_nvm_region_lock_check(arm))) {
115+
uint32_t idx = (arm->mem.nvmctrl.ADDR.bit.ADDR << 1 &
116+
(FLASH_SIZE - 1) & -FLASH_PAGE_SIZE) >> 2;
109117
for (uint32_t off = 0; off != FLASH_PAGE_SIZE >> 2; ++off) {
110118
arm->mem.nvm[idx + off] &= arm->mem.pb[off];
111119
}
112120
}
113121
arm_nvm_clear_page_buffer(&arm->mem);
114122
}
115123

124+
static void arm_nvm_write_aux_page(arm_t *arm) {
125+
if (likely(arm_nvm_aux_region_check(arm))) {
126+
for (uint32_t off = 0; off != FLASH_USER_PAGE_SIZE >> 2; ++off) {
127+
arm->mem.aux[off] &= arm->mem.pb[off];
128+
}
129+
}
130+
arm_nvm_clear_page_buffer(&arm->mem);
131+
}
132+
116133
static void arm_mem_sercom_reset(SERCOM_Type *sercom) {
117134
memset(sercom, 0, sizeof(*sercom));
118135
}
@@ -306,14 +323,11 @@ static uint32_t arm_mem_load_any(arm_t *arm, uint32_t addr) {
306323
return arm->mem.nvm[(addr - FLASH_ADDR) >> 2];
307324
} else if (likely(addr - HMCRAMC0_ADDR < HMCRAMC0_SIZE)) { // Internal SRAM
308325
return arm->mem.ram[(addr - HMCRAMC0_ADDR) >> 2];
309-
} else if (unlikely(addr < HPB0_ADDR)) {
310-
if (addr - NVMCTRL_OTP1 < 8) {
311-
return 0;
312-
}
313-
if (addr - NVMCTRL_OTP2 < 8) {
314-
return 0;
326+
} else if (unlikely(addr < HPB0_ADDR)) { // Auxiliary Flash
327+
if (addr - NVMCTRL_USER < FLASH_USER_PAGE_SIZE) {
328+
return arm->mem.aux[(addr - NVMCTRL_USER) >> 2];
315329
}
316-
if (addr - NVMCTRL_OTP4 < 8) {
330+
if (addr - NVMCTRL_OTP4 < 16) {
317331
return 0;
318332
}
319333
if (addr == 0x80A00C) {
@@ -801,21 +815,32 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t
801815
uint8_t offset = addr >> 2 & 0xFF;
802816
assert(!((addr & 3) | (val & mask)) &&
803817
"Address should be aligned and mask should be valid");
804-
if (unlikely(addr - FLASH_ADDR < FLASH_SIZE)) { // Page Buffer
818+
if (likely(addr - HMCRAMC0_ADDR < HMCRAMC0_SIZE)) { // Internal SRAM
819+
uint32_t *ptr = &arm->mem.ram[(addr - HMCRAMC0_ADDR) >> 2];
820+
*ptr = (*ptr & mask) | val;
821+
return;
822+
} else if (unlikely(addr - FLASH_ADDR < FLASH_SIZE)) { // Page Buffer
805823
if (likely(!(mask & mask >> 16))) { // no 8-bit writes
806824
uint32_t *ptr = &arm->mem.pb[((addr - FLASH_ADDR) & (FLASH_PAGE_SIZE - 1)) >> 2];
807825
*ptr = (*ptr & mask) | val;
808826
arm->mem.nvmctrl.ADDR.bit.ADDR = (addr - FLASH_ADDR) >> 1 | (mask & 1);
809827
if (unlikely(!(mask >> 16) && !~(addr | -FLASH_PAGE_SIZE | 3) &&
810-
!arm->mem.nvmctrl.CTRLB.bit.MANW)) {
811-
arm_nvm_write_page(arm, false);
828+
!arm->mem.nvmctrl.CTRLB.bit.MANW)) {
829+
arm_nvm_write_page(arm);
830+
}
831+
return;
832+
}
833+
} else if (unlikely(addr - NVMCTRL_USER < FLASH_USER_PAGE_SIZE)) { // User Page Buffer
834+
if (likely(!(mask & mask >> 16))) { // no 8-bit writes
835+
uint32_t *ptr = &arm->mem.pb[((addr - NVMCTRL_USER) & (FLASH_USER_PAGE_SIZE - 1)) >> 2];
836+
*ptr = (*ptr & mask) | val;
837+
arm->mem.nvmctrl.ADDR.bit.ADDR = (addr - FLASH_USER_PAGE_ADDR) >> 1 | (mask & 1);
838+
if (unlikely(!(mask >> 16) && !~(addr | -FLASH_USER_PAGE_SIZE | 3) &&
839+
!arm->mem.nvmctrl.CTRLB.bit.MANW)) {
840+
arm_nvm_write_aux_page(arm);
812841
}
813842
return;
814843
}
815-
} else if (likely(addr - HMCRAMC0_ADDR < HMCRAMC0_SIZE)) { // Internal SRAM
816-
uint32_t *ptr = &arm->mem.ram[(addr - HMCRAMC0_ADDR) >> 2];
817-
*ptr = (*ptr & mask) | val;
818-
return;
819844
} else if (unlikely(addr < HPB0_ADDR)) {
820845
} else if (unlikely(addr < HPB1_ADDR)) { // Peripheral Bridge A
821846
uint32_t id = ID_PAC0 + ((addr - HPB0_ADDR) >> 10);
@@ -969,16 +994,16 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t
969994
if ((val & NVMCTRL_CTRLA_CMDEX_Msk) == NVMCTRL_CTRLA_CMDEX_KEY) {
970995
switch (val & NVMCTRL_CTRLA_CMD_Msk) {
971996
case NVMCTRL_CTRLA_CMD_ER:
972-
arm_nvm_erase_row(arm, false);
997+
arm_nvm_erase_row(arm);
973998
return;
974999
case NVMCTRL_CTRLA_CMD_WP:
975-
arm_nvm_write_page(arm, false);
1000+
arm_nvm_write_page(arm);
9761001
return;
9771002
case NVMCTRL_CTRLA_CMD_EAR:
978-
arm_nvm_erase_row(arm, true);
1003+
arm_nvm_erase_aux_row(arm);
9791004
return;
9801005
case NVMCTRL_CTRLA_CMD_WAP:
981-
arm_nvm_write_page(arm, true);
1006+
arm_nvm_write_aux_page(arm);
9821007
return;
9831008
case NVMCTRL_CTRLA_CMD_SF:
9841009
break;

core/arm/armmem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ typedef union {
115115
} SERCOM_Type;
116116

117117
typedef struct arm_mem {
118-
uint32_t *ram, *nvm, pb[FLASH_PAGE_SIZE >> 2];
118+
uint32_t *ram, *nvm, pb[FLASH_PAGE_SIZE >> 2], aux[FLASH_USER_PAGE_SIZE >> 2];
119119
PM_Type pm;
120120
GCLK_Type gclk;
121121
NVMCTRL_Type nvmctrl;

0 commit comments

Comments
 (0)