use crate::ll_api::{ll_cmd::*, FlashOperate};
use core::marker::PhantomData;
use embedded_storage::{
self,
nor_flash::{NorFlashError, NorFlashErrorKind},
};
pub const READ_SIZE: usize = 1;
pub enum Blocking {}
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error {
Prog,
Size,
Miss,
Seq,
Protected,
Unaligned,
Parallelism,
Other,
}
impl From<i32> for Error {
fn from(value: i32) -> Self {
match value {
-1 => Self::Prog,
-2 => Self::Size,
-3 => Self::Miss,
-4 => Self::Seq,
-5 => Self::Protected,
-6 => Self::Unaligned,
-7 => Self::Parallelism,
_ => Self::Other,
}
}
}
impl NorFlashError for Error {
fn kind(&self) -> NorFlashErrorKind {
match self {
Self::Size => NorFlashErrorKind::OutOfBounds,
Self::Unaligned => NorFlashErrorKind::NotAligned,
_ => NorFlashErrorKind::Other,
}
}
}
pub struct Flash<
const PAGE_SIZE: usize,
const PAGE_NUM: usize,
const MINI_WRITE_SIZE: usize = 4,
const MINI_READ_SIZE: usize = 1,
MODE = Blocking,
> {
pub(crate) _mode: PhantomData<MODE>,
}
impl<
const PAGE_SIZE: usize,
const PAGE_NUM: usize,
const MINI_WRITE_SIZE: usize,
const MINI_READ_SIZE: usize,
> Flash<PAGE_SIZE, PAGE_NUM, MINI_WRITE_SIZE, MINI_READ_SIZE, Blocking>
{
pub fn new_blocking() -> Self {
Self { _mode: PhantomData }
}
}
impl<
const PAGE_SIZE: usize,
const PAGE_NUM: usize,
const MINI_WRITE_SIZE: usize,
const MINI_READ_SIZE: usize,
MODE,
> Flash<PAGE_SIZE, PAGE_NUM, MINI_WRITE_SIZE, MINI_READ_SIZE, MODE>
{
pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
let result = ll_invoke_inner!(
INVOKE_ID_FLASH_OPERATE,
FlashOperate::Read,
offset,
bytes.as_mut_ptr(),
bytes.len()
);
if result < 0 {
return Err(result.into());
}
Ok(())
}
pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
let result = ll_invoke_inner!(
INVOKE_ID_FLASH_OPERATE,
FlashOperate::Write,
offset,
bytes.as_ptr(),
bytes.len()
);
if result < 0 {
return Err(result.into());
}
Ok(())
}
pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
let result = ll_invoke_inner!(INVOKE_ID_FLASH_OPERATE, FlashOperate::Erase, from, to);
if result < 0 {
return Err(result.into());
}
Ok(())
}
}
impl<
const PAGE_SIZE: usize,
const PAGE_NUM: usize,
const MINI_WRITE_SIZE: usize,
const MINI_READ_SIZE: usize,
MODE,
> embedded_storage::nor_flash::ErrorType
for Flash<PAGE_SIZE, PAGE_NUM, MINI_WRITE_SIZE, MINI_READ_SIZE, MODE>
{
type Error = Error;
}
impl<
const PAGE_SIZE: usize,
const PAGE_NUM: usize,
const MINI_WRITE_SIZE: usize,
const MINI_READ_SIZE: usize,
MODE,
> embedded_storage::nor_flash::ReadNorFlash
for Flash<PAGE_SIZE, PAGE_NUM, MINI_WRITE_SIZE, MINI_READ_SIZE, MODE>
{
const READ_SIZE: usize = MINI_READ_SIZE;
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
self.blocking_read(offset, bytes)
}
fn capacity(&self) -> usize {
PAGE_SIZE * PAGE_NUM
}
}
impl<
const PAGE_SIZE: usize,
const PAGE_NUM: usize,
const MINI_WRITE_SIZE: usize,
const MINI_READ_SIZE: usize,
MODE,
> embedded_storage::nor_flash::NorFlash
for Flash<PAGE_SIZE, PAGE_NUM, MINI_WRITE_SIZE, MINI_READ_SIZE, MODE>
{
const WRITE_SIZE: usize = MINI_WRITE_SIZE;
const ERASE_SIZE: usize = PAGE_SIZE;
fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
self.blocking_write(offset, bytes)
}
fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
self.blocking_erase(from, to)
}
}