Commit 46a60a4c authored by Jake Read's avatar Jake Read
Browse files

local flashstorage lib works up to 8192 bytes

parent 6e4853a6
...@@ -50,7 +50,7 @@ void Step_CL::init(void){ ...@@ -50,7 +50,7 @@ void Step_CL::init(void){
#define BYTES_PER_PAGE 512 #define BYTES_PER_PAGE 512
#define FLOATS_PER_PAGE 128 #define FLOATS_PER_PAGE 128
#define PAGES_PER_BLOCK 16 // for 8192 bytes / block #define PAGES_PER_BLOCK 16 // for 8192 bytes / block
#define LUT_SIZE 128 #define LUT_SIZE 2048
//const float __attribute__((__aligned__(BYTES_PER_PAGE))) lut[LUT_SIZE] = {}; //const float __attribute__((__aligned__(BYTES_PER_PAGE))) lut[LUT_SIZE] = {};
//const void* page_ptr; //const void* page_ptr;
...@@ -69,7 +69,7 @@ uint32_t bi = 0; ...@@ -69,7 +69,7 @@ uint32_t bi = 0;
FlashStorage(flash_storage, flts); FlashStorage(flash_storage, flts);
void flash_write_init(void){ void flash_write_init(void){
bi = 0;
} }
void flash_write_page(void){ void flash_write_page(void){
...@@ -110,7 +110,7 @@ void Step_CL::print_table(void){ ...@@ -110,7 +110,7 @@ void Step_CL::print_table(void){
// the calib routine // the calib routine
boolean Step_CL::calibrate(void){ boolean Step_CL::calibrate(void){
flash_write_init(); flash_write_init();
for(uint8_t i = 0; i < LUT_SIZE; i ++){ for(uint32_t i = 0; i < LUT_SIZE; i ++){
flash_write_value(i * 1.1F); flash_write_value(i * 1.1F);
} }
return true; return true;
......
...@@ -25,18 +25,13 @@ FlashClass::FlashClass(const void *flash_addr, uint32_t size) : ...@@ -25,18 +25,13 @@ FlashClass::FlashClass(const void *flash_addr, uint32_t size) :
PAGE_SIZE(pageSizes[NVMCTRL->PARAM.bit.PSZ]), PAGE_SIZE(pageSizes[NVMCTRL->PARAM.bit.PSZ]),
PAGES(NVMCTRL->PARAM.bit.NVMP), PAGES(NVMCTRL->PARAM.bit.NVMP),
MAX_FLASH(PAGE_SIZE * PAGES), MAX_FLASH(PAGE_SIZE * PAGES),
#if defined(__SAMD51__)
ROW_SIZE(MAX_FLASH / 64), ROW_SIZE(MAX_FLASH / 64),
#else
ROW_SIZE(PAGE_SIZE * 4),
#endif
flash_address((volatile void *)flash_addr), flash_address((volatile void *)flash_addr),
flash_size(size) flash_size(size)
{ {
} }
static inline uint32_t read_unaligned_uint32(const void *data) static inline uint32_t read_unaligned_uint32(const void *data){
{
union { union {
uint32_t u32; uint32_t u32;
uint8_t u8[4]; uint8_t u8[4];
...@@ -49,10 +44,8 @@ static inline uint32_t read_unaligned_uint32(const void *data) ...@@ -49,10 +44,8 @@ static inline uint32_t read_unaligned_uint32(const void *data)
return res.u32; return res.u32;
} }
#if defined(__SAMD51__)
// Invalidate all CMCC cache entries if CMCC cache is enabled. // Invalidate all CMCC cache entries if CMCC cache is enabled.
static void invalidate_CMCC_cache() static void invalidate_CMCC_cache(){
{
if (CMCC->SR.bit.CSTS) { // CR -> SR if (CMCC->SR.bit.CSTS) { // CR -> SR
CMCC->CTRL.bit.CEN = 0; CMCC->CTRL.bit.CEN = 0;
while (CMCC->SR.bit.CSTS) {} while (CMCC->SR.bit.CSTS) {}
...@@ -60,17 +53,14 @@ static void invalidate_CMCC_cache() ...@@ -60,17 +53,14 @@ static void invalidate_CMCC_cache()
CMCC->CTRL.bit.CEN = 1; CMCC->CTRL.bit.CEN = 1;
} }
} }
#endif
void FlashClass::write(const volatile void *flash_ptr, const void *data, uint32_t size) void FlashClass::write(const volatile void *flash_ptr, const void *data, uint32_t size){
{
// Calculate data boundaries // Calculate data boundaries
size = (size + 3) / 4; size = (size + 3) / 4;
volatile uint32_t *dst_addr = (volatile uint32_t *)flash_ptr; volatile uint32_t *dst_addr = (volatile uint32_t *)flash_ptr;
const uint8_t *src_addr = (uint8_t *)data; const uint8_t *src_addr = (uint8_t *)data;
// Disable automatic page write // Disable automatic page write
#if defined(__SAMD51__)
NVMCTRL->CTRLA.bit.WMODE = 0; NVMCTRL->CTRLA.bit.WMODE = 0;
while (NVMCTRL->STATUS.bit.READY == 0) { } while (NVMCTRL->STATUS.bit.READY == 0) { }
// Disable NVMCTRL cache while writing, per SAMD51 errata. // Disable NVMCTRL cache while writing, per SAMD51 errata.
...@@ -78,20 +68,12 @@ void FlashClass::write(const volatile void *flash_ptr, const void *data, uint32_ ...@@ -78,20 +68,12 @@ void FlashClass::write(const volatile void *flash_ptr, const void *data, uint32_
bool original_CACHEDIS1 = NVMCTRL->CTRLA.bit.CACHEDIS1; bool original_CACHEDIS1 = NVMCTRL->CTRLA.bit.CACHEDIS1;
NVMCTRL->CTRLA.bit.CACHEDIS0 = true; NVMCTRL->CTRLA.bit.CACHEDIS0 = true;
NVMCTRL->CTRLA.bit.CACHEDIS1 = true; NVMCTRL->CTRLA.bit.CACHEDIS1 = true;
#else
NVMCTRL->CTRLB.bit.MANW = 1;
#endif
// Do writes in pages // Do writes in pages
while (size) { while (size) {
// Execute "PBC" Page Buffer Clear // Execute "PBC" Page Buffer Clear
#if defined(__SAMD51__)
NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_PBC; NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_PBC;
while (NVMCTRL->INTFLAG.bit.DONE == 0) { } while (NVMCTRL->INTFLAG.bit.DONE == 0) { }
#else
NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_PBC;
while (NVMCTRL->INTFLAG.bit.READY == 0) { }
#endif
// Fill page buffer // Fill page buffer
uint32_t i; uint32_t i;
...@@ -103,22 +85,16 @@ void FlashClass::write(const volatile void *flash_ptr, const void *data, uint32_ ...@@ -103,22 +85,16 @@ void FlashClass::write(const volatile void *flash_ptr, const void *data, uint32_
} }
// Execute "WP" Write Page // Execute "WP" Write Page
#if defined(__SAMD51__)
NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_WP; NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_WP;
while (NVMCTRL->INTFLAG.bit.DONE == 0) { } while (NVMCTRL->INTFLAG.bit.DONE == 0) { }
invalidate_CMCC_cache(); invalidate_CMCC_cache();
// Restore original NVMCTRL cache settings. // Restore original NVMCTRL cache settings.
NVMCTRL->CTRLA.bit.CACHEDIS0 = original_CACHEDIS0; NVMCTRL->CTRLA.bit.CACHEDIS0 = original_CACHEDIS0;
NVMCTRL->CTRLA.bit.CACHEDIS1 = original_CACHEDIS1; NVMCTRL->CTRLA.bit.CACHEDIS1 = original_CACHEDIS1;
#else
NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_WP;
while (NVMCTRL->INTFLAG.bit.READY == 0) { }
#endif
} }
} }
void FlashClass::erase(const volatile void *flash_ptr, uint32_t size) void FlashClass::erase(const volatile void *flash_ptr, uint32_t size){
{
const uint8_t *ptr = (const uint8_t *)flash_ptr; const uint8_t *ptr = (const uint8_t *)flash_ptr;
while (size > ROW_SIZE) { while (size > ROW_SIZE) {
erase(ptr); erase(ptr);
...@@ -128,22 +104,14 @@ void FlashClass::erase(const volatile void *flash_ptr, uint32_t size) ...@@ -128,22 +104,14 @@ void FlashClass::erase(const volatile void *flash_ptr, uint32_t size)
erase(ptr); erase(ptr);
} }
void FlashClass::erase(const volatile void *flash_ptr) void FlashClass::erase(const volatile void *flash_ptr){
{
#if defined(__SAMD51__)
NVMCTRL->ADDR.reg = ((uint32_t)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) { } while (!NVMCTRL->INTFLAG.bit.DONE) { }
invalidate_CMCC_cache(); invalidate_CMCC_cache();
#else
NVMCTRL->ADDR.reg = ((uint32_t)flash_ptr) / 2;
NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_ER;
while (!NVMCTRL->INTFLAG.bit.READY) { }
#endif
} }
void FlashClass::read(const volatile void *flash_ptr, void *data, uint32_t size) void FlashClass::read(const volatile void *flash_ptr, void *data, uint32_t size){
{
memcpy(data, (const void *)flash_ptr, size); memcpy(data, (const void *)flash_ptr, size);
} }
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
#define PPCAT_NX(A, B) A ## B #define PPCAT_NX(A, B) A ## B
#define PPCAT(A, B) PPCAT_NX(A, B) #define PPCAT(A, B) PPCAT_NX(A, B)
#if defined(__SAMD51__) #define Flash(name, size) \
#define Flash(name, size) \
__attribute__((__aligned__(8192))) \ __attribute__((__aligned__(8192))) \
static const uint8_t PPCAT(_data,name)[(size+8191)/8192*8192] = { }; \ static const uint8_t PPCAT(_data,name)[(size+8191)/8192*8192] = { }; \
FlashClass name(PPCAT(_data,name), size); FlashClass name(PPCAT(_data,name), size);
...@@ -35,17 +34,6 @@ ...@@ -35,17 +34,6 @@
__attribute__((__aligned__(8192))) \ __attribute__((__aligned__(8192))) \
static const uint8_t PPCAT(_data,name)[(sizeof(T)+8191)/8192*8192] = { }; \ static const uint8_t PPCAT(_data,name)[(sizeof(T)+8191)/8192*8192] = { }; \
FlashStorageClass<T> name(PPCAT(_data,name)); FlashStorageClass<T> name(PPCAT(_data,name));
#else
#define Flash(name, size) \
__attribute__((__aligned__(256))) \
static const uint8_t PPCAT(_data,name)[(size+255)/256*256] = { }; \
FlashClass name(PPCAT(_data,name), size);
#define FlashStorage(name, T) \
__attribute__((__aligned__(256))) \
static const uint8_t PPCAT(_data,name)[(sizeof(T)+255)/256*256] = { }; \
FlashStorageClass<T> name(PPCAT(_data,name));
#endif
class FlashClass { class FlashClass {
public: public:
......
...@@ -872,4 +872,6 @@ OK, today will bring this library into the local build and see about figuring wh ...@@ -872,4 +872,6 @@ OK, today will bring this library into the local build and see about figuring wh
- pages are 512 bytes - pages are 512 bytes
- blocks are 16 pages - blocks are 16 pages
This means a block is 8192, makes sense this is where flashstorage aligns itself. I need 8 blocks total for the full LUT. This means a block is 8192, makes sense this is where flashstorage aligns itself. I need 8 blocks total for the full LUT.
\ No newline at end of file
Interesting, now that I fixed this error which appeared when it was compiling locally, I can get past 512 bytes with my example. Could try the big one...
\ 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