use embedded_storage::nor_flash::NorFlash;
pub trait Platform: Crc + NorFlash {}
impl<T: Crc + NorFlash> Platform for T {}
pub type FnCrc32 = fn(init: u32, data: &[u8]) -> u32;
pub trait Crc {
fn crc32(init: u32, data: &[u8]) -> u32;
}
pub trait AlignedOps: Platform {
fn align_read(size: usize) -> usize {
align_ceil(size, Self::READ_SIZE)
}
fn align_write_ceil(size: usize) -> usize {
align_ceil(size, Self::WRITE_SIZE)
}
fn align_write_floor(size: usize) -> usize {
align_floor(size, Self::WRITE_SIZE)
}
}
#[inline(always)]
const fn align_ceil(size: usize, alignment: usize) -> usize {
if size.is_power_of_two() {
size.saturating_add(alignment - 1) & !(alignment - 1)
} else {
size.saturating_add(alignment - 1) / alignment * alignment
}
}
#[inline(always)]
const fn align_floor(size: usize, alignment: usize) -> usize {
if size.is_power_of_two() {
size & !(alignment - 1)
} else {
size / alignment * alignment
}
}
impl<T: Platform> AlignedOps for T {}
#[cfg(any(
feature = "esp32",
feature = "esp32s2",
feature = "esp32s3",
feature = "esp32c2",
feature = "esp32c3",
feature = "esp32c6",
feature = "esp32h2",
))]
mod chip {
use crate::platform::Crc;
use embedded_storage::nor_flash::{ErrorType, NorFlash};
use esp_storage::{FlashStorage, FlashStorageError};
pub struct EspFlash<'d> {
inner: FlashStorage<'d>,
}
impl<'d> EspFlash<'d> {
pub fn new(inner: FlashStorage<'d>) -> Self {
Self { inner }
}
}
impl ErrorType for EspFlash<'_> {
type Error = FlashStorageError;
}
impl NorFlash for EspFlash<'_> {
const WRITE_SIZE: usize = FlashStorage::WRITE_SIZE;
const ERASE_SIZE: usize = FlashStorage::ERASE_SIZE;
fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
self.inner.erase(from, to)
}
fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
self.inner.write(offset, bytes)
}
}
impl embedded_storage::nor_flash::ReadNorFlash for EspFlash<'_> {
const READ_SIZE: usize = FlashStorage::READ_SIZE;
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
self.inner.read(offset, bytes)
}
fn capacity(&self) -> usize {
self.inner.capacity()
}
}
impl Crc for EspFlash<'_> {
fn crc32(init: u32, data: &[u8]) -> u32 {
esp_hal::rom::crc::crc32_le(init, data)
}
}
impl Crc for &mut EspFlash<'_> {
fn crc32(init: u32, data: &[u8]) -> u32 {
esp_hal::rom::crc::crc32_le(init, data)
}
}
}
#[cfg(any(
feature = "esp32",
feature = "esp32s2",
feature = "esp32s3",
feature = "esp32c2",
feature = "esp32c3",
feature = "esp32c6",
feature = "esp32h2",
))]
pub use chip::*;