- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Labels:
-
Serial NOR
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Best regadrs,
Scott
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Bump
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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