@@ -34,6 +34,9 @@ pub enum NorFlashErrorKind {
3434 /// The arguments are out of bounds.
3535 OutOfBounds ,
3636
37+ /// The cell already was written or cannot be written properly with provided value
38+ DirtyWrite ,
39+
3740 /// Error specific to the implementation.
3841 Other ,
3942}
@@ -49,6 +52,7 @@ impl core::fmt::Display for NorFlashErrorKind {
4952 match self {
5053 Self :: NotAligned => write ! ( f, "Arguments are not properly aligned" ) ,
5154 Self :: OutOfBounds => write ! ( f, "Arguments are out of bounds" ) ,
55+ Self :: DirtyWrite => write ! ( f, "Dirty write operation" ) ,
5256 Self :: Other => write ! ( f, "An implementation specific error occurred" ) ,
5357 }
5458 }
@@ -385,3 +389,132 @@ where
385389 Ok ( ( ) )
386390 }
387391}
392+
393+ /// Simple RAM-backed flash storage implementation for tests
394+ #[ derive( Clone , Copy , Debug ) ]
395+ pub struct MockFlash <
396+ const CAPACITY : usize ,
397+ const READ_SIZE : usize = 1 ,
398+ const WRITE_SIZE : usize = 1 ,
399+ const ERASE_SIZE : usize = { 1 << 10 } ,
400+ const ERASE_BYTE : u8 = 0xff ,
401+ const MULTI_WRITE : bool = false,
402+ > {
403+ data : [ u8 ; CAPACITY ] ,
404+ }
405+
406+ impl <
407+ const CAPACITY : usize ,
408+ const READ_SIZE : usize ,
409+ const WRITE_SIZE : usize ,
410+ const ERASE_SIZE : usize ,
411+ const ERASE_BYTE : u8 ,
412+ const MULTI_WRITE : bool ,
413+ > Default for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
414+ {
415+ fn default ( ) -> Self {
416+ Self {
417+ data : [ ERASE_BYTE ; CAPACITY ] ,
418+ }
419+ }
420+ }
421+
422+ impl <
423+ const CAPACITY : usize ,
424+ const READ_SIZE : usize ,
425+ const WRITE_SIZE : usize ,
426+ const ERASE_SIZE : usize ,
427+ const ERASE_BYTE : u8 ,
428+ const MULTI_WRITE : bool ,
429+ > core:: ops:: Deref
430+ for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
431+ {
432+ type Target = [ u8 ; CAPACITY ] ;
433+
434+ fn deref ( & self ) -> & Self :: Target {
435+ & self . data
436+ }
437+ }
438+
439+ impl <
440+ const CAPACITY : usize ,
441+ const READ_SIZE : usize ,
442+ const WRITE_SIZE : usize ,
443+ const ERASE_SIZE : usize ,
444+ const ERASE_BYTE : u8 ,
445+ const MULTI_WRITE : bool ,
446+ > core:: ops:: DerefMut
447+ for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
448+ {
449+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
450+ & mut self . data
451+ }
452+ }
453+
454+ impl <
455+ const CAPACITY : usize ,
456+ const READ_SIZE : usize ,
457+ const WRITE_SIZE : usize ,
458+ const ERASE_SIZE : usize ,
459+ const ERASE_BYTE : u8 ,
460+ const MULTI_WRITE : bool ,
461+ > ErrorType for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
462+ {
463+ type Error = NorFlashErrorKind ;
464+ }
465+
466+ impl <
467+ const CAPACITY : usize ,
468+ const READ_SIZE : usize ,
469+ const WRITE_SIZE : usize ,
470+ const ERASE_SIZE : usize ,
471+ const ERASE_BYTE : u8 ,
472+ const MULTI_WRITE : bool ,
473+ > ReadNorFlash for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
474+ {
475+ const READ_SIZE : usize = READ_SIZE ;
476+
477+ fn read ( & mut self , offset : u32 , bytes : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
478+ check_read ( self , offset, bytes. len ( ) ) ?;
479+ bytes. copy_from_slice ( & self . data [ offset as usize ..] [ ..bytes. len ( ) ] ) ;
480+ Ok ( ( ) )
481+ }
482+
483+ fn capacity ( & self ) -> usize {
484+ CAPACITY
485+ }
486+ }
487+
488+ impl <
489+ const CAPACITY : usize ,
490+ const READ_SIZE : usize ,
491+ const WRITE_SIZE : usize ,
492+ const ERASE_SIZE : usize ,
493+ const ERASE_BYTE : u8 ,
494+ const MULTI_WRITE : bool ,
495+ > NorFlash for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
496+ {
497+ const WRITE_SIZE : usize = WRITE_SIZE ;
498+ const ERASE_SIZE : usize = ERASE_SIZE ;
499+ const ERASE_BYTE : u8 = ERASE_BYTE ;
500+
501+ fn write ( & mut self , offset : u32 , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
502+ check_write ( self , offset, bytes. len ( ) ) ?;
503+ for ( dst, src) in self . data [ offset as usize ..] . iter_mut ( ) . zip ( bytes) {
504+ if !MULTI_WRITE && * dst != ERASE_BYTE {
505+ return Err ( NorFlashErrorKind :: DirtyWrite ) ;
506+ }
507+ * dst &= * src;
508+ if * src != * dst {
509+ return Err ( NorFlashErrorKind :: DirtyWrite ) ;
510+ }
511+ }
512+ Ok ( ( ) )
513+ }
514+
515+ fn erase ( & mut self , from : u32 , to : u32 ) -> Result < ( ) , Self :: Error > {
516+ check_erase ( self , from, to) ?;
517+ self . data [ from as usize ..to as usize ] . fill ( ERASE_BYTE ) ;
518+ Ok ( ( ) )
519+ }
520+ }
0 commit comments