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