@@ -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 }
@@ -379,3 +383,132 @@ where
379383 Ok ( ( ) )
380384 }
381385}
386+
387+ /// Simple RAM-backed flash storage implementation for tests
388+ #[ derive( Clone , Copy , Debug ) ]
389+ pub struct MockFlash <
390+ const CAPACITY : usize ,
391+ const READ_SIZE : usize = 1 ,
392+ const WRITE_SIZE : usize = 1 ,
393+ const ERASE_SIZE : usize = { 1 << 10 } ,
394+ const ERASE_BYTE : u8 = 0xff ,
395+ const MULTI_WRITE : bool = false,
396+ > {
397+ data : [ u8 ; CAPACITY ] ,
398+ }
399+
400+ impl <
401+ const CAPACITY : usize ,
402+ const READ_SIZE : usize ,
403+ const WRITE_SIZE : usize ,
404+ const ERASE_SIZE : usize ,
405+ const ERASE_BYTE : u8 ,
406+ const MULTI_WRITE : bool ,
407+ > Default for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
408+ {
409+ fn default ( ) -> Self {
410+ Self {
411+ data : [ ERASE_BYTE ; CAPACITY ] ,
412+ }
413+ }
414+ }
415+
416+ impl <
417+ const CAPACITY : usize ,
418+ const READ_SIZE : usize ,
419+ const WRITE_SIZE : usize ,
420+ const ERASE_SIZE : usize ,
421+ const ERASE_BYTE : u8 ,
422+ const MULTI_WRITE : bool ,
423+ > core:: ops:: Deref
424+ for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
425+ {
426+ type Target = [ u8 ; CAPACITY ] ;
427+
428+ fn deref ( & self ) -> & Self :: Target {
429+ & self . data
430+ }
431+ }
432+
433+ impl <
434+ const CAPACITY : usize ,
435+ const READ_SIZE : usize ,
436+ const WRITE_SIZE : usize ,
437+ const ERASE_SIZE : usize ,
438+ const ERASE_BYTE : u8 ,
439+ const MULTI_WRITE : bool ,
440+ > core:: ops:: DerefMut
441+ for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
442+ {
443+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
444+ & mut self . data
445+ }
446+ }
447+
448+ impl <
449+ const CAPACITY : usize ,
450+ const READ_SIZE : usize ,
451+ const WRITE_SIZE : usize ,
452+ const ERASE_SIZE : usize ,
453+ const ERASE_BYTE : u8 ,
454+ const MULTI_WRITE : bool ,
455+ > ErrorType for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
456+ {
457+ type Error = NorFlashErrorKind ;
458+ }
459+
460+ impl <
461+ const CAPACITY : usize ,
462+ const READ_SIZE : usize ,
463+ const WRITE_SIZE : usize ,
464+ const ERASE_SIZE : usize ,
465+ const ERASE_BYTE : u8 ,
466+ const MULTI_WRITE : bool ,
467+ > ReadNorFlash for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
468+ {
469+ const READ_SIZE : usize = READ_SIZE ;
470+
471+ fn read ( & mut self , offset : u32 , bytes : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
472+ check_read ( self , offset, bytes. len ( ) ) ?;
473+ bytes. copy_from_slice ( & self . data [ offset as usize ..] [ ..bytes. len ( ) ] ) ;
474+ Ok ( ( ) )
475+ }
476+
477+ fn capacity ( & self ) -> usize {
478+ CAPACITY
479+ }
480+ }
481+
482+ impl <
483+ const CAPACITY : usize ,
484+ const READ_SIZE : usize ,
485+ const WRITE_SIZE : usize ,
486+ const ERASE_SIZE : usize ,
487+ const ERASE_BYTE : u8 ,
488+ const MULTI_WRITE : bool ,
489+ > NorFlash for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
490+ {
491+ const WRITE_SIZE : usize = WRITE_SIZE ;
492+ const ERASE_SIZE : usize = ERASE_SIZE ;
493+
494+ fn write ( & mut self , offset : u32 , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
495+ check_write ( self , offset, bytes. len ( ) ) ?;
496+ for ( dst, src) in self . data [ offset as usize ..] . iter_mut ( ) . zip ( bytes) {
497+ if !MULTI_WRITE && * dst != ERASE_BYTE {
498+ return Err ( NorFlashErrorKind :: DirtyWrite ) ;
499+ }
500+ * dst &= * src;
501+ if * src != * dst {
502+ return Err ( NorFlashErrorKind :: DirtyWrite ) ;
503+ }
504+ }
505+ Ok ( ( ) )
506+ }
507+
508+ fn erase ( & mut self , from : u32 , to : u32 ) -> Result < ( ) , Self :: Error > {
509+ check_erase ( self , from, to) ?;
510+ self . data [ from as usize ..to as usize ] . fill ( ERASE_BYTE ) ;
511+ Ok ( ( ) )
512+ }
513+ }
514+
0 commit comments