@@ -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.
@@ -115,26 +126,29 @@ macro_rules! algorithm {
115126 } ) => {
116127 static mut _IS_INIT: bool = false ;
117128 static mut _ALGO_INSTANCE: core:: mem:: MaybeUninit <$type> = core:: mem:: MaybeUninit :: uninit( ) ;
118-
129+
119130 core:: arch:: global_asm!( ".section .PrgData, \" aw\" " ) ;
120-
131+
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,7 +199,8 @@ macro_rules! algorithm {
178199 $crate:: erase_chip!( $type) ;
179200 $crate:: read_flash!( $type) ;
180201 $crate:: verify!( $type) ;
181-
202+ $crate:: blank_check!( $type) ;
203+
182204 #[ allow( non_upper_case_globals) ]
183205 #[ no_mangle]
184206 #[ used]
@@ -217,7 +239,7 @@ macro_rules! algorithm {
217239 }
218240 ] ,
219241 } ;
220-
242+
221243 #[ repr( C ) ]
222244 pub struct FlashDeviceDescription {
223245 vers: u16 ,
@@ -230,17 +252,17 @@ macro_rules! algorithm {
230252 empty: u8 ,
231253 program_time_out: u32 ,
232254 erase_time_out: u32 ,
233-
255+
234256 flash_sectors: [ FlashSector ; $crate:: count!( $( $size) * ) + 1 ] ,
235257 }
236-
258+
237259 #[ repr( C ) ]
238260 #[ derive( Copy , Clone ) ]
239261 pub struct FlashSector {
240262 size: u32 ,
241263 address: u32 ,
242264 }
243-
265+
244266 #[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
245267 #[ repr( u16 ) ]
246268 pub enum DeviceType {
@@ -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,15 @@ 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 ] =
327+ core:: slice:: from_raw_parts_mut( data, size as usize ) ;
328+ ( this, data_slice)
329+ } ;
302330 match <$type as $crate:: FlashAlgorithm >:: read_flash( this, addr, data_slice) {
303331 Ok ( ( ) ) => 0 ,
304332 Err ( e) => e. get( ) ,
@@ -321,10 +349,12 @@ macro_rules! verify {
321349 #[ no_mangle]
322350 #[ link_section = ".entry" ]
323351 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+ } ;
328358
329359 if data. is_null( ) {
330360 match <$type as $crate:: FlashAlgorithm >:: verify( this, addr, size, None ) {
@@ -343,6 +373,34 @@ macro_rules! verify {
343373 } ;
344374}
345375
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+
346404#[ doc( hidden) ]
347405#[ macro_export]
348406macro_rules! count {
0 commit comments