1212#![ deny( unsafe_code) ]
1313
1414use core:: ops:: { Add , Sub } ;
15+ use heapless:: { consts:: * , Vec } ;
1516use 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