@@ -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.
@@ -121,20 +132,23 @@ macro_rules! algorithm {
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,6 +199,7 @@ macro_rules! algorithm {
178
199
$crate:: erase_chip!( $type) ;
179
200
$crate:: read_flash!( $type) ;
180
201
$crate:: verify!( $type) ;
202
+ $crate:: blank_check!( $type) ;
181
203
182
204
#[ allow( non_upper_case_globals) ]
183
205
#[ no_mangle]
@@ -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,14 @@ 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 ] = core:: slice:: from_raw_parts_mut( data, size as usize ) ;
327
+ ( this, data_slice)
328
+ } ;
302
329
match <$type as $crate:: FlashAlgorithm >:: read_flash( this, addr, data_slice) {
303
330
Ok ( ( ) ) => 0 ,
304
331
Err ( e) => e. get( ) ,
@@ -321,10 +348,12 @@ macro_rules! verify {
321
348
#[ no_mangle]
322
349
#[ link_section = ".entry" ]
323
350
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( ) ;
351
+ let this = unsafe {
352
+ if !_IS_INIT {
353
+ return 1 ;
354
+ }
355
+ & mut * _ALGO_INSTANCE. as_mut_ptr( )
356
+ } ;
328
357
329
358
if data. is_null( ) {
330
359
match <$type as $crate:: FlashAlgorithm >:: verify( this, addr, size, None ) {
@@ -343,6 +372,34 @@ macro_rules! verify {
343
372
} ;
344
373
}
345
374
375
+ #[ doc( hidden) ]
376
+ #[ macro_export]
377
+ #[ cfg( not( feature = "blank-check" ) ) ]
378
+ macro_rules! blank_check {
379
+ ( $type: ty) => { } ;
380
+ }
381
+ #[ doc( hidden) ]
382
+ #[ macro_export]
383
+ #[ cfg( feature = "blank-check" ) ]
384
+ macro_rules! blank_check {
385
+ ( $type: ty) => {
386
+ #[ no_mangle]
387
+ #[ link_section = ".entry" ]
388
+ pub unsafe extern "C" fn BlankCheck ( addr: u32 , size: u32 ) -> u32 {
389
+ let this = unsafe {
390
+ if !_IS_INIT {
391
+ return 1 ;
392
+ }
393
+ & mut * _ALGO_INSTANCE. as_mut_ptr( )
394
+ } ;
395
+ match <$type as $crate:: FlashAlgorithm >:: blank_check( this, addr, size) {
396
+ Ok ( ( ) ) => 0 ,
397
+ Err ( e) => e. get( ) ,
398
+ }
399
+ }
400
+ } ;
401
+ }
402
+
346
403
#[ doc( hidden) ]
347
404
#[ macro_export]
348
405
macro_rules! count {
0 commit comments