I am writing to the internal flash of my SAMD21G18A microcontroller.
I want to erase one row (4 pages), and manually write to one page just to understand the NVMCTRL abit more.
this is the code FYI:
#include <sam.h>
setup()
{
//code
#define KEY 0xA500
#define PAGE_BUFFER_CLR 0x0044
#define WRITE_PAGE 0x0004
#define ERASE_ROW 0x0002
uint8_t data [64];
int i = 0;
for(i = 0; i < 64; i++)
data[i] = i+10;
uint8_t val[64];
for(i = 0; i < 64; i++)
val[i] = 0;
uint8_t * src_ptr = data;
uint8_t * dest_ptr = val;
uint16_t ADDR_VAL;
uint16_t addr = 0x4000;
uint16_t addr_start_of_region = 0x0000;
ADDR_VAL = (addr - addr_start_of_region) / 2;
//erase region
NVMCTRL->ADDR.reg = ADDR_VAL;
delay(1);
NVMCTRL->CTRLA.reg = KEY | ERASE_ROW;
delay(1);
while(!NVMCTRL->INTFLAG.bit.READY);
delay(1);
delay(100);
//write to one page at address 0x4000
NVMCTRL->CTRLB.bit.MANW = 1;
delay(1);
//clear buffer
NVMCTRL->CTRLA.reg = KEY | PAGE_BUFFER_CLR;
delay(1);
while(!NVMCTRL->INTFLAG.bit.READY);
delay(1);
//write to dest
for(i = 0; i < 64; i ++)
dest_ptr[i] = src_ptr[i];
NVMCTRL->CTRLA.reg = KEY | WRITE_PAGE;
delay(1);
delay(100);
}
loop()
{}
This is my understanding of the write to the NVM procedure as per the NVMCTRL chapter (chapter 22) of the datasheet (link).
my intended address is 0x4000, hence
NVMCTRL->ADDR.reg = 0x2000
as our address = start_of_region_address + 2*ADDR`send erase row command
NVMCTRL->CTRLA.reg = 0xA502
clear the page buffer
NVMCTRL->CTRLA.reg = 0xA544
address the main address space directly via the AHB bus. i.e
for(int i = 0; i < 64; i++){dest[i] = src[i]}
where 64 is the page size in bytes, and dest and src are pointers (uint8_t*
)send the write command
NVMCTRL->CTRLA.reg = 0xA504
However, when I write and build the code above, debug and watch the memory I only see 0xFFFFFFFF starting at address 0x4000.
Any help would be really appreciated.
STATUS
register there is the security enabled / disabled bit. \$\endgroup\$