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
14impl<T: Crc> Crc for &mut T {
15 fn crc32(init: u32, data: &[u8]) -> u32 {
16 T::crc32(init, data)
17 }
18}
19
20pub fn software_crc32(init: u32, data: &[u8]) -> u32 {
34 let mut crc = init ^ 0xFFFFFFFF;
35
36 for &byte in data {
37 crc ^= byte as u32;
38 for _ in 0..8 {
39 if crc & 1 != 0 {
40 crc = (crc >> 1) ^ 0xEDB88320;
41 } else {
42 crc >>= 1;
43 }
44 }
45 }
46
47 crc ^ 0xFFFFFFFF
48}
49
50pub trait AlignedOps: Platform {
51 fn align_read(size: usize) -> usize {
52 align_ceil(size, Self::READ_SIZE)
53 }
54
55 fn align_write_ceil(size: usize) -> usize {
56 align_ceil(size, Self::WRITE_SIZE)
57 }
58
59 fn align_write_floor(size: usize) -> usize {
60 align_floor(size, Self::WRITE_SIZE)
61 }
62}
63
64#[inline(always)]
65const fn align_ceil(size: usize, alignment: usize) -> usize {
66 if size.is_power_of_two() {
67 size.saturating_add(alignment - 1) & !(alignment - 1)
68 } else {
69 size.saturating_add(alignment - 1) / alignment * alignment
70 }
71}
72
73#[inline(always)]
74const fn align_floor(size: usize, alignment: usize) -> usize {
75 if size.is_power_of_two() {
76 size & !(alignment - 1)
77 } else {
78 size / alignment * alignment
79 }
80}
81
82impl<T: Platform> AlignedOps for T {}
83
84#[cfg(any(
85 feature = "esp32",
86 feature = "esp32s2",
87 feature = "esp32s3",
88 feature = "esp32c2",
89 feature = "esp32c3",
90 feature = "esp32c6",
91 feature = "esp32h2",
92))]
93mod chip {
94 use esp_storage::FlashStorage;
95
96 use crate::platform::Crc;
97
98 impl Crc for FlashStorage<'_> {
99 fn crc32(init: u32, data: &[u8]) -> u32 {
100 esp_hal::rom::crc::crc32_le(init, data)
101 }
102 }
103}