Skip to main content
Mr Alireza Najafi
Associate
August 4, 2021
Solved

Eeprom emulation problem in spc5660b

  • August 4, 2021
  • 2 replies
  • 1466 views

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.

This topic has been closed for replies.
Best answer by zambrano.luigi

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

2 replies

Mr Alireza Najafi
Associate
August 16, 2021

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);

}

}

}

 }

...

zambrano.luigi
zambrano.luigiBest answer
ST Employee
September 1, 2021

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