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){ ...@@ -50,98 +50,76 @@ void Step_CL::init(void){
// s/o to mechaduino code for this // 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 #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 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 void flash_wait_ready(void){
static const unsigned floats_per_page = page_size / sizeof(float); // count of floats that can be stored in each page while(NVMCTRL->STATUS.bit.READY == 0);
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;
} }
static void flash_disable_cache(void){ // erase block at this addr
NVMCTRL->CTRLA.bit.CACHEDIS0 = 1; void flash_erase_block(uint32_t *dst){
NVMCTRL->CTRLA.bit.CACHEDIS1 = 1; flash_wait_ready();
} // do 'erase row'
NVMCTRL->ADDR.reg = start_addr;//(uint32_t)dst;
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);
NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_EB; NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_EB;
//while(!NVMCTRL->INTFLAG.bit.DONE); flash_wait_ready();
while(!NVMCTRL->STATUS.bit.READY);
} }
static inline uint32_t read_unaligned_uint32(const void *data) // writes blocks of four four bit words: i.e. 4 floats per row, 4 uint32, etc
{ #define QUAD_WORD (4 * 4)
union { void flash_write_words(uint32_t *dst, uint32_t *src, uint32_t n_words){
uint32_t u32; sysError("writing quad to addr: 0x" + String(dst[0], HEX));
uint8_t u8[4]; // set manuel page write
} res; NVMCTRL->CTRLA.bit.WMODE = NVMCTRL_CTRLA_WMODE_MAN;
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;
}
static void flash_write_page(const volatile void *flash_ptr, const void *data, uint32_t size){ // execute page buffer clear
// disable cache, flash_wait_ready();
// 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);
NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_PBC; NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_PBC;
while(!NVMCTRL->STATUS.bit.READY); flash_wait_ready();
// do page buffer write (?)
volatile uint32_t *dst_addr = (volatile uint32_t *)flash_ptr; // write em ?
const uint8_t *src_addr = (uint8_t*)data; while(n_words > 0){
uint32_t i; // more than 4 words left?
for (i=0; i<(PAGE_SIZE/4) && size; i++) { uint32_t len = 4 < n_words ? 4 : n_words;
*dst_addr = read_unaligned_uint32(src_addr); // write one quad word into page buffer (is ... the flash address?)
src_addr += 4; for(uint32_t i = 0; i < 4; i ++){
dst_addr++; if(i < len){
size--; 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("quad complete");
sysError("page write"); delay(10);
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();
} }
static void flash_write_value(float val){ // ok, I think I can try this: I keep a row of vals, 4 of 'em, then on wrap, I write
page[page_f ++] = val; // using erase / then write, using the lut as the start,
if(page_f < floats_per_page) return; // I'll try to do it once, to start, then read it out...
// page is full, commit to flash
sysError("will write 0x" + String((uintptr_t) page_ptr, HEX) + " " + String(num_pages_written)); void flash_write_init(void){
flash_write_page(page_ptr, page, sizeof(page)); temp_indice = 0;
delay(10); }
// reset counters
// page_ptr += sizeof(page); void flash_write_value(float val){
page_f = 0; sysError("flt: " + String(val));
memset(page, 0, sizeof(page)); 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 // the calib routine
...@@ -201,8 +179,8 @@ boolean Step_CL::calibrate(void){ ...@@ -201,8 +179,8 @@ boolean Step_CL::calibrate(void){
// (2) build the table, walk all encoder counts... // (2) build the table, walk all encoder counts...
// now to build the actual table... // now to build the actual table...
// want to start with the 0 indice, // want to start with the 0 indice,
start_flash_write(); flash_write_init();
for(uint16_t e = 0; e < ENCODER_COUNTS; e ++){ for(uint16_t e = 0; e < 4; e ++){
// find the interval that spans this sample // find the interval that spans this sample
boolean bi = false; boolean bi = false;
int16_t interval = -1; int16_t interval = -1;
...@@ -300,7 +278,7 @@ boolean Step_CL::calibrate(void){ ...@@ -300,7 +278,7 @@ boolean Step_CL::calibrate(void){
} }
void Step_CL::print_table(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]; float ra = lut[e];
sysError("e: " + String(e) + " ra: " + String(ra, 4)); sysError("e: " + String(e) + " ra: " + String(ra, 4));
delay(5); delay(5);
......
...@@ -802,4 +802,12 @@ Have to erase before write, to set back to 1's: flash memory writes by pulling z ...@@ -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: I can also check the UF2 bootloader, which uses flash:
https://github.com/microsoft/uf2-samdx1/blob/master/src/flash_samd51.c https://github.com/microsoft/uf2-samdx1/blob/master/src/flash_samd51.c
\ No newline at end of file
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