Em_EEPROM Functions Not Performed Correctly when EEPROM Data Is Corrupted - KBA228069

Version: **

Context: PSoC® Creator™ 4.2 project with the Em_EEPROM Component v2_0, v2_10 or v2_20, for PSoC 3, PSoC 4, PSoC 5LP, or PSoC 6 MCU devices.

ModusToolbox™ IDE project with psoc6sw-1.0 or psoc6sw-1.1 libraries which uses the Emulated EEPROM middleware for PSoC 6 MCU.

Issue: Data in the Em_EEPROM may be corrupted due to an unexpected reset or power loss while the Em_EEPROM Component performs the write operation. The following functions may work incorrectly when the Em_EEPROM Component is started with corrupted data:

  • Cy_Em_EEPROM_Write()
  • Cy_Em_EEPROM_Erase()
  • Cy_Em_EEPROM_NumWrites()

 

  • Em_EEPROM_Write()
  • Em_EEPROM_Erase()
  • Em_EEPROM_NumWrites()

Cause: This issue occurs because the internal Em_EEPROM data is not validated before usage.

Note: The workaround provided in this article works only when Redundant Copy is disabled. It implements calculation and check of the CRC on the Em_EEPROM data header, which contains the Sequence Number.

With the workaround code, Em_EEPROM calculates and writes CRC on Write and Erase operations; CRC is checked in the FindLastWrittenRow() function called in the Init() function.

Fix for this issue along with other improvements is already implemented in the Em_EEPROM middleware v2.0 for PSoC 6 MCU in ModusToolbox and will be implemented in PSoC Creator Em_EEPROM Component v3.0.

Workaround:

  1. Find the cy_em_eeprom.c file. Depending on the PSoC family and Component version, this file is located in one of the following directories:

PSoC Creator 4.2 and PSoC 3, PSoC 4, or PSoC 5LP:

·         C:\Users\<Username>\Documents\PSoC Creator\4.2\Downloads ( 4.2).cylib\Em_EEPROM_Dynamic_v2_10\API\cy_em_eeprom.c

·         C:\Users\<Username>\Documents\PSoC Creator\4.2\Downloads ( 4.2).cylib\Em_EEPROM_Dynamic_v2_20\API\cy_em_eeprom.c

 

PSoC Creator 4.2 and  PSoC 6 MCU:

·         C:\Program Files (x86)\Cypress\PDL\3.0.4\middleware\em_eeprom\cy_em_eeprom.c

·         C:\Program Files (x86)\Cypress\PDL\3.1.0\middleware\em_eeprom\cy_em_eeprom.c

 

ModusToolbox and PSoC 6 MCU:

·         <user_home>\ModusToolbox_1.0\libraries\psoc6sw-1.0\components\psoc6mw\em_eeprom\cy_em_eeprom.c

·         <user_home>\ModusToolbox_1.1\libraries\psoc6sw-1.1\components\psoc6mw\em_eeprom\cy_em_eeprom.c

 

     2.    Create a backup for the cy_em_eeprom.c file and modify the code inside as follows.

Note: You must run your our editor software with Administrator rights to modify the cy_em_eeprom.c file for PSoC Creator 4.2 and PSoC 6 MCU.

 

2.1.       Apply the workaround described in KBA227502.

2.2.       Modify the Cy_Em_EEPROM_Write() function. Locate lines with the following code:

            /* Write the data to the specified flash row */

            ret = WriteRow(emEepromRowAddr, writeRamBuffer, context);

            tmpRowAddr = emEepromRowAddr;

 

Insert the following code before the lines that you located in the previous step:

 

            /* Calculate the checksum of a data header if redundant copy is disabled */

            if(0u == context->redundantCopy)

            {

                writeRamBuffer[CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET_U32] = (uint32_t)

                        CalcChecksum((uint8_t *) &writeRamBuffer[0],

                                                  CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET);

            }

 

2.3.       Modify the Cy_Em_EEPROM_Erase() function. Locate lines with the following code:

 

        if(0u != context->redundantCopy)

        {

            writeRamBuffer[CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET_U32] = (uint32_t)

                        CalcChecksum((uint8_t *) &writeRamBuffer[CY_EM_EEPROM_EEPROM_DATA_OFFSET_U32],

                                                  CY_EM_EEPROM_EEPROM_DATA_LEN);

        }

 

and insert the following code before the lines that you located in the previous step:

 

        else

        {

            /* Calculate the checksum of a data header if redundant copy is disabled */

            writeRamBuffer[CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET_U32] = (uint32_t)

                    CalcChecksum((uint8_t *) &writeRamBuffer[0],

                                              CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET);

        }

 

2.4.       Modify the FindLastWrittenRow() function. Locate lines with the following code:

 

                /* Some record in EEPROM was found. Store found sequence

                * number and row address.

                */

                prevSeqNum = seqNum;

                *lastWrRowPtr = emEepromAddr;

 

and insert the following code before the lines that you located in the previous step:

 

            if((*(uint32_t *)(emEepromAddr + CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET)) ==

                ((uint32_t) CalcChecksum((uint8_t *)emEepromAddr,

                                                    CY_EM_EEPROM_HEADER_CHECKSUM_OFFSET)))

            {

                /* Some record in EEPROM was found. Store found sequence

                * number and row address.

                */

                prevSeqNum = seqNum;

                *lastWrRowPtr = emEepromAddr;

            }

1.