diff options
| author | Timo Kröger <[email protected]> | 2022-06-26 22:59:39 +0200 |
|---|---|---|
| committer | Timo Kröger <[email protected]> | 2022-08-26 15:44:58 +0200 |
| commit | 84240d49eaf208691d0785e060ee13a7a14f0671 (patch) | |
| tree | 2f4bf109dc5879ab0337173fe490b90b79d26ea0 | |
| parent | f31116cafaeea7746aec19903fb1c73adaea9ea6 (diff) | |
stm32wl: Fix RCC
* `MSIRGSEL = 1` was required for MSI accept the updated MSI range
* Reorder enable and clock switching to properly handle the jump from
the default 4MHz MSI to a higher MSI freuquency
| -rw-r--r-- | embassy-stm32/src/rcc/wl.rs | 116 |
1 files changed, 59 insertions, 57 deletions
diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 69c192c67..347674918 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs | |||
| @@ -202,54 +202,11 @@ impl Default for Config { | |||
| 202 | 202 | ||
| 203 | pub(crate) unsafe fn init(config: Config) { | 203 | pub(crate) unsafe fn init(config: Config) { |
| 204 | let (sys_clk, sw, vos) = match config.mux { | 204 | let (sys_clk, sw, vos) = match config.mux { |
| 205 | ClockSrc::HSI16 => { | 205 | ClockSrc::HSI16 => (HSI_FREQ.0, 0x01, VoltageScale::Range2), |
| 206 | // Enable HSI16 | 206 | ClockSrc::HSE32 => (HSE32_FREQ.0, 0x02, VoltageScale::Range1), |
| 207 | RCC.cr().write(|w| w.set_hsion(true)); | 207 | ClockSrc::MSI(range) => (range.freq(), 0x00, range.vos()), |
| 208 | while !RCC.cr().read().hsirdy() {} | ||
| 209 | |||
| 210 | (HSI_FREQ.0, 0x01, VoltageScale::Range2) | ||
| 211 | } | ||
| 212 | ClockSrc::HSE32 => { | ||
| 213 | // Enable HSE32 | ||
| 214 | RCC.cr().write(|w| { | ||
| 215 | w.set_hsebyppwr(true); | ||
| 216 | w.set_hseon(true); | ||
| 217 | }); | ||
| 218 | while !RCC.cr().read().hserdy() {} | ||
| 219 | |||
| 220 | (HSE32_FREQ.0, 0x02, VoltageScale::Range1) | ||
| 221 | } | ||
| 222 | ClockSrc::MSI(range) => { | ||
| 223 | RCC.cr().write(|w| { | ||
| 224 | w.set_msirange(range.into()); | ||
| 225 | w.set_msion(true); | ||
| 226 | }); | ||
| 227 | |||
| 228 | while !RCC.cr().read().msirdy() {} | ||
| 229 | |||
| 230 | (range.freq(), 0x00, range.vos()) | ||
| 231 | } | ||
| 232 | }; | 208 | }; |
| 233 | 209 | ||
| 234 | RCC.cfgr().modify(|w| { | ||
| 235 | w.set_sw(sw.into()); | ||
| 236 | if config.ahb_pre == AHBPrescaler::NotDivided { | ||
| 237 | w.set_hpre(0); | ||
| 238 | } else { | ||
| 239 | w.set_hpre(config.ahb_pre.into()); | ||
| 240 | } | ||
| 241 | w.set_ppre1(config.apb1_pre.into()); | ||
| 242 | w.set_ppre2(config.apb2_pre.into()); | ||
| 243 | }); | ||
| 244 | |||
| 245 | RCC.extcfgr().modify(|w| { | ||
| 246 | if config.shd_ahb_pre == AHBPrescaler::NotDivided { | ||
| 247 | w.set_shdhpre(0); | ||
| 248 | } else { | ||
| 249 | w.set_shdhpre(config.shd_ahb_pre.into()); | ||
| 250 | } | ||
| 251 | }); | ||
| 252 | |||
| 253 | let ahb_freq: u32 = match config.ahb_pre { | 210 | let ahb_freq: u32 = match config.ahb_pre { |
| 254 | AHBPrescaler::NotDivided => sys_clk, | 211 | AHBPrescaler::NotDivided => sys_clk, |
| 255 | pre => { | 212 | pre => { |
| @@ -288,16 +245,6 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 288 | } | 245 | } |
| 289 | }; | 246 | }; |
| 290 | 247 | ||
| 291 | let apb3_freq = shd_ahb_freq; | ||
| 292 | |||
| 293 | if config.enable_lsi { | ||
| 294 | let csr = RCC.csr().read(); | ||
| 295 | if !csr.lsion() { | ||
| 296 | RCC.csr().modify(|w| w.set_lsion(true)); | ||
| 297 | while !RCC.csr().read().lsirdy() {} | ||
| 298 | } | ||
| 299 | } | ||
| 300 | |||
| 301 | // Adjust flash latency | 248 | // Adjust flash latency |
| 302 | let flash_clk_src_freq: u32 = shd_ahb_freq; | 249 | let flash_clk_src_freq: u32 = shd_ahb_freq; |
| 303 | let ws = match vos { | 250 | let ws = match vos { |
| @@ -319,6 +266,61 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 319 | 266 | ||
| 320 | while FLASH.acr().read().latency() != ws {} | 267 | while FLASH.acr().read().latency() != ws {} |
| 321 | 268 | ||
| 269 | match config.mux { | ||
| 270 | ClockSrc::HSI16 => { | ||
| 271 | // Enable HSI16 | ||
| 272 | RCC.cr().write(|w| w.set_hsion(true)); | ||
| 273 | while !RCC.cr().read().hsirdy() {} | ||
| 274 | } | ||
| 275 | ClockSrc::HSE32 => { | ||
| 276 | // Enable HSE32 | ||
| 277 | RCC.cr().write(|w| { | ||
| 278 | w.set_hsebyppwr(true); | ||
| 279 | w.set_hseon(true); | ||
| 280 | }); | ||
| 281 | while !RCC.cr().read().hserdy() {} | ||
| 282 | } | ||
| 283 | ClockSrc::MSI(range) => { | ||
| 284 | let cr = RCC.cr().read(); | ||
| 285 | assert!(!cr.msion() || cr.msirdy()); | ||
| 286 | RCC.cr().write(|w| { | ||
| 287 | w.set_msirgsel(true); | ||
| 288 | w.set_msirange(range.into()); | ||
| 289 | w.set_msion(true); | ||
| 290 | }); | ||
| 291 | while !RCC.cr().read().msirdy() {} | ||
| 292 | } | ||
| 293 | } | ||
| 294 | |||
| 295 | RCC.extcfgr().modify(|w| { | ||
| 296 | if config.shd_ahb_pre == AHBPrescaler::NotDivided { | ||
| 297 | w.set_shdhpre(0); | ||
| 298 | } else { | ||
| 299 | w.set_shdhpre(config.shd_ahb_pre.into()); | ||
| 300 | } | ||
| 301 | }); | ||
| 302 | |||
| 303 | RCC.cfgr().modify(|w| { | ||
| 304 | w.set_sw(sw.into()); | ||
| 305 | if config.ahb_pre == AHBPrescaler::NotDivided { | ||
| 306 | w.set_hpre(0); | ||
| 307 | } else { | ||
| 308 | w.set_hpre(config.ahb_pre.into()); | ||
| 309 | } | ||
| 310 | w.set_ppre1(config.apb1_pre.into()); | ||
| 311 | w.set_ppre2(config.apb2_pre.into()); | ||
| 312 | }); | ||
| 313 | |||
| 314 | // TODO: switch voltage range | ||
| 315 | |||
| 316 | if config.enable_lsi { | ||
| 317 | let csr = RCC.csr().read(); | ||
| 318 | if !csr.lsion() { | ||
| 319 | RCC.csr().modify(|w| w.set_lsion(true)); | ||
| 320 | while !RCC.csr().read().lsirdy() {} | ||
| 321 | } | ||
| 322 | } | ||
| 323 | |||
| 322 | set_freqs(Clocks { | 324 | set_freqs(Clocks { |
| 323 | sys: Hertz(sys_clk), | 325 | sys: Hertz(sys_clk), |
| 324 | ahb1: Hertz(ahb_freq), | 326 | ahb1: Hertz(ahb_freq), |
| @@ -326,7 +328,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 326 | ahb3: Hertz(shd_ahb_freq), | 328 | ahb3: Hertz(shd_ahb_freq), |
| 327 | apb1: Hertz(apb1_freq), | 329 | apb1: Hertz(apb1_freq), |
| 328 | apb2: Hertz(apb2_freq), | 330 | apb2: Hertz(apb2_freq), |
| 329 | apb3: Hertz(apb3_freq), | 331 | apb3: Hertz(shd_ahb_freq), |
| 330 | apb1_tim: Hertz(apb1_tim_freq), | 332 | apb1_tim: Hertz(apb1_tim_freq), |
| 331 | apb2_tim: Hertz(apb2_tim_freq), | 333 | apb2_tim: Hertz(apb2_tim_freq), |
| 332 | }); | 334 | }); |
