{"record":{"id":"2ba11410e253b70a","repo":"embassy-rs/embassy","slug":"read-corruption-for-stm32f42xxg-and-stm32f43xxg-in","errorCode":null,"errorMessage":"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","messagePattern":"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","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"embassy-stm32/src/flash/f4.rs","lineNumber":275,"sourceCode":"        feature = \"stm32f427vg\",\n        feature = \"stm32f427zg\",\n        feature = \"stm32f429ag\",\n        feature = \"stm32f429bg\",\n        feature = \"stm32f429ig\",\n        feature = \"stm32f429ng\",\n        feature = \"stm32f429vg\",\n        feature = \"stm32f429zg\",\n        feature = \"stm32f437ig\",\n        feature = \"stm32f437vg\",\n        feature = \"stm32f437zg\",\n        feature = \"stm32f439bg\",\n        feature = \"stm32f439ig\",\n        feature = \"stm32f439ng\",\n        feature = \"stm32f439vg\",\n        feature = \"stm32f439zg\",\n    ))]\n    if second_bank_read && pac::DBGMCU.idcode().read().rev_id() < REVISION_3 && !pa12_is_output_pull_low() {\n        panic!(\n            \"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\"\n        );\n    }\n}\n\n#[allow(unused)]\nfn pa12_is_output_pull_low() -> bool {\n    use pac::GPIOA;\n    use pac::gpio::vals;\n    const PIN: usize = 12;\n    GPIOA.moder().read().moder(PIN) == vals::Moder::Output\n        && GPIOA.pupdr().read().pupdr(PIN) == vals::Pupdr::PullDown\n        && GPIOA.odr().read().odr(PIN) == vals::Odr::Low\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-stm32/src/flash/f4.rs#L257-L293","documentation":"Same errata 2.2.11 as the I-variant case, but for STM32F42x/43xG 1MB parts when the flash is in dual-bank mode: reading the second bank with rev_id below revision 3 while PA12 is not an output driven low corrupts reads. Embassy panics to avoid returning silently corrupted data.","triggerScenarios":"Second-bank flash read on stm32f42xxG/stm32f43xxG with rev_id < REVISION_3, dual-bank mode active, and PA12 not configured as output-pull-low.","commonSituations":"1MB F4 chips configured dual-bank via the db1m option byte, PA12 used for USB or GPIO, flash operations on early silicon revisions.","solutions":["Drive PA12 as a low output before any flash access on affected revisions.","Use silicon revision 3+ parts where errata 2.2.11 is fixed.","Reconfigure the option bytes to single-bank mode (db1m) so second-bank reads never occur, if 1MB single-bank fits your needs.","Pick a different pin for USB/GPIO functions so PA12 stays tied low during flash operations."],"exampleFix":"// before\nlet mut flash = Flash::new(p.FLASH); // dual-bank G variant, PA12 in use, rev<3: panics\n// after\nlet mut pa12 = Output::new(p.PA12, Level::Low, Speed::Low);\ndrop(pa12); // ensure PA12 is output-low before flash use\nlet mut flash = Flash::new(p.FLASH);","handlingStrategy":"validation","validationCode":"// guard: only perform second-bank reads when safe\nfn second_bank_read_safe(rev_id: u16, pa12_low: bool, dual_bank: bool) -> bool {\n    !(dual_bank && rev_id < 3 && !pa12_low)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid PA12 (USB D+) duty on 1MB dual-bank F42x/43xG parts below rev 3","Use single-bank option-byte config when dual-bank is not required","Verify chip revision early in bring-up"],"tags":["rust","embassy","embedded","stm32","flash","hardware-errata"],"backgroundTag":"unsupported-platform","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}