From 9cf75d7eac11cacf545f1848d06808fc9fb745e1 Mon Sep 17 00:00:00 2001 From: Christian Enderle Date: Thu, 17 Oct 2024 19:40:27 +0200 Subject: [PATCH] stm32/flash: add support for l5 --- embassy-stm32/src/flash/l.rs | 134 ++++++++++++++++++++++++++------- embassy-stm32/src/flash/mod.rs | 7 +- 2 files changed, 110 insertions(+), 31 deletions(-) diff --git a/embassy-stm32/src/flash/l.rs b/embassy-stm32/src/flash/l.rs index a0bfeb395..ea00bf499 100644 --- a/embassy-stm32/src/flash/l.rs +++ b/embassy-stm32/src/flash/l.rs @@ -23,6 +23,9 @@ pub(crate) unsafe fn lock() { w.set_prglock(true); w.set_pelock(true); }); + + #[cfg(any(flash_l5))] + pac::FLASH.nscr().modify(|w| w.set_nslock(true)); } pub(crate) unsafe fn unlock() { @@ -46,6 +49,14 @@ pub(crate) unsafe fn unlock() { pac::FLASH.prgkeyr().write_value(0x1314_1516); } } + + #[cfg(any(flash_l5))] + { + if pac::FLASH.nscr().read().nslock() { + pac::FLASH.nskeyr().write_value(0x4567_0123); + pac::FLASH.nskeyr().write_value(0xCDEF_89AB); + } + } } pub(crate) unsafe fn enable_blocking_write() { @@ -53,11 +64,17 @@ pub(crate) unsafe fn enable_blocking_write() { #[cfg(any(flash_wl, flash_wb, flash_l4))] pac::FLASH.cr().write(|w| w.set_pg(true)); + + #[cfg(any(flash_l5))] + pac::FLASH.nscr().write(|w| w.set_nspg(true)); } pub(crate) unsafe fn disable_blocking_write() { #[cfg(any(flash_wl, flash_wb, flash_l4))] pac::FLASH.cr().write(|w| w.set_pg(false)); + + #[cfg(any(flash_l5))] + pac::FLASH.nscr().write(|w| w.set_nspg(false)); } pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { @@ -84,13 +101,25 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E write_volatile(sector.start as *mut u32, 0xFFFFFFFF); } - #[cfg(any(flash_wl, flash_wb, flash_l4))] + #[cfg(any(flash_wl, flash_wb, flash_l4, flash_l5))] { let idx = (sector.start - super::FLASH_BASE as u32) / super::BANK1_REGION.erase_size as u32; #[cfg(flash_l4)] let (idx, bank) = if idx > 255 { (idx - 256, true) } else { (idx, false) }; + #[cfg(flash_l5)] + let (idx, bank) = if pac::FLASH.optr().read().dbank() { + if idx > 255 { + (idx - 256, Some(true)) + } else { + (idx, Some(false)) + } + } else { + (idx, None) + }; + + #[cfg(not(flash_l5))] pac::FLASH.cr().modify(|w| { w.set_per(true); w.set_pnb(idx as u8); @@ -101,6 +130,16 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E #[cfg(any(flash_l4))] w.set_bker(bank); }); + + #[cfg(flash_l5)] + pac::FLASH.nscr().modify(|w| { + w.set_nsper(true); + w.set_nspnb(idx as u8); + if let Some(bank) = bank { + w.set_nsbker(bank); + } + w.set_nsstrt(true); + }); } let ret: Result<(), Error> = wait_ready_blocking(); @@ -108,6 +147,9 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E #[cfg(any(flash_wl, flash_wb, flash_l4))] pac::FLASH.cr().modify(|w| w.set_per(false)); + #[cfg(any(flash_l5))] + pac::FLASH.nscr().modify(|w| w.set_nsper(false)); + #[cfg(any(flash_l0, flash_l1))] pac::FLASH.pecr().modify(|w| { w.set_erase(false); @@ -121,42 +163,78 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E pub(crate) unsafe fn clear_all_err() { // read and write back the same value. // This clears all "write 1 to clear" bits. + #[cfg(not(flash_l5))] pac::FLASH.sr().modify(|_| {}); + + #[cfg(flash_l5)] + pac::FLASH.nssr().modify(|_| {}); } unsafe fn wait_ready_blocking() -> Result<(), Error> { loop { - let sr = pac::FLASH.sr().read(); + #[cfg(not(flash_l5))] + { + let sr = pac::FLASH.sr().read(); - if !sr.bsy() { - #[cfg(any(flash_wl, flash_wb, flash_l4))] - if sr.progerr() { - return Err(Error::Prog); + if !sr.bsy() { + #[cfg(any(flash_wl, flash_wb, flash_l4))] + if sr.progerr() { + return Err(Error::Prog); + } + + if sr.wrperr() { + return Err(Error::Protected); + } + + if sr.pgaerr() { + return Err(Error::Unaligned); + } + + if sr.sizerr() { + return Err(Error::Size); + } + + #[cfg(any(flash_wl, flash_wb, flash_l4))] + if sr.miserr() { + return Err(Error::Miss); + } + + #[cfg(any(flash_wl, flash_wb, flash_l4))] + if sr.pgserr() { + return Err(Error::Seq); + } + + return Ok(()); } + } - if sr.wrperr() { - return Err(Error::Protected); + #[cfg(flash_l5)] + { + let nssr = pac::FLASH.nssr().read(); + + if !nssr.nsbsy() { + if nssr.nsprogerr() { + return Err(Error::Prog); + } + + if nssr.nswrperr() { + return Err(Error::Protected); + } + + if nssr.nspgaerr() { + return Err(Error::Unaligned); + } + + if nssr.nssizerr() { + return Err(Error::Size); + } + + if nssr.nspgserr() { + return Err(Error::Seq); + } + + return Ok(()); } - - if sr.pgaerr() { - return Err(Error::Unaligned); - } - - if sr.sizerr() { - return Err(Error::Size); - } - - #[cfg(any(flash_wl, flash_wb, flash_l4))] - if sr.miserr() { - return Err(Error::Miss); - } - - #[cfg(any(flash_wl, flash_wb, flash_l4))] - if sr.pgserr() { - return Err(Error::Seq); - } - - return Ok(()); } } } diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs index bce638db0..d64a1c28a 100644 --- a/embassy-stm32/src/flash/mod.rs +++ b/embassy-stm32/src/flash/mod.rs @@ -91,7 +91,7 @@ pub enum FlashBank { Bank2 = 1, } -#[cfg_attr(any(flash_l0, flash_l1, flash_l4, flash_wl, flash_wb), path = "l.rs")] +#[cfg_attr(any(flash_l0, flash_l1, flash_l4, flash_l5, flash_wl, flash_wb), path = "l.rs")] #[cfg_attr(flash_f0, path = "f0.rs")] #[cfg_attr(any(flash_f1, flash_f3), path = "f1f3.rs")] #[cfg_attr(flash_f2, path = "f2.rs")] @@ -105,8 +105,9 @@ pub enum FlashBank { #[cfg_attr(flash_u0, path = "u0.rs")] #[cfg_attr( not(any( - flash_l0, flash_l1, flash_l4, flash_wl, flash_wb, flash_f0, flash_f1, flash_f2, flash_f3, flash_f4, flash_f7, - flash_g0, flash_g4c2, flash_g4c3, flash_g4c4, flash_h7, flash_h7ab, flash_u5, flash_h50, flash_u0 + flash_l0, flash_l1, flash_l4, flash_l5, flash_wl, flash_wb, flash_f0, flash_f1, flash_f2, flash_f3, flash_f4, + flash_f7, flash_g0, flash_g0, flash_g4c2, flash_g4c3, flash_g4c4, flash_h7, flash_h7ab, flash_u5, flash_h50, + flash_u0 )), path = "other.rs" )]