1use embedded_storage::nor_flash::NorFlash;
2use embedded_storage::nor_flash::ReadNorFlash;
3use embedded_storage::nor_flash::RmwNorFlashStorage;
4
5pub type Error = embedded_storage::nor_flash::NorFlashErrorKind;
11
12#[derive(Debug)]
14pub struct NorMemory<
15 B: BufferBackend,
16 const READ_SIZE: usize,
17 const WRITE_SIZE: usize,
18 const ERASE_SIZE: usize,
19> {
20 pub(crate) buffer: B,
21}
22
23impl<B: BufferBackend, const READ_SIZE: usize, const WRITE_SIZE: usize, const ERASE_SIZE: usize>
24 NorMemory<B, READ_SIZE, WRITE_SIZE, ERASE_SIZE>
25{
26 pub fn storage(self) -> NorStorage<B, READ_SIZE, WRITE_SIZE, ERASE_SIZE> {
28 NorStorage {
29 wrapper: self,
30 merge_buffer: vec![0u8; ERASE_SIZE],
31 }
32 }
33}
34
35pub trait BufferBackend {
37 fn with_data<F>(&self, from: usize, to: usize, f: F) -> Result<(), Error>
39 where
40 F: FnMut(&[u8]) -> Result<(), Error>;
41
42 fn with_data_mut<F>(&mut self, from: usize, to: usize, f: F) -> Result<(), Error>
44 where
45 F: FnMut(&mut [u8]) -> Result<(), Error>;
46
47 fn size(&self) -> usize;
49}
50
51#[derive(Debug)]
53pub struct NorStorage<
54 B: BufferBackend,
55 const READ_SIZE: usize,
56 const WRITE_SIZE: usize,
57 const ERASE_SIZE: usize,
58> {
59 wrapper: NorMemory<B, READ_SIZE, WRITE_SIZE, ERASE_SIZE>,
60 merge_buffer: Vec<u8>,
61}
62
63impl<B: BufferBackend, const READ_SIZE: usize, const WRITE_SIZE: usize, const ERASE_SIZE: usize>
64 NorStorage<B, READ_SIZE, WRITE_SIZE, ERASE_SIZE>
65{
66 pub fn nor_flash(self) -> NorMemory<B, READ_SIZE, WRITE_SIZE, ERASE_SIZE> {
68 self.wrapper
69 }
70}
71
72impl<B: BufferBackend, const READ_SIZE: usize, const WRITE_SIZE: usize, const ERASE_SIZE: usize>
73 embedded_storage::nor_flash::ErrorType for NorMemory<B, READ_SIZE, WRITE_SIZE, ERASE_SIZE>
74{
75 type Error = embedded_storage::nor_flash::NorFlashErrorKind;
76}
77
78impl<B: BufferBackend, const READ_SIZE: usize, const WRITE_SIZE: usize, const ERASE_SIZE: usize>
79 ReadNorFlash for NorMemory<B, READ_SIZE, WRITE_SIZE, ERASE_SIZE>
80{
81 const READ_SIZE: usize = READ_SIZE;
82
83 fn read(&mut self, address: u32, buf: &mut [u8]) -> Result<(), Error> {
85 if address as usize + buf.len() > self.capacity() {
86 return Err(embedded_storage::nor_flash::NorFlashErrorKind::OutOfBounds);
87 }
88 let start = address as usize;
89 let end = start + buf.len();
90 self.buffer.with_data(start, end, |data| {
91 buf.copy_from_slice(data);
92 Ok(())
93 })
94 }
95
96 fn capacity(&self) -> usize {
98 self.buffer.size()
99 }
100}
101
102impl<B: BufferBackend, const READ_SIZE: usize, const WRITE_SIZE: usize, const ERASE_SIZE: usize>
103 NorFlash for NorMemory<B, READ_SIZE, WRITE_SIZE, ERASE_SIZE>
104{
105 const WRITE_SIZE: usize = WRITE_SIZE;
106 const ERASE_SIZE: usize = ERASE_SIZE;
107
108 fn erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
110 if !(from as usize).is_multiple_of(ERASE_SIZE) {
111 return Err(Error::NotAligned);
112 }
113 if !(to as usize).is_multiple_of(ERASE_SIZE) {
114 return Err(Error::NotAligned);
115 }
116 if to < from {
117 return Err(Error::OutOfBounds);
118 }
119 if to as usize > NorMemory::capacity(self) {
120 return Err(Error::OutOfBounds);
121 }
122 if from == to {
123 return Ok(());
125 }
126 self.buffer
127 .with_data_mut(from as usize, to as usize, |data| {
128 let len = data.len();
129 if from as usize + len != to as usize {
130 return Err(Error::OutOfBounds);
132 }
133 data[..len].fill(0xFF);
134 Ok(())
135 })
136 }
137
138 fn write(&mut self, offset: u32, data: &[u8]) -> Result<(), Error> {
140 let cap = self.capacity();
141 if offset as usize + data.len() > cap {
142 return Err(Error::OutOfBounds);
143 }
144 self.buffer
145 .with_data_mut(offset as usize, offset as usize + data.len(), |buf| {
146 buf.copy_from_slice(data);
147 Ok(())
148 })
149 }
150}
151
152impl<B: BufferBackend, const READ_SIZE: usize, const WRITE_SIZE: usize, const ERASE_SIZE: usize>
153 embedded_storage::ReadStorage for NorStorage<B, READ_SIZE, WRITE_SIZE, ERASE_SIZE>
154{
155 type Error = embedded_storage::nor_flash::NorFlashErrorKind;
156
157 fn read(&mut self, address: u32, buf: &mut [u8]) -> Result<(), Error> {
159 let mut storage = RmwNorFlashStorage::new(&mut self.wrapper, &mut self.merge_buffer[..]);
160 storage.read(address, buf)
161 }
162
163 fn capacity(&self) -> usize {
165 self.wrapper.capacity()
166 }
167}
168
169impl<B: BufferBackend, const READ_SIZE: usize, const WRITE_SIZE: usize, const ERASE_SIZE: usize>
170 embedded_storage::Storage for NorStorage<B, READ_SIZE, WRITE_SIZE, ERASE_SIZE>
171{
172 fn write(&mut self, address: u32, buf: &[u8]) -> Result<(), Error> {
174 let mut storage = RmwNorFlashStorage::new(&mut self.wrapper, &mut self.merge_buffer[..]);
175 storage.write(address, buf)
176 }
177}