@@ -30,6 +30,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
3030pub const FUNCTION_ERASE : u32 = 1 ;
3131pub const FUNCTION_PROGRAM : u32 = 2 ;
3232pub const FUNCTION_VERIFY : u32 = 3 ;
33+ pub const FUNCTION_BLANKCHECK : u32 = 4 ;
3334
3435pub type ErrorCode = core:: num:: NonZeroU32 ;
3536
@@ -84,13 +85,23 @@ pub trait FlashAlgorithm: Sized + 'static {
8485 /// * `data` - The data.
8586 #[ cfg( feature = "read-flash" ) ]
8687 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 > ;
8797}
8898
8999#[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
90100pub enum Function {
91101 Erase = 1 ,
92102 Program = 2 ,
93103 Verify = 3 ,
104+ BlankCheck = 4 ,
94105}
95106
96107/// A macro to define a new flash algoritm.
@@ -121,20 +132,23 @@ macro_rules! algorithm {
121132 #[ no_mangle]
122133 #[ link_section = ".entry" ]
123134 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 ;
126140 }
127- _IS_INIT = true ;
128141 let function = match function {
129142 1 => $crate:: Function :: Erase ,
130143 2 => $crate:: Function :: Program ,
131144 3 => $crate:: Function :: Verify ,
145+ 4 => $crate:: Function :: BlankCheck ,
132146 _ => core:: panic!( "This branch can only be reached if the host library sent an unknown function code." )
133147 } ;
134148 match <$type as $crate:: FlashAlgorithm >:: new( addr, clock, function) {
135149 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 } ;
138152 0
139153 }
140154 Err ( e) => e. get( ) ,
@@ -143,20 +157,24 @@ macro_rules! algorithm {
143157 #[ no_mangle]
144158 #[ link_section = ".entry" ]
145159 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 ;
148166 }
149- _ALGO_INSTANCE. as_mut_ptr( ) . drop_in_place( ) ;
150- _IS_INIT = false ;
151167 0
152168 }
153169 #[ no_mangle]
154170 #[ link_section = ".entry" ]
155171 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+ } ;
160178 match <$type as $crate:: FlashAlgorithm >:: erase_sector( this, addr) {
161179 Ok ( ( ) ) => 0 ,
162180 Err ( e) => e. get( ) ,
@@ -165,11 +183,14 @@ macro_rules! algorithm {
165183 #[ no_mangle]
166184 #[ link_section = ".entry" ]
167185 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+ } ;
173194 match <$type as $crate:: FlashAlgorithm >:: program_page( this, addr, data_slice) {
174195 Ok ( ( ) ) => 0 ,
175196 Err ( e) => e. get( ) ,
@@ -178,6 +199,7 @@ macro_rules! algorithm {
178199 $crate:: erase_chip!( $type) ;
179200 $crate:: read_flash!( $type) ;
180201 $crate:: verify!( $type) ;
202+ $crate:: blank_check!( $type) ;
181203
182204 #[ allow( non_upper_case_globals) ]
183205 #[ no_mangle]
@@ -268,10 +290,12 @@ macro_rules! erase_chip {
268290 #[ no_mangle]
269291 #[ link_section = ".entry" ]
270292 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+ } ;
275299 match <$type as $crate:: FlashAlgorithm >:: erase_all( this) {
276300 Ok ( ( ) ) => 0 ,
277301 Err ( e) => e. get( ) ,
@@ -294,11 +318,14 @@ macro_rules! read_flash {
294318 #[ no_mangle]
295319 #[ link_section = ".entry" ]
296320 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+ } ;
302329 match <$type as $crate:: FlashAlgorithm >:: read_flash( this, addr, data_slice) {
303330 Ok ( ( ) ) => 0 ,
304331 Err ( e) => e. get( ) ,
@@ -321,10 +348,12 @@ macro_rules! verify {
321348 #[ no_mangle]
322349 #[ link_section = ".entry" ]
323350 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+ } ;
328357
329358 if data. is_null( ) {
330359 match <$type as $crate:: FlashAlgorithm >:: verify( this, addr, size, None ) {
@@ -343,6 +372,34 @@ macro_rules! verify {
343372 } ;
344373}
345374
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+
346403#[ doc( hidden) ]
347404#[ macro_export]
348405macro_rules! count {
0 commit comments