2025-10-20 10:40 AM
Hello,
maybe this is bit off-topic, but does anybody know if it is possible to suspend an ERASE operation and write to another (previously erased) sector?
I want to save a page in flash in case of a power outage and want to interrupt a probably ongoing ERASE.
If so, is this possible in internal flash or only in external flash?
In our design there are 2 QUAD SPI NOR flash connected to the dual QSPI- and one QUAD SPI NOR to a SPI interface of the STM32H75x. It would be surely possible to write to an idle flash while the other is busy erasing a sector. But it would be nice if write-while-erase-suspended would work on a single flash.
The documentation of flash is confusing e.g. in the MICRON flash, which is soldered on the STM32H753_EVAL board, it seems there is difference in sector erase and erase command:
The MACRONIX AN0247 says that programming is allowed
but the datasheet says that only read is allowed in suspended state
Any experience here, has anybody checked this out?
Solved! Go to Solution.
2025-10-23 6:39 AM
Got my suspend/resume test working. I experienced two problems with the MT25QL. First, writing to flash after erase suspend works not for 4kB sectors. Now I use 64kB sector erase. Second, the program must wait for the WIP bit cleared after erase suspend before issuing a page write. It is not sufficient to wait for the erase suspend bit set only. The MT25QL maintains a negated copy of the WIP status register bit in the flag register. So both bits must be verified by reading the flag register. First I did not wait for WIP cleared and the following write did not succeed. The write seemed to be ignored because the program failure bit was not set.
Yes, flash management is getting quite complex. Besides the mentioned EE emulation with "emergency write", in normal operation there are asynchronous accesses to flash resources from multiple threads which must be synchronized. These read/write requests also have a higher prio than the "garbage collector" running data copy and sector erases in the background. This will require a statemachine and thread synchronization.
2025-10-20 1:49 PM - edited 2025-10-20 1:51 PM
Yes, this feature is intended exactly for cases like yours.
I've considered it for some project, with a flash of different type. But in the end decided to prepare the reserved blank page during the start-up, when there are no changes to save yet, so power failure at this time cannot cause any info loss.
You can test and measure how long it takes to suspend and write. Consider that you may be unable to resume the erase and the volatile state of the flash can be lost. The erase should be repeated later, or this sector will be left in awkward state.
2025-10-21 9:20 AM
Hi @Pavel A.
I need a sort of EE emulation layer with data buffered in RAM. A busy ERASE, run by the garbage collector, shall be killed or suspended in case of emergency shutdown in order to write the data in RAM to flash.
Q: Did you test the write-while-erase-suspended feature and if so, which flash did you use? I doubt all kind of flash support it.
2025-10-21 1:14 PM - edited 2025-10-21 1:20 PM
I've tested suspension on a parallel, memory-mapped NOR flash (IS29GL256). Reading is faster than over QSPI but programming is similarly complicated. We have a simple "journaling" method, suitable for our application. It is not based on the ST "eeprom emulation" examples.
2025-10-21 2:52 PM
Yes, I'd probably lean toward a journalling method too, with two 32KB or 64KB Erase Blocks, where one is typically held in an erased state ready to accommodate a small structure written in a cyclic manner.
Shouldn't be too hard to code something. The ST EEPROM emulation is probably overkill with address and byte/word meta data.
A small structure, with a sequence count, and perhaps an invalidation bit (knock-down to zero), that aligns well with the 256-byte page boundaries.
2025-10-21 3:20 PM
@Tesla DeLorean If I understand correctly the OP's problem is to write *while* some other block is erasing. This problem exists even with the journaling method, if the flash chip does not allow writes to one block while erasing other block.
2025-10-21 10:16 PM
Hi,
first I stuck on RWW flash (MX25LWxxx) to perform write-while-erase.The problem seems to be that there is only one charge pump, you can erase or program only but not both at the same time.
I switched to write-while-erase-suspended but to my surprise, it seems the feature is not supported by MACRONIX, at least not at the high density flash, e.g. MX66L01G.
Page Programm commands are not supported (02h, 12h, 38h, 3Eh) but RSTEN and RST 66h/99h.
If the flash does not support write-while-erase-suspended, a flash reset and re-init might be workaround.
My hope now is that write-while-erase-suspended is supported by MICRON e.g. MT25QL01G:
Yes, the ST EE emulation is quite complicated and the data flow written to flash is hard to debug in case of error. The good thing is that source code is available and maintained by ST.
Most probably I'll use a circular buffer. I have a structure in RAM which is appended to the circular buffer each time the data is modified. Perhaps I'll add a "lazy-write" feature to speed up read and heavy update operations in order to reduce writes to flash. Outdated data is erased as soon the border of a full sector is reached. This erase must be be suspended in case of "emergency shutdown".
2025-10-22 2:16 AM - edited 2025-10-22 8:25 AM
Hi @Pavel A.
I programmed a test according to this sequence here
Implementation of Program/Erase Suspend and Resume Operations in Serial NOR Flash
Although the bits in status and flag register behave exactly as mentioned here, a following page read returns 0xff bytes. It seems that the write-during-erase-suspended is ignored.
Did you use a similar sequence on your parallel flash? Maybe I can do the same on a ISGL064.
BTW: On my board reading from ISGL064 is only 12MB/s. I guess this is because ST MCUs do not support the faster asynchronous page read mode. Using the MT25QL01G in dual QSPI mode I measured 86MB/s at 50MHz DTR read and 96MB/s at (overclocked) 66MHz DTR read (the DMA seems to be the limiting factor).
2025-10-22 9:14 AM - edited 2025-10-22 9:22 AM
@Pavel A. Yes, understood.
That's why you kind of want to get the pre-erase completed early, have your own flagging so you know it's active, or not.
Do it whilst having time and a viable supply. It's invocation should be relatively sporadic depending on the size and frequency of the anticipated data structure and write, and the amount of erase blocks you commit to the strategy. Hard to gauge the volumes as presented.
Not sure it's about the charge-pump as much as it is about time, and the writes being the least time critical, and not synchronous with the MCU, where the NOR Flash is anticipated to be 99.99% reading at most advantageous speed and synchronous.
If the erase is on going, one can enqueue a pending write, and get to it next, or abort. Either way you'd have to spin on the "WIP/BUSY" to release the device, or complete, and in some parts spin similarly when the Write Enable is sent prior to the Write Page. Goes to how you build your state-machine. In any case you're going to need to serialize things, even for reading, as most can't do it concurrently with a write/erase, and those that can are playing slight of hand to mask the confliction. The user code is going to need to be smart enough to recognize and deconflict.
The balance here is going to depend on how much erasing is being done, and the time it takes, and the life of the collapsing supply.
I will note that the Micron's historically have been quite rapid to erase when the cells (sectors/blocks) are already erased, so would assume they have some meta-data at the erase-block size architecture.
It should be possible to readily know if you have an erase in progress, and at what time it started. The "unknown" typically is if you abort an erase within the block you're going to attempt the write, as it's going to be harder to gauge how far/deep it got, which again comes down to having a pool of pre-erased blocks to draw from, and not creating a race-condition. The SDCard/eMMC are NAND, have typically it has a very deep pool, with very large internal "blocks", and the LBA are remapped on-the-fly, via meta-data and hash-tables, so a write-in-place tends toward a copy/insert into a new preerased block rather than cache-erase-write in real-time, and the now discarded current block is thrown into a pile to be erased in the background.
2025-10-22 10:12 AM - edited 2025-10-22 10:30 AM
Sorry I don't have access to that project anymore. But I recall that it worked. Made unit tests for each used feature.
@Tesla DeLorean Probably the state machine with write - while - erase can be like following:
int erasing_sector_num = -1;
bool erase_sector(int n)
{
if (-1 == erasing_sector_num) {
erasing_sector_num = n;
return flash_erase_sector_begin(n); // start async operation
}
if (flash_get_status(erasing_sector_num) == STATUS_ERASE_SUSPENDED) {
flash_resume_erase(erasing_sector_num);
return false; // concurrent erases not allowed
}
if (flash_get_status(erasing_sector_num) == STATUS_READY) {
erasing_sector_num = n;
return flash_erase_sector_begin(n); // start async operation
}
return false; // still busy
}
bool write_data(int sector, unsigned offset, const void *data, unsigned size)
{
if (erasing_sector_num == -1)
return flash_program(sector, offset, data, size); //synchronous write
// Async erase was started
if (flash_get_status(erasing_sector_num) == STATUS_BUSY) { //still erasing
flash_suspend_erase(erasing_sector_num);
}
bool b = false;
b = flash_program(sector, offset, data, size); //synchronous write
if (flash_get_status(erasing_sector_num) == STATUS_ERASE_SUSPENDED) {
flash_resume_erase(erasing_sector_num); // this takes some time
} else if (flash_get_status(erasing_sector_num) == STATUS_READY) {
erasing_sector_num = -1; // erase complete
}
return b;
}