embedded-c-sdk-bind-hal 0.13.0

Embedded C SDK bind HAL
Documentation
use crate::ll_api::{FlashOperate, ll_cmd::*};
use core::marker::PhantomData;
use embedded_storage::{
    self,
    nor_flash::{NorFlashError, NorFlashErrorKind},
};

pub const READ_SIZE: usize = 1;

/// Blocking flash mode typestate.
pub enum Blocking {}

/// Async flash mode typestate.
// pub enum Async {}

/// Flash error
///
#[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,
        }
    }
}

/// Internal flash memory driver.
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>
{
    /// Create a new flash driver, usable in blocking mode.
    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>
{
    /// Blocking read.
    ///
    /// NOTE: `offset` is an offset from the flash start, NOT an absolute address.
    /// For example, to read address `0x0800_1234` you have to use offset `0x1234`.
    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(())
    }

    /// Blocking write.
    ///
    /// NOTE: `offset` is an offset from the flash start, NOT an absolute address.
    /// For example, to write address `0x0800_1234` you have to use offset `0x1234`.
    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(())
    }

    /// Blocking erase.
    ///
    /// NOTE: `from` and `to` are offsets from the flash start, NOT an absolute address.
    /// For example, to erase address `0x0801_0000` you have to use offset `0x1_0000`.
    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)
    }
}