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