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