- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
- Labels:
-
Memory Nor Flash
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Thank you for contacting Cypress Technical Support, an Infineon Technologies Company. Can you provide answer to the following questions?
- What is the expected data and incorrect data when error happening?
- Was the error happening at location random or specific location (e.g., specific Write Buffer, or specific sector etc.)?
- What was the operation right before the error read? Polling status register to complete then read the data immediately?
- I understand it is difficult to reproduce. Is it possible to test with the first read at another location (i.e., the location not in the Write Buffer just programmed)? I’d like to see the error associated with the read operation or the Write Buffer just programmed.
- “if we change the source code we never encounter the issue” – what did you change in the source code?
Thank you
Regards,
Bushra
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
sysFlash_WriteFo(FLASH_BASE_FLASH_ADDRESS, LLD_UNLOCK_ADDR1, NOR_UNLOCK_DATA1);
sysFlash_WriteFo(FLASH_BASE_FLASH_ADDRESS, LLD_UNLOCK_ADDR2, NOR_UNLOCK_DATA2);
sysFlash_WriteFo(FLASH_BASE_FLASH_ADDRESS, LLD_UNLOCK_ADDR1, NOR_UNLOCK_BYPASS_ENTRY_CMD);
/* Write program command, buffer size */
sysFlash_WriteF(address, NOR_WRITE_BUFFER_LOAD_CMD);
sysFlash_WriteF(address, (UINT16)(numwordInloop-1) );
for (cur_add=address; cur_add-address < (numwordInloop<<1); cur_add
+=sizeof(UINT16))
{
expect = *memBuf;
memBuf ++;
sysFlash_WriteF(cur_add, expect);
}
cur_add -= sizeof(UINT16); /* can't advance beyond end of array */
sysFlash_WriteF(cur_add, NOR_WRITE_BUFFER_PGM_CONFIRM_CMD);
sysFlash_WaitUntilReady( FLASH_PROGRAM_TIMEOUT)
sysFlash_WriteF(FLASH_BASE_FLASH_ADDRESS, NOR_SECSI_SECTOR_EXIT_SETUP_CMD);
sysFlash_WriteF(FLASH_BASE_FLASH_ADDRESS, NOR_SECSI_SECTOR_EXIT_CMD);
{
DEBUG_MSG("Debug: flashPtr %x - length %d\n", flashPtr, length, 3, 4, 5, 6);
DumpNFlash((char*)flashPtr, length);
Dump((char*)buffer, length);
status = flWriteFault;
}
{
int i;
unsigned char* p_d;
unsigned char* p_s;
p_d = (unsigned char*)d;
p_s = (unsigned char*)s;
for (i=0; i<l; i++)
{
if (p_d[i] != p_s[i])
{
return 1;
}
}
return 0;
}
Best Regards,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello
Are you using timeout timer to determine the Programming completeness? What is the value of FLASH_PROGRAM_TIMEOUT ? Is it Typical Buffer Program time or Maximum Buffer Program time?
/* Then wait until done */
sysFlash_WaitUntilReady( FLASH_PROGRAM_TIMEOUT)
Btw, Timeout timer is not the best approach to check program/erase completeness (not efficient). The suggested approach is to read/check Status Register. The timeout timer (Maximum Program (or erase) time) is usually used with Status Register checking together, to stop the dead loop in the case something wrong happening and maximum erase/program time is reached.
Thank you
Regards,
Bushra
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Yes of course we use the timeout to stop the dead loop when we pool the status Register.
We have a version with the first byte dumped. Each time it is the first byte and several time its 4 times the same value 0x0C first read and 0x4C the second one
and the location is never at the same place.
Version X (first byte not dumped during the comparison)
Debug: flashPtr 41f7c600 - index 0
p_d[i]0xb1 != p_s[i]0xb1
Version X+1:
Run1:
b_cmp: flashPtr 41f9b800 - index 0
p_d[i]0x0c != p_s[i]0x4c
->
-> b_cmp: flashPtr 41f4ee00 - index 0
p_d[i]0x0c != p_s[i]0x4c
b_cmp: flashPtr 41cfa000 - index 0
p_d[i]0x0c != p_s[i]0x4c
b_cmp: flashPtr 40d0ea00 - index 0
p_d[i]0x0c != p_s[i]0x4c
b_cmp: flashPtr 40e41e00 - index 0
p_d[i]0x0c != p_s[i]0x4c
b_cmp: flashPtr 4121fa00 - index 0
p_d[i]0x0c != p_s[i]0x4c
b_cmp: flashPtr 414dfe00 - index 0
p_d[i]0x0c != p_s[i]0x4c
b_cmp: flashPtr 41bb5e00 - index 0
p_d[i]0x11 != p_s[i]0x91
Run2
b_cmp: flashPtr 41743400 - index 0
p_d[i]0x0c != p_s[i]0x4c
-> b_cmp: flashPtr 41ad6400 - index 0
p_d[i]0x0c != p_s[i]0x4c
b_cmp: flashPtr 41fe9c00 - index 0
p_d[i]0x0c != p_s[i]0x4c
b_cmp: flashPtr 41cf6200 - index 0
p_d[i]0x0c != p_s[i]0x4c
b_cmp: flashPtr 413eba00 - index 0
p_d[i]0x11 != p_s[i]0x91
Run 3 :
b_cmp: flashPtr 417c8200 - index 0
p_d[i]0x0c != p_s[i]0x4c
b_cmp: flashPtr 41c93e00 - index 0
p_d[i]0x0c != p_s[i]0x4c
b_cmp: flashPtr 41578800 - index 0
p_d[i]0x0c != p_s[i]0x4c
b_cmp: flashPtr 416b2600 - index 0
p_d[i]0x0c != p_s[i]0x4c
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
“we use the timeout to stop the dead loop when we pool the status Register”
– In the code we reviewed, did not see Status Register polling. Only see “sysFlash_WaitUntilReady( FLASH_PROGRAM_TIMEOUT)”. Does this function include both Status Register polling and Timeout timer? Can we take a look at the implementation of this function? What is the FLASH_PROGRAM_TIMEOUT value? Is it set as Typical Buffer Program time or Maximum Buffer Program time specified in datasheet?
The read data 0x0C & 0x4C looks like typical program in progress state, which has DQ6 toggling. The read data 0x11 & 0x91 looks like the transitional state at the time of Buffer program completion. One more read is needed to read out the correct programmed data.
Thank you
Regards,
Bushra
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just an info:
The data 0x4C and 0x91 are the correct data written in the flash and not the toggling
Best Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Another information concerning the Run with First Byte trace where we have 0x0c and then the correct data 0x4c.
After this first check failed we retry the comparison with b_cmp function for all the data written in the flash and all is OK.
Best Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Here is the source code for sysFlash_WaitUntilReady()
/* PROGRAM_TIMEOUT_CYCLES = # of times to check for status ready after
program commands are issued to the device */
#define FLASH_PROGRAM_TIMEOUT 1000000L
UINT8 sysFlash_WaitUntilReady(UINT32 timeout)
{
if ( semTake(FlashSemId,FLASH_SEM_TIMEOUT) == ERROR)
{
LOG("Error : SemTake timeout for WaitUntilReady\n\r");
return (FALSE);
}
while (timeout)
{
if ( mIsStatusReady( sysFlash_ReadStatus() ))
{
semGive(FlashSemId);
return ( TRUE );
}
timeout--;
}
semGive(FlashSemId);
return ( FALSE );
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
The polling code “sysFlash_WaitUntilReady()” looks good. The failure symptom and the logs seem like the 1st byte read happened at the time that flash data bus in the transitional state switching from state machine to memory array data. Can you please provide more test/failure details by answering these questions?
- What is the Status Register value of the last read when sysFlash_WaitUntilReady() returns?
- At the time of the error happening, did sysFlash_WaitUntilReady() return TRUE or FALSE? We did not see the return value was checked in the code we reviewed earlier.
/* Then wait until done */
sysFlash_WaitUntilReady( FLASH_PROGRAM_TIMEOUT)
How many flash devices have been tested with the same software and how many have the same issue?
Thank you
Regards,
Bushra
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I made a test with the folowing code to chek Error in Status register and to check the bit 6 toggling :
UINT8 sysFlash_WaitUntilReady(UINT32 timeout)
{
FLASH_FDATA status, statusToggleBit;
if ( semTake(FlashSemId,FLASH_SEM_TIMEOUT) == ERROR)
{
LOG("Error : SemTake timeout for WaitUntilReady\n\r");
return (FALSE);
}
while (timeout)
{
status = sysFlash_ReadStatus();
if ( mIsStatusReady( status ))
{
if (status & 0x7F)
{
printf("Status Register Error : 0x%08x \n",status);
}
/* Check Toggle Bit 6 */
sysFlash_ReadF(FLASH_BASE_FLASH_ADDRESS, &status);
sysFlash_ReadF(FLASH_BASE_FLASH_ADDRESS, &statusToggleBit);
if (status != statusToggleBit)
{
printf("Toggle Bit 6 0x%08x 0x%08x \n",status, statusToggleBit);
}
else
{
semGive(FlashSemId);
return ( TRUE );
}
}
timeout--;
}
semGive(FlashSemId);
return ( FALSE );
}
The result is :
->
-> b_cmp: flashPtr 417ae200 - index 0
p_d[i]0x0c != p_s[i]0x4c
-> b_cmp: flashPtr 40fe3200 - index 0
p_d[i]0x0c != p_s[i]0x4c
1. Answer
If no trace from sysFlash_WaitUntilReady() means status registers is 0x80.
To test my code I put a breakpoint and the Status when ready and it was 0xAC80 and the double read for toggle bit 6 was the data expected.
2. Answer
If the sysFlash_WaitUntilReady return FALSE we exit the ProgramFunction and we don't compare the data.
When we have the error we enter in b_cmp function so it means the sysFlash_WaitUntilReady() function return TRUE.
For the moment I have 2 boards with the problem and One for the moment without.
One who return 0x0c and then 0x4c
the second return 0x30 then 0xb0
Its very strange that the data is always the same.
Best Regards,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
From the code I reviewed (see below code quoted), I don’t see sysFlash_WaitUntilReady() return value is checked. It is called, then Exit Bypass Mode, then enter b_cmp() function to verify data. Please let me know if my understanding is not correct. Or is the code I reviewed are snippets and some related code not included?
/* Then wait until done */
sysFlash_WaitUntilReady( FLASH_PROGRAM_TIMEOUT)
/* Exit Bypass Mode to return device to read array mode */
sysFlash_WriteF(FLASH_BASE_FLASH_ADDRESS, NOR_SECSI_SECTOR_EXIT_SETUP_CMD);
sysFlash_WriteF(FLASH_BASE_FLASH_ADDRESS, NOR_SECSI_SECTOR_EXIT_CMD);
/* verify the data in flash with the buffer to write */
if ( b_cmp((void FAR0 *) flashPtr, (void FAR1*)buffer,length) != 0 )
From the original sysFlash_WaitUntilReady() implementation, in the case timer times out, the function returns false.
In the sysFlash_WaitUntilReady() test code, double reads for toggle bit 6 is added. However, if the timer times out before program complete (i.e., mIsStatusReady( status ) is not true) , this code will not be executed.
As you mentioned “To test my code I put a breakpoint and the Status when ready and it was 0xAC80 and the double read for toggle bit 6 was the data expected.” – Do you mean when you saw this result, you still have the 1st byte read error?
Can you please do below test:
- Enlarge the timeout timer (i.e., FLASH_PROGRAM_TIMEOUT) 10 times, test if the error goes away
- Move compare data (b_cmp) function to the place after program complete and before Exit Unlock Bypass mode, to see if any difference
- Test with the same code, only remove Unlock Bypass Mode (i.e., normal program mode), to see if any difference
- If all above 3 tests do not have improvement, please do below
- After flash is completely power on, do a hardware reset (i.e., keeps power supply stable and drive RESET# signal low for a while. Refer to datasheet hardware reset timing requirement). Then test to see if the error goes away
- Capture Power On Reset timing (including Vcc, Vio, RESET#, CS# signals), with the time measurements of tVCS, tVIOS, tRH, tCEH. (If VCC and VIO are tied together on the board, then VIO and VIOS are not necessary)
Thank you
Regards,
Bushra
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Yes of course the code is snippet to avoid to much trace. Send me an Email and I can send you all the source code.
From the original sysFlash_WaitUntilReady() implementation, in the case timer times out, the function returns false.
UserARI => Yes it return false but we never enter in it.
Our timeout is minimum 5s and I made a test with an infinit loop but the bug still happend.
Here an snippet of the code :
/* Make sure part is ready */
if ( !sysFlash_WaitUntilReady(FLASH_PROGRAM_TIMEOUT) )
{
stat.Result = StatTimeout;
if (returnSR)
{
stat.SR = sysFlash_ReadStatus();
}
if (memBuf != NULL)
{
free(memBuf);
}
semGive(FlashSemId);
return (stat );
}
/* Write program command, buffer size and data then wait until done */
if (g_FlashType == NewFlashType)
{
/* Enter in Cypress Unlock ByPass Mode */
sysFlash_WriteFo(FLASH_BASE_FLASH_ADDRESS, LLD_UNLOCK_ADDR1, NOR_UNLOCK_DATA1);
sysFlash_WriteFo(FLASH_BASE_FLASH_ADDRESS, LLD_UNLOCK_ADDR2, NOR_UNLOCK_DATA2);
/*sysFlash_WriteFo(FLASH_BASE_FLASH_ADDRESS, LLD_UNLOCK_ADDR1, NOR_UNLOCK_BYPASS_ENTRY_CMD);*/
/* Write program command, buffer size */
sysFlash_WriteF(address, NOR_WRITE_BUFFER_LOAD_CMD);
sysFlash_WriteF(address, (UINT16)(numwordInloop-1) );
}
else
{
/* Write program command, buffer size */
sysFlash_WriteF(address, FLASH_WRITE_TO_BUFFER);
sysFlash_WriteF(address, (UINT16)(numwordInloop-1) );
}
/* Write Data */
for (cur_add=address; cur_add-address < (numwordInloop<<1); cur_add
+=sizeof(UINT16))
{
expect = *memBuf;
memBuf ++;
sysFlash_WriteF(cur_add, expect);
}
cur_add -= sizeof(UINT16); /* can't advance beyond end of array */
/* Program Buffer to Flash (confirm) */
if (g_FlashType == NewFlashType)
{
sysFlash_WriteF(cur_add, NOR_WRITE_BUFFER_PGM_CONFIRM_CMD);
}
else
{
sysFlash_WriteF(cur_add, FLASH_CONFIRM);
}
/* Then wait until done */
if (!sysFlash_WaitUntilReady( FLASH_PROGRAM_TIMEOUT))
{
stat.Result = StatTimeout;
if (returnSR)
{
stat.SR = sysFlash_ReadStatus();
}
if (memBuf != NULL)
{
free(memBuf);
}
semGive(FlashSemId);
return (stat );
}
We never enter in Timeout because has you can see there is a bug when freeing the memBuf and the application Crash. But we never see it.
In the sysFlash_WaitUntilReady() test code, double reads for toggle bit 6 is added. However, if the timer times out before program complete (i.e., mIsStatusReady( status ) is not true) , this code will not be executed.
UserARI => Yes you are right but I add this test after the Ready status to check the Bit 6 toggling (it's not in my original code)
As you mentioned “To test my code I put a breakpoint and the Status when ready and it was 0xAC80 and the double read for toggle bit 6 was the data expected.” – Do you mean when you saw this result, you still have the 1st byte read error?
UserARI => I never see the bug when debugging but when the bug appear there is no error statusRegister = 0xXX80 and no toggle bit 6.
Can you please do below test:
- Enlarge the timeout timer (i.e., FLASH_PROGRAM_TIMEOUT) 10 times, test if the error goes away
UserARI => Yes the bug is still present with en infinit loop
- Move compare data (b_cmp) function to the place after program complete and before Exit Unlock Bypass mode, to see if any difference
- Test with the same code, only remove Unlock Bypass Mode (i.e., normal program mode), to see if any difference
UserARI => I suppress the ByPassMode for the Write-Buffer and the bug is still present
For Harware test I need help with Hardware team and I tell you.
Thank you very much for your help
Best regards,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I made a mistach, our Timeout is 5ms .
Regards.