diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-04-12 21:42:36 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-04-12 21:42:36 +0000 |
| commit | 6d0e6d563dfd900a56ee6b6b3cf48a2af53c6cd4 (patch) | |
| tree | b92b609e8a6323a3d4c88cd4eef6b2ff22e313df | |
| parent | 5d48153bd752af283ced3621aa7e75ed6a67a0a2 (diff) | |
| parent | 8f6fccf012f76ba264042381b351f874735ca35e (diff) | |
Merge #714
714: add more clock options for l4 and l5 r=Dirbaio a=ant32
- added an assert so it panics if pll48div is not 48Mhz
- added MSI as a clock source for PLL
- removed hsi48 option for MCUs mentioned in l4 rcc presentation
- copied some code from l4 to l5, but don't have a way of testing it.
Co-authored-by: Philip A Reimer <[email protected]>
| -rw-r--r-- | embassy-stm32/src/rcc/l4.rs | 21 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l5.rs | 28 | ||||
| -rw-r--r-- | examples/stm32l4/src/bin/rng.rs | 7 |
3 files changed, 51 insertions, 5 deletions
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index 549adc82e..3b84fb9b8 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs | |||
| @@ -96,6 +96,7 @@ pub enum APBPrescaler { | |||
| 96 | pub enum PLLSource { | 96 | pub enum PLLSource { |
| 97 | HSI16, | 97 | HSI16, |
| 98 | HSE(Hertz), | 98 | HSE(Hertz), |
| 99 | MSI(MSIRange), | ||
| 99 | } | 100 | } |
| 100 | 101 | ||
| 101 | seq_macro::seq!(N in 8..=86 { | 102 | seq_macro::seq!(N in 8..=86 { |
| @@ -192,6 +193,7 @@ impl From<PLLSource> for Pllsrc { | |||
| 192 | match val { | 193 | match val { |
| 193 | PLLSource::HSI16 => Pllsrc::HSI16, | 194 | PLLSource::HSI16 => Pllsrc::HSI16, |
| 194 | PLLSource::HSE(_) => Pllsrc::HSE, | 195 | PLLSource::HSE(_) => Pllsrc::HSE, |
| 196 | PLLSource::MSI(_) => Pllsrc::MSI, | ||
| 195 | } | 197 | } |
| 196 | } | 198 | } |
| 197 | } | 199 | } |
| @@ -275,6 +277,7 @@ pub struct Config { | |||
| 275 | Option<PLLSAI1QDiv>, | 277 | Option<PLLSAI1QDiv>, |
| 276 | Option<PLLSAI1PDiv>, | 278 | Option<PLLSAI1PDiv>, |
| 277 | )>, | 279 | )>, |
| 280 | #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] | ||
| 278 | pub hsi48: bool, | 281 | pub hsi48: bool, |
| 279 | } | 282 | } |
| 280 | 283 | ||
| @@ -287,6 +290,7 @@ impl Default for Config { | |||
| 287 | apb1_pre: APBPrescaler::NotDivided, | 290 | apb1_pre: APBPrescaler::NotDivided, |
| 288 | apb2_pre: APBPrescaler::NotDivided, | 291 | apb2_pre: APBPrescaler::NotDivided, |
| 289 | pllsai1: None, | 292 | pllsai1: None, |
| 293 | #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] | ||
| 290 | hsi48: false, | 294 | hsi48: false, |
| 291 | } | 295 | } |
| 292 | } | 296 | } |
| @@ -341,6 +345,18 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 341 | while !RCC.cr().read().hsirdy() {} | 345 | while !RCC.cr().read().hsirdy() {} |
| 342 | HSI16_FREQ | 346 | HSI16_FREQ |
| 343 | } | 347 | } |
| 348 | PLLSource::MSI(range) => { | ||
| 349 | // Enable MSI | ||
| 350 | RCC.cr().write(|w| { | ||
| 351 | let bits: Msirange = range.into(); | ||
| 352 | w.set_msirange(bits); | ||
| 353 | w.set_msipllen(false); // should be turned on if LSE is started | ||
| 354 | w.set_msirgsel(true); | ||
| 355 | w.set_msion(true); | ||
| 356 | }); | ||
| 357 | while !RCC.cr().read().msirdy() {} | ||
| 358 | range.into() | ||
| 359 | } | ||
| 344 | }; | 360 | }; |
| 345 | 361 | ||
| 346 | // Disable PLL | 362 | // Disable PLL |
| @@ -366,7 +382,9 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 366 | }); | 382 | }); |
| 367 | 383 | ||
| 368 | // Enable as clock source for USB, RNG if PLL48 divisor is provided | 384 | // Enable as clock source for USB, RNG if PLL48 divisor is provided |
| 369 | if pll48div.is_some() { | 385 | if let Some(pll48div) = pll48div { |
| 386 | let freq = (src_freq / prediv.to_div() * mul.to_mul()) / pll48div.to_div(); | ||
| 387 | assert!(freq == 48_000_000); | ||
| 370 | RCC.ccipr().modify(|w| { | 388 | RCC.ccipr().modify(|w| { |
| 371 | w.set_clk48sel(0b10); | 389 | w.set_clk48sel(0b10); |
| 372 | }); | 390 | }); |
| @@ -408,6 +426,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 408 | } | 426 | } |
| 409 | }; | 427 | }; |
| 410 | 428 | ||
| 429 | #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] | ||
| 411 | if config.hsi48 { | 430 | if config.hsi48 { |
| 412 | RCC.crrcr().modify(|w| w.set_hsi48on(true)); | 431 | RCC.crrcr().modify(|w| w.set_hsi48on(true)); |
| 413 | while !RCC.crrcr().read().hsi48rdy() {} | 432 | while !RCC.crrcr().read().hsi48rdy() {} |
diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs index a502cb4e2..dba5ec3b7 100644 --- a/embassy-stm32/src/rcc/l5.rs +++ b/embassy-stm32/src/rcc/l5.rs | |||
| @@ -96,6 +96,7 @@ pub enum APBPrescaler { | |||
| 96 | pub enum PLLSource { | 96 | pub enum PLLSource { |
| 97 | HSI16, | 97 | HSI16, |
| 98 | HSE(Hertz), | 98 | HSE(Hertz), |
| 99 | MSI(MSIRange), | ||
| 99 | } | 100 | } |
| 100 | 101 | ||
| 101 | seq_macro::seq!(N in 8..=86 { | 102 | seq_macro::seq!(N in 8..=86 { |
| @@ -192,6 +193,7 @@ impl From<PLLSource> for Pllsrc { | |||
| 192 | match val { | 193 | match val { |
| 193 | PLLSource::HSI16 => Pllsrc::HSI16, | 194 | PLLSource::HSI16 => Pllsrc::HSI16, |
| 194 | PLLSource::HSE(_) => Pllsrc::HSE, | 195 | PLLSource::HSE(_) => Pllsrc::HSE, |
| 196 | PLLSource::MSI(_) => Pllsrc::MSI, | ||
| 195 | } | 197 | } |
| 196 | } | 198 | } |
| 197 | } | 199 | } |
| @@ -275,6 +277,7 @@ pub struct Config { | |||
| 275 | Option<PLLSAI1QDiv>, | 277 | Option<PLLSAI1QDiv>, |
| 276 | Option<PLLSAI1PDiv>, | 278 | Option<PLLSAI1PDiv>, |
| 277 | )>, | 279 | )>, |
| 280 | pub hsi48: bool, | ||
| 278 | } | 281 | } |
| 279 | 282 | ||
| 280 | impl Default for Config { | 283 | impl Default for Config { |
| @@ -286,6 +289,7 @@ impl Default for Config { | |||
| 286 | apb1_pre: APBPrescaler::NotDivided, | 289 | apb1_pre: APBPrescaler::NotDivided, |
| 287 | apb2_pre: APBPrescaler::NotDivided, | 290 | apb2_pre: APBPrescaler::NotDivided, |
| 288 | pllsai1: None, | 291 | pllsai1: None, |
| 292 | hsi48: false, | ||
| 289 | } | 293 | } |
| 290 | } | 294 | } |
| 291 | } | 295 | } |
| @@ -339,6 +343,18 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 339 | while !RCC.cr().read().hsirdy() {} | 343 | while !RCC.cr().read().hsirdy() {} |
| 340 | HSI16_FREQ | 344 | HSI16_FREQ |
| 341 | } | 345 | } |
| 346 | PLLSource::MSI(range) => { | ||
| 347 | // Enable MSI | ||
| 348 | RCC.cr().write(|w| { | ||
| 349 | let bits: Msirange = range.into(); | ||
| 350 | w.set_msirange(bits); | ||
| 351 | w.set_msipllen(false); // should be turned on if LSE is started | ||
| 352 | w.set_msirgsel(true); | ||
| 353 | w.set_msion(true); | ||
| 354 | }); | ||
| 355 | while !RCC.cr().read().msirdy() {} | ||
| 356 | range.into() | ||
| 357 | } | ||
| 342 | }; | 358 | }; |
| 343 | 359 | ||
| 344 | // Disable PLL | 360 | // Disable PLL |
| @@ -364,7 +380,9 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 364 | }); | 380 | }); |
| 365 | 381 | ||
| 366 | // Enable as clock source for USB, RNG if PLL48 divisor is provided | 382 | // Enable as clock source for USB, RNG if PLL48 divisor is provided |
| 367 | if pll48div.is_some() { | 383 | if let Some(pll48div) = pll48div { |
| 384 | let freq = (src_freq / prediv.to_div() * mul.to_mul()) / pll48div.to_div(); | ||
| 385 | assert!(freq == 48_000_000); | ||
| 368 | RCC.ccipr1().modify(|w| { | 386 | RCC.ccipr1().modify(|w| { |
| 369 | w.set_clk48msel(0b10); | 387 | w.set_clk48msel(0b10); |
| 370 | }); | 388 | }); |
| @@ -406,6 +424,14 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 406 | } | 424 | } |
| 407 | }; | 425 | }; |
| 408 | 426 | ||
| 427 | if config.hsi48 { | ||
| 428 | RCC.crrcr().modify(|w| w.set_hsi48on(true)); | ||
| 429 | while !RCC.crrcr().read().hsi48rdy() {} | ||
| 430 | |||
| 431 | // Enable as clock source for USB, RNG and SDMMC | ||
| 432 | RCC.ccipr1().modify(|w| w.set_clk48msel(0)); | ||
| 433 | } | ||
| 434 | |||
| 409 | // Set flash wait states | 435 | // Set flash wait states |
| 410 | // VCORE Range 0 (performance), others TODO | 436 | // VCORE Range 0 (performance), others TODO |
| 411 | FLASH.acr().modify(|w| { | 437 | FLASH.acr().modify(|w| { |
diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs index 5f75c1ff1..03773e61b 100644 --- a/examples/stm32l4/src/bin/rng.rs +++ b/examples/stm32l4/src/bin/rng.rs | |||
| @@ -12,12 +12,13 @@ use panic_probe as _; | |||
| 12 | 12 | ||
| 13 | fn config() -> Config { | 13 | fn config() -> Config { |
| 14 | let mut config = Config::default(); | 14 | let mut config = Config::default(); |
| 15 | // 72Mhz clock (16 / 1 * 18 / 4) | ||
| 15 | config.rcc.mux = ClockSrc::PLL( | 16 | config.rcc.mux = ClockSrc::PLL( |
| 16 | PLLSource::HSI16, | 17 | PLLSource::HSI16, |
| 17 | PLLClkDiv::Div2, | 18 | PLLClkDiv::Div4, |
| 18 | PLLSrcDiv::Div1, | 19 | PLLSrcDiv::Div1, |
| 19 | PLLMul::Mul8, | 20 | PLLMul::Mul18, |
| 20 | Some(PLLClkDiv::Div2), | 21 | Some(PLLClkDiv::Div6), // 48Mhz (16 / 1 * 18 / 6) |
| 21 | ); | 22 | ); |
| 22 | config | 23 | config |
| 23 | } | 24 | } |
