1use crate::stm32::{flash, FLASH};
4
5use core::convert::TryInto;
6
7pub const FLASH_START: u32 = 0x0800_0000;
8pub const FLASH_END: u32 = 0x080F_FFFF;
9
10const _RDPRT_KEY: u16 = 0x00A5;
11const KEY1: u32 = 0x45670123;
12const KEY2: u32 = 0xCDEF89AB;
13
14pub const SZ_1K: u32 = 1024;
15
16pub type Result<T> = core::result::Result<T, Error>;
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
19pub enum Error {
20 AddressLargerThanFlash,
21 AddressMisaligned,
22 LengthNotMultiple2,
23 LengthTooLong,
24 EraseError,
25 ProgrammingError,
26 WriteError,
27 VerifyError,
28 UnlockError,
29 LockError,
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
33pub enum FlashSize {
34 Sz16K = 16,
35 Sz32K = 32,
36 Sz64K = 64,
37 Sz128K = 128,
38 Sz256K = 256,
39 Sz384K = 384,
40 Sz512K = 512,
41 Sz768K = 768,
42 Sz1M = 1024,
43}
44impl FlashSize {
45 const fn kbytes(self) -> u32 {
46 SZ_1K * self as u32
47 }
48}
49
50pub struct FlashWriter<'a, const SECTOR_SZ_KB: u32> {
51 flash: &'a mut Parts,
52 flash_sz: FlashSize,
53 verify: bool,
54}
55impl<'a, const SECTOR_SZ_KB: u32> FlashWriter<'a, SECTOR_SZ_KB> {
56 fn unlock(&mut self) -> Result<()> {
57 while self.flash.sr.sr().read().bsy().bit_is_set() {}
59
60 unsafe {
66 self.flash.keyr.keyr().write(|w| w.keyr().bits(KEY1));
67 }
68 unsafe {
69 self.flash.keyr.keyr().write(|w| w.keyr().bits(KEY2));
70 }
71
72 match self.flash.cr.cr().read().lock().bit_is_clear() {
74 true => Ok(()),
75 false => Err(Error::UnlockError),
76 }
77 }
78
79 fn lock(&mut self) -> Result<()> {
80 while self.flash.sr.sr().read().bsy().bit_is_set() {}
82
83 self.flash.cr.cr().modify(|_, w| w.lock().set_bit());
85
86 match self.flash.cr.cr().read().lock().bit_is_set() {
88 true => Ok(()),
89 false => Err(Error::LockError),
90 }
91 }
92
93 fn valid_address(&self, offset: u32) -> Result<()> {
94 if FLASH_START
95 .checked_add(offset)
96 .ok_or(Error::AddressLargerThanFlash)?
97 > FLASH_END
98 {
99 Err(Error::AddressLargerThanFlash)
100 } else if offset & 0x1 != 0 {
101 Err(Error::AddressMisaligned)
102 } else {
103 Ok(())
104 }
105 }
106
107 fn valid_length(&self, offset: u32, length: usize) -> Result<()> {
108 if offset
109 .checked_add(length as u32)
110 .ok_or(Error::LengthTooLong)?
111 > self.flash_sz.kbytes() as u32
112 {
113 Err(Error::LengthTooLong)
114 } else if length & 0x1 != 0 {
115 Err(Error::LengthNotMultiple2)
116 } else {
117 Ok(())
118 }
119 }
120
121 pub fn page_erase(&mut self, start_offset: u32) -> Result<()> {
123 self.valid_address(start_offset)?;
124
125 self.unlock()?;
127
128 self.flash.cr.cr().modify(|_, w| w.per().set_bit());
130
131 let page = start_offset / (SECTOR_SZ_KB as u32);
132
133 unsafe {
139 self.flash
140 .cr
141 .cr()
142 .write(|w| w.pnb().bits(page.try_into().unwrap()));
143 }
144
145 self.flash.cr.cr().modify(|_, w| w.strt().set_bit());
147
148 while self.flash.sr.sr().read().bsy().bit_is_set() {}
150
151 let sr = self.flash.sr.sr().read();
153
154 self.flash.cr.cr().modify(|_, w| w.per().clear_bit());
156
157 self.lock()?;
159
160 if sr.wrperr().bit_is_set() {
161 self.flash.sr.sr().modify(|_, w| w.wrperr().set_bit());
162 Err(Error::EraseError)
163 } else {
164 if self.verify {
165 let size = SECTOR_SZ_KB;
171 let start = start_offset & !(size - 1);
172 for idx in (start..start + size).step_by(2) {
173 let write_address = (FLASH_START + idx as u32) as *const u16;
174 let verify: u16 = unsafe { core::ptr::read_volatile(write_address) };
175 if verify != 0xFFFF {
176 return Err(Error::VerifyError);
177 }
178 }
179 }
180
181 Ok(())
182 }
183 }
184
185 pub fn erase(&mut self, start_offset: u32, length: usize) -> Result<()> {
187 self.valid_length(start_offset, length)?;
188
189 for offset in
191 (start_offset..start_offset + length as u32).step_by(SECTOR_SZ_KB.try_into().unwrap())
192 {
193 self.page_erase(offset)?;
194 }
195
196 Ok(())
198 }
199
200 pub fn read(&self, offset: u32, length: usize) -> Result<&[u8]> {
202 self.valid_address(offset)?;
203
204 if offset + length as u32 > self.flash_sz.kbytes() as u32 {
205 return Err(Error::LengthTooLong);
206 }
207
208 let address = (FLASH_START + offset) as *const _;
209
210 Ok(
211 unsafe { core::slice::from_raw_parts(address, length) },
217 )
218 }
219
220 pub fn write(&mut self, offset: u32, data: &[u8]) -> Result<()> {
222 self.valid_length(offset, data.len())?;
223
224 self.unlock()?;
226
227 for idx in (0..data.len()).step_by(2) {
228 self.valid_address(offset + idx as u32)?;
229
230 let write_address = (FLASH_START + offset + idx as u32) as *mut u16;
231
232 self.flash.cr.cr().modify(|_, w| w.pg().set_bit());
234
235 while self.flash.sr.sr().read().bsy().bit_is_set() {}
236
237 let hword: u16 = (data[idx] as u16) | (data[idx + 1] as u16) << 8;
240
241 unsafe { core::ptr::write_volatile(write_address, hword) };
243
244 while self.flash.sr.sr().read().bsy().bit_is_set() {}
246
247 self.flash.cr.cr().modify(|_, w| w.pg().clear_bit());
249
250 if self.flash.sr.sr().read().pgaerr().bit_is_set() {
252 self.flash.sr.sr().modify(|_, w| w.pgaerr().clear_bit());
253
254 self.lock()?;
255 return Err(Error::ProgrammingError);
256 } else if self.flash.sr.sr().read().wrperr().bit_is_set() {
257 self.flash.sr.sr().modify(|_, w| w.wrperr().clear_bit());
258
259 self.lock()?;
260 return Err(Error::WriteError);
261 } else if self.verify {
262 let verify: u16 = unsafe { core::ptr::read_volatile(write_address) };
265 if verify != hword {
266 self.lock()?;
267 return Err(Error::VerifyError);
268 }
269 }
270 }
271
272 self.lock()?;
274 Ok(())
275 }
276
277 pub fn change_verification(&mut self, verify: bool) {
288 self.verify = verify;
289 }
290}
291
292pub trait FlashExt {
294 fn constrain(self) -> Parts;
296}
297
298impl FlashExt for FLASH {
299 fn constrain(self) -> Parts {
300 Parts {
301 acr: ACR { _0: () },
302 cr: CR { _0: () },
303 eccr: ECCR { _0: () },
304 keyr: KEYR { _0: () },
305 _optkeyr: OPTKEYR { _0: () },
306 _optr: OPTR { _0: () },
307 _pcrop1sr: PCROP1SR { _0: () },
308 _pcrop1er: PCROP1ER { _0: () },
309 pdkeyr: PDKEYR { _0: () },
310 sec1r: SEC1R { _0: () },
311 sr: SR { _0: () },
312 _wrp1ar: WRP1AR { _0: () },
313 _wrp1br: WRP1BR { _0: () },
314 }
315 }
316}
317
318pub struct Parts {
320 pub acr: ACR,
322
323 pub(crate) cr: CR,
325
326 pub(crate) eccr: ECCR,
328
329 pub(crate) keyr: KEYR,
331
332 pub(crate) _optkeyr: OPTKEYR,
334
335 pub(crate) _optr: OPTR,
337
338 pub(crate) _pcrop1sr: PCROP1SR,
340
341 pub(crate) _pcrop1er: PCROP1ER,
343
344 pub(crate) pdkeyr: PDKEYR,
346
347 pub(crate) sec1r: SEC1R,
349
350 pub(crate) sr: SR,
352
353 pub(crate) _wrp1ar: WRP1AR,
355
356 pub(crate) _wrp1br: WRP1BR,
358}
359impl Parts {
360 #[cfg(any(feature = "stm32g431", feature = "stm32g441",))]
361 pub fn writer(&mut self, flash_sz: FlashSize) -> FlashWriter<{ 2 * SZ_1K }> {
362 FlashWriter {
363 flash: self,
364 flash_sz,
365 verify: true,
366 }
367 }
368 #[cfg(any(
369 feature = "stm32g471",
370 feature = "stm32g473",
371 feature = "stm32g474",
372 feature = "stm32g483",
373 feature = "stm32g484",
374 feature = "stm32g491",
375 feature = "stm32g4a1",
376 ))]
377 pub fn writer(&mut self, flash_sz: FlashSize) -> FlashWriter<{ 4 * SZ_1K }> {
378 FlashWriter {
379 flash: self,
380 flash_sz,
381 verify: true,
382 }
383 }
384}
385
386pub struct ACR {
388 _0: (),
389}
390
391#[allow(dead_code)]
392impl ACR {
393 pub(crate) fn acr(&mut self) -> &flash::ACR {
394 unsafe { &(*FLASH::ptr()).acr }
396 }
397}
398
399pub struct CR {
401 _0: (),
402}
403
404#[allow(dead_code)]
405impl CR {
406 pub(crate) fn cr(&mut self) -> &flash::CR {
407 unsafe { &(*FLASH::ptr()).cr }
409 }
410}
411
412pub struct ECCR {
414 _0: (),
415}
416
417#[allow(dead_code)]
418impl ECCR {
419 pub(crate) fn eccr(&mut self) -> &flash::ECCR {
420 unsafe { &(*FLASH::ptr()).eccr }
422 }
423}
424
425pub struct KEYR {
427 _0: (),
428}
429
430#[allow(dead_code)]
431impl KEYR {
432 pub(crate) fn keyr(&mut self) -> &flash::KEYR {
433 unsafe { &(*FLASH::ptr()).keyr }
435 }
436}
437
438pub struct OPTKEYR {
440 _0: (),
441}
442
443#[allow(dead_code)]
444impl OPTKEYR {
445 pub(crate) fn optkeyr(&mut self) -> &flash::OPTKEYR {
446 unsafe { &(*FLASH::ptr()).optkeyr }
448 }
449}
450
451pub struct OPTR {
453 _0: (),
454}
455
456#[allow(dead_code)]
457impl OPTR {
458 pub(crate) fn optr(&mut self) -> &flash::OPTR {
459 unsafe { &(*FLASH::ptr()).optr }
461 }
462}
463
464pub struct PCROP1SR {
466 _0: (),
467}
468
469#[allow(dead_code)]
470impl PCROP1SR {
471 pub(crate) fn pcrop1sr(&mut self) -> &flash::PCROP1SR {
472 unsafe { &(*FLASH::ptr()).pcrop1sr }
474 }
475}
476
477pub struct PCROP1ER {
479 _0: (),
480}
481
482#[allow(dead_code)]
483impl PCROP1ER {
484 pub(crate) fn pcrop1er(&mut self) -> &flash::PCROP1ER {
485 unsafe { &(*FLASH::ptr()).pcrop1er }
487 }
488}
489
490pub struct PDKEYR {
492 _0: (),
493}
494
495#[allow(dead_code)]
496impl PDKEYR {
497 pub(crate) fn pdkeyr(&mut self) -> &flash::PDKEYR {
498 unsafe { &(*FLASH::ptr()).pdkeyr }
500 }
501}
502
503pub struct SEC1R {
505 _0: (),
506}
507
508#[allow(dead_code)]
509impl SEC1R {
510 pub(crate) fn sec1r(&mut self) -> &flash::SEC1R {
511 unsafe { &(*FLASH::ptr()).sec1r }
513 }
514}
515
516pub struct SR {
518 _0: (),
519}
520
521#[allow(dead_code)]
522impl SR {
523 pub(crate) fn sr(&mut self) -> &flash::SR {
524 unsafe { &(*FLASH::ptr()).sr }
526 }
527}
528
529pub struct WRP1AR {
531 _0: (),
532}
533
534#[allow(dead_code)]
535impl WRP1AR {
536 pub(crate) fn wrp1ar(&mut self) -> &flash::WRP1AR {
537 unsafe { &(*FLASH::ptr()).wrp1ar }
539 }
540}
541
542pub struct WRP1BR {
544 _0: (),
545}
546
547#[allow(dead_code)]
548impl WRP1BR {
549 pub(crate) fn wrp1br(&mut self) -> &flash::WRP1BR {
550 unsafe { &(*FLASH::ptr()).wrp1br }
552 }
553}