diff options
| author | Rasmus Melchior Jacobsen <[email protected]> | 2023-05-25 20:55:12 +0200 |
|---|---|---|
| committer | Rasmus Melchior Jacobsen <[email protected]> | 2023-05-25 20:55:12 +0200 |
| commit | b412784a7aea102ef53744fbb11d473fa3c0c984 (patch) | |
| tree | 165888ae10601ac15a37a17f2b19af7eadfa772d /embassy-stm32 | |
| parent | 8073bf22e92791618e1a11c58901f5b98ff002d1 (diff) | |
Add runtime checks for errata 2.2.11
Diffstat (limited to 'embassy-stm32')
| -rw-r--r-- | embassy-stm32/src/flash/common.rs | 3 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/f4.rs | 73 |
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 | ||
| 383 | pub(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)] | ||
| 443 | fn 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)] |
| 384 | mod tests { | 455 | mod 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; |
