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