diff options
| author | Philip A Reimer <[email protected]> | 2022-04-01 22:22:41 -0600 |
|---|---|---|
| committer | Philip A Reimer <[email protected]> | 2022-04-01 22:42:43 -0600 |
| commit | 1f59f8e7d0a6e89a8a2eba2a9fcac0c0657672dc (patch) | |
| tree | 3e31bca6bbf5dda8cf677caf23b6244f43508d30 | |
| parent | a9e63167e1ec230ca3d28da771378f5f4936a840 (diff) | |
add pllsai1 and allow for 120Mhz clock on stm32l4+
| -rw-r--r-- | embassy-stm32/src/rcc/l4.rs | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 68b960d7c..3b4c786f6 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs | |||
| @@ -55,6 +55,9 @@ impl Default for MSIRange { | |||
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | pub type PLL48Div = PLLClkDiv; | 57 | pub type PLL48Div = PLLClkDiv; |
| 58 | pub type PLLSAI1RDiv = PLLClkDiv; | ||
| 59 | pub type PLLSAI1QDiv = PLLClkDiv; | ||
| 60 | pub type PLLSAI1PDiv = PLLClkDiv; | ||
| 58 | 61 | ||
| 59 | /// PLL divider | 62 | /// PLL divider |
| 60 | #[derive(Clone, Copy)] | 63 | #[derive(Clone, Copy)] |
| @@ -265,6 +268,13 @@ pub struct Config { | |||
| 265 | pub ahb_pre: AHBPrescaler, | 268 | pub ahb_pre: AHBPrescaler, |
| 266 | pub apb1_pre: APBPrescaler, | 269 | pub apb1_pre: APBPrescaler, |
| 267 | pub apb2_pre: APBPrescaler, | 270 | pub apb2_pre: APBPrescaler, |
| 271 | pub pllsai1: Option<( | ||
| 272 | PLLMul, | ||
| 273 | PLLSrcDiv, | ||
| 274 | Option<PLLSAI1RDiv>, | ||
| 275 | Option<PLLSAI1QDiv>, | ||
| 276 | Option<PLLSAI1PDiv>, | ||
| 277 | )>, | ||
| 268 | } | 278 | } |
| 269 | 279 | ||
| 270 | impl Default for Config { | 280 | impl Default for Config { |
| @@ -275,6 +285,7 @@ impl Default for Config { | |||
| 275 | ahb_pre: AHBPrescaler::NotDivided, | 285 | ahb_pre: AHBPrescaler::NotDivided, |
| 276 | apb1_pre: APBPrescaler::NotDivided, | 286 | apb1_pre: APBPrescaler::NotDivided, |
| 277 | apb2_pre: APBPrescaler::NotDivided, | 287 | apb2_pre: APBPrescaler::NotDivided, |
| 288 | pllsai1: None, | ||
| 278 | } | 289 | } |
| 279 | } | 290 | } |
| 280 | } | 291 | } |
| @@ -315,7 +326,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 315 | (freq.0, Sw::HSE) | 326 | (freq.0, Sw::HSE) |
| 316 | } | 327 | } |
| 317 | ClockSrc::PLL(src, div, prediv, mul, pll48div) => { | 328 | ClockSrc::PLL(src, div, prediv, mul, pll48div) => { |
| 318 | let freq = match src { | 329 | let src_freq = match src { |
| 319 | PLLSource::HSE(freq) => { | 330 | PLLSource::HSE(freq) => { |
| 320 | // Enable HSE | 331 | // Enable HSE |
| 321 | RCC.cr().write(|w| w.set_hseon(true)); | 332 | RCC.cr().write(|w| w.set_hseon(true)); |
| @@ -334,8 +345,11 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 334 | RCC.cr().modify(|w| w.set_pllon(false)); | 345 | RCC.cr().modify(|w| w.set_pllon(false)); |
| 335 | while RCC.cr().read().pllrdy() {} | 346 | while RCC.cr().read().pllrdy() {} |
| 336 | 347 | ||
| 337 | let freq = (freq / prediv.to_div() * mul.to_mul()) / div.to_div(); | 348 | let freq = (src_freq / prediv.to_div() * mul.to_mul()) / div.to_div(); |
| 338 | 349 | ||
| 350 | #[cfg(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx))] | ||
| 351 | assert!(freq <= 120_000_000); | ||
| 352 | #[cfg(not(any(stm32l4px, stm32l4qx, stm32l4rx, stm32l4sx)))] | ||
| 339 | assert!(freq <= 80_000_000); | 353 | assert!(freq <= 80_000_000); |
| 340 | 354 | ||
| 341 | RCC.pllcfgr().write(move |w| { | 355 | RCC.pllcfgr().write(move |w| { |
| @@ -356,6 +370,33 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 356 | }); | 370 | }); |
| 357 | } | 371 | } |
| 358 | 372 | ||
| 373 | if let Some((mul, prediv, r_div, q_div, p_div)) = config.pllsai1 { | ||
| 374 | RCC.pllsai1cfgr().write(move |w| { | ||
| 375 | w.set_pllsai1n(mul.into()); | ||
| 376 | w.set_pllsai1m(prediv.into()); | ||
| 377 | if let Some(r_div) = r_div { | ||
| 378 | w.set_pllsai1r(r_div.into()); | ||
| 379 | w.set_pllsai1ren(true); | ||
| 380 | } | ||
| 381 | if let Some(q_div) = q_div { | ||
| 382 | w.set_pllsai1q(q_div.into()); | ||
| 383 | w.set_pllsai1qen(true); | ||
| 384 | let freq = (src_freq / prediv.to_div() * mul.to_mul()) / q_div.to_div(); | ||
| 385 | if freq == 48_000_000 { | ||
| 386 | RCC.ccipr().modify(|w| { | ||
| 387 | w.set_clk48sel(0b1); | ||
| 388 | }); | ||
| 389 | } | ||
| 390 | } | ||
| 391 | if let Some(p_div) = p_div { | ||
| 392 | w.set_pllsai1pdiv(p_div.into()); | ||
| 393 | w.set_pllsai1pen(true); | ||
| 394 | } | ||
| 395 | }); | ||
| 396 | |||
| 397 | RCC.cr().modify(|w| w.set_pllsai1on(true)); | ||
| 398 | } | ||
| 399 | |||
| 359 | // Enable PLL | 400 | // Enable PLL |
| 360 | RCC.cr().modify(|w| w.set_pllon(true)); | 401 | RCC.cr().modify(|w| w.set_pllon(true)); |
| 361 | while !RCC.cr().read().pllrdy() {} | 402 | while !RCC.cr().read().pllrdy() {} |
