PSOC 4 Flash Em_EEPROM stuck issue when Reading & Writing and solution
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
Symptoms
Diagnosis
Customer use PSOC 4 CY8C4147AZI-S455 to design Remote controller, implement Segment LCD+ Capsense+ System control function, use Flash Em_EEPROM (version: V2.2) component to store system parameter, and the remote controller was used in hotel room, and when room ID card insert in power supply booth ,the AC power on ,and indoor aircon & remote controller start work, when remove the ID card ,the ac power down, indoor aircon & remote controller stop work
They feedback the remote controller can’t start up and no display after several working months.
We read the bad remote controller, and found the code section are the same, and EEPROM data are different from each other
We re-program the bad remote controller, and it can run well again
Solution
We checked KBA227502 & KBA227530 &KBA228069and modified cy_em_eeprom.c the following code
Cy_Em_EEPROM_Read() |
|
if((CY_EM_EEPROM_SUCCESS == ret) && (0u != seqNum)) { numRowReads = (context->numberOfRows <= seqNum) ? (context->numberOfRows) : (seqNum); numRowReads--; for(i = (seqNum - numRowReads); i <= seqNum; i++) { startRowAddr = GetRowAddrBySeqNum(i, context); if (0u != startRowAddr) { ...
|
if((CY_EM_EEPROM_SUCCESS == ret) && (0u != seqNum)) { numRowReads = (context->numberOfRows <= seqNum) ? (context->numberOfRows) : (seqNum); for(i = 0; i < numRowReads; i++) { startRowAddr = GetRowAddrBySeqNum(seqNum - ((numRowReads - 1) - i), context); if (0u != startRowAddr) { ...
|
|
|
CheckCrcAndCopy() |
|
if(CY_EM_EEPROM_SUCCESS == ret) { (void)memcpy((void *)(dstAddr), (void *)(writeRamBuffer + rowOffset), numBytes); }
|
if(CY_EM_EEPROM_SUCCESS == ret) { (void)memcpy((void *)(dstAddr), (void *)((uint32_t)writeRamBuffer + rowOffset), numBytes); }
|
|
|
Cy_Em_EEPROM_Write() |
|
/* Write the data to the specified flash row */ ret = WriteRow(emEepromRowAddr, writeRamBuffer, context); tmpRowAddr = emEepromRowAddr;
|
/* 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); } /* Write the data to the specified flash row */ ret = WriteRow(emEepromRowAddr, writeRamBuffer, context); tmpRowAddr = emEepromRowAddr;
|
|
Cy_Em_EEPROM_Erase() |
|
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); }
|
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); } 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); }
|
|
|
FindLastWrittenRow() |
|
/* Some record in EEPROM was found. Store found sequence * number and row address. */ prevSeqNum = seqNum; *lastWrRowPtr = emEepromAddr;
|
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; }
|
|
But we still found Cy_Em_EEPROM_Write() following issue
for(; i <= seqNum; i++)
{
……
}
When seqNum=0xFFFFFFFF ,the for loop will loop forever ,and no chance jump out
So we need to add some special deal before it
if(seqNum >= (0xFFFFFFF0))
{
seqNum=1;
}
Cy_Em_EEPROM_Write() |
|
for(wrCnt = 0u; wrCnt < numWrites; wrCnt++) { uint32 skipOperation = 0u; /* Get the sequence number of the last written row */ uint32 seqNum = CY_EM_EEPROM_GET_SEQ_NUM(emEepromRowAddr);
/* Get the address of the row to be written. The "emEepromRowAddr" may be * updated with the proper address (if wear leveling is used). The * "emEepromRowRdAddr" will point to the row address from which the historic * data will be read into the RAM buffer. */ GetNextRowToWrite(seqNum, &emEepromRowAddr, &emEepromRowRdAddr, context); |
for(wrCnt = 0u; wrCnt < numWrites; wrCnt++) { uint32 skipOperation = 0u; /* Get the sequence number of the last written row */ uint32 seqNum = CY_EM_EEPROM_GET_SEQ_NUM(emEepromRowAddr);
if(seqNum >= (0xFFFFFFF0)) { seqNum=1; }
/* Get the address of the row to be written. The "emEepromRowAddr" may be * updated with the proper address (if wear leveling is used). The * "emEepromRowRdAddr" will point to the row address from which the historic * data will be read into the RAM buffer. */ GetNextRowToWrite(seqNum, &emEepromRowAddr, &emEepromRowRdAddr, context); |
|
We have modified cy_em_eeprom.c ,and download the attached file
Please update it as the following path:
C:\Program Files (x86)\Cypress\PSoC Creator\4.X\PSoC Creator\psoc\content\CyComponentLibrary\CyComponentLibrary.cylib\Em_EEPROM_Dynamic_v2_X\API