Commit 099d24a8 authored by Jake Read's avatar Jake Read
Browse files

fail to write flash, stash to nuke and try again

parent b6003cb0
......@@ -46,6 +46,105 @@ void Step_CL::init(void){
//lut = flash_lut.read();
}
// das lut / flash stuff,
// 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] = {};
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;
}
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);
NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_EB;
//while(!NVMCTRL->INTFLAG.bit.DONE);
while(!NVMCTRL->STATUS.bit.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;
}
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);
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--;
}
// 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();
}
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));
}
// the calib routine
boolean Step_CL::calibrate(void){
// (1) first, build a table for 200 full steps w/ encoder averaged values at each step
float phase_angle = 0.0F;
......@@ -102,6 +201,7 @@ 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 ++){
// find the interval that spans this sample
boolean bi = false;
......@@ -179,26 +279,30 @@ boolean Step_CL::calibrate(void){
float offset = (spot - er0) / intSpan;
// find real angle offset at e, modulo for the bad interval
float ra = (ra0 + (ra1 - ra0) * offset);
// wrap to 360 degs,
/*
if(ra < 0.0F){
ra += 360.0F;
} else if (ra > 360.0F){
ra -= 360.0F;
}
*/
// log those
if(bi){
sysError("e: " + String(e) + " ra: " + String(ra, 4) + " BI");
// + " span: " + String(intSpan) + " offset: " + String(offset));
// sysError("i0: " + String(interval) + " " + String(calib_readings[interval])
// + " i1: " + String(calib_readings[interval + 1])
// + " BI");
} else {
sysError("e: " + String(e) + " ra: " + String(ra, 4));
if(false){
if(bi){
sysError("e: " + String(e) + " ra: " + String(ra, 4) + " BI");
// + " span: " + String(intSpan) + " offset: " + String(offset));
// sysError("i0: " + String(interval) + " " + String(calib_readings[interval])
// + " i1: " + String(calib_readings[interval + 1])
// + " BI");
} else {
sysError("e: " + String(e) + " ra: " + String(ra, 4));
}
delay(10);
}
delay(10);
// ok, have the real angle (ra) at the encoder tick (e), now write it
flash_write_value(ra); // this just happens in order, we zeroe'd out global counters at the start
} // end sweep thru 2^14 pts
sysError("calib complete");
return true; // went OK
}
void Step_CL::print_table(void){
for(uint16_t e = 0; e < ENCODER_COUNTS; e ++){
float ra = lut[e];
sysError("e: " + String(e) + " ra: " + String(ra, 4));
delay(5);
}
}
\ No newline at end of file
......@@ -32,6 +32,7 @@ class Step_CL {
static Step_CL* getInstance(void);
void init(void);
boolean calibrate(void);
void print_table(void);
//float __attribute__((__aligned__(256))) lut[16384]; // nor does this !
//float lut[16384]; // nor does this work
//step_cl_calib_table_t lut; // not even this works ?? too big ??
......
......@@ -151,12 +151,18 @@ void OSAP::handleAppPacket(uint8_t *pck, uint16_t pl, uint16_t ptr, uint16_t seg
switch(pck[ptr]){
case AK_RUNCALIB:
ptr ++; // walk stepcode
step_cl->calibrate();
reply[rl ++] = AK_RUNCALIB;
if(step_cl->calibrate()){
reply[rl ++] = AK_OK;
} else {
reply[rl ++] = AK_ERR;
}
// do step
break;
case AK_READCALIB:
ptr ++; // walk readcode
ptr ++; // walk readcode
reply[rl ++] = AK_READCALIB;
step_cl->print_table();
// do work
break;
default:
......
......@@ -10,6 +10,10 @@ With 2x A4950s on the DAC, AS5047P on the encoder, etc.
- haven't tested with '+ve' signed calibrations, i.e. if motor += magnetic step does encoder += tick step.
## Evaluation
- static holding, watch encoder wobble when torque applied (can see ticks moving around even w/o motor torque being overcome), measure again with closed loop: can we hold *better* than static pointing?
## 2020 10 06
OK, today am just waking this thing up. Have magnet glued (curing) on the back of the motor now, and one encoder soldered up on an old module-based stepper board - code should be the same.
......@@ -549,7 +553,7 @@ Yeah this looks all kinds of wrong.
Borked, indeed. Will check tomorrow. Errors just before the BI (nan, so our of index somewhere?) and the BI looks close but not quite there.
## 2020 10 08
## 2020 10 09
Ok, updating the interpolation, seems messy but I think (?) maybe this shot will work - at least for -ve signed samples.
......@@ -763,4 +767,39 @@ boolean Step_CL::calibrate(void){
}
```
So next up is writing that to flash so that I can use it.
\ No newline at end of file
So next up is writing that to flash so that I can use it.
Alright! Flash memory.
Seems like I've most of it written - just copying from mechaduino, but after I write these out, I freeze up the micro.
Yeah, welp, I think I might have to get into the datasheet and do this au manuel. I've learned that when I declare a const variable, it goes into the flash memory. I think my 'alignment' of that will set it up in pages, so I 'align' it to the page size, which I can read to be 512 bytes... I'll take a minute, see how this goes. Bummer it's Friday, I was pumped to get this up and running this week.
## 2020 10 13
Setting up the NVM Controller today to try to write pages into flash. Not sure why this was crashing before, probably something simple.
I don't think there's a clock / init I have to do to wake up the flash controller, seems like that would be kind of crazy. Yeah, 25.6.1.1 clarifies this.
I'm also not sure where the bootloader is in here, and seems likely that I might write it over.
'addressable on the AHB bus'
I think I almost get this, need to figure this note about disabling cache.. some erratta... am at 25.6.6
Trying with just doing automatic quad word writing, which I think auto increments the page-write pointer, not sure about what happens for the page buffer though. I should check via the mechaduino code and flash storage code...
Ok this is hella opaque, 25.6.6.2 ... `procedure for manual page writes`
- the block to be written must be erased before the write command is given
- write to the page buffer by addressing the nvm main address space directly (crazy)
- cmd = wp to write the full contents of the page buffer into the nvm at the page pointed to by addr
I fully don't understand this, but it seems like it should be straightforward. Likely next step is to burn it all down and try again from scratch. I should see if I can write *anything* and move away from this calib-then-write situation, which is probably complicating things.
#### Aboot Flash
Have to erase before write, to set back to 1's: flash memory writes by pulling zeroes low, and has to operate in blocks.
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
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