Description
Ive been putting together a library for the WinBond W25N series of NAND flash ICs and I would like to make a trait for NAND analogous to the current NOR traits.
NAND Flash is different enough from NOR that I think it needs its own traits. The key difference being the expectation that blocks will go bad and the ability for the flash chip to indicate this (as mentioned here).
My first pass at the traits are here, with my implementations for my specific device here.
The key differences between it and NOR are:
- Addition of
BlockFail
andBlockFailing
Errors (see below) - Offset is u64 instead of u32 for larger than 4Gb devices
- There is a
block_status
method that can inform of manufacturer marked bad blocks or ECC failures (see below).
I am no expert on this, but based on the flash IC i am using and the datasheets I have read, this should fit. Hopefully people with more experience can chime in.
#58 inspired me to put this together, but I would say that SD cards and NAND flash are quite different beasts due to the lack of wear-levelling and bad block handling in the latter. Someone may correct me on this though.
Given that the target of these traits would be a filesystem or flash translation layer, something that lines up well with the Storage trait in littlefs2 seems appropriate.
Some initial thoughts:
- Should this all be one trait rather than R/W split?
- I have omitted the MultiWrite trait for now - I do not know if this is a thing in NAND flash
- Could these features be part of the NOR traits?
Errors:
pub enum NandFlashErrorKind {
/// The arguments are not properly aligned.
NotAligned,
/// The arguments are out of bounds.
OutOfBounds,
/// Block has failed either during erase, write or read checksum.
/// Contains byte address of failed block, or [None] if specific block unknown
BlockFail(Option<u64>),
/// Block is failing but operation was successful i.e ECC corrected read.
/// Contains byte address of failing block, or [None] if specific block unknown
BlockFailing(Option<u64>),
/// Error specific to the implementation.
Other,
}
block_status:
/// Read only NAND flash trait.
pub trait ReadNandFlash: ErrorType {
...
/// Check if the block is marked as bad
fn block_status(&mut self, address: u64) -> Result<BlockStatus, Self::Error>;
}
pub enum BlockStatus {
/// Marked OK and passes ECC / Checksum
Ok,
/// Not marked as failed by the manufacturer
MarkedOk,
/// Marked as failed or failed ECC / Checksum
Failed,
}