#![no_std]
#[allow(unused_imports)]
use core::{future::{poll_fn, Future}, task::Poll};
#[allow(unused_imports)]
use embedded_hal_async::{digital::Wait, spi::ErrorKind};
use spi_handle::SpiHandle;
use embedded_hal_async::spi::SpiBus;
use yield_now::yield_now;
mod yield_now;
pub struct W25Q<S: SpiHandle>{
spi: S
}
impl <S: SpiHandle> W25Q<S>{
pub fn new(spi: S) -> Self {
Self {
spi
}
}
pub async fn read_status_reg_1(&mut self) -> Result<u8, ErrorKind> {
let mut spi = self.spi.select().await;
let mut out = [0u8];
spi.write(&[0x05]).await?;
spi.read(&mut out).await?;
Ok(out[0])
}
pub async fn is_busy(&mut self) -> Result<bool, ErrorKind> {
Ok(self.read_status_reg_1().await? % 2 == 1)
}
pub async fn until_ready(&mut self) -> Result<(), ErrorKind> {
while self.is_busy().await? {
yield_now::yield_now().await;
}
Ok(())
}
pub async fn write_enable(&mut self) -> Result<(), ErrorKind> {
let mut spi = self.spi.select().await;
spi.write(&[0x06]).await?;
Ok(())
}
pub async fn prepare_write(&mut self) -> Result<(), ErrorKind> {
self.until_ready().await?;
self.write_enable().await?;
Ok(())
}
pub async fn page(&mut self, addr: u32, words: &[u8]) -> Result<u32, ErrorKind> {
self.prepare_write().await?;
let mut spi = self.spi.select().await;
spi.write(&[0x02]).await?;
spi.write(&[((addr >> 16) & 0xFF) as u8, ((addr >> 8) & 0xFF) as u8, ((addr & 0xFF) as u8)]).await?;
spi.write(words).await?;
Ok(words.len() as u32)
}
pub async fn sector_erase(&mut self, addr: u32) -> Result<(), ErrorKind>{
let mut spi = self.spi.select().await;
spi.write(&[0x20]).await?;
spi.write(&[((addr >> 16) & 0xFF) as u8, ((addr >> 8) & 0xFF) as u8, ((addr & 0xFF) as u8)]).await?;
Ok(())
}
pub async fn read_data(&mut self, addr: u32, words: &mut[u8]) -> Result<(), ErrorKind>{
self.until_ready().await?;
let mut spi = self.spi.select().await;
spi.write(&[0x03]).await?;
spi.write(&[((addr >> 16) & 0xFF) as u8, ((addr >> 8) & 0xFF) as u8, ((addr & 0xFF) as u8)]).await?;
spi.read(words).await?;
Ok(())
}
pub async fn chip_erase(&mut self) -> Result<(), ErrorKind>{
self.prepare_write().await?;
let mut spi = self.spi.select().await;
spi.write(&[0x60]).await?;
Ok(())
}
pub async fn block_64kb_erase(&mut self, addr:u32) -> Result<(), ErrorKind>{
let mut spi = self.spi.select().await;
spi.write(&[0xD8]).await?;
spi.write(&[((addr >> 16) & 0xFF) as u8, ((addr >> 8) & 0xFF) as u8, ((addr & 0xFF) as u8)]).await?;
Ok(())
}
pub async fn block_32kb_erase(&mut self, addr:u32) -> Result<(), ErrorKind>{
let mut spi = self.spi.select().await;
spi.write(&[0x52]).await?;
spi.write(&[((addr >> 16) & 0xFF) as u8, ((addr >> 8) & 0xFF) as u8, ((addr & 0xFF) as u8)]).await?;
Ok(())
}
pub async fn suspend(&mut self) -> Result<(), ErrorKind>{
let mut spi = self.spi.select().await;
spi.write(&[0x75]).await?;
Ok(())
}
pub async fn resume(&mut self) -> Result<(), ErrorKind>{
let mut spi = self.spi.select().await;
spi.write(&[0x7A]).await?;
Ok(())
}
pub async fn read_device_id(&mut self) -> Result<u8, ErrorKind>{
let mut spi = self.spi.select().await;
spi.write(&[0x90]).await?;
spi.write(&[0,0,0]).await?;
let mut array: [u8; 2] = [0; 2];
spi.read(&mut array).await?;
Ok(array[1])
}
}
pub struct Logger {
current_addr: u32
}
#[allow(unused_assignments)]
impl Logger {
pub fn new() -> Self {
Logger {
current_addr: 0
}
}
pub async fn log_partial_page(&mut self, flash: &mut W25Q<impl SpiHandle>, msg: &[u8]) -> Result<(), ErrorKind> {
flash.page(self.current_addr, msg).await?;
self.current_addr += msg.len() as u32;
Ok(())
}
pub async fn log(&mut self, flash: &mut W25Q<impl SpiHandle>, msg: &[u8]) -> Result<(), ErrorKind> {
while flash.is_busy().await? {
yield_now().await;
}
for i in 0..((msg.len()/4096) + 1){
flash.sector_erase(self.current_addr + (i as u32)*(4096)).await.unwrap();
}
let start = self.current_addr as usize;
let end = self.current_addr as usize + msg.len();
let mut msg_i = 0;
let first_full_page = ((self.current_addr as usize / 256) + 1) * 256;
self.log_partial_page(flash, &msg[0..(first_full_page - start)]).await?;
msg_i = first_full_page - start;
while ((self.current_addr as usize / 256) + 1) * 256 <= end {
self.log_partial_page(flash, &msg[msg_i..(msg_i + 256)]).await?;
msg_i += 256;
}
self.log_partial_page(flash, &msg[msg_i..]).await?;
Ok(())
}
pub async fn erase(&mut self, flash: &mut W25Q<impl SpiHandle>) -> Result<(), ErrorKind> {
let next_sector = ((self.current_addr as usize / 4096) + 1) * 4096;
flash.sector_erase(next_sector as u32).await?;
Ok(())
}
pub async fn reset_address(&mut self) -> Result<(), ErrorKind> {
self.current_addr = 0;
Ok(())
}
}