Skip to content

Commit c00158c

Browse files
committed
Check if a cosmo flash sector is erased before erasing
The Winbond flash chip on Cosmo has a unique flash erase algorithm that significantly penalizes erasing already erased sectors. Check for this case before running a sector erase command. Before real 3m31.962s user 0m4.325s sys 0m3.188s After real 2m0.817s user 0m4.380s sys 0m3.305s
1 parent e08ac24 commit c00158c

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

drv/cosmo-hf/src/main.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ impl FlashDriver {
270270

271271
/// Erases the 64KiB flash sector containing the given address
272272
fn flash_sector_erase(&mut self, addr: FlashAddr) {
273+
if self.flash_is_sector_erased(addr) {
274+
return;
275+
}
273276
self.flash_write_enable();
274277
self.drv.data_bytes.set_count(0);
275278
self.drv.addr.set_addr(addr.0);
@@ -281,6 +284,34 @@ impl FlashDriver {
281284
self.wait_flash_busy(Trace::SectorEraseBusy);
282285
}
283286

287+
/// Returns true if the full 64KB sector is erased
288+
/// (all bits are set to `1`)
289+
fn flash_is_sector_erased(&mut self, addr: FlashAddr) -> bool {
290+
let cnt = SECTOR_SIZE_BYTES / (PAGE_SIZE_BYTES as u32);
291+
for i in 0..cnt {
292+
let addr = addr.0 + i * (PAGE_SIZE_BYTES as u32);
293+
self.clear_fifos();
294+
self.drv.data_bytes.set_count(PAGE_SIZE_BYTES as u16);
295+
self.drv.addr.set_addr(addr);
296+
self.drv.dummy_cycles.set_count(8);
297+
self.drv.instr.set_opcode(instr::FAST_READ_QUAD_OUTPUT_4B);
298+
let mut erased = true;
299+
// We need to complete the read of the full PAGE_SIZE
300+
// even if we find a non-erased byte
301+
for _ in 0..PAGE_SIZE_BYTES.div_ceil(4) {
302+
self.wait_fpga_rx();
303+
let v = self.drv.rx_fifo_rdata.fifo_data();
304+
if v != u32::MAX {
305+
erased = false;
306+
}
307+
}
308+
if !erased {
309+
return false;
310+
}
311+
}
312+
true
313+
}
314+
284315
/// Reads data from the given address into a `BufWriter`
285316
///
286317
/// This function will only return an error if it fails to read from a

0 commit comments

Comments
 (0)