The issue:
I can't seem to figure out how to write\read Flash when there is less then a FLASH page (512 bytes) to be written. I want to write multiple records in a single page without the need to write them all at once.
So far I have not been able to succeed.
My Code:
uint8_t *data= "pointer to datastructure of 100 bytes";
for(i=0;i<100;i++)
{
data[i] = i;//Put 0 upto 99..
}
//Request flash storing
StoreData(&data[0]);
StoreData(&data[0]);
StoreData(&data[0]);
StoreData(&data[0]);
#include "fsl_flash.h"
#define START_FLASH_STORAGE (0x00059000)
uint32_t au32DataCopy[STORE_DATA_SIZE];
uint32_t au32DataCopy2[STORE_DATA_SIZE];
unsigned long FlashBufferHead=0;
PUBLIC bool StoreData(uint8_t *inp)
{
uint32_t *pu32Start = (uint32_t *)(START_FLASH_STORAGE+FlashBufferHead);
uint8_t *data=(uint8_t*)&inp[0];
uint8_t *datacopy=(uint8_t*)&au32DataCopy[0];
uint8_t *datacopy2=(uint8_t*)&au32DataCopy2[0];
flash_status_t driver_result;
uint32_t i, u32StartPage;
Initialize_FlashCircBuffer();
/* erase sector if first write in new page */
if (FlashBufferHead % 512 == 0)
{
u32StartPage = (uint32)pu32Start;
u32StartPage /= 512;
LOG_ERROR("Erase page: % d", u32StartPage);
driver_result = FLASH_ErasePages(FLASH, u32StartPage, 1);
if (driver_result != kStatus_FLASH_Success)
{
LOG_ERROR("Flash read unsuccessful");
}
}
driver_result = FLASH_Program(FLASH, pu32Start, (uint32_t*)inp, 100);
if (driver_result != kStatus_FLASH_Success)
{
LOG_ERROR("Flash read unsuccessful");
}
/* Read back data */
uint32_t temp[4];
for (i = 0; i < 100; i += 4)
{
FLASH_Read(FLASH, (uint8_t *)(pu32Start + i), 0, (uint32_t *)temp);
memcpy(&au32DataCopy[i], (void *)temp, sizeof(temp));
}
/* Read back data again---debug issue */
for (i = 0; i < 100; i += 4)
{
FLASH_Read(FLASH, (uint8_t *)(START_FLASH_STORAGE + i), 0, (uint32_t *)temp);
memcpy(&au32DataCopy2[i], (void *)temp, sizeof(temp));
}
/* determine if saved correctly */
for (i = 0; i < 100; i++)
{
if(data[i] != datacopy[i])
{
LOG_ERROR("Flash verify unsuccessful");
}
}
LOG_ERROR("verify completed..?");
FlashBufferHead +=100;
}
Result:
At first I was increasing my flash location pointer by 100 (using FlashBufferHead ) during each run to allow a multiple of 100 bytes per pages to be saved. The second run I notice an offset in the values read. The values written are there, but seem to start 4 bytes later. I expected to be able to write at least in multiples of 4 bytes.
(...sorry my mcuxpresso is really buggy now... no screenshot yet...)
If I'm increasing pointer to flash by 256. The second run byte 35 is always read back as a different value then was requested to write. All other 100 bytes are written\read correctly.
If I'm increasing my flash location pointer by 512, this always results in a FLASH_ErasePages call before each write. Then there are no issues.
Code from fsl_flash.c
int FLASH_Program(FLASH_Type *pFLASH, uint32_t *pu32Start, uint32_t *pu32Data, uint32_t u32Length)
{
int status = 0;
uint32_t end = (uint32_t)pu32Start + u32Length;
uint32_t padding = (FLASH_PAGE_SIZE - (end & (FLASH_PAGE_SIZE-1))) & (FLASH_PAGE_SIZE-1);
pFLASH->INT_CLR_STATUS = FLASH_STAT_ALL;
pFLASH->AUTOPROG = FLASH_AUTO_PAGE;
memcpy(pu32Start, pu32Data, u32Length);
while (padding-- > 0)
{
*(uint8_t*)end ++ = 0;
}
status = FLASH_Wait(pFLASH);
pFLASH->AUTOPROG = FLASH_AUTO_OFF;
return status;
}