First byte check fail after Write to Buffer command

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
UserARI
Level 1
Level 1
5 replies posted 5 sign-ins First reply posted

Hello,

We have an issue using flash S29GL512T.
 
We use the VxWorks OS with its TFFS management to access the Flash device.
Our Flash driver use the Unlock ByPass mode when programming the flash using the Write-to-Buffer command (with 512Bytes max).
 
The occurrence of the issue is very very low (around 1 time in a week) and  we haven't the exact scenario to reproduce it because sometimes we never encountered it.
 
Our driver when it programs a buffer in Flash (512bytes or less) wait for Flash ready by pooling the status register
Then it compares the flash content with the buffer we want to program.
 
Sometimes the first byte in flash doesn't match with the first one in the buffer to write.
During this error case we dump the Flash content and the buffer one.
The dump show not differencies.
It means that the first read for the comparison is not correct and the second is OK.
 
Normally there is no concurrent access which  put the Flash waiting for a read access like the Status Register
We are not able to trace the content of the first read because if we change the source code we never encounter the issue.
 
Do you know if there is an Errata concerning the ByPass Mode where the first read is not ready for accessing the Data ?
 
Which method you advise concerning Write buffer command, standard method, Unlock Bypass one or Both are equivalent ?
 
Any support you could bring would be much appreciated.
 
Best Regards
 

0 Likes
13 Replies
BushraH_91
Moderator
Moderator
Moderator
750 replies posted 50 likes received 250 solutions authored

Hello,

Thank you for contacting Cypress Technical Support, an Infineon Technologies Company.  Can you provide answer to the following questions?

  1. What is the expected data and incorrect data when error happening?
  2. Was the error happening at location random or specific location (e.g., specific Write Buffer, or specific sector etc.)?
  3. What was the operation right before the error read? Polling status register to complete then read the data immediately?
  4. 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.
  5. “if we change the source code we never encounter the issue” – what did you change in the source code?

 

Thank you

Regards,

Bushra

0 Likes
UserARI
Level 1
Level 1
5 replies posted 5 sign-ins First reply posted
Hi Bushra,
 
The error for the few reproduction we can see happened in any location when comparing the first byte written of a page  just after the Exiting Unlock Bypass command (before we check the Status register for WriteToBuffer Cmd in Unlock Mode).
We never see the content of this first byte because we never reproduce it with this check (store the first byte in a variable and check it).
At this moment we can't reproduce it with exactly the same source code and we don't know what is the exact scenario to reproduce it.
 
Our code looks like this where each Write are max 512 Bytes aligned with Page:
 
 
      /* 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) );

    /* 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 */
    
    sysFlash_WriteF(cur_add, NOR_WRITE_BUFFER_PGM_CONFIRM_CMD);
 
    /* 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 )
  {
    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 b_cmp(void FAR0* d, void FAR1* s, int l)
{
  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,
Arnaud

0 Likes
BushraH_91
Moderator
Moderator
Moderator
750 replies posted 50 likes received 250 solutions authored

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

0 Likes
UserARI
Level 1
Level 1
5 replies posted 5 sign-ins First reply posted

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

0 Likes
BushraH_91
Moderator
Moderator
Moderator
750 replies posted 50 likes received 250 solutions authored

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

0 Likes

Just an info:

The data 0x4C and 0x91 are the correct data written in the flash and not the toggling

 

Best Regards

0 Likes

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

0 Likes
UserARI
Level 1
Level 1
5 replies posted 5 sign-ins First reply posted

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

0 Likes
BushraH_91
Moderator
Moderator
Moderator
750 replies posted 50 likes received 250 solutions authored

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?

  1. What is the Status Register value of the last read when sysFlash_WaitUntilReady() returns?
  2. 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

0 Likes
UserARI
Level 1
Level 1
5 replies posted 5 sign-ins First reply posted

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,

0 Likes
BushraH_91
Moderator
Moderator
Moderator
750 replies posted 50 likes received 250 solutions authored

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:

  1. Enlarge the timeout timer (i.e., FLASH_PROGRAM_TIMEOUT) 10 times, test if the error goes away
  2. Move compare data (b_cmp) function to the place after program complete and before Exit Unlock Bypass mode, to see if any difference
  3. Test with the same code, only remove Unlock Bypass Mode (i.e., normal program mode), to see if any difference
  4. If all above 3 tests do not have improvement, please do below
    1. 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
    2. 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)

BushraH_91_0-1617039779554.jpeg

Thank you

Regards,

Bushra

0 Likes
UserARI
Level 1
Level 1
5 replies posted 5 sign-ins First reply posted

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:

  1. 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

  1. Move compare data (b_cmp) function to the place after program complete and before Exit Unlock Bypass mode, to see if any difference
  2. 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,

0 Likes
UserARI
Level 1
Level 1
5 replies posted 5 sign-ins First reply posted

Hello,

I made a mistach, our Timeout is 5ms .

Regards.

0 Likes