Commit 8f611864 authored by Jake Read's avatar Jake Read
Browse files

no hangs, does not read / write tho

parent 099d24a8
......@@ -50,98 +50,76 @@ void Step_CL::init(void){
// s/o to mechaduino code for this
#define PAGE_SIZE 512 // start_flash_write reports this bit value, use datasheet 25.8.3 to reference
const float __attribute__((__aligned__(PAGE_SIZE))) lut[ENCODER_COUNTS] = {};
const uint32_t start_addr = 0x10000000;
float temp_quad[4];
uint8_t temp_indice;
static const unsigned page_size = PAGE_SIZE; // size of each page in flash mem, read out w/ NVMCTRL->PARAM.bit.PSZ
static const unsigned floats_per_page = page_size / sizeof(float); // count of floats that can be stored in each page
static float page[floats_per_page]; // a temporary page-width of floats, to buffer before writing to flash mem
static unsigned page_f; // the page[page_f - 1] == the last float we wrote
static const void * page_ptr = (const uint8_t *) lut; // ptr to the address in flash memory where we want to write
static unsigned num_pages_written; // counting
static void start_flash_write(void){
num_pages_written = 0;
page_f = 0;
sysError("Writing to flash 0x" + String((uintptr_t) page_ptr, HEX));
sysError("Page size PSZ= " + String(NVMCTRL->PARAM.bit.PSZ)); // datasheet for this
// try with wqw, and auto update?
NVMCTRL->CTRLA.bit.WMODE = NVMCTRL_CTRLA_WMODE_MAN;
void flash_wait_ready(void){
while(NVMCTRL->STATUS.bit.READY == 0);
}
static void flash_disable_cache(void){
NVMCTRL->CTRLA.bit.CACHEDIS0 = 1;
NVMCTRL->CTRLA.bit.CACHEDIS1 = 1;
}
static void flash_enable_cache(void){
NVMCTRL->CTRLA.bit.CACHEDIS0 = 0;
NVMCTRL->CTRLA.bit.CACHEDIS1 = 0;
}
static void flash_erase_page(const volatile void *flash_ptr){
NVMCTRL->ADDR.reg = ((uint32_t)flash_ptr);
// erase block at this addr
void flash_erase_block(uint32_t *dst){
flash_wait_ready();
// do 'erase row'
NVMCTRL->ADDR.reg = start_addr;//(uint32_t)dst;
NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_EB;
//while(!NVMCTRL->INTFLAG.bit.DONE);
while(!NVMCTRL->STATUS.bit.READY);
flash_wait_ready();
}
static inline uint32_t read_unaligned_uint32(const void *data)
{
union {
uint32_t u32;
uint8_t u8[4];
} res;
const uint8_t *d = (const uint8_t *)data;
res.u8[0] = d[0];
res.u8[1] = d[1];
res.u8[2] = d[2];
res.u8[3] = d[3];
return res.u32;
}
// writes blocks of four four bit words: i.e. 4 floats per row, 4 uint32, etc
#define QUAD_WORD (4 * 4)
void flash_write_words(uint32_t *dst, uint32_t *src, uint32_t n_words){
sysError("writing quad to addr: 0x" + String(dst[0], HEX));
// set manuel page write
NVMCTRL->CTRLA.bit.WMODE = NVMCTRL_CTRLA_WMODE_MAN;
static void flash_write_page(const volatile void *flash_ptr, const void *data, uint32_t size){
// disable cache,
// sysError("disable cache");
// flash_disable_cache();
// erase the page,
sysError("erase");
flash_erase_page(flash_ptr);
// copy into page buffer (?)
// do page buffer clear
sysError("page buffer clear");
NVMCTRL->ADDR.reg = ((uint32_t)flash_ptr);
// execute page buffer clear
flash_wait_ready();
NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_PBC;
while(!NVMCTRL->STATUS.bit.READY);
// do page buffer write (?)
volatile uint32_t *dst_addr = (volatile uint32_t *)flash_ptr;
const uint8_t *src_addr = (uint8_t*)data;
uint32_t i;
for (i=0; i<(PAGE_SIZE/4) && size; i++) {
*dst_addr = read_unaligned_uint32(src_addr);
src_addr += 4;
dst_addr++;
size--;
flash_wait_ready();
// write em ?
while(n_words > 0){
// more than 4 words left?
uint32_t len = 4 < n_words ? 4 : n_words;
// write one quad word into page buffer (is ... the flash address?)
for(uint32_t i = 0; i < 4; i ++){
if(i < len){
dst[i] = src[i];
} else {
dst[i] = 0xffffffff; // tail ends write to solid 1's
}
}
// erase the block
flash_erase_block(dst);
// trigger the write
NVMCTRL->ADDR.reg = (uint32_t)dst;
NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_WQW;
// advance thru quad words
dst += len;
src += len;
n_words -= len;
}
// do page write (writes to page in ADDR register, from page buffer)
sysError("page write");
NVMCTRL->ADDR.reg = ((uint32_t)flash_ptr);
NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_WP;
while(!NVMCTRL->STATUS.bit.READY);
// re-enable cache
// sysError("enable cache");
// flash_enable_cache();
sysError("quad complete");
delay(10);
}
static void flash_write_value(float val){
page[page_f ++] = val;
if(page_f < floats_per_page) return;
// page is full, commit to flash
sysError("will write 0x" + String((uintptr_t) page_ptr, HEX) + " " + String(num_pages_written));
flash_write_page(page_ptr, page, sizeof(page));
delay(10);
// reset counters
// page_ptr += sizeof(page);
page_f = 0;
memset(page, 0, sizeof(page));
// ok, I think I can try this: I keep a row of vals, 4 of 'em, then on wrap, I write
// using erase / then write, using the lut as the start,
// I'll try to do it once, to start, then read it out...
void flash_write_init(void){
temp_indice = 0;
}
void flash_write_value(float val){
sysError("flt: " + String(val));
temp_quad[temp_indice ++] = val;
if(temp_indice > 3){
flash_write_words((uint32_t *)lut, (uint32_t *)temp_quad, 4);
temp_indice = 0;
}
}
// the calib routine
......@@ -201,8 +179,8 @@ boolean Step_CL::calibrate(void){
// (2) build the table, walk all encoder counts...
// now to build the actual table...
// want to start with the 0 indice,
start_flash_write();
for(uint16_t e = 0; e < ENCODER_COUNTS; e ++){
flash_write_init();
for(uint16_t e = 0; e < 4; e ++){
// find the interval that spans this sample
boolean bi = false;
int16_t interval = -1;
......@@ -300,7 +278,7 @@ boolean Step_CL::calibrate(void){
}
void Step_CL::print_table(void){
for(uint16_t e = 0; e < ENCODER_COUNTS; e ++){
for(uint16_t e = 0; e < 4; e ++){
float ra = lut[e];
sysError("e: " + String(e) + " ra: " + String(ra, 4));
delay(5);
......
......@@ -802,4 +802,12 @@ Have to erase before write, to set back to 1's: flash memory writes by pulling z
I can also check the UF2 bootloader, which uses flash:
https://github.com/microsoft/uf2-samdx1/blob/master/src/flash_samd51.c
\ No newline at end of file
https://github.com/microsoft/uf2-samdx1/blob/master/src/flash_samd51.c
This code seems to have a much better handle on things in any case. I should try something straightforward to start.
Well, I think I might be writing into memory, but I've no way of reading it out - or I crash when I try to dereference the address. Will try making that const... Same.
I suspect I am writing into some bad spaces. This code (which *is* better) is expecting a pointer to a uint32, not the actual 'raw' uint32 addr... and I was previously trying to write to 0xF0000000 which is well out of range, I meant to do 0x10000000...
To clarify, I'll write the base fns with real void* rs...
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment