use spi;
use storage::Storage;
+const SECTOR_SIZE: usize = 4096;
+
pub struct Mx25l {
cs_gpio: u32,
cs_gpio_pin: u32,
enum Command {
READ = 0x03,
RDSR = 0x05,
+ WREN = 0x06,
+ SE = 0x20,
RDID = 0x9f,
}
+pub enum Error {
+ UnalignedAddress = 1,
+}
+
+const SR_WIP: u8 = 1 << 0;
+
impl Mx25l {
pub fn new(cs_gpio: u32, cs_gpio_pin: u32) -> Mx25l {
Mx25l {
})
}
+ pub fn erase_sector(&self, address: usize) -> Result<(), Error> {
+ if (address & (SECTOR_SIZE - 1)) != 0 {
+ return Err(Error::UnalignedAddress);
+ }
+
+ self.write_enable();
+
+ self.with_selected(|| {
+ spi::tx8(spi::SPI0, Command::SE as u8);
+
+ spi::tx8(spi::SPI0, (address >> 16) as u8);
+ spi::tx8(spi::SPI0, (address >> 8) as u8);
+ spi::tx8(spi::SPI0, (address >> 0) as u8);
+ });
+
+ while self.write_in_progress() {
+ }
+
+ Ok(())
+ }
+
+ fn write_enable(&self) {
+ self.with_selected(|| {
+ spi::tx8(spi::SPI0, Command::WREN as u8);
+ });
+ }
+
+ fn write_in_progress(&self) -> bool {
+ (self.read_status() & SR_WIP) != 0
+ }
+
fn with_selected<F, T>(&self, func: F) -> T
where F: FnOnce() -> T
{