1
- use crate :: { iter:: IterableByOverlaps , Region , Storage } ;
1
+ use crate :: { iter:: IterableByOverlaps , ReadStorage , Region , Storage } ;
2
2
3
- /// NOR flash trait.
4
- pub trait NorFlash {
3
+ /// Read only NOR flash trait.
4
+ pub trait ReadNorFlash {
5
5
/// An enumeration of storage errors
6
6
type Error ;
7
7
8
+ /// The minumum number of bytes the storage peripheral can read
9
+ const READ_SIZE : usize ;
10
+
8
11
/// Read a slice of data from the storage peripheral, starting the read
9
12
/// operation at the given address, and reading `bytes.len()` bytes.
10
13
///
11
14
/// This should throw an error in case `bytes.len()` will be larger than
12
15
/// the peripheral end address.
13
16
fn try_read ( & mut self , address : u32 , bytes : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > ;
14
17
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
+
15
30
/// Erase the given storage range, clearing all data within `[from..to]`.
16
31
/// The given range will contain all 1s afterwards.
17
32
///
@@ -28,15 +43,6 @@ pub trait NorFlash {
28
43
/// It is not allowed to write to the same word twice.
29
44
/// `address` and `bytes.len()` must both be multiples of `write_size()` and properly aligned.
30
45
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 ;
40
46
}
41
47
42
48
/// Marker trait for NorFlash relaxing the restrictions on `write`.
@@ -51,28 +57,15 @@ pub trait NorFlash {
51
57
/// - Rest of the bits in the page are guaranteed to be unchanged
52
58
pub trait MultiwriteNorFlash : NorFlash { }
53
59
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
-
67
60
struct Page {
68
61
pub start : u32 ,
69
- pub size : u32 ,
62
+ pub size : usize ,
70
63
}
71
64
72
65
impl Page {
73
- fn new ( index : u32 , size : u32 ) -> Self {
66
+ fn new ( index : u32 , size : usize ) -> Self {
74
67
Self {
75
- start : index * size,
68
+ start : index * size as u32 ,
76
69
size,
77
70
}
78
71
}
@@ -89,26 +82,47 @@ impl Region for Page {
89
82
}
90
83
}
91
84
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
+ {
93
99
type Error = S :: Error ;
94
100
95
101
fn try_read ( & mut self , address : u32 , bytes : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
96
102
// Nothing special to be done for reads
97
103
self . 0 . try_read ( address, bytes)
98
104
}
99
105
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
+ {
100
115
fn try_write ( & mut self , address : u32 , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
101
116
// 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 ;
117
+ let last_page = ( self . 0 . capacity ( ) / S :: ERASE_SIZE ) - 1 ;
104
118
105
119
// `data` is the part of `bytes` contained within `page`,
106
120
// 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 ) )
121
+ for ( data, page, addr) in ( 0 ..last_page as u32 )
122
+ . map ( move |i| Page :: new ( i, S :: ERASE_SIZE ) )
109
123
. overlaps ( bytes, address)
110
124
{
111
- let merge_buffer = & mut [ 0u8 ; MAX_PAGE_SIZE ] [ 0 ..erase_size as usize ] ;
125
+ let merge_buffer = & mut [ 0u8 ; 2048 ] ;
112
126
let offset_into_page = addr. saturating_sub ( page. start ) as usize ;
113
127
114
128
self . try_read ( page. start , merge_buffer) ?;
@@ -124,10 +138,6 @@ impl<S: NorFlash> Storage for RmwNorFlashStorage<S> {
124
138
}
125
139
Ok ( ( ) )
126
140
}
127
-
128
- fn capacity ( & self ) -> u32 {
129
- self . 0 . capacity ( )
130
- }
131
141
}
132
142
133
143
// FIXME: Requires specialization to take advantage of MultiwriteNorFlash?
0 commit comments