2021-08-04 06:34 AM
Hi
I have a serious problem with EEPROM emulation
Writing and reading commands from EEPROM work well at first glance.
When I read the ST documentation related to EEPROM "UM0558", I noticed one thing and that is "swaping". Swap should be done when block is full. To test, I wrote about 1023 4-byte words in one address (Update a unique ID about 1023 time). But for 1024 words an error occurred and from then on everything went wrong.
for (i=0;i<1050;i++){
eewritebuf[0]=i;
result = FSL_WriteEeprom(&eepromConf,0,4,(UINT32)&eewritebuf,callback);
}
Why not update for 1024 and later. If everything is correct, it should be possible to update ID 0 to 1024 onwards.
Solved! Go to Solution.
2021-09-01 01:30 AM
Hi,
the behavior is due to the swap procedure. The EEPROM Emulation store in flash the data related to the different records + some metadata for each record. If you write 1024 times the same record, the first flash block (16KB) used by the EEPROM Emulation will be full. So, on the next record writing a swap will be necessary. The swap moves the valid records in a new flash block and erases the old flash block. During the erase of the old block, it is not possible to program any new record in the new block because all blocks of the Data Flash (used by the EEPROM Emulation) are in the same partition. So, when the swap starts, it is necessary to wait that the erase of the old block is completed before to start to write new records in the new block. Below you can find an example of code that works fine:
UINT32 oldActiveBlockIndex;
test_string_print(&SD1, "WRITE 1050 records in the Eeprom: ");
for (i=0; i < 1050; i++){
eewritebuf[0]=i;
oldActiveBlockIndex = eepromConf.activeBlockIndex;
result = FSL_WriteEeprom(&eepromConf, 0, 4, (UINT32)&eewritebuf, callback);
if (result != EE_OK) {
checkResult(result);
return 0;
}
/* If swap is needed, wait for erase completion */
if (oldActiveBlockIndex != eepromConf.activeBlockIndex)
{
oldActiveBlockIndex = eepromConf.activeBlockIndex;
osalThreadDelayMilliseconds(1000);
FSL_MainFunction(NULL_CALLBACK);
osalThreadDelayMilliseconds(1000);
}
}
Regards,
Luigi
2021-08-16 05:49 AM
I did the SWAP manually.
The question is why to write 1024th times on ID0 the whole program hangs and always the return situation is EE_INFO_HVOP_INPROGRESS ?
#include "components.h"
#include "eed_cfg.h"
#define SIZEEEPROMBLOCK 1023U
unsigned int tmp[32] = { 0 };
UINT32 readbackTmp[SIZEEEPROMBLOCK]={0};
#define setbit(var,bit) (var |= (0x01 << (bit)))
#define clrbit(var,bit) (var &= (~(0x01 << (bit))))
#define chckbit(var,bit) (var & ((0x01 << (bit))))
UINT32 RDerror=0;
UINT32 WRerror=0;
UINT32 eewritebuf[1]={0x55aa55bb};
UINT32 eereadbuf[1];
UINT32 result;
uint32_t i;
UINT32 faildAddr;
UINT64 faildData;
void callback(void);
void callback(void)
{
}
int main(void)
{
componentsInit();
FSL_RemoveEeprom(&eepromConf,callback);
result = FSL_InitEeprom(&eepromConf, callback);
for (i=0;i<1050;i++)
{
eewritebuf[0]=i;
result = FSL_WriteEeprom(&eepromConf,i,4,(UINT32)&eewritebuf,callback);
////SWAPP
if (result>=0x00002000)
{
result=FSL_AbortFunction(&eepromConf);
//Read back
for (unsigned int readindex = 0; readindex <= SIZEEEPROMBLOCK; readindex++)
{
if (FSL_ReadEeprom(&eepromConf,readindex,(UINT32)&readbackTmp[readindex],callback)==0)
{
setbit(tmp[readindex / 32], readindex % 32);
}
}
//remove EEPROM
FSL_RemoveEeprom(&eepromConf,callback);
result = FSL_InitEeprom(&eepromConf, callback);
//Write back
for (unsigned int writeindex =0;writeindex<=SIZEEEPROMBLOCK;writeindex++)
{
if (chckbit(tmp[writeindex / 32], writeindex % 32))
{
FSL_WriteEeprom(&eepromConf,writeindex,4,(UINT32)&readbackTmp[writeindex],callback);
}
}
}
}
...
2021-09-01 01:30 AM
Hi,
the behavior is due to the swap procedure. The EEPROM Emulation store in flash the data related to the different records + some metadata for each record. If you write 1024 times the same record, the first flash block (16KB) used by the EEPROM Emulation will be full. So, on the next record writing a swap will be necessary. The swap moves the valid records in a new flash block and erases the old flash block. During the erase of the old block, it is not possible to program any new record in the new block because all blocks of the Data Flash (used by the EEPROM Emulation) are in the same partition. So, when the swap starts, it is necessary to wait that the erase of the old block is completed before to start to write new records in the new block. Below you can find an example of code that works fine:
UINT32 oldActiveBlockIndex;
test_string_print(&SD1, "WRITE 1050 records in the Eeprom: ");
for (i=0; i < 1050; i++){
eewritebuf[0]=i;
oldActiveBlockIndex = eepromConf.activeBlockIndex;
result = FSL_WriteEeprom(&eepromConf, 0, 4, (UINT32)&eewritebuf, callback);
if (result != EE_OK) {
checkResult(result);
return 0;
}
/* If swap is needed, wait for erase completion */
if (oldActiveBlockIndex != eepromConf.activeBlockIndex)
{
oldActiveBlockIndex = eepromConf.activeBlockIndex;
osalThreadDelayMilliseconds(1000);
FSL_MainFunction(NULL_CALLBACK);
osalThreadDelayMilliseconds(1000);
}
}
Regards,
Luigi