+ pub fn erase_all(&self) {
+ self.write_enable();
+
+ self.with_selected(|| {
+ spi::tx8(spi::SPI0, Command::CE as u8);
+ });
+
+ while self.write_in_progress() {
+ }
+ }
+
+ 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(())
+ }
+
+ pub fn program_page(&self, address: usize, buffer: &[u8; PAGE_SIZE])
+ -> Result<(), Error> {
+ if (address & (PAGE_SIZE - 1)) != 0 {
+ return Err(Error::UnalignedAddress);
+ }
+
+ if buffer.iter().all(|&b| b == 0xff) {
+ return Ok(());
+ }
+
+ self.write_enable();
+
+ self.with_selected(|| {
+ spi::tx8(spi::SPI0, Command::PP 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 &b in buffer.iter() {
+ spi::tx8(spi::SPI0, b);
+ }
+ });
+
+ 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
+ }
+