1- use crate :: { iter:: IterableByOverlaps , Region , Storage } ;
1+ use crate :: { iter:: IterableByOverlaps , ReadStorage , Region , Storage } ;
22
3- /// NOR flash trait.
4- pub trait NorFlash {
3+ /// Read only NOR flash trait.
4+ pub trait ReadNorFlash {
55 /// An enumeration of storage errors
66 type Error ;
77
8+ /// The minumum number of bytes the storage peripheral can read
9+ const READ_SIZE : usize ;
10+
811 /// Read a slice of data from the storage peripheral, starting the read
912 /// operation at the given address, and reading `bytes.len()` bytes.
1013 ///
1114 /// This should throw an error in case `bytes.len()` will be larger than
1215 /// the peripheral end address.
1316 fn try_read ( & mut self , address : u32 , bytes : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > ;
1417
18+ /// The capacity of the peripheral in bytes.
19+ fn capacity ( & self ) -> usize ;
20+ }
21+
22+ /// NOR flash trait.
23+ pub trait NorFlash : ReadNorFlash {
24+ /// The minumum number of bytes the storage peripheral can write
25+ const WRITE_SIZE : usize ;
26+
27+ /// The minumum number of bytes the storage peripheral can erase
28+ const ERASE_SIZE : usize ;
29+
1530 /// Erase the given storage range, clearing all data within `[from..to]`.
1631 /// The given range will contain all 1s afterwards.
1732 ///
@@ -28,15 +43,6 @@ pub trait NorFlash {
2843 /// It is not allowed to write to the same word twice.
2944 /// `address` and `bytes.len()` must both be multiples of `write_size()` and properly aligned.
3045 fn try_write ( & mut self , address : u32 , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > ;
31-
32- /// The erase granularity of the storage peripheral
33- fn erase_size ( & self ) -> u32 ;
34-
35- /// The minumum write size of the storage peripheral
36- fn write_size ( & self ) -> u32 ;
37-
38- /// The capacity of the peripheral in bytes.
39- fn capacity ( & self ) -> u32 ;
4046}
4147
4248/// Marker trait for NorFlash relaxing the restrictions on `write`.
@@ -51,28 +57,15 @@ pub trait NorFlash {
5157/// - Rest of the bits in the page are guaranteed to be unchanged
5258pub trait MultiwriteNorFlash : NorFlash { }
5359
54- ///
55- pub struct RmwNorFlashStorage < S : NorFlash > ( S ) ;
56-
57- // FIXME: Not sure how to do this correctly? Ideally we could have `const fn erase_size()` or some const generic?
58- const MAX_PAGE_SIZE : usize = 2048 ;
59-
60- impl < S : NorFlash > RmwNorFlashStorage < S > {
61- /// Instantiate a new generic `Storage` from a `NorFlash` peripheral
62- pub fn new ( nor_flash : S ) -> Self {
63- Self ( nor_flash)
64- }
65- }
66-
6760struct Page {
6861 pub start : u32 ,
69- pub size : u32 ,
62+ pub size : usize ,
7063}
7164
7265impl Page {
73- fn new ( index : u32 , size : u32 ) -> Self {
66+ fn new ( index : u32 , size : usize ) -> Self {
7467 Self {
75- start : index * size,
68+ start : index * size as u32 ,
7669 size,
7770 }
7871 }
@@ -89,26 +82,48 @@ impl Region for Page {
8982 }
9083}
9184
92- impl < S : NorFlash > Storage for RmwNorFlashStorage < S > {
85+ ///
86+ pub struct RmwNorFlashStorage < S > ( S ) ;
87+
88+ impl < S > RmwNorFlashStorage < S > {
89+ /// Instantiate a new generic `Storage` from a `NorFlash` peripheral
90+ pub fn new ( nor_flash : S ) -> Self {
91+ Self ( nor_flash)
92+ }
93+ }
94+
95+ impl < S > ReadStorage for RmwNorFlashStorage < S >
96+ where
97+ S : ReadNorFlash ,
98+ {
9399 type Error = S :: Error ;
94100
95101 fn try_read ( & mut self , address : u32 , bytes : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
96102 // Nothing special to be done for reads
97103 self . 0 . try_read ( address, bytes)
98104 }
99105
106+ fn capacity ( & self ) -> usize {
107+ self . 0 . capacity ( )
108+ }
109+ }
110+
111+ impl < S > Storage for RmwNorFlashStorage < S >
112+ where
113+ S : NorFlash ,
114+ // [u8; S::ERASE_SIZE]: Sized,
115+ {
100116 fn try_write ( & mut self , address : u32 , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
101117 // Perform read/modify/write operations on the byte slice.
102- let erase_size = self . 0 . erase_size ( ) ;
103- let last_page = ( self . 0 . capacity ( ) / erase_size) - 1 ;
118+ let last_page = ( self . 0 . capacity ( ) / S :: ERASE_SIZE ) - 1 ;
104119
105120 // `data` is the part of `bytes` contained within `page`,
106121 // and `addr` in the address offset of `page` + any offset into the page as requested by `address`
107- for ( data, page, addr) in ( 0 ..last_page)
108- . map ( move |i| Page :: new ( i, erase_size ) )
122+ for ( data, page, addr) in ( 0 ..last_page as u32 )
123+ . map ( move |i| Page :: new ( i, S :: ERASE_SIZE ) )
109124 . overlaps ( bytes, address)
110125 {
111- let merge_buffer = & mut [ 0u8 ; MAX_PAGE_SIZE ] [ 0 ..erase_size as usize ] ;
126+ let merge_buffer = & mut [ 0u8 ; 2048 ] ;
112127 let offset_into_page = addr. saturating_sub ( page. start ) as usize ;
113128
114129 self . try_read ( page. start , merge_buffer) ?;
@@ -124,10 +139,6 @@ impl<S: NorFlash> Storage for RmwNorFlashStorage<S> {
124139 }
125140 Ok ( ( ) )
126141 }
127-
128- fn capacity ( & self ) -> u32 {
129- self . 0 . capacity ( )
130- }
131142}
132143
133144// FIXME: Requires specialization to take advantage of MultiwriteNorFlash?
0 commit comments