@@ -19,6 +19,7 @@ use embedded_storage::nor_flash::{
19
19
type WORD = u32 ;
20
20
const WORD_SIZE : usize = core:: mem:: size_of :: < WORD > ( ) ;
21
21
const PAGE_SIZE : usize = 4 * 1024 ;
22
+ const PAGE_ERASE_TIME : u32 = 85 ;
22
23
23
24
/// Interface to an NVMC instance.
24
25
pub struct Nvmc < T : Instance > {
44
45
( self . nvmc , self . storage )
45
46
}
46
47
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
+
47
91
fn enable_erase ( & self ) {
48
92
#[ cfg( not( any( feature = "9160" , feature = "5340-app" ) ) ) ]
49
93
self . nvmc . config . write ( |w| w. wen ( ) . een ( ) ) ;
@@ -91,6 +135,21 @@ where
91
135
self . wait_ready ( ) ;
92
136
}
93
137
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
+
94
153
#[ inline]
95
154
fn write_word ( & mut self , word_offset : usize , word : u32 ) {
96
155
#[ cfg( not( any( feature = "9160" , feature = "5340-app" ) ) ) ]
0 commit comments