Skip to content

Commit 0ca3bed

Browse files
committed
Extract RmwNorFlash impl to separate PR
1 parent 55f8505 commit 0ca3bed

File tree

1 file changed

+0
-192
lines changed

1 file changed

+0
-192
lines changed

src/nor_flash.rs

Lines changed: 0 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use crate::{iter::IterableByOverlaps, ReadStorage, Region, Storage};
2-
31
/// Read only NOR flash trait.
42
pub trait ReadNorFlash {
53
/// An enumeration of storage errors
@@ -54,193 +52,3 @@ pub trait NorFlash: ReadNorFlash {
5452
/// - Bits that were 0 on flash are guaranteed to stay as 0
5553
/// - Rest of the bits in the page are guaranteed to be unchanged
5654
pub trait MultiwriteNorFlash: NorFlash {}
57-
58-
struct Page {
59-
pub start: u32,
60-
pub size: usize,
61-
}
62-
63-
impl Page {
64-
fn new(index: u32, size: usize) -> Self {
65-
Self {
66-
start: index * size as u32,
67-
size,
68-
}
69-
}
70-
71-
/// The end address of the page
72-
const fn end(&self) -> u32 {
73-
self.start + self.size as u32
74-
}
75-
}
76-
77-
impl Region for Page {
78-
/// Checks if an address offset is contained within the page
79-
fn contains(&self, address: u32) -> bool {
80-
(self.start <= address) && (self.end() > address)
81-
}
82-
}
83-
84-
///
85-
pub struct RmwNorFlashStorage<'a, S> {
86-
storage: S,
87-
merge_buffer: &'a mut [u8],
88-
}
89-
90-
impl<'a, S> RmwNorFlashStorage<'a, S>
91-
where
92-
S: NorFlash,
93-
{
94-
/// Instantiate a new generic `Storage` from a `NorFlash` peripheral
95-
///
96-
/// **NOTE** This will panic if the provided merge buffer,
97-
/// is smaller than the erase size of the flash peripheral
98-
pub fn new(nor_flash: S, merge_buffer: &'a mut [u8]) -> Self {
99-
if merge_buffer.len() < S::ERASE_SIZE {
100-
panic!("Merge buffer is too small");
101-
}
102-
103-
Self {
104-
storage: nor_flash,
105-
merge_buffer,
106-
}
107-
}
108-
}
109-
110-
impl<'a, S> ReadStorage for RmwNorFlashStorage<'a, S>
111-
where
112-
S: ReadNorFlash,
113-
{
114-
type Error = S::Error;
115-
116-
fn try_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
117-
// Nothing special to be done for reads
118-
self.storage.try_read(offset, bytes)
119-
}
120-
121-
fn capacity(&self) -> usize {
122-
self.storage.capacity()
123-
}
124-
}
125-
126-
impl<'a, S> Storage for RmwNorFlashStorage<'a, S>
127-
where
128-
S: NorFlash,
129-
{
130-
fn try_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
131-
// Perform read/modify/write operations on the byte slice.
132-
let last_page = self.storage.capacity() / S::ERASE_SIZE;
133-
134-
// `data` is the part of `bytes` contained within `page`,
135-
// and `addr` in the address offset of `page` + any offset into the page as requested by `address`
136-
for (data, page, addr) in (0..last_page as u32)
137-
.map(move |i| Page::new(i, S::ERASE_SIZE))
138-
.overlaps(bytes, offset)
139-
{
140-
let offset_into_page = addr.saturating_sub(page.start) as usize;
141-
142-
self.storage
143-
.try_read(page.start, &mut self.merge_buffer[..S::ERASE_SIZE])?;
144-
145-
// If we cannot write multiple times to the same page, we will have to erase it
146-
self.storage.try_erase(page.start, page.end())?;
147-
self.merge_buffer[..S::ERASE_SIZE]
148-
.iter_mut()
149-
.skip(offset_into_page)
150-
.zip(data)
151-
.for_each(|(byte, input)| *byte = *input);
152-
self.storage
153-
.try_write(page.start, &self.merge_buffer[..S::ERASE_SIZE])?;
154-
}
155-
Ok(())
156-
}
157-
}
158-
159-
///
160-
pub struct RmwMultiwriteNorFlashStorage<'a, S> {
161-
storage: S,
162-
merge_buffer: &'a mut [u8],
163-
}
164-
165-
impl<'a, S> RmwMultiwriteNorFlashStorage<'a, S>
166-
where
167-
S: MultiwriteNorFlash,
168-
{
169-
/// Instantiate a new generic `Storage` from a `NorFlash` peripheral
170-
///
171-
/// **NOTE** This will panic if the provided merge buffer,
172-
/// is smaller than the erase size of the flash peripheral
173-
pub fn new(nor_flash: S, merge_buffer: &'a mut [u8]) -> Self {
174-
if merge_buffer.len() < S::ERASE_SIZE {
175-
panic!("Merge buffer is too small");
176-
}
177-
178-
Self {
179-
storage: nor_flash,
180-
merge_buffer,
181-
}
182-
}
183-
}
184-
185-
impl<'a, S> ReadStorage for RmwMultiwriteNorFlashStorage<'a, S>
186-
where
187-
S: ReadNorFlash,
188-
{
189-
type Error = S::Error;
190-
191-
fn try_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
192-
// Nothing special to be done for reads
193-
self.storage.try_read(offset, bytes)
194-
}
195-
196-
fn capacity(&self) -> usize {
197-
self.storage.capacity()
198-
}
199-
}
200-
201-
impl<'a, S> Storage for RmwMultiwriteNorFlashStorage<'a, S>
202-
where
203-
S: MultiwriteNorFlash,
204-
{
205-
fn try_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
206-
// Perform read/modify/write operations on the byte slice.
207-
let last_page = self.storage.capacity() / S::ERASE_SIZE;
208-
209-
// `data` is the part of `bytes` contained within `page`,
210-
// and `addr` in the address offset of `page` + any offset into the page as requested by `address`
211-
for (data, page, addr) in (0..last_page as u32)
212-
.map(move |i| Page::new(i, S::ERASE_SIZE))
213-
.overlaps(bytes, offset)
214-
{
215-
let offset_into_page = addr.saturating_sub(page.start) as usize;
216-
217-
self.storage
218-
.try_read(page.start, &mut self.merge_buffer[..S::ERASE_SIZE])?;
219-
220-
let rhs = &self.merge_buffer[offset_into_page..S::ERASE_SIZE];
221-
let is_subset = data.iter().zip(rhs.iter()).all(|(a, b)| *a & *b == *a);
222-
223-
// Check if we can write the data block directly, under the limitations imposed by NorFlash:
224-
// - We can only change 1's to 0's
225-
if is_subset {
226-
// Use `merge_buffer` as allocation for padding `data` to `WRITE_SIZE`
227-
let offset = addr as usize % S::WRITE_SIZE;
228-
let alligned_end = data.len() % S::WRITE_SIZE;
229-
self.merge_buffer[..S::WRITE_SIZE].fill(0xff);
230-
self.merge_buffer[offset..data.len()].copy_from_slice(data);
231-
self.storage
232-
.try_write(addr - offset as u32, &self.merge_buffer[..S::WRITE_SIZE])?;
233-
} else {
234-
self.storage.try_erase(page.start, page.end())?;
235-
self.merge_buffer[..S::ERASE_SIZE]
236-
.iter_mut()
237-
.skip(offset_into_page)
238-
.zip(data)
239-
.for_each(|(byte, input)| *byte = *input);
240-
self.storage
241-
.try_write(page.start, &self.merge_buffer[..S::ERASE_SIZE])?;
242-
}
243-
}
244-
Ok(())
245-
}
246-
}

0 commit comments

Comments
 (0)