1use embedded_storage::nor_flash::NorFlash;
2
3pub trait Platform: Crc + NorFlash {}
5
6impl<T: Crc + NorFlash> Platform for T {}
7
8pub type FnCrc32 = fn(init: u32, data: &[u8]) -> u32;
9
10pub trait Crc {
11 fn crc32(init: u32, data: &[u8]) -> u32;
12}
13
14pub trait AlignedOps: Platform {
15 fn align_read(size: usize) -> usize {
16 align_ceil(size, Self::READ_SIZE)
17 }
18
19 fn align_write_ceil(size: usize) -> usize {
20 align_ceil(size, Self::WRITE_SIZE)
21 }
22
23 fn align_write_floor(size: usize) -> usize {
24 align_floor(size, Self::WRITE_SIZE)
25 }
26}
27
28#[inline(always)]
29const fn align_ceil(size: usize, alignment: usize) -> usize {
30 if size.is_power_of_two() {
31 size.saturating_add(alignment - 1) & !(alignment - 1)
32 } else {
33 size.saturating_add(alignment - 1) / alignment * alignment
34 }
35}
36
37#[inline(always)]
38const fn align_floor(size: usize, alignment: usize) -> usize {
39 if size.is_power_of_two() {
40 size & !(alignment - 1)
41 } else {
42 size / alignment * alignment
43 }
44}
45
46impl<T: Platform> AlignedOps for T {}
47
48#[cfg(any(
49 feature = "esp32",
50 feature = "esp32s2",
51 feature = "esp32s3",
52 feature = "esp32c2",
53 feature = "esp32c3",
54 feature = "esp32c6",
55 feature = "esp32h2",
56))]
57mod chip {
58 use crate::platform::Crc;
59 use embedded_storage::nor_flash::{ErrorType, NorFlash};
60 use esp_storage::{FlashStorage, FlashStorageError};
61
62 pub struct EspFlash<'d> {
63 inner: FlashStorage<'d>,
64 }
65
66 impl<'d> EspFlash<'d> {
67 pub fn new(inner: FlashStorage<'d>) -> Self {
68 Self { inner }
69 }
70 }
71
72 impl ErrorType for EspFlash<'_> {
73 type Error = FlashStorageError;
74 }
75
76 impl NorFlash for EspFlash<'_> {
77 const WRITE_SIZE: usize = FlashStorage::WRITE_SIZE;
78 const ERASE_SIZE: usize = FlashStorage::ERASE_SIZE;
79
80 fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
81 self.inner.erase(from, to)
83 }
84
85 fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
86 self.inner.write(offset, bytes)
88 }
89 }
90
91 impl embedded_storage::nor_flash::ReadNorFlash for EspFlash<'_> {
92 const READ_SIZE: usize = FlashStorage::READ_SIZE;
93
94 fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
95 self.inner.read(offset, bytes)
97 }
98
99 fn capacity(&self) -> usize {
100 self.inner.capacity()
101 }
102 }
103
104 impl Crc for EspFlash<'_> {
105 fn crc32(init: u32, data: &[u8]) -> u32 {
106 esp_hal::rom::crc::crc32_le(init, data)
107 }
108 }
109 impl Crc for &mut EspFlash<'_> {
110 fn crc32(init: u32, data: &[u8]) -> u32 {
111 esp_hal::rom::crc::crc32_le(init, data)
112 }
113 }
114}
115
116#[cfg(any(
117 feature = "esp32",
118 feature = "esp32s2",
119 feature = "esp32s3",
120 feature = "esp32c2",
121 feature = "esp32c3",
122 feature = "esp32c6",
123 feature = "esp32h2",
124))]
125pub use chip::*;