@@ -19,6 +19,7 @@ use embedded_storage::nor_flash::{
1919type WORD = u32 ;
2020const WORD_SIZE : usize = core:: mem:: size_of :: < WORD > ( ) ;
2121const PAGE_SIZE : usize = 4 * 1024 ;
22+ const PAGE_ERASE_TIME : u32 = 85 ;
2223
2324/// Interface to an NVMC instance.
2425pub struct Nvmc < T : Instance > {
4445 ( self . nvmc , self . storage )
4546 }
4647
48+ #[ cfg( not( any( feature = "9160" , feature = "5340-app" ) ) ) ]
49+ /// Erases the given storage range using partial erase feature. This allows
50+ /// application to handle interrupts while erasing memory by dividing the
51+ /// time CPU is halted in smaller periods.
52+ ///
53+ /// # Errors
54+ ///
55+ /// Returns an error if the arguments are not aligned, out of bounds or when
56+ /// period is not in range from 1 to 127 inclusive.
57+ pub fn partial_erase (
58+ & mut self ,
59+ from : u32 ,
60+ to : u32 ,
61+ period : u32 ,
62+ ) -> Result < ( ) , <Self as ErrorType >:: Error > {
63+ let ( from, to) = ( from as usize , to as usize ) ;
64+ if from > to || to > self . capacity ( ) {
65+ return Err ( NvmcError :: OutOfBounds ) ;
66+ }
67+ if from % PAGE_SIZE != 0 || to % PAGE_SIZE != 0 {
68+ return Err ( NvmcError :: Unaligned ) ;
69+ }
70+ let ( page_from, page_to) = ( from / PAGE_SIZE , to / PAGE_SIZE ) ;
71+
72+ if period & !0x7F != 0 || period == 0 {
73+ return Err ( NvmcError :: OutOfBounds ) ;
74+ }
75+
76+ self . nvmc
77+ . erasepagepartialcfg
78+ . write ( |w| unsafe { w. bits ( period) } ) ;
79+ for page_offset in page_from..page_to {
80+ // According to nRF52840 manual (section 4.3.9.9) CONFIG.WEN must be
81+ // enabled before every partial erase and disabled after every
82+ // partial erase
83+ self . enable_erase ( ) ;
84+ self . partial_erase_page ( page_offset, period) ;
85+ self . enable_read ( ) ;
86+ }
87+
88+ Ok ( ( ) )
89+ }
90+
4791 fn enable_erase ( & self ) {
4892 #[ cfg( not( any( feature = "9160" , feature = "5340-app" ) ) ) ]
4993 self . nvmc . config . write ( |w| w. wen ( ) . een ( ) ) ;
@@ -91,6 +135,21 @@ where
91135 self . wait_ready ( ) ;
92136 }
93137
138+ #[ cfg( not( any( feature = "9160" , feature = "5340-app" ) ) ) ]
139+ #[ inline]
140+ fn partial_erase_page ( & mut self , page_offset : usize , period : u32 ) {
141+ let bits = & mut ( self . storage [ page_offset * PAGE_SIZE ] ) as * mut _ as u32 ;
142+ let mut time_left = PAGE_ERASE_TIME ;
143+ while time_left > 0 {
144+ self . nvmc
145+ . erasepagepartial
146+ . write ( |w| unsafe { w. bits ( bits) } ) ;
147+ self . wait_ready ( ) ;
148+
149+ time_left = time_left. saturating_sub ( period) ;
150+ }
151+ }
152+
94153 #[ inline]
95154 fn write_word ( & mut self , word_offset : usize , word : u32 ) {
96155 #[ cfg( not( any( feature = "9160" , feature = "5340-app" ) ) ) ]
0 commit comments