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

Version 3

    Author: BennyJ_71           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.