@@ -14,6 +14,7 @@ use nucleo_wl55jc_bsp::hal::{
14
14
} ;
15
15
use panic_probe as _;
16
16
use rand:: Rng as RngTrait ;
17
+ use static_assertions as sa;
17
18
18
19
const FREQ : u32 = 48_000_000 ;
19
20
const CYC_PER_MICRO : u32 = FREQ / 1000 / 1000 ;
@@ -39,6 +40,9 @@ mod tests {
39
40
struct TestArgs {
40
41
flash : pac:: FLASH ,
41
42
page : Page ,
43
+ // address to use for testing
44
+ // incremented by the test after the address is programmed
45
+ addr : usize ,
42
46
rng : Rng ,
43
47
}
44
48
@@ -71,6 +75,7 @@ mod tests {
71
75
TestArgs {
72
76
flash : dp. FLASH ,
73
77
page,
78
+ addr : page. addr ( ) ,
74
79
rng,
75
80
}
76
81
}
@@ -123,7 +128,7 @@ mod tests {
123
128
let mut flash: Flash = Flash :: unlock ( & mut ta. flash ) ;
124
129
125
130
let start: u32 = DWT :: get_cycle_count ( ) ;
126
- unwrap ! ( unsafe { flash. fast_program( BUF . as_ptr( ) , ta. page . addr( ) as * mut u64 ) } ) ;
131
+ unwrap ! ( unsafe { flash. fast_program( BUF . as_ptr( ) , ta. addr as * mut u64 ) } ) ;
127
132
let end: u32 = DWT :: get_cycle_count ( ) ;
128
133
let elapsed: u32 = end. wrapping_sub ( start) ;
129
134
@@ -134,35 +139,31 @@ mod tests {
134
139
135
140
for ( idx, & dw) in unsafe { BUF } . iter ( ) . enumerate ( ) {
136
141
let expected: u64 = unsafe {
137
- ( ta. page . addr ( ) as * const u64 )
142
+ ( ta. addr as * const u64 )
138
143
. offset ( unwrap ! ( idx. try_into( ) ) )
139
144
. read_volatile ( )
140
145
} ;
141
146
defmt:: assert_eq!( dw, expected) ;
142
147
}
148
+
149
+ // increment address by program size
150
+ ta. addr += 256 ;
143
151
}
144
152
145
153
#[ test]
146
154
fn standard_program ( ta : & mut TestArgs ) {
147
- let addr: usize = {
148
- let unaligned_addr: usize = ta
149
- . rng
150
- . gen_range ( ta. page . addr ( ) + 256 ..ta. page . addr ( ) + Page :: SIZE - 1 ) ;
151
- unaligned_addr - ( unaligned_addr % size_of :: < u64 > ( ) )
152
- } ;
153
-
154
155
let data: u64 = ta. rng . gen_range ( 1 ..u64:: MAX - 1 ) ;
155
156
defmt:: assert_ne!( data, u64 :: MAX ) ;
156
157
defmt:: assert_ne!( data, 0 ) ;
157
158
158
- defmt:: info!( "Writing {:#016X} to {:#08X}" , data, addr) ;
159
+ defmt:: info!( "Writing {:#016X} to {:#08X}" , data, ta . addr) ;
159
160
160
- defmt:: assert_eq!( unsafe { read_volatile( addr as * const u64 ) } , u64 :: MAX ) ;
161
+ defmt:: assert_eq!( unsafe { read_volatile( ta . addr as * const u64 ) } , u64 :: MAX ) ;
161
162
162
163
let mut flash: Flash = Flash :: unlock ( & mut ta. flash ) ;
163
164
164
165
let start: u32 = DWT :: get_cycle_count ( ) ;
165
- unwrap ! ( unsafe { flash. standard_program( & data, addr as * mut u64 ) } ) ;
166
+ unwrap ! ( unsafe { flash. standard_program( & data, ta . addr as * mut u64 ) } ) ;
166
167
let end: u32 = DWT :: get_cycle_count ( ) ;
167
168
let elapsed: u32 = end. wrapping_sub ( start) ;
168
169
@@ -171,6 +172,82 @@ mod tests {
171
172
elapsed / CYC_PER_MICRO
172
173
) ;
173
174
174
- defmt:: assert_eq!( unsafe { read_volatile( addr as * const u64 ) } , data) ;
175
+ defmt:: assert_eq!( unsafe { read_volatile( ta. addr as * const u64 ) } , data) ;
176
+
177
+ // increment address by program size
178
+ ta. addr += size_of :: < u64 > ( ) ;
179
+ }
180
+
181
+ #[ test]
182
+ fn standard_program_generic_zero_size ( ta : & mut TestArgs ) {
183
+ type ZeroSizeType = ( ) ;
184
+
185
+ sa:: assert_eq_size!( ZeroSizeType , [ u8 ; 0 ] ) ;
186
+
187
+ let my_zero_size_type: ZeroSizeType = ( ) ;
188
+
189
+ let mut flash: Flash = Flash :: unlock ( & mut ta. flash ) ;
190
+
191
+ // check flash is erased
192
+ defmt:: assert_eq!( unsafe { read_volatile( ta. addr as * const u64 ) } , u64 :: MAX ) ;
193
+
194
+ unwrap ! ( unsafe {
195
+ flash. standard_program_generic( & my_zero_size_type, ta. addr as * mut ZeroSizeType )
196
+ } ) ;
197
+
198
+ // check flash was not modified
199
+ defmt:: assert_eq!( unsafe { read_volatile( ta. addr as * const u64 ) } , u64 :: MAX ) ;
200
+ }
201
+
202
+ #[ test]
203
+ fn standard_program_generic ( ta : & mut TestArgs ) {
204
+ #[ derive( defmt:: Format , PartialEq , Eq ) ]
205
+ struct Keys {
206
+ eui : [ u8 ; 8 ] ,
207
+ key : [ u8 ; 16 ] ,
208
+ }
209
+
210
+ #[ derive( defmt:: Format , PartialEq , Eq ) ]
211
+ #[ repr( align( 8 ) ) ]
212
+ struct TestStruct {
213
+ connected : bool ,
214
+ keys : Keys ,
215
+ framecount_down : u32 ,
216
+ framecount_up : u32 ,
217
+ }
218
+
219
+ sa:: assert_eq_align!( TestStruct , u64 ) ;
220
+
221
+ let data = TestStruct {
222
+ connected : false ,
223
+ keys : Keys {
224
+ eui : [ 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 ] ,
225
+ key : [
226
+ 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 ,
227
+ 0x06 , 0x07 , 0x08 ,
228
+ ] ,
229
+ } ,
230
+ framecount_up : 12 ,
231
+ framecount_down : 120 ,
232
+ } ;
233
+
234
+ defmt:: info!( "Writing {} to {:#08X}" , data, ta. addr) ;
235
+
236
+ let mut flash: Flash = Flash :: unlock ( & mut ta. flash ) ;
237
+
238
+ let start: u32 = DWT :: get_cycle_count ( ) ;
239
+ unwrap ! ( unsafe { flash. standard_program_generic( & data, ta. addr as * mut TestStruct ) } ) ;
240
+ let end: u32 = DWT :: get_cycle_count ( ) ;
241
+ let elapsed: u32 = end. wrapping_sub ( start) ;
242
+
243
+ let size = core:: mem:: size_of :: < TestStruct > ( ) ;
244
+
245
+ defmt:: info!(
246
+ "{}B program duration: {=u32:us} seconds" ,
247
+ size,
248
+ elapsed / CYC_PER_MICRO
249
+ ) ;
250
+
251
+ defmt:: assert_eq!( unsafe { read_volatile( ta. addr as * const TestStruct ) } , data) ;
175
252
}
176
253
}
0 commit comments