1use crate::pac::FLASH0;
2
3pub type PageData = [u32; 64];
4
5const UNCACHED_BASE: u32 = 0xC000000;
6
7const PROTECTION_CONFIRM_CODE: u32 = 0x8AFE15C3;
8
9const PROTECTION_CONFIRM_OFFSET: u32 = 512;
10
11const BYTES_PER_UCB: u32 = 1024;
12
13const UCB0: u32 = UNCACHED_BASE;
14
15pub struct FlashSector {
16 pub number: u8,
17 pub offset: usize,
18 pub size: usize,
19}
20
21impl FlashSector {
22 pub fn contains(&self, offset: usize) -> bool {
23 self.offset <= offset && offset < self.offset + self.size
24 }
25}
26
27pub struct FlashSectorIterator {
28 index: u8,
29 start_sector: u8,
30 start_offset: usize,
31 end_offset: usize,
32}
33
34impl FlashSectorIterator {
35 fn new(start_sector: u8, start_offset: usize, end_offset: usize) -> Self {
36 Self {
37 index: 0,
38 start_sector,
39 start_offset,
40 end_offset,
41 }
42 }
43}
44
45impl Iterator for FlashSectorIterator {
46 type Item = FlashSector;
47 fn next(&mut self) -> Option<Self::Item> {
48 if self.start_offset >= self.end_offset {
49 None
50 } else {
51 let size = match self.index {
52 8..=11 => 0x20000,
53 _ => 0x4000,
54 };
55
56 let sector = FlashSector {
57 number: self.start_sector + self.index,
58 offset: self.start_offset,
59 size,
60 };
61 self.index += 1;
62 self.start_offset += size;
63
64 Some(sector)
65 }
66 }
67}
68
69#[derive(Copy, Clone, Debug)]
70pub enum Margin {
71 Default,
72 Tight0,
73 Tight1,
74}
75
76#[derive(Copy, Clone, Debug)]
77pub enum User {
78 User0,
79 User1,
80 User2,
81}
82
83impl From<User> for u32 {
84 fn from(value: User) -> Self {
85 value as u32
86 }
87}
88
89#[derive(Copy, Clone, Debug)]
90pub enum Event {
91 VerifyAndOperationError,
92 CommandSequenceError,
93 ProtectionError,
94 SingleBitError,
95 DoubleBitError,
96 EndOfBusy,
97}
98
99pub struct Flash {
100 pub regs: FLASH0,
101}
102
103impl Flash {
106 pub fn new(flash: FLASH0) -> Self {
107 Self { regs: flash }
108 }
109
110 pub fn is_busy(&self) -> bool {
111 self.regs.fsr().read().pbusy().bit_is_set()
112 }
113
114 pub fn enable_wait_state_for_ecc(&self) {
116 self.regs.fcon().write(|w| w.wsecpf().set_bit());
117 }
118
119 pub fn disable_wait_state_for_ecc(&self) {
120 self.regs.fcon().write(|w| w.wsecpf().clear_bit());
121 }
122
123 pub fn enable_dynamic_idle(&self) {
124 self.regs.fcon().write(|w| w.idle().set_bit());
125 }
126
127 pub fn disable_dynamic_idle(&self) {
128 self.regs.fcon().write(|w| w.idle().clear_bit());
129 }
130
131 pub fn enable_sleep_request(&self) {
132 self.regs.fcon().write(|w| w.sleep().set_bit());
133 }
134
135 pub fn disable_sleep_request(&self) {
136 self.regs.fcon().write(|w| w.sleep().clear_bit());
137 }
138
139 pub fn set_margin(&self, margin: Margin) {
140 match margin {
141 Margin::Default => self.regs.marp().write(|w| w.margin().value1()),
143 Margin::Tight0 => self.regs.marp().write(|w| w.margin().value2()),
144 Margin::Tight1 => self.regs.marp().write(|w| w.margin().value3()),
145 };
146 }
147
148 pub fn enable_double_bit_error_trap(&self) {
149 self.regs.marp().write(|w| w.trapdis().clear_bit());
150 }
151
152 pub fn disable_double_bit_error_trap(&self) {
153 self.regs.marp().write(|w| w.trapdis().set_bit());
154 }
155
156 pub fn set_wait_states(&self, wait_states: u8) {
157 self.regs
159 .fcon()
160 .write(|w| unsafe { w.wspflash().bits(wait_states) });
161 }
162
163 pub fn install_bmi(&self) {
164 unimplemented!();
165 }
166
167 pub fn install_protection(&self, user: User, mask: u32, password0: u32, password1: u32) {
168 self.enter_page_mode_command();
170 self.load_page_command(mask, 0);
171 self.load_page_command(mask, 0);
172 self.load_page_command(password0, password1);
173 self.load_page_command(password0, password1);
174 let mut index = 0;
175
176 while index < 56 {
177 self.load_page_command(0, 0);
178 index += 2;
179 }
180
181 let start_address = (UCB0 + (user as u32 * BYTES_PER_UCB)) as *mut u32;
182
183 self.write_ucb_page_command(start_address);
184
185 while self.regs.fsr().read().pbusy().bit_is_set() {}
186 }
187
188 pub fn confirm_protection(&self, user: User) {
189 self.enter_page_mode_command();
191 self.load_page_command(PROTECTION_CONFIRM_CODE, 0);
192 self.load_page_command(PROTECTION_CONFIRM_CODE, 0);
193 let mut index = 0;
194
195 while index < 60 {
196 self.load_page_command(0, 0);
197 index += 2;
198 }
199
200 let start_address = (UNCACHED_BASE + (user as u32 * 1024) + 512) as *mut u32;
201
202 self.write_ucb_page_command(start_address);
203
204 while self.regs.fsr().read().pbusy().bit_is_set() {}
205 }
206
207 pub fn verify_read_protection(&self, password0: u32, password1: u32) -> bool {
208 let result = if self.regs.fsr().read().proin().bit_is_set() {
209 self.clear_status();
210 self.disable_read_protection_command(password0, password1);
211 self.regs.fsr().read().rprodis().bit_is_set()
212 } else {
213 false
214 };
215
216 result
217 }
218
219 pub fn verify_write_protection(
220 &self,
221 user: User,
222 _mask: u32,
223 password0: u32,
224 password1: u32,
225 ) -> bool {
226 let mut result = false;
227 let wproinx = match user {
228 User::User0 => self.regs.fsr().read().wproin0().bit_is_set(),
229 User::User1 => self.regs.fsr().read().wproin1().bit_is_set(),
230 User::User2 => self.regs.fsr().read().wproin2().bit_is_set(),
231 };
232
233 if wproinx {
234 self.clear_status();
235 self.disable_sector_write_protection_command(user, password0, password1);
236 let wprodisx = match user {
237 User::User0 => self.regs.fsr().read().wprodis0().bit_is_set(),
238 User::User1 => self.regs.fsr().read().wprodis1().bit_is_set(),
239 User::User2 => false, };
241
242 result = wprodisx && self.regs.fsr().read().bits() == (_mask & 0xFFFF7FFF);
243 }
244
245 result
246 }
247
248 pub fn resume_protection(&self) {
249 let address1 = (UNCACHED_BASE + 0x5554) as *mut u32;
250 unsafe {
251 *address1 = 0x5E;
252 }
253 }
254
255 pub fn repair_physical_sector(&self) {
256 self.clear_status();
257 self.repair_physical_sector_command();
258 }
259
260 pub fn erase_physical_sector(&self, address: *mut u32) {
261 self.clear_status();
262 self.erase_physical_sector_command(address);
263 while self.regs.fsr().read().pbusy().bit_is_set() {}
264 }
265
266 pub fn erase_ucb(&self, ucb_start_address: *mut u32) {
267 let address1 = (UNCACHED_BASE + 0x5554) as *mut u32;
268 let address2 = (UNCACHED_BASE + 0xAAA8) as *mut u32;
269
270 unsafe {
271 *address1 = 0xAA;
272 *address2 = 0x55;
273 *address1 = 0x80;
274 *address1 = 0xAA;
275 *address2 = 0x55;
276 *ucb_start_address = 0xC0;
277 }
278
279 while self.regs.fsr().read().pbusy().bit_is_set() {}
280 }
281
282 pub fn reset(&self) {
284 let address1 = (UNCACHED_BASE + 0x5554) as *mut u32;
285 unsafe {
286 *address1 = 0xF0;
287 }
288 }
289
290 fn enter_page_mode_command(&self) {
291 let address = (UNCACHED_BASE + 0x5554) as *mut u32;
292
293 unsafe {
294 *address = 0x50;
295 }
296 }
297
298 fn load_page_command(&self, low_word: u32, high_word: u32) {
299 let address_low = (UNCACHED_BASE + 0x55F0) as *mut u32;
300 let address_high = (UNCACHED_BASE + 0x55F4) as *mut u32;
301
302 unsafe {
303 *address_low = low_word;
304 *address_high = high_word;
305 }
306 }
307
308 fn write_page_command(&self, start_address: *mut u32) {
309 let address1 = (UNCACHED_BASE + 0x5554) as *mut u32;
310 let address2 = (UNCACHED_BASE + 0xAAA8) as *mut u32;
311
312 unsafe {
313 *address1 = 0xAA;
314 *address2 = 0x55;
315 *address1 = 0xA0;
316 *start_address = 0xAA;
317 }
318 }
319
320 fn write_ucb_page_command(&self, start_address: *mut u32) {
321 let address1 = (UNCACHED_BASE + 0x5554) as *mut u32;
322 let address2 = (UNCACHED_BASE + 0xAAA8) as *mut u32;
323
324 unsafe {
325 *address1 = 0xAA;
326 *address2 = 0x55;
327 *address1 = 0xC0;
328 *start_address = 0xAA;
329 }
330 }
331
332 fn erase_sector_command(&self, start_address: *mut u32) {
333 let address1 = (UNCACHED_BASE + 0x5554) as *mut u32;
334 let address2 = (UNCACHED_BASE + 0xAAA8) as *mut u32;
335
336 unsafe {
337 *address1 = 0xAA;
338 *address2 = 0x55;
339 *address1 = 0x80;
340 *address1 = 0xAA;
341 *address2 = 0x55;
342 *start_address = 0x30;
343 }
344 }
345
346 fn disable_sector_write_protection_command(&self, user: User, password0: u32, password1: u32) {
347 let address1 = (UNCACHED_BASE + 0x5554) as *mut u32;
348 let address2 = (UNCACHED_BASE + 0xAAA8) as *mut u32;
349 let address3 = (UNCACHED_BASE + 0x553C) as *mut u32;
350 let address4 = (UNCACHED_BASE + 0x5558) as *mut u32;
351
352 unsafe {
353 *address1 = 0xAA;
354 *address2 = 0x55;
355 *address3 = user as u32;
356 *address2 = password0;
357 *address2 = password1;
358 *address4 = 0x05;
359 }
360 }
361
362 fn disable_read_protection_command(&self, password0: u32, password1: u32) {
363 let address1 = (UNCACHED_BASE + 0x5554) as *mut u32;
364 let address2 = (UNCACHED_BASE + 0xAAA8) as *mut u32;
365 let address3 = (UNCACHED_BASE + 0x553C) as *mut u32;
366 let address4 = (UNCACHED_BASE + 0x5558) as *mut u32;
367
368 unsafe {
369 *address1 = 0x55;
370 *address2 = 0xAA;
371 *address3 = 0x00;
372 *address2 = password0;
373 *address2 = password1;
374 *address4 = 0x08;
375 }
376 }
377
378 fn erase_physical_sector_command(&self, start_address: *mut u32) {
379 let address1 = (UNCACHED_BASE + 0x5554) as *mut u32;
380 let address2 = (UNCACHED_BASE + 0xAAA8) as *mut u32;
381
382 unsafe {
383 *address1 = 0xAA;
384 *address2 = 0x55;
385 *address1 = 0x80;
386 *address1 = 0xAA;
387 *address2 = 0x55;
388 *start_address = 0x40;
389 }
390 }
391
392 fn repair_physical_sector_command(&self) {
395 let address1 = (UNCACHED_BASE + 0x5554) as *mut u32;
396 let address2 = (UNCACHED_BASE + 0xAAA8) as *mut u32;
397 let sector4 = (UNCACHED_BASE + 0x10000) as *mut u32;
398
399 unsafe {
400 *address1 = 0xAA;
401 *address2 = 0x55;
402 *address1 = 0x80;
403 *address1 = 0xAA;
404 *address2 = 0x55;
405 *sector4 = 0x40;
406 }
407 }
408
409 pub fn clear_status(&self) {
410 let address = (UNCACHED_BASE + 0x5554) as *mut u32;
411 unsafe {
412 *address = 0xF5;
413 }
414 }
415
416 pub fn get_status(&self) -> u32 {
417 self.regs.fsr().read().bits()
418 }
419
420 pub fn enable_event(&self, event: Event) {
421 match event {
422 Event::VerifyAndOperationError => self.regs.fcon().write(|w| w.voperm().set_bit()),
423 Event::CommandSequenceError => self.regs.fcon().write(|w| w.sqerm().set_bit()),
424 Event::ProtectionError => self.regs.fcon().write(|w| w.proerm().set_bit()),
425 Event::SingleBitError => self.regs.fcon().write(|w| w.pfsberm().set_bit()),
426 Event::DoubleBitError => self.regs.fcon().write(|w| w.pfdberm().set_bit()),
427 Event::EndOfBusy => self.regs.fcon().write(|w| w.eobm().set_bit()),
428 };
429 }
430
431 pub fn disable_event(&self, event: Event) {
432 match event {
433 Event::VerifyAndOperationError => self.regs.fcon().write(|w| w.voperm().clear_bit()),
434 Event::CommandSequenceError => self.regs.fcon().write(|w| w.sqerm().clear_bit()),
435 Event::ProtectionError => self.regs.fcon().write(|w| w.proerm().clear_bit()),
436 Event::SingleBitError => self.regs.fcon().write(|w| w.pfsberm().clear_bit()),
437 Event::DoubleBitError => self.regs.fcon().write(|w| w.pfdberm().clear_bit()),
438 Event::EndOfBusy => self.regs.fcon().write(|w| w.eobm().clear_bit()),
439 };
440 }
441
442 pub fn program_page(&self, address: *mut u32, data: PageData) {
443 let mut index = 0;
444
445 self.clear_status();
446 self.enter_page_mode_command();
447
448 while index < data.len() {
449 self.load_page_command(data[index], data[index + 1]);
450 index += 2;
451 }
452 self.write_page_command(address);
453
454 while self.regs.fsr().read().pbusy().bit_is_set() {}
455 }
456
457 pub fn erase_sector(&self, address: *mut u32) {
458 self.clear_status();
459 self.erase_sector_command(address);
460 while self.regs.fsr().read().pbusy().bit_is_set() {}
461 }
462}