aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/flash
diff options
context:
space:
mode:
authorRasmus Melchior Jacobsen <[email protected]>2023-05-25 20:55:12 +0200
committerRasmus Melchior Jacobsen <[email protected]>2023-05-25 20:55:12 +0200
commitb412784a7aea102ef53744fbb11d473fa3c0c984 (patch)
tree165888ae10601ac15a37a17f2b19af7eadfa772d /embassy-stm32/src/flash
parent8073bf22e92791618e1a11c58901f5b98ff002d1 (diff)
Add runtime checks for errata 2.2.11
Diffstat (limited to 'embassy-stm32/src/flash')
-rw-r--r--embassy-stm32/src/flash/common.rs3
-rw-r--r--embassy-stm32/src/flash/f4.rs73
2 files changed, 75 insertions, 1 deletions
diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs
index 547e30312..3eb4a0f18 100644
--- a/embassy-stm32/src/flash/common.rs
+++ b/embassy-stm32/src/flash/common.rs
@@ -85,6 +85,9 @@ pub(super) fn read_blocking(base: u32, size: u32, offset: u32, bytes: &mut [u8])
85 return Err(Error::Size); 85 return Err(Error::Size);
86 } 86 }
87 87
88 #[cfg(flash_f4)]
89 family::assert_not_corrupted_read();
90
88 let start_address = base + offset; 91 let start_address = base + offset;
89 let flash_data = unsafe { core::slice::from_raw_parts(start_address as *const u8, bytes.len()) }; 92 let flash_data = unsafe { core::slice::from_raw_parts(start_address as *const u8, bytes.len()) };
90 bytes.copy_from_slice(flash_data); 93 bytes.copy_from_slice(flash_data);
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs
index e8ac95ae2..488584212 100644
--- a/embassy-stm32/src/flash/f4.rs
+++ b/embassy-stm32/src/flash/f4.rs
@@ -380,6 +380,77 @@ fn get_result(sr: Sr) -> Result<(), Error> {
380 } 380 }
381} 381}
382 382
383pub(crate) fn assert_not_corrupted_read() {
384 #[allow(unused)]
385 const REVISION_3: u16 = 0x2001;
386
387 #[cfg(any(
388 feature = "stm32f427ai",
389 feature = "stm32f427ii",
390 feature = "stm32f427vi",
391 feature = "stm32f427zi",
392 feature = "stm32f429ai",
393 feature = "stm32f429bi",
394 feature = "stm32f429ii",
395 feature = "stm32f429ni",
396 feature = "stm32f429vi",
397 feature = "stm32f429zi",
398 feature = "stm32f437ai",
399 feature = "stm32f437ii",
400 feature = "stm32f437vi",
401 feature = "stm32f437zi",
402 feature = "stm32f439ai",
403 feature = "stm32f439bi",
404 feature = "stm32f439ii",
405 feature = "stm32f439ni",
406 feature = "stm32f439vi",
407 feature = "stm32f439zi",
408 ))]
409 if unsafe { pac::DBGMCU.idcode().read().rev_id() < REVISION_3 && pa12_is_output_pull_low() } {
410 panic!("Read corruption for stm32f42xxI and stm32f43xxI when PA12 is in use for chips below revision 3, see errata 2.2.11");
411 }
412
413 #[cfg(any(
414 feature = "stm32f427ag",
415 feature = "stm32f427ig",
416 feature = "stm32f427vg",
417 feature = "stm32f427zg",
418 feature = "stm32f429ag",
419 feature = "stm32f429bg",
420 feature = "stm32f429ig",
421 feature = "stm32f429ng",
422 feature = "stm32f429vg",
423 feature = "stm32f429zg",
424 feature = "stm32f437ig",
425 feature = "stm32f437vg",
426 feature = "stm32f437zg",
427 feature = "stm32f439bg",
428 feature = "stm32f439ig",
429 feature = "stm32f439ng",
430 feature = "stm32f439vg",
431 feature = "stm32f439zg",
432 ))]
433 if unsafe {
434 pac::FLASH.optcr().read().db1m()
435 && pac::DBGMCU.idcode().read().rev_id() < REVISION_3
436 && pa12_is_output_pull_low()
437 } {
438 panic!("Read corruption for stm32f42xxG and stm32f43xxG in dual bank mode when PA12 is in use for chips below revision 3, see errata 2.2.11");
439 }
440}
441
442#[allow(unused)]
443fn pa12_is_output_pull_low() -> bool {
444 use pac::gpio::vals;
445 use pac::GPIOA;
446 const PIN: usize = 12;
447 unsafe {
448 GPIOA.moder().read().moder(PIN) == vals::Moder::OUTPUT
449 && GPIOA.pupdr().read().pupdr(PIN) == vals::Pupdr::PULLDOWN
450 && GPIOA.odr().read().odr(PIN) == vals::Odr::LOW
451 }
452}
453
383#[cfg(test)] 454#[cfg(test)]
384mod tests { 455mod tests {
385 use super::*; 456 use super::*;
@@ -387,7 +458,7 @@ mod tests {
387 458
388 #[test] 459 #[test]
389 #[cfg(stm32f429)] 460 #[cfg(stm32f429)]
390 fn can_get_sector_single_bank() { 461 fn can_get_sector() {
391 const SMALL_SECTOR_SIZE: u32 = 16 * 1024; 462 const SMALL_SECTOR_SIZE: u32 = 16 * 1024;
392 const MEDIUM_SECTOR_SIZE: u32 = 64 * 1024; 463 const MEDIUM_SECTOR_SIZE: u32 = 64 * 1024;
393 const LARGE_SECTOR_SIZE: u32 = 128 * 1024; 464 const LARGE_SECTOR_SIZE: u32 = 128 * 1024;