@@ -30,6 +30,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
30
30
pub const FUNCTION_ERASE : u32 = 1 ;
31
31
pub const FUNCTION_PROGRAM : u32 = 2 ;
32
32
pub const FUNCTION_VERIFY : u32 = 3 ;
33
+ pub const FUNCTION_BLANKCHECK : u32 = 4 ;
33
34
34
35
pub type ErrorCode = core:: num:: NonZeroU32 ;
35
36
@@ -84,13 +85,23 @@ pub trait FlashAlgorithm: Sized + 'static {
84
85
/// * `data` - The data.
85
86
#[ cfg( feature = "read-flash" ) ]
86
87
fn read_flash ( & mut self , address : u32 , data : & mut [ u8 ] ) -> Result < ( ) , ErrorCode > ;
88
+
89
+ /// Verify that flash is blank.
90
+ ///
91
+ /// # Arguments
92
+ ///
93
+ /// * `address` - The start address of the flash to check.
94
+ /// * `size` - The length of the area to check.
95
+ #[ cfg( feature = "blank-check" ) ]
96
+ fn blank_check ( & mut self , address : u32 , size : u32 ) -> Result < ( ) , ErrorCode > ;
87
97
}
88
98
89
99
#[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
90
100
pub enum Function {
91
101
Erase = 1 ,
92
102
Program = 2 ,
93
103
Verify = 3 ,
104
+ BlankCheck = 4 ,
94
105
}
95
106
96
107
/// A macro to define a new flash algoritm.
@@ -115,26 +126,29 @@ macro_rules! algorithm {
115
126
} ) => {
116
127
static mut _IS_INIT: bool = false ;
117
128
static mut _ALGO_INSTANCE: core:: mem:: MaybeUninit <$type> = core:: mem:: MaybeUninit :: uninit( ) ;
118
-
129
+
119
130
core:: arch:: global_asm!( ".section .PrgData, \" aw\" " ) ;
120
-
131
+
121
132
#[ no_mangle]
122
133
#[ link_section = ".entry" ]
123
134
pub unsafe extern "C" fn Init ( addr: u32 , clock: u32 , function: u32 ) -> u32 {
124
- if _IS_INIT {
125
- UnInit ( ) ;
135
+ unsafe {
136
+ if _IS_INIT {
137
+ UnInit ( ) ;
138
+ }
139
+ _IS_INIT = true ;
126
140
}
127
- _IS_INIT = true ;
128
141
let function = match function {
129
142
1 => $crate:: Function :: Erase ,
130
143
2 => $crate:: Function :: Program ,
131
144
3 => $crate:: Function :: Verify ,
145
+ 4 => $crate:: Function :: BlankCheck ,
132
146
_ => core:: panic!( "This branch can only be reached if the host library sent an unknown function code." )
133
147
} ;
134
148
match <$type as $crate:: FlashAlgorithm >:: new( addr, clock, function) {
135
149
Ok ( inst) => {
136
- _ALGO_INSTANCE. as_mut_ptr( ) . write( inst) ;
137
- _IS_INIT = true ;
150
+ unsafe { _ALGO_INSTANCE. as_mut_ptr( ) . write( inst) } ;
151
+ unsafe { _IS_INIT = true } ;
138
152
0
139
153
}
140
154
Err ( e) => e. get( ) ,
@@ -143,20 +157,24 @@ macro_rules! algorithm {
143
157
#[ no_mangle]
144
158
#[ link_section = ".entry" ]
145
159
pub unsafe extern "C" fn UnInit ( ) -> u32 {
146
- if !_IS_INIT {
147
- return 1 ;
160
+ unsafe {
161
+ if !_IS_INIT {
162
+ return 1 ;
163
+ }
164
+ _ALGO_INSTANCE. as_mut_ptr( ) . drop_in_place( ) ;
165
+ _IS_INIT = false ;
148
166
}
149
- _ALGO_INSTANCE. as_mut_ptr( ) . drop_in_place( ) ;
150
- _IS_INIT = false ;
151
167
0
152
168
}
153
169
#[ no_mangle]
154
170
#[ link_section = ".entry" ]
155
171
pub unsafe extern "C" fn EraseSector ( addr: u32 ) -> u32 {
156
- if !_IS_INIT {
157
- return 1 ;
158
- }
159
- let this = & mut * _ALGO_INSTANCE. as_mut_ptr( ) ;
172
+ let this = unsafe {
173
+ if !unsafe { _IS_INIT } {
174
+ return 1 ;
175
+ }
176
+ & mut * _ALGO_INSTANCE. as_mut_ptr( )
177
+ } ;
160
178
match <$type as $crate:: FlashAlgorithm >:: erase_sector( this, addr) {
161
179
Ok ( ( ) ) => 0 ,
162
180
Err ( e) => e. get( ) ,
@@ -165,11 +183,14 @@ macro_rules! algorithm {
165
183
#[ no_mangle]
166
184
#[ link_section = ".entry" ]
167
185
pub unsafe extern "C" fn ProgramPage ( addr: u32 , size: u32 , data: * const u8 ) -> u32 {
168
- if !_IS_INIT {
169
- return 1 ;
170
- }
171
- let this = & mut * _ALGO_INSTANCE. as_mut_ptr( ) ;
172
- let data_slice: & [ u8 ] = unsafe { core:: slice:: from_raw_parts( data, size as usize ) } ;
186
+ let ( this, data_slice) = unsafe {
187
+ if !_IS_INIT {
188
+ return 1 ;
189
+ }
190
+ let this = & mut * _ALGO_INSTANCE. as_mut_ptr( ) ;
191
+ let data_slice: & [ u8 ] = core:: slice:: from_raw_parts( data, size as usize ) ;
192
+ ( this, data_slice)
193
+ } ;
173
194
match <$type as $crate:: FlashAlgorithm >:: program_page( this, addr, data_slice) {
174
195
Ok ( ( ) ) => 0 ,
175
196
Err ( e) => e. get( ) ,
@@ -178,7 +199,8 @@ macro_rules! algorithm {
178
199
$crate:: erase_chip!( $type) ;
179
200
$crate:: read_flash!( $type) ;
180
201
$crate:: verify!( $type) ;
181
-
202
+ $crate:: blank_check!( $type) ;
203
+
182
204
#[ allow( non_upper_case_globals) ]
183
205
#[ no_mangle]
184
206
#[ used]
@@ -217,7 +239,7 @@ macro_rules! algorithm {
217
239
}
218
240
] ,
219
241
} ;
220
-
242
+
221
243
#[ repr( C ) ]
222
244
pub struct FlashDeviceDescription {
223
245
vers: u16 ,
@@ -230,17 +252,17 @@ macro_rules! algorithm {
230
252
empty: u8 ,
231
253
program_time_out: u32 ,
232
254
erase_time_out: u32 ,
233
-
255
+
234
256
flash_sectors: [ FlashSector ; $crate:: count!( $( $size) * ) + 1 ] ,
235
257
}
236
-
258
+
237
259
#[ repr( C ) ]
238
260
#[ derive( Copy , Clone ) ]
239
261
pub struct FlashSector {
240
262
size: u32 ,
241
263
address: u32 ,
242
264
}
243
-
265
+
244
266
#[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
245
267
#[ repr( u16 ) ]
246
268
pub enum DeviceType {
@@ -268,10 +290,12 @@ macro_rules! erase_chip {
268
290
#[ no_mangle]
269
291
#[ link_section = ".entry" ]
270
292
pub unsafe extern "C" fn EraseChip ( ) -> u32 {
271
- if !_IS_INIT {
272
- return 1 ;
273
- }
274
- let this = & mut * _ALGO_INSTANCE. as_mut_ptr( ) ;
293
+ let this = unsafe {
294
+ if !_IS_INIT {
295
+ return 1 ;
296
+ }
297
+ & mut * _ALGO_INSTANCE. as_mut_ptr( )
298
+ } ;
275
299
match <$type as $crate:: FlashAlgorithm >:: erase_all( this) {
276
300
Ok ( ( ) ) => 0 ,
277
301
Err ( e) => e. get( ) ,
@@ -294,11 +318,15 @@ macro_rules! read_flash {
294
318
#[ no_mangle]
295
319
#[ link_section = ".entry" ]
296
320
pub unsafe extern "C" fn ReadFlash ( addr: u32 , size: u32 , data: * mut u8 ) -> u32 {
297
- if !_IS_INIT {
298
- return 1 ;
299
- }
300
- let this = & mut * _ALGO_INSTANCE. as_mut_ptr( ) ;
301
- let data_slice: & mut [ u8 ] = unsafe { core:: slice:: from_raw_parts_mut( data, size as usize ) } ;
321
+ let ( this, data_slice) = unsafe {
322
+ if !_IS_INIT {
323
+ return 1 ;
324
+ }
325
+ let this = & mut * _ALGO_INSTANCE. as_mut_ptr( ) ;
326
+ let data_slice: & mut [ u8 ] =
327
+ core:: slice:: from_raw_parts_mut( data, size as usize ) ;
328
+ ( this, data_slice)
329
+ } ;
302
330
match <$type as $crate:: FlashAlgorithm >:: read_flash( this, addr, data_slice) {
303
331
Ok ( ( ) ) => 0 ,
304
332
Err ( e) => e. get( ) ,
@@ -321,10 +349,12 @@ macro_rules! verify {
321
349
#[ no_mangle]
322
350
#[ link_section = ".entry" ]
323
351
pub unsafe extern "C" fn Verify ( addr: u32 , size: u32 , data: * const u8 ) -> u32 {
324
- if !_IS_INIT {
325
- return 1 ;
326
- }
327
- let this = & mut * _ALGO_INSTANCE. as_mut_ptr( ) ;
352
+ let this = unsafe {
353
+ if !_IS_INIT {
354
+ return 1 ;
355
+ }
356
+ & mut * _ALGO_INSTANCE. as_mut_ptr( )
357
+ } ;
328
358
329
359
if data. is_null( ) {
330
360
match <$type as $crate:: FlashAlgorithm >:: verify( this, addr, size, None ) {
@@ -343,6 +373,34 @@ macro_rules! verify {
343
373
} ;
344
374
}
345
375
376
+ #[ doc( hidden) ]
377
+ #[ macro_export]
378
+ #[ cfg( not( feature = "blank-check" ) ) ]
379
+ macro_rules! blank_check {
380
+ ( $type: ty) => { } ;
381
+ }
382
+ #[ doc( hidden) ]
383
+ #[ macro_export]
384
+ #[ cfg( feature = "blank-check" ) ]
385
+ macro_rules! blank_check {
386
+ ( $type: ty) => {
387
+ #[ no_mangle]
388
+ #[ link_section = ".entry" ]
389
+ pub unsafe extern "C" fn BlankCheck ( addr: u32 , size: u32 ) -> u32 {
390
+ let this = unsafe {
391
+ if !_IS_INIT {
392
+ return 1 ;
393
+ }
394
+ & mut * _ALGO_INSTANCE. as_mut_ptr( )
395
+ } ;
396
+ match <$type as $crate:: FlashAlgorithm >:: blank_check( this, addr, size) {
397
+ Ok ( ( ) ) => 0 ,
398
+ Err ( e) => e. get( ) ,
399
+ }
400
+ }
401
+ } ;
402
+ }
403
+
346
404
#[ doc( hidden) ]
347
405
#[ macro_export]
348
406
macro_rules! count {
0 commit comments