@@ -16,6 +16,7 @@ use lpc55_hal::{
1616 traits:: flash:: WriteErase ,
1717 typestates:: init_state:: Enabled ,
1818} ;
19+ use lpc55_pac:: PRINCE ;
1920
2021use super :: MEMORY_REGIONS ;
2122
@@ -64,7 +65,7 @@ pub const BLOCK_COUNT: usize = {
6465
6566const PRINCE_REGION2_START : usize = 0x80_000 ;
6667const PRINCE_SUBREGION_SIZE : usize = 8 * 1024 ;
67- const PRINCE_REGION2_ENABLE : u32 = {
68+ const PRINCE_REGION2_MASK : u32 = {
6869 // FS must be placed in PRINCE Region 2
6970 assert ! ( FS_START >= PRINCE_REGION2_START ) ;
7071 let offset = FS_START - PRINCE_REGION2_START ;
@@ -80,33 +81,60 @@ const PRINCE_REGION2_ENABLE: u32 = {
8081 // --> disable subregion_count subregions, enable the remaining ones
8182 0xffffffff << subregion_count
8283} ;
83- const PRINCE_REGION2_DISABLE : u32 = 0 ;
8484
85- pub fn enable ( prince : & mut Prince < Enabled > ) {
86- prince . set_region_enable ( Region :: Region2 , PRINCE_REGION2_ENABLE ) ;
85+ pub struct PrinceConfig {
86+ sr_enable2 : u32 ,
8787}
8888
89- pub fn disable ( prince : & mut Prince < Enabled > ) {
90- prince. set_region_enable ( Region :: Region2 , PRINCE_REGION2_DISABLE ) ;
91- }
89+ impl PrinceConfig {
90+ pub fn new ( prince : & PRINCE ) -> Self {
91+ Self {
92+ sr_enable2 : prince. sr_enable2 . read ( ) . bits ( ) ,
93+ }
94+ }
95+
96+ fn sr_enable2 ( & self , filesystem : bool ) -> u32 {
97+ if filesystem {
98+ // enable the default regions and the filesystem regions
99+ self . sr_enable2 | PRINCE_REGION2_MASK
100+ } else {
101+ // enable the default regions without the filesystem regions
102+ self . sr_enable2 & !PRINCE_REGION2_MASK
103+ }
104+ }
105+
106+ pub fn enable_filesystem ( & self , prince : & mut Prince < Enabled > ) {
107+ prince. set_region_enable ( Region :: Region2 , self . sr_enable2 ( true ) ) ;
108+ }
92109
93- pub fn with_enabled < T > ( prince : & mut Prince < Enabled > , mut f : impl FnMut ( ) -> T ) -> T {
94- enable ( prince) ;
95- let result = f ( ) ;
96- disable ( prince) ;
97- result
110+ pub fn disable_filesystem ( & self , prince : & mut Prince < Enabled > ) {
111+ prince. set_region_enable ( Region :: Region2 , self . sr_enable2 ( false ) ) ;
112+ }
113+
114+ pub fn with_filesystem < F : FnMut ( ) -> T , T > ( & self , prince : & mut Prince < Enabled > , mut f : F ) -> T {
115+ self . enable_filesystem ( prince) ;
116+ let result = f ( ) ;
117+ self . disable_filesystem ( prince) ;
118+ result
119+ }
98120}
99121
100122pub struct InternalFilesystem {
101123 flash_gordon : FlashGordon ,
102124 prince : Prince < Enabled > ,
125+ prince_config : PrinceConfig ,
103126}
104127
105128impl InternalFilesystem {
106- pub fn new ( flash_gordon : FlashGordon , prince : Prince < Enabled > ) -> Self {
129+ pub fn new (
130+ flash_gordon : FlashGordon ,
131+ prince : Prince < Enabled > ,
132+ prince_config : PrinceConfig ,
133+ ) -> Self {
107134 Self {
108135 flash_gordon,
109136 prince,
137+ prince_config,
110138 }
111139 }
112140}
@@ -123,7 +151,7 @@ impl Storage for InternalFilesystem {
123151 type LOOKAHEAD_SIZE = littlefs_params:: LOOKAHEAD_SIZE ;
124152
125153 fn read ( & mut self , off : usize , buf : & mut [ u8 ] ) -> Result < usize > {
126- with_enabled ( & mut self . prince , || {
154+ self . prince_config . with_filesystem ( & mut self . prince , || {
127155 let flash: * const u8 = ( FS_START + off) as * const u8 ;
128156 #[ allow( clippy:: needless_range_loop) ]
129157 for i in 0 ..buf. len ( ) {
@@ -135,7 +163,8 @@ impl Storage for InternalFilesystem {
135163
136164 fn write ( & mut self , off : usize , data : & [ u8 ] ) -> Result < usize > {
137165 let ret = self . prince . write_encrypted ( |prince| {
138- with_enabled ( prince, || self . flash_gordon . write ( FS_START + off, data) )
166+ self . prince_config
167+ . with_filesystem ( prince, || self . flash_gordon . write ( FS_START + off, data) )
139168 } ) ;
140169 ret. map ( |_| data. len ( ) ) . map_err ( |_| Error :: IO )
141170 }
@@ -152,3 +181,43 @@ impl Storage for InternalFilesystem {
152181 Ok ( BLOCK_SIZE * pages)
153182 }
154183}
184+
185+ #[ cfg( test) ]
186+ mod tests {
187+ use super :: * ;
188+
189+ #[ test]
190+ fn test_prince_sr_enable2 ( ) {
191+ // currently, the first 9 regions are used for the firmware, so the first 9 bits should
192+ // stay the same. the rest should be 0 if the filesystem is disabled or 1 if it is
193+ // enabled.
194+
195+ let none = 0 ;
196+ let all = u32:: MAX ;
197+ let firmware = 0b1_11111111 ;
198+ let filesystem = 0b11111111_11111111_11111110_00000000 ;
199+
200+ assert_eq ! ( PRINCE_REGION2_MASK , filesystem) ;
201+ assert_eq ! ( firmware ^ filesystem, all) ;
202+
203+ let config = PrinceConfig { sr_enable2 : none } ;
204+ assert_eq ! ( config. sr_enable2( false ) , none) ;
205+ assert_eq ! ( config. sr_enable2( true ) , filesystem) ;
206+
207+ let config = PrinceConfig { sr_enable2 : all } ;
208+ assert_eq ! ( config. sr_enable2( false ) , firmware) ;
209+ assert_eq ! ( config. sr_enable2( true ) , all) ;
210+
211+ let config = PrinceConfig { sr_enable2 : firmware } ;
212+ assert_eq ! ( config. sr_enable2( false ) , firmware) ;
213+ assert_eq ! ( config. sr_enable2( true ) , all) ;
214+
215+ let config = PrinceConfig { sr_enable2 : 1 } ;
216+ assert_eq ! ( config. sr_enable2( false ) , 1 ) ;
217+ assert_eq ! ( config. sr_enable2( true ) , 0b11111111_11111111_11111110_00000001 ) ;
218+
219+ let config = PrinceConfig { sr_enable2 : 0x3fff } ;
220+ assert_eq ! ( config. sr_enable2( false ) , firmware) ;
221+ assert_eq ! ( config. sr_enable2( true ) , all) ;
222+ }
223+ }
0 commit comments