Skip to content

Commit 52a1352

Browse files
authored
Merge pull request #6 from Sympatron/nor-flash
Add NOR flash trait
2 parents 02f86de + b461f3d commit 52a1352

File tree

1 file changed

+79
-2
lines changed

1 file changed

+79
-2
lines changed

src/lib.rs

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#![deny(unsafe_code)]
1313

1414
use core::ops::{Add, Sub};
15+
use heapless::{consts::*, Vec};
1516
use nb;
1617

1718
/// Currently contains [`OverlapIterator`]
@@ -66,8 +67,8 @@ pub trait Region {
6667
fn contains(&self, address: Address) -> bool;
6768
}
6869

69-
/// Storage trait
70-
pub trait ReadWrite {
70+
/// Transparent storage trait
71+
pub trait ReadWriteStorage {
7172
/// An enumeration of storage errors
7273
type Error;
7374

@@ -86,8 +87,84 @@ pub trait ReadWrite {
8687
fn range(&self) -> (Address, Address);
8788

8889
/// Erase the given storage range, clearing all data within `[from..to]`.
90+
fn try_erase(&mut self, from: Address, to: Address) -> nb::Result<(), Self::Error>;
91+
}
92+
93+
/// NOR flash region trait.
94+
pub trait NorFlashRegion {
95+
/// The range of possible addresses within the region.
96+
///
97+
/// (start_addr, end_addr)
98+
fn range(&self) -> (Address, Address);
99+
/// Maximum number of bytes that can be written at once.
100+
fn page_size(&self) -> usize;
101+
/// List of avalable erase sizes in this region.
102+
/// Should be sorted in ascending order.
103+
/// Currently limited to 5 sizes, but could be increased if necessary.
104+
fn erase_sizes(&self) -> Vec<usize, U5>;
105+
}
106+
107+
/// Blanket implementation for all types implementing [`NorFlashRegion`]
108+
impl<T: NorFlashRegion> Region for T {
109+
fn contains(&self, address: Address) -> bool {
110+
let (start, end) = self.range();
111+
address.0 >= start.0 && address.0 < end.0
112+
}
113+
}
114+
115+
/// NOR flash storage trait
116+
pub trait NorFlash {
117+
/// An enumeration of storage errors
118+
type Error;
119+
/// Region type
120+
type Region: NorFlashRegion;
121+
122+
/// Read a slice of data from the storage peripheral, starting the read
123+
/// operation at the given address, and reading until end address
124+
/// (`self.range().1`) or buffer length, whichever comes first.
125+
fn try_read(&mut self, address: Address, bytes: &mut [u8]) -> nb::Result<(), Self::Error>;
126+
127+
/// Write a slice of data to the storage peripheral, starting the write
128+
/// operation at the given address.
129+
///
130+
/// Since this is done on a NOR flash all bytes are anded with the current
131+
/// content in the flash. This means no 0s can to turned into 1s this way.
132+
fn try_write(&mut self, address: Address, bytes: &[u8]) -> nb::Result<(), Self::Error>;
133+
134+
/// Erase the given storage range, clearing all data within `[from..to]`.
135+
/// The given range will contain all 1s afterwards.
89136
///
90137
/// This should return an error if the range is not aligned to a proper
91138
/// erase resolution
92139
fn try_erase(&mut self, from: Address, to: Address) -> nb::Result<(), Self::Error>;
140+
141+
/// Get all distinct memory reagions. These must not overlap, but can be disjoint.
142+
/// Most chips will return a single region, but some chips have regions with
143+
/// different erase sizes.
144+
/// Currently limited to 4 regions, but could be increased if necessary
145+
fn regions(&self) -> Vec<Self::Region, U4>;
146+
}
147+
148+
/// Marker trait for NOR flashes with uniform erase and page sizes across the whole
149+
/// address range
150+
pub trait UniformNorFlash {}
151+
152+
/// Blanket implementation for all types implementing [`NorFlash`] and [`UniformNorFlash`]
153+
impl<T: NorFlash + UniformNorFlash> NorFlashRegion for T {
154+
/// The range of possible addresses within the peripheral.
155+
///
156+
/// (start_addr, end_addr)
157+
fn range(&self) -> (Address, Address) {
158+
self.regions()[0].range()
159+
}
160+
/// Maximum number of bytes that can be written at once.
161+
fn page_size(&self) -> usize {
162+
self.regions()[0].page_size()
163+
}
164+
/// List of avalable erase sizes in this region.
165+
/// Should be sorted in ascending order.
166+
/// Currently limited to 5 sizes, but could be increased if necessary.
167+
fn erase_sizes(&self) -> Vec<usize, U5> {
168+
self.regions()[0].erase_sizes()
169+
}
93170
}

0 commit comments

Comments
 (0)