1use crate::pac::{flash, FLASH};
4
5pub const FLASH_START: u32 = 0x0800_0000;
6pub const FLASH_END: u32 = 0x080F_FFFF;
7
8const _RDPRT_KEY: u16 = 0x00A5;
9const KEY1: u32 = 0x45670123;
10const KEY2: u32 = 0xCDEF89AB;
11
12pub const SZ_1K: u16 = 1024;
13
14pub type Result<T> = core::result::Result<T, Error>;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
17pub enum Error {
18 AddressLargerThanFlash,
19 AddressMisaligned,
20 LengthNotMultiple2,
21 LengthTooLong,
22 EraseError,
23 ProgrammingError,
24 WriteError,
25 VerifyError,
26 UnlockError,
27 LockError,
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
31pub enum SectorSize {
32 Sz1K = 1,
33 Sz2K = 2,
34 Sz4K = 4,
35}
36impl SectorSize {
37 const fn kbytes(self) -> u16 {
38 SZ_1K * self as u16
39 }
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
43pub enum FlashSize {
44 Sz16K = 16,
45 Sz32K = 32,
46 Sz64K = 64,
47 Sz128K = 128,
48 Sz256K = 256,
49 Sz384K = 384,
50 Sz512K = 512,
51 Sz768K = 768,
52 Sz1M = 1024,
53}
54impl FlashSize {
55 const fn kbytes(self) -> u32 {
56 SZ_1K as u32 * self as u32
57 }
58}
59
60pub struct FlashWriter<'a> {
61 flash: &'a mut Parts,
62 sector_sz: SectorSize,
63 flash_sz: FlashSize,
64 verify: bool,
65}
66impl FlashWriter<'_> {
67 fn unlock(&mut self) -> Result<()> {
68 while self.flash.sr.sr().read().bsy().bit_is_set() {}
70
71 unsafe {
77 self.flash.keyr.keyr().write(|w| w.key().bits(KEY1));
78 }
79 unsafe {
80 self.flash.keyr.keyr().write(|w| w.key().bits(KEY2));
81 }
82
83 match self.flash.cr.cr().read().lock().bit_is_clear() {
85 true => Ok(()),
86 false => Err(Error::UnlockError),
87 }
88 }
89
90 fn lock(&mut self) -> Result<()> {
91 while self.flash.sr.sr().read().bsy().bit_is_set() {}
93
94 self.flash.cr.cr().modify(|_, w| w.lock().set_bit());
96
97 match self.flash.cr.cr().read().lock().bit_is_set() {
99 true => Ok(()),
100 false => Err(Error::LockError),
101 }
102 }
103
104 fn valid_address(&self, offset: u32) -> Result<()> {
105 if FLASH_START + offset > FLASH_END {
106 Err(Error::AddressLargerThanFlash)
107 } else if offset & 0x1 != 0 {
108 Err(Error::AddressMisaligned)
109 } else {
110 Ok(())
111 }
112 }
113
114 fn valid_length(&self, offset: u32, length: usize) -> Result<()> {
115 if offset + length as u32 > self.flash_sz.kbytes() {
116 Err(Error::LengthTooLong)
117 } else if length & 0x1 != 0 {
118 Err(Error::LengthNotMultiple2)
119 } else {
120 Ok(())
121 }
122 }
123
124 pub fn page_erase(&mut self, start_offset: u32) -> Result<()> {
126 self.valid_address(start_offset)?;
127
128 self.unlock()?;
130
131 self.flash.cr.cr().modify(|_, w| w.per().set_bit());
133
134 unsafe {
140 self.flash
141 .ar
142 .ar()
143 .write(|w| w.far().bits(FLASH_START + start_offset));
144 }
145
146 self.flash.cr.cr().modify(|_, w| w.strt().set_bit());
148
149 cortex_m::asm::nop();
155
156 while self.flash.sr.sr().read().bsy().bit_is_set() {}
158
159 let sr = self.flash.sr.sr().read();
161
162 self.flash.cr.cr().modify(|_, w| w.per().clear_bit());
164
165 self.lock()?;
167
168 if sr.wrprterr().bit_is_set() {
169 self.flash.sr.sr().modify(|_, w| w.wrprterr().bit(true));
171 Err(Error::EraseError)
172 } else {
173 if self.verify {
174 let size = self.sector_sz.kbytes() as u32;
180 let start = start_offset & !(size - 1);
181 for idx in (start..start + size).step_by(2) {
182 let write_address = (FLASH_START + idx) as *const u16;
183 let verify: u16 = unsafe { core::ptr::read_volatile(write_address) };
184 if verify != 0xFFFF {
185 return Err(Error::VerifyError);
186 }
187 }
188 }
189
190 Ok(())
191 }
192 }
193
194 pub fn erase(&mut self, start_offset: u32, length: usize) -> Result<()> {
196 self.valid_length(start_offset, length)?;
197
198 for offset in
200 (start_offset..start_offset + length as u32).step_by(self.sector_sz.kbytes() as usize)
201 {
202 self.page_erase(offset)?;
203 }
204
205 Ok(())
207 }
208
209 pub fn read(&self, offset: u32, length: usize) -> Result<&[u8]> {
211 self.valid_address(offset)?;
212
213 if offset + length as u32 > self.flash_sz.kbytes() {
214 return Err(Error::LengthTooLong);
215 }
216
217 let address = (FLASH_START + offset) as *const _;
218
219 Ok(
220 unsafe { core::slice::from_raw_parts(address, length) },
226 )
227 }
228
229 pub fn write(&mut self, offset: u32, data: &[u8]) -> Result<()> {
231 self.valid_length(offset, data.len())?;
232
233 self.unlock()?;
235
236 for idx in (0..data.len()).step_by(2) {
237 self.valid_address(offset + idx as u32)?;
238
239 let write_address = (FLASH_START + offset + idx as u32) as *mut u16;
240
241 self.flash.cr.cr().modify(|_, w| w.pg().set_bit());
243
244 while self.flash.sr.sr().read().bsy().bit_is_set() {}
245
246 let hword: u16 = (data[idx] as u16) | ((data[idx + 1] as u16) << 8);
249
250 unsafe { core::ptr::write_volatile(write_address, hword) };
252
253 while self.flash.sr.sr().read().bsy().bit_is_set() {}
255
256 self.flash.cr.cr().modify(|_, w| w.pg().clear_bit());
258
259 if self.flash.sr.sr().read().pgerr().bit_is_set() {
261 self.flash.sr.sr().modify(|_, w| w.pgerr().bit(true));
263
264 self.lock()?;
265 return Err(Error::ProgrammingError);
266 } else if self.flash.sr.sr().read().wrprterr().bit_is_set() {
267 self.flash.sr.sr().modify(|_, w| w.wrprterr().bit(true));
269
270 self.lock()?;
271 return Err(Error::WriteError);
272 } else if self.verify {
273 let verify: u16 = unsafe { core::ptr::read_volatile(write_address) };
276 if verify != hword {
277 self.lock()?;
278 return Err(Error::VerifyError);
279 }
280 }
281 }
282
283 self.lock()?;
285 Ok(())
286 }
287
288 pub fn change_verification(&mut self, verify: bool) {
299 self.verify = verify;
300 }
301}
302
303pub trait FlashExt {
305 fn constrain(self) -> Parts;
307}
308
309impl FlashExt for FLASH {
310 fn constrain(self) -> Parts {
311 Parts {
312 acr: ACR,
313 ar: AR,
314 cr: CR,
315 keyr: KEYR,
316 _obr: OBR,
317 _optkeyr: OPTKEYR,
318 sr: SR,
319 _wrpr: WRPR,
320 }
321 }
322}
323
324pub struct Parts {
326 pub acr: ACR,
328
329 pub(crate) ar: AR,
331
332 pub(crate) cr: CR,
334
335 pub(crate) keyr: KEYR,
337
338 pub(crate) _obr: OBR,
340
341 pub(crate) _optkeyr: OPTKEYR,
343
344 pub(crate) sr: SR,
346
347 pub(crate) _wrpr: WRPR,
349}
350impl Parts {
351 pub fn writer(&mut self, sector_sz: SectorSize, flash_sz: FlashSize) -> FlashWriter<'_> {
352 FlashWriter {
353 flash: self,
354 sector_sz,
355 flash_sz,
356 verify: true,
357 }
358 }
359}
360
361#[non_exhaustive]
363pub struct ACR;
364
365#[allow(dead_code)]
366impl ACR {
367 pub(crate) fn acr(&mut self) -> &flash::ACR {
368 unsafe { (*FLASH::ptr()).acr() }
370 }
371}
372
373#[non_exhaustive]
375pub struct AR;
376
377#[allow(dead_code)]
378impl AR {
379 pub(crate) fn ar(&mut self) -> &flash::AR {
380 unsafe { (*FLASH::ptr()).ar() }
382 }
383}
384
385#[non_exhaustive]
387pub struct CR;
388
389#[allow(dead_code)]
390impl CR {
391 pub(crate) fn cr(&mut self) -> &flash::CR {
392 unsafe { (*FLASH::ptr()).cr() }
394 }
395}
396
397#[non_exhaustive]
399pub struct KEYR;
400
401#[allow(dead_code)]
402impl KEYR {
403 pub(crate) fn keyr(&mut self) -> &flash::KEYR {
404 unsafe { (*FLASH::ptr()).keyr() }
406 }
407}
408
409#[non_exhaustive]
411pub struct OBR;
412
413#[allow(dead_code)]
414impl OBR {
415 pub(crate) fn obr(&mut self) -> &flash::OBR {
416 unsafe { (*FLASH::ptr()).obr() }
418 }
419}
420
421#[non_exhaustive]
423pub struct OPTKEYR;
424
425#[allow(dead_code)]
426impl OPTKEYR {
427 pub(crate) fn optkeyr(&mut self) -> &flash::OPTKEYR {
428 unsafe { (*FLASH::ptr()).optkeyr() }
430 }
431}
432
433#[non_exhaustive]
435pub struct SR;
436
437#[allow(dead_code)]
438impl SR {
439 pub(crate) fn sr(&mut self) -> &flash::SR {
440 unsafe { (*FLASH::ptr()).sr() }
442 }
443}
444
445#[non_exhaustive]
447pub struct WRPR;
448
449#[allow(dead_code)]
450impl WRPR {
451 pub(crate) fn wrpr(&mut self) -> &flash::WRPR {
452 unsafe { (*FLASH::ptr()).wrpr() }
454 }
455}