X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=src%2Fcommon%2Fmx25l.rs;h=2c498cefa6950d5459f5a9764fc964bb536971f5;hb=bd6395210b3c1672288987f2c150c43e68ca5cfa;hp=6e74f4ac006bf52dfae59b808882f0981e21e3ac;hpb=2be180cd54e988fa5abf0eabb7ee7138f31469f0;p=gps-watch.git diff --git a/src/common/mx25l.rs b/src/common/mx25l.rs index 6e74f4a..2c498ce 100644 --- a/src/common/mx25l.rs +++ b/src/common/mx25l.rs @@ -23,6 +23,9 @@ use gpio; use spi; +use storage::Storage; + +const SECTOR_SIZE: usize = 4096; pub struct Mx25l { cs_gpio: u32, @@ -30,10 +33,19 @@ pub struct Mx25l { } 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 { @@ -62,6 +74,37 @@ impl 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(&self, func: F) -> T where F: FnOnce() -> T { @@ -74,3 +117,19 @@ impl Mx25l { r } } + +impl Storage for Mx25l { + fn read(&self, address: usize, buffer: &mut [u8]) { + self.with_selected(|| { + spi::tx8(spi::SPI0, Command::READ 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); + + for i in 0..buffer.len() { + buffer[i] = spi::tx8(spi::SPI0, 0xff); + } + }) + } +}