basic flash implementation using rom functions

This commit is contained in:
Robin Appelman 2020-08-26 00:16:08 +02:00
commit b25148060c
2 changed files with 93 additions and 7 deletions

View file

@ -3,7 +3,11 @@ name = "esp8266-flash"
version = "0.1.0" version = "0.1.0"
authors = ["Robin Appelman <robin@icewind.nl>"] authors = ["Robin Appelman <robin@icewind.nl>"]
edition = "2018" edition = "2018"
description = "A driver for the esp8266 onboard flash"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
xtensa-lx106-rt = "0.0.1"
spi-memory = "0.2.0"
embedded-hal = "0.2.4"
esp8266 = "0.0.6"
void = { version = "1.0.2", default-features = false }

View file

@ -1,7 +1,89 @@
#[cfg(test)] #![no_std]
mod tests {
#[test] use void::Void;
fn it_works() { use embedded_hal::blocking::spi::Transfer;
assert_eq!(2 + 2, 4); use embedded_hal::digital::v2::OutputPin;
use spi_memory::{BlockDevice, Error, Read};
use xtensa_lx106_rt::rom::{SPIRead, SPIEraseSector, SPIEraseChip, SPIWrite};
use esp8266::SPI0;
const SECTOR_SIZE: u32 = 4096;
pub struct FlashSpi(SPI0);
/// Dummy chip select, since the onboard flash spi uses a hardware chip select
pub struct DummyCS;
impl Transfer<u8> for FlashSpi {
type Error = Void;
fn transfer<'w>(&mut self, _words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
unreachable!()
} }
} }
impl OutputPin for DummyCS {
type Error = Void;
fn set_low(&mut self) -> Result<(), Self::Error> {
unreachable!()
}
fn set_high(&mut self) -> Result<(), Self::Error> {
unreachable!()
}
}
/// Access for the ESP8266 builtin flash
pub struct ESPFlash {
spi: FlashSpi
}
impl ESPFlash {
pub fn new(spi: SPI0) -> Self {
// take ownership of SPI0 to ensure nobody else can mess with the spi
ESPFlash {
spi: FlashSpi(spi)
}
}
pub fn decompose(self) -> SPI0 {
self.spi.0
}
}
impl BlockDevice<u32, FlashSpi, DummyCS> for ESPFlash {
/// Erase 4K sectors
fn erase_sectors(&mut self, addr: u32, amount: usize) -> Result<(), Error<FlashSpi, DummyCS>> {
let start_sector = addr / SECTOR_SIZE;
for i in 0..(amount as u32) {
unsafe {
SPIEraseSector(start_sector + i);
}
}
Ok(())
}
fn erase_all(&mut self) -> Result<(), Error<FlashSpi, DummyCS>> {
unsafe {
SPIEraseChip();
}
Ok(())
}
fn write_bytes(&mut self, addr: u32, data: &mut [u8]) -> Result<(), Error<FlashSpi, DummyCS>> {
unsafe {
SPIWrite(addr, data.as_ptr(), data.len() as u32);
}
Ok(())
}
}
impl Read<u32, FlashSpi, DummyCS> for ESPFlash {
fn read(&mut self, addr: u32, buf: &mut [u8]) -> Result<(), Error<FlashSpi, DummyCS>> {
unsafe {
SPIRead(addr, buf.as_mut_ptr() as *mut _, buf.len() as u32);
}
Ok(())
}
}