S25FL512S Erase Functionality Issue

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

cross mob
Anonymous
Not applicable

We have designed in the S25FL512S to be used with a Tiva processor for onboard storage. I am facing some issues with the erase functionality where the erase does not take place unless I poll SR1 continuously in a loop. The problem is very apparent in the Bulk Erase command, but I will only need to use Sector Erase which also seems to fail in a similar fashion.

The following sequence works well, and the loop exits after 1-2 minutes:

1. Bulk Erase

2. do {

         Status = RDSR1;

    } while(Status != BUSY);

The following sequence doesn't work and the loop exits almost immediately after 2-3 loops. After some testing, it looks like the SR1 reads 0x03 the firsst time, 0xFF the second time and 0x0 from the third time onwards forever.

1. Bulk Erase

2. do {

          DELAY;

         Status = RDSR1;

    } while(Status != BUSY);

The DELAY can be either a task switch, a simple for loop delay or even a check point.

We intend to use this in a lower priority task which may get preempted and hence delayed while checking the status.

Has anyone faced a similar issue? Is there a resolution for this?

0 Likes
8 Replies
Apurva_S
Moderator
Moderator
Moderator
100 likes received 500 replies posted 250 solutions authored

Hi,

Thank you for contacting Cypress Community.

If you go through the structure of the Status Register given on page 49 of the data sheet (Link to the datasheet - http://www.cypress.com/file/177971/download), you will notice that the last bit is the WIP bit. When this bit is HIGH it indicates that the device is busy performing some operation. While WIP is HIGH, only Read Status (RDSR1 or RDSR2), Erase Suspend (ERSP), Program Suspend (PGSP), Clear Status Register (CLSR), and Software Reset (RESET) commands may be accepted. No other command will be accepted.

Hence, whenever we perform an erase operation, we poll the WIP bit to check its status. Only when the WIP bit goes low, we can give a new command to the device.

The description of the Work In Progress (WIP) bit is also given on page 50 of the datasheet.

Can you give us a little more detail about what you are trying to do in that DELAY inside the do while loop in the second code snippet that doesn't work. If possible, could you share your full code with us?

Thanks and Regards,

Apurva

0 Likes
Anonymous
Not applicable

Hey Apurva

In the code snippets, when I check for "(Status != Busy)" what I'm actually checking for is "((SR1 & 0x61) != 0)" where I check for WIP as well as P_ERR and E_ERR.

The DELAY is a task switch, where we go and perform other tasks and only return when we are done with the other tasks. For testing the delay, I tried the task switching, a for loop delay as well as a break point in the code.

If there is no delay in there while I continuously loop checking SR1, the processor stays in that loop for about 2 minutes which is the right amount of time for Bulk Erase. If I do include the delay, it exits the loop almost immediately.

Regards

Easswar

0 Likes

Hello Easswar,

Could you help us to understand your status polling code a little bit more? In general, there is two ways implemeting it.

(a) keep CS# going LOW, keep reading an updated status repeatedly without newly issueing an RDSR instruction until the status indicates the erase completion. (b) issue an RDSR instruction followed by reading a status one time, repeat the cycle.

In case of implementation (a), it is important for the flash to keep the CS# LOW until the end of status polling. Without it, the next reading will be a tri-state of SO signal.

pastedImage_0.png

Best regadrs,

Scott

0 Likes
Anonymous
Not applicable

Hey Scott

I have actually tried both methods you mention there.

a) Generally I use this loop -

     while((status& 0x61) != 0) {

          CS Low

          Send RDSR Command

          status = Read SPI byte

          CS High

          Delay 5 milliseconds

     }

b) I also tried this -

     CS Low

     Send RDSR Command

     while((status& 0x61) != 0) {

          status = Read SPI byte

          Delay 5 milliseconds

     }

     CS High

In both cases, the loop exits almost immediately after a Bulk Erase command if the Delay is 1 millisecond or more, it stays in the loop approximately 2 minutes when the Delay is removed.

0 Likes

Hello Easswar,

Is it possible to program one of BP (block protection) bits on SR before having a bulk erase test if your application doesn't need to protect for the testing? And then could you add some code to print out the value of status register when it exits the loop?

while((status& 0x61) != 0) {

          CS Low

          Send RDSR Command

          status = Read SPI byte

          CS High

          Delay 5 milliseconds

     }

Print status

I would like to see if the last status read has the bit set of BP, which may explain the read SR is valid or was prevented by some other reason. Thanks!

Best regards,

Scott

0 Likes
Anonymous
Not applicable

Hey Scott

So I tried writing the BP bits to 001 and  011. By printing the status as you suggested, I read back 0x6 and 0xE respectively.

I was confused at first as to why the Write Enable bit was still set after the Bulk Erase and on poring over the  datasheet found that the Bulk Erase command does not work if any of the BP bits are set.

As the issue seems to be with delays in milliseconds, I'm not sure if I would be able to faithfully reproduce this issue with just a sector erase.

Thanks

Easswar

0 Likes
Anonymous
Not applicable

Bump

0 Likes

Hello Easswar,

I made a test code (pseudo code below) with my S25FL512S and found there was no erase failure with a 5ms delay inside a ready/busy polling loop (erase total 256 blocks). FYI, dev_status_ptr is a buffer to receive a status enumerator (it returns dev_not_busy when the device status & 0x61 == 0). I guess the delay doesn't seem to be a problem...

    SetTimer(polling_type);

    do {

        slld_StatusGet(sys_addr, dev_status_ptr, poll_data, 1);

        Sleep(5); //scott

        if (*dev_status_ptr == dev_not_busy)

            break;

    } while (!g_bTimeout);

Best regards,

Scott Heo

0 Likes