diff options
| author | Christian Enderle <[email protected]> | 2024-10-17 19:40:27 +0200 |
|---|---|---|
| committer | Christian Enderle <[email protected]> | 2024-10-17 20:17:01 +0200 |
| commit | 9cf75d7eac11cacf545f1848d06808fc9fb745e1 (patch) | |
| tree | c9594bb246f6a5fae0bfbaebf8c5fc809ae284b1 | |
| parent | 0225c2a0f2ac7fbca5fe1c4d048a09c70738bcb3 (diff) | |
stm32/flash: add support for l5
| -rw-r--r-- | embassy-stm32/src/flash/l.rs | 128 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/mod.rs | 7 |
2 files changed, 107 insertions, 28 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() { | |||
| 23 | w.set_prglock(true); | 23 | w.set_prglock(true); |
| 24 | w.set_pelock(true); | 24 | w.set_pelock(true); |
| 25 | }); | 25 | }); |
| 26 | |||
| 27 | #[cfg(any(flash_l5))] | ||
| 28 | pac::FLASH.nscr().modify(|w| w.set_nslock(true)); | ||
| 26 | } | 29 | } |
| 27 | 30 | ||
| 28 | pub(crate) unsafe fn unlock() { | 31 | pub(crate) unsafe fn unlock() { |
| @@ -46,6 +49,14 @@ pub(crate) unsafe fn unlock() { | |||
| 46 | pac::FLASH.prgkeyr().write_value(0x1314_1516); | 49 | pac::FLASH.prgkeyr().write_value(0x1314_1516); |
| 47 | } | 50 | } |
| 48 | } | 51 | } |
| 52 | |||
| 53 | #[cfg(any(flash_l5))] | ||
| 54 | { | ||
| 55 | if pac::FLASH.nscr().read().nslock() { | ||
| 56 | pac::FLASH.nskeyr().write_value(0x4567_0123); | ||
| 57 | pac::FLASH.nskeyr().write_value(0xCDEF_89AB); | ||
| 58 | } | ||
| 59 | } | ||
| 49 | } | 60 | } |
| 50 | 61 | ||
| 51 | pub(crate) unsafe fn enable_blocking_write() { | 62 | pub(crate) unsafe fn enable_blocking_write() { |
| @@ -53,11 +64,17 @@ pub(crate) unsafe fn enable_blocking_write() { | |||
| 53 | 64 | ||
| 54 | #[cfg(any(flash_wl, flash_wb, flash_l4))] | 65 | #[cfg(any(flash_wl, flash_wb, flash_l4))] |
| 55 | pac::FLASH.cr().write(|w| w.set_pg(true)); | 66 | pac::FLASH.cr().write(|w| w.set_pg(true)); |
| 67 | |||
| 68 | #[cfg(any(flash_l5))] | ||
| 69 | pac::FLASH.nscr().write(|w| w.set_nspg(true)); | ||
| 56 | } | 70 | } |
| 57 | 71 | ||
| 58 | pub(crate) unsafe fn disable_blocking_write() { | 72 | pub(crate) unsafe fn disable_blocking_write() { |
| 59 | #[cfg(any(flash_wl, flash_wb, flash_l4))] | 73 | #[cfg(any(flash_wl, flash_wb, flash_l4))] |
| 60 | pac::FLASH.cr().write(|w| w.set_pg(false)); | 74 | pac::FLASH.cr().write(|w| w.set_pg(false)); |
| 75 | |||
| 76 | #[cfg(any(flash_l5))] | ||
| 77 | pac::FLASH.nscr().write(|w| w.set_nspg(false)); | ||
| 61 | } | 78 | } |
| 62 | 79 | ||
| 63 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { | 80 | 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 | |||
| 84 | write_volatile(sector.start as *mut u32, 0xFFFFFFFF); | 101 | write_volatile(sector.start as *mut u32, 0xFFFFFFFF); |
| 85 | } | 102 | } |
| 86 | 103 | ||
| 87 | #[cfg(any(flash_wl, flash_wb, flash_l4))] | 104 | #[cfg(any(flash_wl, flash_wb, flash_l4, flash_l5))] |
| 88 | { | 105 | { |
| 89 | let idx = (sector.start - super::FLASH_BASE as u32) / super::BANK1_REGION.erase_size as u32; | 106 | let idx = (sector.start - super::FLASH_BASE as u32) / super::BANK1_REGION.erase_size as u32; |
| 90 | 107 | ||
| 91 | #[cfg(flash_l4)] | 108 | #[cfg(flash_l4)] |
| 92 | let (idx, bank) = if idx > 255 { (idx - 256, true) } else { (idx, false) }; | 109 | let (idx, bank) = if idx > 255 { (idx - 256, true) } else { (idx, false) }; |
| 93 | 110 | ||
| 111 | #[cfg(flash_l5)] | ||
| 112 | let (idx, bank) = if pac::FLASH.optr().read().dbank() { | ||
| 113 | if idx > 255 { | ||
| 114 | (idx - 256, Some(true)) | ||
| 115 | } else { | ||
| 116 | (idx, Some(false)) | ||
| 117 | } | ||
| 118 | } else { | ||
| 119 | (idx, None) | ||
| 120 | }; | ||
| 121 | |||
| 122 | #[cfg(not(flash_l5))] | ||
| 94 | pac::FLASH.cr().modify(|w| { | 123 | pac::FLASH.cr().modify(|w| { |
| 95 | w.set_per(true); | 124 | w.set_per(true); |
| 96 | w.set_pnb(idx as u8); | 125 | w.set_pnb(idx as u8); |
| @@ -101,6 +130,16 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E | |||
| 101 | #[cfg(any(flash_l4))] | 130 | #[cfg(any(flash_l4))] |
| 102 | w.set_bker(bank); | 131 | w.set_bker(bank); |
| 103 | }); | 132 | }); |
| 133 | |||
| 134 | #[cfg(flash_l5)] | ||
| 135 | pac::FLASH.nscr().modify(|w| { | ||
| 136 | w.set_nsper(true); | ||
| 137 | w.set_nspnb(idx as u8); | ||
| 138 | if let Some(bank) = bank { | ||
| 139 | w.set_nsbker(bank); | ||
| 140 | } | ||
| 141 | w.set_nsstrt(true); | ||
| 142 | }); | ||
| 104 | } | 143 | } |
| 105 | 144 | ||
| 106 | let ret: Result<(), Error> = wait_ready_blocking(); | 145 | let ret: Result<(), Error> = wait_ready_blocking(); |
| @@ -108,6 +147,9 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E | |||
| 108 | #[cfg(any(flash_wl, flash_wb, flash_l4))] | 147 | #[cfg(any(flash_wl, flash_wb, flash_l4))] |
| 109 | pac::FLASH.cr().modify(|w| w.set_per(false)); | 148 | pac::FLASH.cr().modify(|w| w.set_per(false)); |
| 110 | 149 | ||
| 150 | #[cfg(any(flash_l5))] | ||
| 151 | pac::FLASH.nscr().modify(|w| w.set_nsper(false)); | ||
| 152 | |||
| 111 | #[cfg(any(flash_l0, flash_l1))] | 153 | #[cfg(any(flash_l0, flash_l1))] |
| 112 | pac::FLASH.pecr().modify(|w| { | 154 | pac::FLASH.pecr().modify(|w| { |
| 113 | w.set_erase(false); | 155 | w.set_erase(false); |
| @@ -121,42 +163,78 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E | |||
| 121 | pub(crate) unsafe fn clear_all_err() { | 163 | pub(crate) unsafe fn clear_all_err() { |
| 122 | // read and write back the same value. | 164 | // read and write back the same value. |
| 123 | // This clears all "write 1 to clear" bits. | 165 | // This clears all "write 1 to clear" bits. |
| 166 | #[cfg(not(flash_l5))] | ||
| 124 | pac::FLASH.sr().modify(|_| {}); | 167 | pac::FLASH.sr().modify(|_| {}); |
| 168 | |||
| 169 | #[cfg(flash_l5)] | ||
| 170 | pac::FLASH.nssr().modify(|_| {}); | ||
| 125 | } | 171 | } |
| 126 | 172 | ||
| 127 | unsafe fn wait_ready_blocking() -> Result<(), Error> { | 173 | unsafe fn wait_ready_blocking() -> Result<(), Error> { |
| 128 | loop { | 174 | loop { |
| 129 | let sr = pac::FLASH.sr().read(); | 175 | #[cfg(not(flash_l5))] |
| 130 | 176 | { | |
| 131 | if !sr.bsy() { | 177 | let sr = pac::FLASH.sr().read(); |
| 132 | #[cfg(any(flash_wl, flash_wb, flash_l4))] | 178 | |
| 133 | if sr.progerr() { | 179 | if !sr.bsy() { |
| 134 | return Err(Error::Prog); | 180 | #[cfg(any(flash_wl, flash_wb, flash_l4))] |
| 181 | if sr.progerr() { | ||
| 182 | return Err(Error::Prog); | ||
| 183 | } | ||
| 184 | |||
| 185 | if sr.wrperr() { | ||
| 186 | return Err(Error::Protected); | ||
| 187 | } | ||
| 188 | |||
| 189 | if sr.pgaerr() { | ||
| 190 | return Err(Error::Unaligned); | ||
| 191 | } | ||
| 192 | |||
| 193 | if sr.sizerr() { | ||
| 194 | return Err(Error::Size); | ||
| 195 | } | ||
| 196 | |||
| 197 | #[cfg(any(flash_wl, flash_wb, flash_l4))] | ||
| 198 | if sr.miserr() { | ||
| 199 | return Err(Error::Miss); | ||
| 200 | } | ||
| 201 | |||
| 202 | #[cfg(any(flash_wl, flash_wb, flash_l4))] | ||
| 203 | if sr.pgserr() { | ||
| 204 | return Err(Error::Seq); | ||
| 205 | } | ||
| 206 | |||
| 207 | return Ok(()); | ||
| 135 | } | 208 | } |
| 209 | } | ||
| 136 | 210 | ||
| 137 | if sr.wrperr() { | 211 | #[cfg(flash_l5)] |
| 138 | return Err(Error::Protected); | 212 | { |
| 139 | } | 213 | let nssr = pac::FLASH.nssr().read(); |
| 140 | 214 | ||
| 141 | if sr.pgaerr() { | 215 | if !nssr.nsbsy() { |
| 142 | return Err(Error::Unaligned); | 216 | if nssr.nsprogerr() { |
| 143 | } | 217 | return Err(Error::Prog); |
| 218 | } | ||
| 144 | 219 | ||
| 145 | if sr.sizerr() { | 220 | if nssr.nswrperr() { |
| 146 | return Err(Error::Size); | 221 | return Err(Error::Protected); |
| 147 | } | 222 | } |
| 148 | 223 | ||
| 149 | #[cfg(any(flash_wl, flash_wb, flash_l4))] | 224 | if nssr.nspgaerr() { |
| 150 | if sr.miserr() { | 225 | return Err(Error::Unaligned); |
| 151 | return Err(Error::Miss); | 226 | } |
| 152 | } | ||
| 153 | 227 | ||
| 154 | #[cfg(any(flash_wl, flash_wb, flash_l4))] | 228 | if nssr.nssizerr() { |
| 155 | if sr.pgserr() { | 229 | return Err(Error::Size); |
| 156 | return Err(Error::Seq); | 230 | } |
| 157 | } | 231 | |
| 232 | if nssr.nspgserr() { | ||
| 233 | return Err(Error::Seq); | ||
| 234 | } | ||
| 158 | 235 | ||
| 159 | return Ok(()); | 236 | return Ok(()); |
| 237 | } | ||
| 160 | } | 238 | } |
| 161 | } | 239 | } |
| 162 | } | 240 | } |
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 { | |||
| 91 | Bank2 = 1, | 91 | Bank2 = 1, |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | #[cfg_attr(any(flash_l0, flash_l1, flash_l4, flash_wl, flash_wb), path = "l.rs")] | 94 | #[cfg_attr(any(flash_l0, flash_l1, flash_l4, flash_l5, flash_wl, flash_wb), path = "l.rs")] |
| 95 | #[cfg_attr(flash_f0, path = "f0.rs")] | 95 | #[cfg_attr(flash_f0, path = "f0.rs")] |
| 96 | #[cfg_attr(any(flash_f1, flash_f3), path = "f1f3.rs")] | 96 | #[cfg_attr(any(flash_f1, flash_f3), path = "f1f3.rs")] |
| 97 | #[cfg_attr(flash_f2, path = "f2.rs")] | 97 | #[cfg_attr(flash_f2, path = "f2.rs")] |
| @@ -105,8 +105,9 @@ pub enum FlashBank { | |||
| 105 | #[cfg_attr(flash_u0, path = "u0.rs")] | 105 | #[cfg_attr(flash_u0, path = "u0.rs")] |
| 106 | #[cfg_attr( | 106 | #[cfg_attr( |
| 107 | not(any( | 107 | not(any( |
| 108 | flash_l0, flash_l1, flash_l4, flash_wl, flash_wb, flash_f0, flash_f1, flash_f2, flash_f3, flash_f4, flash_f7, | 108 | flash_l0, flash_l1, flash_l4, flash_l5, flash_wl, flash_wb, flash_f0, flash_f1, flash_f2, flash_f3, flash_f4, |
| 109 | flash_g0, flash_g4c2, flash_g4c3, flash_g4c4, flash_h7, flash_h7ab, flash_u5, flash_h50, flash_u0 | 109 | flash_f7, flash_g0, flash_g0, flash_g4c2, flash_g4c3, flash_g4c4, flash_h7, flash_h7ab, flash_u5, flash_h50, |
| 110 | flash_u0 | ||
| 110 | )), | 111 | )), |
| 111 | path = "other.rs" | 112 | path = "other.rs" |
| 112 | )] | 113 | )] |
