From 4fe344ebc0f4e030ff7a03755f27e66e9ad0476f Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 13 Nov 2023 00:52:01 +0100 Subject: [PATCH 1/2] stm32/rcc: consistent casing and naming for PLL enums. --- embassy-stm32/src/rcc/f2.rs | 46 +++++++++---------- embassy-stm32/src/rcc/g0.rs | 14 +++--- embassy-stm32/src/rcc/g4.rs | 14 +++--- embassy-stm32/src/rcc/l0l1.rs | 10 ++-- embassy-stm32/src/rcc/l4l5.rs | 14 +++--- embassy-stm32/src/rcc/u5.rs | 22 ++++----- embassy-stm32/src/rcc/wba.rs | 8 ++-- examples/stm32f2/src/bin/pll.rs | 14 +++--- examples/stm32g4/src/bin/adc.rs | 4 +- examples/stm32g4/src/bin/pll.rs | 4 +- examples/stm32g4/src/bin/usb_serial.rs | 8 ++-- examples/stm32l4/src/bin/rng.rs | 4 +- examples/stm32l4/src/bin/rtc.rs | 2 +- .../src/bin/spe_adin1110_http_server.rs | 4 +- examples/stm32l4/src/bin/usb_serial.rs | 2 +- examples/stm32l5/src/bin/rng.rs | 4 +- examples/stm32l5/src/bin/usb_ethernet.rs | 2 +- examples/stm32l5/src/bin/usb_hid_mouse.rs | 2 +- examples/stm32l5/src/bin/usb_serial.rs | 2 +- examples/stm32u5/src/bin/usb_serial.rs | 2 +- examples/stm32wl/src/bin/lora_lorawan.rs | 2 +- examples/stm32wl/src/bin/lora_p2p_receive.rs | 2 +- examples/stm32wl/src/bin/lora_p2p_send.rs | 2 +- examples/stm32wl/src/bin/random.rs | 2 +- examples/stm32wl/src/bin/rtc.rs | 2 +- tests/stm32/src/common.rs | 30 ++++++------ 26 files changed, 111 insertions(+), 111 deletions(-) diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index 9a66e75a..00480222 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs @@ -1,7 +1,7 @@ use crate::pac::flash::vals::Latency; use crate::pac::rcc::vals::Sw; pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Pllm as PLLPreDiv, Plln as PLLMul, Pllp as PLLPDiv, Pllq as PLLQDiv, Pllsrc as PLLSrc, + Hpre as AHBPrescaler, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllsrc as PllSource, Ppre as APBPrescaler, }; use crate::pac::{FLASH, RCC}; @@ -35,30 +35,30 @@ pub enum HSESrc { } #[derive(Clone, Copy)] -pub struct PLLConfig { - pub pre_div: PLLPreDiv, - pub mul: PLLMul, - pub p_div: PLLPDiv, - pub q_div: PLLQDiv, +pub struct Pll { + pub pre_div: PllPreDiv, + pub mul: PllMul, + pub divp: PllPDiv, + pub divq: PllQDiv, } -impl Default for PLLConfig { +impl Default for Pll { fn default() -> Self { - PLLConfig { - pre_div: PLLPreDiv::DIV16, - mul: PLLMul::MUL192, - p_div: PLLPDiv::DIV2, - q_div: PLLQDiv::DIV4, + Pll { + pre_div: PllPreDiv::DIV16, + mul: PllMul::MUL192, + divp: PllPDiv::DIV2, + divq: PllQDiv::DIV4, } } } -impl PLLConfig { +impl Pll { pub fn clocks(&self, src_freq: Hertz) -> PLLClocks { let in_freq = src_freq / self.pre_div; let vco_freq = src_freq / self.pre_div * self.mul; - let main_freq = vco_freq / self.p_div; - let pll48_freq = vco_freq / self.q_div; + let main_freq = vco_freq / self.divp; + let pll48_freq = vco_freq / self.divq; PLLClocks { in_freq, vco_freq, @@ -172,8 +172,8 @@ impl VoltageScale { pub struct Config { pub hse: Option, pub hsi: bool, - pub pll_mux: PLLSrc, - pub pll: PLLConfig, + pub pll_mux: PllSource, + pub pll: Pll, pub mux: ClockSrc, pub voltage: VoltageScale, pub ahb_pre: AHBPrescaler, @@ -188,8 +188,8 @@ impl Default for Config { Config { hse: None, hsi: true, - pll_mux: PLLSrc::HSI, - pll: PLLConfig::default(), + pll_mux: PllSource::HSI, + pll: Pll::default(), voltage: VoltageScale::Range3, mux: ClockSrc::HSI, ahb_pre: AHBPrescaler::DIV1, @@ -217,13 +217,13 @@ pub(crate) unsafe fn init(config: Config) { } let pll_src_freq = match config.pll_mux { - PLLSrc::HSE => { + PllSource::HSE => { let hse_config = config .hse .unwrap_or_else(|| panic!("HSE must be configured to be used as PLL input")); hse_config.frequency } - PLLSrc::HSI => HSI_FREQ, + PllSource::HSI => HSI_FREQ, }; // Reference: STM32F215xx/217xx datasheet Table 33. Main PLL characteristics @@ -238,8 +238,8 @@ pub(crate) unsafe fn init(config: Config) { w.set_pllsrc(config.pll_mux); w.set_pllm(config.pll.pre_div); w.set_plln(config.pll.mul); - w.set_pllp(config.pll.p_div); - w.set_pllq(config.pll.q_div); + w.set_pllp(config.pll.divp); + w.set_pllq(config.pll.divq); }); let (sys_clk, sw) = match config.mux { diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index 45d41a4e..75613dd2 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs @@ -28,7 +28,7 @@ pub enum ClockSrc { #[derive(Clone, Copy)] pub struct PllConfig { /// The source from which the PLL receives a clock signal - pub source: PllSrc, + pub source: PllSource, /// The initial divisor of that clock signal pub m: Pllm, /// The PLL VCO multiplier, which must be in the range `8..=86`. @@ -48,7 +48,7 @@ impl Default for PllConfig { fn default() -> PllConfig { // HSI / 1 * 8 / 2 = 64 MHz PllConfig { - source: PllSrc::HSI, + source: PllSource::HSI, m: Pllm::DIV1, n: Plln::MUL8, r: Pllr::DIV2, @@ -59,7 +59,7 @@ impl Default for PllConfig { } #[derive(Clone, Copy, Eq, PartialEq)] -pub enum PllSrc { +pub enum PllSource { HSI, HSE(Hertz), } @@ -89,8 +89,8 @@ impl Default for Config { impl PllConfig { pub(crate) fn init(self) -> Hertz { let (src, input_freq) = match self.source { - PllSrc::HSI => (vals::Pllsrc::HSI, HSI_FREQ), - PllSrc::HSE(freq) => (vals::Pllsrc::HSE, freq), + PllSource::HSI => (vals::Pllsrc::HSI, HSI_FREQ), + PllSource::HSE(freq) => (vals::Pllsrc::HSE, freq), }; let m_freq = input_freq / self.m; @@ -121,11 +121,11 @@ impl PllConfig { // > 3. Change the desired parameter. // Enable whichever clock source we're using, and wait for it to become ready match self.source { - PllSrc::HSI => { + PllSource::HSI => { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} } - PllSrc::HSE(_) => { + PllSource::HSE(_) => { RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} } diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index 13eb0c48..48b27255 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs @@ -23,16 +23,16 @@ pub enum ClockSrc { /// PLL clock input source #[derive(Clone, Copy, Debug)] -pub enum PllSrc { +pub enum PllSource { HSI, HSE(Hertz), } -impl Into for PllSrc { +impl Into for PllSource { fn into(self) -> Pllsrc { match self { - PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI => Pllsrc::HSI, + PllSource::HSE(..) => Pllsrc::HSE, + PllSource::HSI => Pllsrc::HSI, } } } @@ -44,7 +44,7 @@ impl Into for PllSrc { /// frequency ranges for each of these settings. pub struct Pll { /// PLL Source clock selection. - pub source: PllSrc, + pub source: PllSource, /// PLL pre-divider pub prediv_m: PllM, @@ -118,13 +118,13 @@ pub struct PllFreq { pub(crate) unsafe fn init(config: Config) { let pll_freq = config.pll.map(|pll_config| { let src_freq = match pll_config.source { - PllSrc::HSI => { + PllSource::HSI => { RCC.cr().write(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} HSI_FREQ } - PllSrc::HSE(freq) => { + PllSource::HSE(freq) => { RCC.cr().write(|w| w.set_hseon(true)); while !RCC.cr().read().hserdy() {} freq diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs index 25a7762a..c3d58e8e 100644 --- a/embassy-stm32/src/rcc/l0l1.rs +++ b/embassy-stm32/src/rcc/l0l1.rs @@ -1,7 +1,7 @@ pub use crate::pac::pwr::vals::Vos as VoltageScale; pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Plldiv as PllDiv, Pllmul as PLLMul, Pllmul as PllMul, - Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, + Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PllDiv, Pllmul as PllMul, Pllsrc as PllSource, + Ppre as APBPrescaler, Sw as ClockSrc, }; use crate::pac::{FLASH, PWR, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -29,7 +29,7 @@ pub struct Hse { #[derive(Clone, Copy)] pub struct Pll { /// PLL source - pub source: PLLSource, + pub source: PllSource, /// PLL multiplication factor. pub mul: PllMul, @@ -116,8 +116,8 @@ pub(crate) unsafe fn init(config: Config) { let pll = config.pll.map(|pll| { let freq = match pll.source { - PLLSource::HSE => hse.unwrap(), - PLLSource::HSI => hsi.unwrap(), + PllSource::HSE => hse.unwrap(), + PllSource::HSI => hsi.unwrap(), }; // Disable PLL diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index c4483910..97f231f6 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -5,7 +5,7 @@ pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; pub use crate::pac::rcc::vals::Hsepre as HsePrescaler; pub use crate::pac::rcc::vals::{ Adcsel as AdcClockSource, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, - Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc, + Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as ClockSrc, }; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -36,7 +36,7 @@ pub struct Hse { #[derive(Clone, Copy)] pub struct Pll { /// PLL source - pub source: PLLSource, + pub source: PllSource, /// PLL pre-divider (DIVM). pub prediv: PllPreDiv, @@ -135,7 +135,7 @@ pub const WPAN_DEFAULT: Config = Config { ls: super::LsConfig::default_lse(), pll: Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL12, divp: Some(PllPDiv::DIV3), // 32 / 2 * 12 / 3 = 64Mhz @@ -456,10 +456,10 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll let Some(pll) = config else { return PllOutput::default() }; let pll_src = match pll.source { - PLLSource::DISABLE => panic!("must not select PLL source as DISABLE"), - PLLSource::HSE => input.hse, - PLLSource::HSI => input.hsi, - PLLSource::MSI => input.msi, + PllSource::DISABLE => panic!("must not select PLL source as DISABLE"), + PllSource::HSE => input.hse, + PllSource::HSI => input.hsi, + PllSource::MSI => input.msi, }; let pll_src = pll_src.unwrap(); diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index c111362b..81bdec88 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -35,7 +35,7 @@ impl Default for ClockSrc { #[derive(Clone, Copy)] pub struct PllConfig { /// The clock source for the PLL. - pub source: PllSrc, + pub source: PllSource, /// The PLL prescaler. /// /// The clock speed of the `source` divided by `m` must be between 4 and 16 MHz. @@ -57,7 +57,7 @@ impl PllConfig { /// A configuration for HSI / 1 * 10 / 1 = 160 MHz pub const fn hsi_160mhz() -> Self { PllConfig { - source: PllSrc::HSI, + source: PllSource::HSI, m: Pllm::DIV1, n: Plln::MUL10, r: Plldiv::DIV1, @@ -67,7 +67,7 @@ impl PllConfig { /// A configuration for MSIS @ 48 MHz / 3 * 10 / 1 = 160 MHz pub const fn msis_160mhz() -> Self { PllConfig { - source: PllSrc::MSIS(Msirange::RANGE_48MHZ), + source: PllSource::MSIS(Msirange::RANGE_48MHZ), m: Pllm::DIV3, n: Plln::MUL10, r: Plldiv::DIV1, @@ -76,7 +76,7 @@ impl PllConfig { } #[derive(Clone, Copy)] -pub enum PllSrc { +pub enum PllSource { /// Use an internal medium speed oscillator as the PLL source. MSIS(Msirange), /// Use the external high speed clock as the system PLL source. @@ -88,12 +88,12 @@ pub enum PllSrc { HSI, } -impl Into for PllSrc { +impl Into for PllSource { fn into(self) -> Pllsrc { match self { - PllSrc::MSIS(..) => Pllsrc::MSIS, - PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI => Pllsrc::HSI, + PllSource::MSIS(..) => Pllsrc::MSIS, + PllSource::HSE(..) => Pllsrc::HSE, + PllSource::HSI => Pllsrc::HSI, } } } @@ -216,9 +216,9 @@ pub(crate) unsafe fn init(config: Config) { ClockSrc::PLL1_R(pll) => { // Configure the PLL source let source_clk = match pll.source { - PllSrc::MSIS(range) => config.init_msis(range), - PllSrc::HSE(hertz) => config.init_hse(hertz), - PllSrc::HSI => config.init_hsi(), + PllSource::MSIS(range) => config.init_msis(range), + PllSource::HSE(hertz) => config.init_hse(hertz), + PllSource::HSI => config.init_hsi(), }; // Calculate the reference clock, which is the source divided by m diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs index 8925d960..c0cd9150 100644 --- a/embassy-stm32/src/rcc/wba.rs +++ b/embassy-stm32/src/rcc/wba.rs @@ -17,16 +17,16 @@ pub enum ClockSrc { } #[derive(Clone, Copy, Debug)] -pub enum PllSrc { +pub enum PllSource { HSE(Hertz), HSI, } -impl Into for PllSrc { +impl Into for PllSource { fn into(self) -> Pllsrc { match self { - PllSrc::HSE(..) => Pllsrc::HSE, - PllSrc::HSI => Pllsrc::HSI, + PllSource::HSE(..) => Pllsrc::HSE, + PllSource::HSI => Pllsrc::HSI, } } } diff --git a/examples/stm32f2/src/bin/pll.rs b/examples/stm32f2/src/bin/pll.rs index 56591b52..feec9001 100644 --- a/examples/stm32f2/src/bin/pll.rs +++ b/examples/stm32f2/src/bin/pll.rs @@ -7,7 +7,7 @@ use core::convert::TryFrom; use defmt::*; use embassy_executor::Spawner; use embassy_stm32::rcc::{ - APBPrescaler, ClockSrc, HSEConfig, HSESrc, PLLConfig, PLLMul, PLLPDiv, PLLPreDiv, PLLQDiv, PLLSrc, + APBPrescaler, ClockSrc, HSEConfig, HSESrc, Pll, PllMul, PllPDiv, PllPreDiv, PllQDiv, PllSource, }; use embassy_stm32::time::Hertz; use embassy_stm32::Config; @@ -25,16 +25,16 @@ async fn main(_spawner: Spawner) { source: HSESrc::Bypass, }); // PLL uses HSE as the clock source - config.rcc.pll_mux = PLLSrc::HSE; - config.rcc.pll = PLLConfig { + config.rcc.pll_mux = PllSource::HSE; + config.rcc.pll = Pll { // 8 MHz clock source / 8 = 1 MHz PLL input - pre_div: unwrap!(PLLPreDiv::try_from(8)), + pre_div: unwrap!(PllPreDiv::try_from(8)), // 1 MHz PLL input * 240 = 240 MHz PLL VCO - mul: unwrap!(PLLMul::try_from(240)), + mul: unwrap!(PllMul::try_from(240)), // 240 MHz PLL VCO / 2 = 120 MHz main PLL output - p_div: PLLPDiv::DIV2, + divp: PllPDiv::DIV2, // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output - q_div: PLLQDiv::DIV5, + divq: PllQDiv::DIV5, }; // System clock comes from PLL (= the 120 MHz main PLL output) config.rcc.mux = ClockSrc::PLL; diff --git a/examples/stm32g4/src/bin/adc.rs b/examples/stm32g4/src/bin/adc.rs index f0573384..63b20c0d 100644 --- a/examples/stm32g4/src/bin/adc.rs +++ b/examples/stm32g4/src/bin/adc.rs @@ -5,7 +5,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::adc::{Adc, SampleTime}; -use embassy_stm32::rcc::{AdcClockSource, ClockSrc, Pll, PllM, PllN, PllR, PllSrc}; +use embassy_stm32::rcc::{AdcClockSource, ClockSrc, Pll, PllM, PllN, PllR, PllSource}; use embassy_stm32::Config; use embassy_time::{Delay, Timer}; use {defmt_rtt as _, panic_probe as _}; @@ -15,7 +15,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.pll = Some(Pll { - source: PllSrc::HSI, + source: PllSource::HSI, prediv_m: PllM::DIV4, mul_n: PllN::MUL85, div_p: None, diff --git a/examples/stm32g4/src/bin/pll.rs b/examples/stm32g4/src/bin/pll.rs index 90c3f8dc..09ef59d4 100644 --- a/examples/stm32g4/src/bin/pll.rs +++ b/examples/stm32g4/src/bin/pll.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, Pll, PllM, PllN, PllR, PllSrc}; +use embassy_stm32::rcc::{ClockSrc, Pll, PllM, PllN, PllR, PllSource}; use embassy_stm32::Config; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.pll = Some(Pll { - source: PllSrc::HSI, + source: PllSource::HSI, prediv_m: PllM::DIV4, mul_n: PllN::MUL85, div_p: None, diff --git a/examples/stm32g4/src/bin/usb_serial.rs b/examples/stm32g4/src/bin/usb_serial.rs index 378e7b98..565b25d6 100644 --- a/examples/stm32g4/src/bin/usb_serial.rs +++ b/examples/stm32g4/src/bin/usb_serial.rs @@ -4,7 +4,7 @@ use defmt::{panic, *}; use embassy_executor::Spawner; -use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, Hsi48Config, Pll, PllM, PllN, PllQ, PllR, PllSrc}; +use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, Hsi48Config, Pll, PllM, PllN, PllQ, PllR, PllSource}; use embassy_stm32::time::Hertz; use embassy_stm32::usb::{self, Driver, Instance}; use embassy_stm32::{bind_interrupts, peripherals, Config}; @@ -25,14 +25,14 @@ async fn main(_spawner: Spawner) { // Change this to `false` to use the HSE clock source for the USB. This example assumes an 8MHz HSE. const USE_HSI48: bool = true; - let pllq_div = if USE_HSI48 { None } else { Some(PllQ::DIV6) }; + let plldivq = if USE_HSI48 { None } else { Some(PllQ::DIV6) }; config.rcc.pll = Some(Pll { - source: PllSrc::HSE(Hertz(8_000_000)), + source: PllSource::HSE(Hertz(8_000_000)), prediv_m: PllM::DIV2, mul_n: PllN::MUL72, div_p: None, - div_q: pllq_div, + div_q: plldivq, // Main system clock at 144 MHz div_r: Some(PllR::DIV2), }); diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs index 553d11c0..e5ad56fb 100644 --- a/examples/stm32l4/src/bin/rng.rs +++ b/examples/stm32l4/src/bin/rng.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, PLLSource, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv}; +use embassy_stm32::rcc::{ClockSrc, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv, PllSource}; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -19,7 +19,7 @@ async fn main(_spawner: Spawner) { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hsi = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL18, divp: None, diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index 69527c9a..d2a2aa1f 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs @@ -22,7 +22,7 @@ async fn main(_spawner: Spawner) { mode: HseMode::Oscillator, }); config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV1, mul: PllMul::MUL20, divp: None, diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 62caeea5..3a7e5370 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -75,7 +75,7 @@ async fn main(spawner: Spawner) { let mut config = embassy_stm32::Config::default(); { use embassy_stm32::rcc::*; - // 80Mhz clock (Source: 8 / SrcDiv: 1 * PLLMul 20 / ClkDiv 2) + // 80Mhz clock (Source: 8 / SrcDiv: 1 * PllMul 20 / ClkDiv 2) // 80MHz highest frequency for flash 0 wait. config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hse = Some(Hse { @@ -83,7 +83,7 @@ async fn main(spawner: Spawner) { mode: HseMode::Oscillator, }); config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV1, mul: PllMul::MUL20, divp: None, diff --git a/examples/stm32l4/src/bin/usb_serial.rs b/examples/stm32l4/src/bin/usb_serial.rs index d977398f..4baf5f05 100644 --- a/examples/stm32l4/src/bin/usb_serial.rs +++ b/examples/stm32l4/src/bin/usb_serial.rs @@ -27,7 +27,7 @@ async fn main(_spawner: Spawner) { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hsi = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs index b9d4cd25..279f4f65 100644 --- a/examples/stm32l5/src/bin/rng.rs +++ b/examples/stm32l5/src/bin/rng.rs @@ -4,7 +4,7 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv}; +use embassy_stm32::rcc::{ClockSrc, Pll, PllMul, PllPreDiv, PllRDiv, PllSource}; use embassy_stm32::rng::Rng; use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; use {defmt_rtt as _, panic_probe as _}; @@ -20,7 +20,7 @@ async fn main(_spawner: Spawner) { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 64Mhz clock (16 / 1 * 8 / 2) - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL8, divp: None, diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index 923193ab..0b0a0e2d 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -49,7 +49,7 @@ async fn main(spawner: Spawner) { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 80Mhz clock (16 / 1 * 10 / 2) - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/examples/stm32l5/src/bin/usb_hid_mouse.rs b/examples/stm32l5/src/bin/usb_hid_mouse.rs index f64d0f34..3614a8e0 100644 --- a/examples/stm32l5/src/bin/usb_hid_mouse.rs +++ b/examples/stm32l5/src/bin/usb_hid_mouse.rs @@ -26,7 +26,7 @@ async fn main(_spawner: Spawner) { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 80Mhz clock (16 / 1 * 10 / 2) - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/examples/stm32l5/src/bin/usb_serial.rs b/examples/stm32l5/src/bin/usb_serial.rs index 58a8898a..f2b894b6 100644 --- a/examples/stm32l5/src/bin/usb_serial.rs +++ b/examples/stm32l5/src/bin/usb_serial.rs @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 80Mhz clock (16 / 1 * 10 / 2) - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL10, divp: None, diff --git a/examples/stm32u5/src/bin/usb_serial.rs b/examples/stm32u5/src/bin/usb_serial.rs index a218d5df..839d6472 100644 --- a/examples/stm32u5/src/bin/usb_serial.rs +++ b/examples/stm32u5/src/bin/usb_serial.rs @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { let mut config = Config::default(); config.rcc.mux = ClockSrc::PLL1_R(PllConfig { - source: PllSrc::HSI, + source: PllSource::HSI, m: Pllm::DIV2, n: Plln::MUL10, r: Plldiv::DIV1, diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs index 226e6786..348e3cdc 100644 --- a/examples/stm32wl/src/bin/lora_lorawan.rs +++ b/examples/stm32wl/src/bin/lora_lorawan.rs @@ -44,7 +44,7 @@ async fn main(_spawner: Spawner) { }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL6, divp: None, diff --git a/examples/stm32wl/src/bin/lora_p2p_receive.rs b/examples/stm32wl/src/bin/lora_p2p_receive.rs index a3bb0c0f..c643ddb1 100644 --- a/examples/stm32wl/src/bin/lora_p2p_receive.rs +++ b/examples/stm32wl/src/bin/lora_p2p_receive.rs @@ -37,7 +37,7 @@ async fn main(_spawner: Spawner) { }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL6, divp: None, diff --git a/examples/stm32wl/src/bin/lora_p2p_send.rs b/examples/stm32wl/src/bin/lora_p2p_send.rs index 08dd0845..7fe8cea3 100644 --- a/examples/stm32wl/src/bin/lora_p2p_send.rs +++ b/examples/stm32wl/src/bin/lora_p2p_send.rs @@ -37,7 +37,7 @@ async fn main(_spawner: Spawner) { }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL6, divp: None, diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs index 1a8822b4..2fd23496 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs @@ -25,7 +25,7 @@ async fn main(_spawner: Spawner) { }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL6, divp: None, diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs index b3b7f9c5..4ffb0bb5 100644 --- a/examples/stm32wl/src/bin/rtc.rs +++ b/examples/stm32wl/src/bin/rtc.rs @@ -24,7 +24,7 @@ async fn main(_spawner: Spawner) { }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL6, divp: None, diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 3668e18c..35f42d28 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -241,16 +241,16 @@ pub fn config() -> Config { source: HSESrc::Bypass, }); // PLL uses HSE as the clock source - config.rcc.pll_mux = PLLSrc::HSE; - config.rcc.pll = PLLConfig { + config.rcc.pll_mux = PllSource::HSE; + config.rcc.pll = Pll { // 8 MHz clock source / 8 = 1 MHz PLL input - pre_div: unwrap!(PLLPreDiv::try_from(8)), + pre_div: unwrap!(PllPreDiv::try_from(8)), // 1 MHz PLL input * 240 = 240 MHz PLL VCO - mul: unwrap!(PLLMul::try_from(240)), + mul: unwrap!(PllMul::try_from(240)), // 240 MHz PLL VCO / 2 = 120 MHz main PLL output - p_div: PLLPDiv::DIV2, + divp: PllPDiv::DIV2, // 240 MHz PLL VCO / 5 = 48 MHz PLL48 output - q_div: PLLQDiv::DIV5, + divq: PllQDiv::DIV5, }; // System clock comes from PLL (= the 120 MHz main PLL output) config.rcc.mux = ClockSrc::PLL; @@ -397,7 +397,7 @@ pub fn config() -> Config { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.hsi = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV1, mul: PllMul::MUL18, divp: None, @@ -416,7 +416,7 @@ pub fn config() -> Config { }); config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { - source: PLLSource::HSE, + source: PllSource::HSE, prediv: PllPreDiv::DIV2, mul: PllMul::MUL6, divp: None, @@ -432,7 +432,7 @@ pub fn config() -> Config { config.rcc.mux = ClockSrc::PLL1_R; config.rcc.pll = Some(Pll { // 110Mhz clock (16 / 4 * 55 / 2) - source: PLLSource::HSI, + source: PllSource::HSI, prediv: PllPreDiv::DIV4, mul: PllMul::MUL55, divp: None, @@ -462,9 +462,9 @@ pub fn config() -> Config { use embassy_stm32::rcc::*; config.rcc.hsi = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI, - mul: PLLMul::MUL4, - div: PLLDiv::DIV2, // 32Mhz clock (16 * 4 / 2) + source: PllSource::HSI, + mul: PllMul::MUL4, + div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) }); config.rcc.mux = ClockSrc::PLL1_P; } @@ -474,9 +474,9 @@ pub fn config() -> Config { use embassy_stm32::rcc::*; config.rcc.hsi = true; config.rcc.pll = Some(Pll { - source: PLLSource::HSI, - mul: PLLMul::MUL4, - div: PLLDiv::DIV2, // 32Mhz clock (16 * 4 / 2) + source: PllSource::HSI, + mul: PllMul::MUL4, + div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) }); config.rcc.mux = ClockSrc::PLL1_P; } From 066dc297ed4508c334effafcc134296cb776eb06 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 13 Nov 2023 01:05:07 +0100 Subject: [PATCH 2/2] stm32/rcc: unify l0l1 and l4l5. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rcc/{l4l5.rs => l.rs} | 393 +++++++++++++++--------- embassy-stm32/src/rcc/l0l1.rs | 190 ------------ embassy-stm32/src/rcc/mod.rs | 3 +- tests/stm32/src/common.rs | 4 +- 5 files changed, 260 insertions(+), 334 deletions(-) rename embassy-stm32/src/rcc/{l4l5.rs => l.rs} (58%) delete mode 100644 embassy-stm32/src/rcc/l0l1.rs diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 7b3a6c2b..37317276 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -58,7 +58,7 @@ rand_core = "0.6.3" sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-1374ed622714ef4702826699ca21cc1f741f4133" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c551c07bf12513dd8346a9fe0bc70cf79f2ea02f" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-1374ed622714ef4702826699ca21cc1f741f4133", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-c551c07bf12513dd8346a9fe0bc70cf79f2ea02f", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l.rs similarity index 58% rename from embassy-stm32/src/rcc/l4l5.rs rename to embassy-stm32/src/rcc/l.rs index 97f231f6..257fd83f 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l.rs @@ -1,12 +1,13 @@ +#[cfg(any(stm32l0, stm32l1))] +pub use crate::pac::pwr::vals::Vos as VoltageScale; use crate::pac::rcc::regs::Cfgr; -#[cfg(any(stm32l4, stm32l5, stm32wb))] +#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] +pub use crate::pac::rcc::vals::Adcsel as AdcClockSource; +#[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))] pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; #[cfg(any(stm32wb, stm32wl))] pub use crate::pac::rcc::vals::Hsepre as HsePrescaler; -pub use crate::pac::rcc::vals::{ - Adcsel as AdcClockSource, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, - Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PllSource, Ppre as APBPrescaler, Sw as ClockSrc, -}; +pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Msirange as MSIRange, Ppre as APBPrescaler, Sw as ClockSrc}; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; @@ -33,25 +34,6 @@ pub struct Hse { pub prescaler: HsePrescaler, } -#[derive(Clone, Copy)] -pub struct Pll { - /// PLL source - pub source: PllSource, - - /// PLL pre-divider (DIVM). - pub prediv: PllPreDiv, - - /// PLL multiplication factor. - pub mul: PllMul, - - /// PLL P division factor. If None, PLL P output is disabled. - pub divp: Option, - /// PLL Q division factor. If None, PLL Q output is disabled. - pub divq: Option, - /// PLL R division factor. If None, PLL R output is disabled. - pub divr: Option, -} - /// Clocks configuration pub struct Config { // base clock sources @@ -79,13 +61,17 @@ pub struct Config { pub shared_ahb_pre: AHBPrescaler, // muxes - #[cfg(any(stm32l4, stm32l5, stm32wb))] + #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))] pub clk48_src: Clk48Src, // low speed LSI/LSE/RTC pub ls: super::LsConfig, + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] pub adc_clock_source: AdcClockSource, + + #[cfg(any(stm32l0, stm32l1))] + pub voltage_scale: VoltageScale, } impl Default for Config { @@ -110,10 +96,13 @@ impl Default for Config { pllsai2: None, #[cfg(crs)] hsi48: Some(Default::default()), - #[cfg(any(stm32l4, stm32l5, stm32wb))] + #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))] clk48_src: Clk48Src::HSI48, ls: Default::default(), + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] adc_clock_source: AdcClockSource::SYS, + #[cfg(any(stm32l0, stm32l1))] + voltage_scale: VoltageScale::RANGE1, } } } @@ -152,20 +141,26 @@ pub const WPAN_DEFAULT: Config = Config { adc_clock_source: AdcClockSource::SYS, }; +fn msi_enable(range: MSIRange) { + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] + RCC.cr().modify(|w| { + #[cfg(not(stm32wb))] + w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); + w.set_msirange(range); + w.set_msipllen(false); + }); + #[cfg(any(stm32l0, stm32l1))] + RCC.icscr().modify(|w| w.set_msirange(range)); + + RCC.cr().modify(|w| w.set_msion(true)); + while !RCC.cr().read().msirdy() {} +} + pub(crate) unsafe fn init(config: Config) { // Switch to MSI to prevent problems with PLL configuration. if !RCC.cr().read().msion() { // Turn on MSI and configure it to 4MHz. - RCC.cr().modify(|w| { - #[cfg(not(stm32wb))] - w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); - w.set_msirange(MSIRange::RANGE4M); - w.set_msipllen(false); - w.set_msion(true) - }); - - // Wait until MSI is running - while !RCC.cr().read().msirdy() {} + msi_enable(MSIRange::RANGE4M) } if RCC.cfgr().read().sws() != ClockSrc::MSI { // Set MSI as a clock source, reset prescalers. @@ -174,6 +169,14 @@ pub(crate) unsafe fn init(config: Config) { while RCC.cfgr().read().sws() != ClockSrc::MSI {} } + // Set voltage scale + #[cfg(any(stm32l0, stm32l1))] + { + while crate::pac::PWR.csr().read().vosf() {} + crate::pac::PWR.cr().write(|w| w.set_vos(config.voltage_scale)); + while crate::pac::PWR.csr().read().vosf() {} + } + #[cfg(stm32l5)] crate::pac::PWR.cr1().modify(|w| { w.set_vos(crate::pac::pwr::vals::Vos::RANGE0); @@ -182,21 +185,16 @@ pub(crate) unsafe fn init(config: Config) { let rtc = config.ls.init(); let msi = config.msi.map(|range| { - // Enable MSI - RCC.cr().modify(|w| { - #[cfg(not(stm32wb))] - w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR); - w.set_msirange(range); - w.set_msion(true); - - // If LSE is enabled, enable calibration of MSI - w.set_msipllen(config.ls.lse.is_some()); - }); - while !RCC.cr().read().msirdy() {} - + msi_enable(range); msirange_to_hertz(range) }); + // If LSE is enabled and the right freq, enable calibration of MSI + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] + if config.ls.lse.map(|x| x.frequency) == Some(Hertz(32_768)) { + RCC.cr().modify(|w| w.set_msipllen(true)); + } + let hsi = config.hsi.then(|| { RCC.cr().modify(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} @@ -218,7 +216,10 @@ pub(crate) unsafe fn init(config: Config) { }); #[cfg(crs)] - let _hsi48 = config.hsi48.map(super::init_hsi48); + let _hsi48 = config.hsi48.map(|config| { + // + super::init_hsi48(config) + }); #[cfg(not(crs))] let _hsi48: Option = None; @@ -251,7 +252,12 @@ pub(crate) unsafe fn init(config: Config) { }), }; - let pll_input = PllInput { hse, hsi, msi }; + let pll_input = PllInput { + hse, + hsi, + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] + msi, + }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); #[cfg(any(stm32l4, stm32l5, stm32wb))] let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); @@ -265,10 +271,13 @@ pub(crate) unsafe fn init(config: Config) { ClockSrc::PLL1_R => pll.r.unwrap(), }; - #[cfg(stm32l4)] + #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))] RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src)); - #[cfg(stm32l5)] - RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src)); + #[cfg(any(rcc_l0_v2))] + let _clk48 = match config.clk48_src { + Clk48Src::HSI48 => _hsi48, + Clk48Src::PLL1_VCO_DIV_2 => pll.clk48, + }; #[cfg(any(stm32l4, stm32l5, stm32wb))] let _clk48 = match config.clk48_src { Clk48Src::HSI48 => _hsi48, @@ -285,16 +294,23 @@ pub(crate) unsafe fn init(config: Config) { let hclk1 = sys_clk / config.ahb_pre; let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre); let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); - #[cfg(not(any(stm32wl5x, stm32wb)))] + #[cfg(any(stm32l4, stm32l5, stm32wlex))] let hclk2 = hclk1; #[cfg(any(stm32wl5x, stm32wb))] let hclk2 = sys_clk / config.core2_ahb_pre; - #[cfg(not(any(stm32wl, stm32wb)))] + #[cfg(any(stm32l4, stm32l5, stm32wlex))] let hclk3 = hclk1; - #[cfg(any(stm32wl, stm32wb))] + #[cfg(any(stm32wl5x, stm32wb))] let hclk3 = sys_clk / config.shared_ahb_pre; // Set flash wait states + #[cfg(any(stm32l0, stm32l1))] + let latency = match (config.voltage_scale, sys_clk.0) { + (VoltageScale::RANGE1, ..=16_000_000) => false, + (VoltageScale::RANGE2, ..=8_000_000) => false, + (VoltageScale::RANGE3, ..=4_200_000) => false, + _ => true, + }; #[cfg(stm32l4)] let latency = match hclk1.0 { 0..=16_000_000 => 0, @@ -330,6 +346,10 @@ pub(crate) unsafe fn init(config: Config) { _ => 4, }; + #[cfg(stm32l1)] + FLASH.acr().write(|w| w.set_acc64(true)); + #[cfg(not(stm32l5))] + FLASH.acr().modify(|w| w.set_prften(true)); FLASH.acr().modify(|w| w.set_latency(latency)); while FLASH.acr().read().latency() != latency {} @@ -341,9 +361,7 @@ pub(crate) unsafe fn init(config: Config) { }); while RCC.cfgr().read().sws() != config.mux {} - #[cfg(stm32l5)] - RCC.ccipr1().modify(|w| w.set_adcsel(config.adc_clock_source)); - #[cfg(not(stm32l5))] + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source)); #[cfg(any(stm32wl, stm32wb))] @@ -361,7 +379,9 @@ pub(crate) unsafe fn init(config: Config) { set_freqs(Clocks { sys: sys_clk, hclk1, + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] hclk2, + #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] hclk3, pclk1, pclk2, @@ -389,6 +409,12 @@ pub(crate) unsafe fn init(config: Config) { }); } +#[cfg(any(stm32l0, stm32l1))] +fn msirange_to_hertz(range: MSIRange) -> Hertz { + Hertz(32_768 * (1 << (range as u8 + 1))) +} + +#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] fn msirange_to_hertz(range: MSIRange) -> Hertz { match range { MSIRange::RANGE100K => Hertz(100_000), @@ -407,20 +433,6 @@ fn msirange_to_hertz(range: MSIRange) -> Hertz { } } -struct PllInput { - hsi: Option, - hse: Option, - msi: Option, -} - -#[allow(unused)] -#[derive(Default)] -struct PllOutput { - p: Option, - q: Option, - r: Option, -} - #[derive(PartialEq, Eq, Clone, Copy)] enum PllInstance { Pll, @@ -449,77 +461,182 @@ fn pll_enable(instance: PllInstance, enabled: bool) { } } -fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> PllOutput { - // Disable PLL - pll_enable(instance, false); +pub use pll::*; - let Some(pll) = config else { return PllOutput::default() }; +#[cfg(any(stm32l0, stm32l1))] +mod pll { + use super::{pll_enable, PllInstance}; + pub use crate::pac::rcc::vals::{Plldiv as PllDiv, Pllmul as PllMul, Pllsrc as PllSource}; + use crate::pac::RCC; + use crate::time::Hertz; - let pll_src = match pll.source { - PllSource::DISABLE => panic!("must not select PLL source as DISABLE"), - PllSource::HSE => input.hse, - PllSource::HSI => input.hsi, - PllSource::MSI => input.msi, - }; + #[derive(Clone, Copy)] + pub struct Pll { + /// PLL source + pub source: PllSource, - let pll_src = pll_src.unwrap(); + /// PLL multiplication factor. + pub mul: PllMul, - let vco_freq = pll_src / pll.prediv * pll.mul; - - let p = pll.divp.map(|div| vco_freq / div); - let q = pll.divq.map(|div| vco_freq / div); - let r = pll.divr.map(|div| vco_freq / div); - - #[cfg(stm32l5)] - if instance == PllInstance::Pllsai2 { - assert!(q.is_none(), "PLLSAI2_Q is not available on L5"); - assert!(r.is_none(), "PLLSAI2_R is not available on L5"); + /// PLL main output division factor. + pub div: PllDiv, } - macro_rules! write_fields { - ($w:ident) => { - $w.set_plln(pll.mul); - if let Some(divp) = pll.divp { - $w.set_pllp(divp); - $w.set_pllpen(true); - } - if let Some(divq) = pll.divq { - $w.set_pllq(divq); - $w.set_pllqen(true); - } - if let Some(divr) = pll.divr { - $w.set_pllr(divr); - $w.set_pllren(true); - } + pub(super) struct PllInput { + pub hsi: Option, + pub hse: Option, + } + + #[allow(unused)] + #[derive(Default)] + pub(super) struct PllOutput { + pub r: Option, + pub clk48: Option, + } + + pub(super) fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> PllOutput { + // Disable PLL + pll_enable(instance, false); + + let Some(pll) = config else { return PllOutput::default() }; + + let pll_src = match pll.source { + PllSource::HSE => unwrap!(input.hse), + PllSource::HSI => unwrap!(input.hsi), }; + + let vco_freq = pll_src * pll.mul; + + let r = vco_freq / pll.div; + let clk48 = (vco_freq == Hertz(96_000_000)).then_some(Hertz(48_000_000)); + + assert!(r <= Hertz(32_000_000)); + + RCC.cfgr().write(move |w| { + w.set_pllmul(pll.mul); + w.set_plldiv(pll.div); + w.set_pllsrc(pll.source); + }); + + // Enable PLL + pll_enable(instance, true); + + PllOutput { r: Some(r), clk48 } + } +} + +#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] +mod pll { + use super::{pll_enable, PllInstance}; + pub use crate::pac::rcc::vals::{ + Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc as PllSource, + }; + use crate::pac::RCC; + use crate::time::Hertz; + + #[derive(Clone, Copy)] + pub struct Pll { + /// PLL source + pub source: PllSource, + + /// PLL pre-divider (DIVM). + pub prediv: PllPreDiv, + + /// PLL multiplication factor. + pub mul: PllMul, + + /// PLL P division factor. If None, PLL P output is disabled. + pub divp: Option, + /// PLL Q division factor. If None, PLL Q output is disabled. + pub divq: Option, + /// PLL R division factor. If None, PLL R output is disabled. + pub divr: Option, + } + + pub(super) struct PllInput { + pub hsi: Option, + pub hse: Option, + pub msi: Option, + } + + #[allow(unused)] + #[derive(Default)] + pub(super) struct PllOutput { + pub p: Option, + pub q: Option, + pub r: Option, + } + + pub(super) fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> PllOutput { + // Disable PLL + pll_enable(instance, false); + + let Some(pll) = config else { return PllOutput::default() }; + + let pll_src = match pll.source { + PllSource::DISABLE => panic!("must not select PLL source as DISABLE"), + PllSource::HSE => unwrap!(input.hse), + PllSource::HSI => unwrap!(input.hsi), + PllSource::MSI => unwrap!(input.msi), + }; + + let vco_freq = pll_src / pll.prediv * pll.mul; + + let p = pll.divp.map(|div| vco_freq / div); + let q = pll.divq.map(|div| vco_freq / div); + let r = pll.divr.map(|div| vco_freq / div); + + #[cfg(stm32l5)] + if instance == PllInstance::Pllsai2 { + assert!(q.is_none(), "PLLSAI2_Q is not available on L5"); + assert!(r.is_none(), "PLLSAI2_R is not available on L5"); + } + + macro_rules! write_fields { + ($w:ident) => { + $w.set_plln(pll.mul); + if let Some(divp) = pll.divp { + $w.set_pllp(divp); + $w.set_pllpen(true); + } + if let Some(divq) = pll.divq { + $w.set_pllq(divq); + $w.set_pllqen(true); + } + if let Some(divr) = pll.divr { + $w.set_pllr(divr); + $w.set_pllren(true); + } + }; + } + + match instance { + PllInstance::Pll => RCC.pllcfgr().write(|w| { + w.set_pllm(pll.prediv); + w.set_pllsrc(pll.source); + write_fields!(w); + }), + #[cfg(any(stm32l4, stm32l5, stm32wb))] + PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { + #[cfg(any(rcc_l4plus, stm32l5))] + w.set_pllm(pll.prediv); + #[cfg(stm32l5)] + w.set_pllsrc(pll.source); + write_fields!(w); + }), + #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] + PllInstance::Pllsai2 => RCC.pllsai2cfgr().write(|w| { + #[cfg(any(rcc_l4plus, stm32l5))] + w.set_pllm(pll.prediv); + #[cfg(stm32l5)] + w.set_pllsrc(pll.source); + write_fields!(w); + }), + } + + // Enable PLL + pll_enable(instance, true); + + PllOutput { p, q, r } } - - match instance { - PllInstance::Pll => RCC.pllcfgr().write(|w| { - w.set_pllm(pll.prediv); - w.set_pllsrc(pll.source); - write_fields!(w); - }), - #[cfg(any(stm32l4, stm32l5, stm32wb))] - PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { - #[cfg(any(rcc_l4plus, stm32l5))] - w.set_pllm(pll.prediv); - #[cfg(stm32l5)] - w.set_pllsrc(pll.source); - write_fields!(w); - }), - #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] - PllInstance::Pllsai2 => RCC.pllsai2cfgr().write(|w| { - #[cfg(any(rcc_l4plus, stm32l5))] - w.set_pllm(pll.prediv); - #[cfg(stm32l5)] - w.set_pllsrc(pll.source); - write_fields!(w); - }), - } - - // Enable PLL - pll_enable(instance, true); - - PllOutput { p, q, r } } diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs deleted file mode 100644 index c3d58e8e..00000000 --- a/embassy-stm32/src/rcc/l0l1.rs +++ /dev/null @@ -1,190 +0,0 @@ -pub use crate::pac::pwr::vals::Vos as VoltageScale; -pub use crate::pac::rcc::vals::{ - Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PllDiv, Pllmul as PllMul, Pllsrc as PllSource, - Ppre as APBPrescaler, Sw as ClockSrc, -}; -use crate::pac::{FLASH, PWR, RCC}; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -#[derive(Clone, Copy, Eq, PartialEq)] -pub enum HseMode { - /// crystal/ceramic oscillator (HSEBYP=0) - Oscillator, - /// external analog clock (low swing) (HSEBYP=1) - Bypass, -} - -#[derive(Clone, Copy, Eq, PartialEq)] -pub struct Hse { - /// HSE frequency. - pub freq: Hertz, - /// HSE mode. - pub mode: HseMode, -} - -#[derive(Clone, Copy)] -pub struct Pll { - /// PLL source - pub source: PllSource, - - /// PLL multiplication factor. - pub mul: PllMul, - - /// PLL main output division factor. - pub div: PllDiv, -} - -/// Clocks configutation -pub struct Config { - // base clock sources - pub msi: Option, - pub hsi: bool, - pub hse: Option, - #[cfg(crs)] - pub hsi48: Option, - - pub pll: Option, - - pub mux: ClockSrc, - pub ahb_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, - - pub ls: super::LsConfig, - pub voltage_scale: VoltageScale, -} - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - msi: Some(MSIRange::RANGE5), - hse: None, - hsi: false, - #[cfg(crs)] - hsi48: Some(Default::default()), - - pll: None, - - mux: ClockSrc::MSI, - ahb_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - voltage_scale: VoltageScale::RANGE1, - ls: Default::default(), - } - } -} - -pub(crate) unsafe fn init(config: Config) { - // Set voltage scale - while PWR.csr().read().vosf() {} - PWR.cr().write(|w| w.set_vos(config.voltage_scale)); - while PWR.csr().read().vosf() {} - - let rtc = config.ls.init(); - - let msi = config.msi.map(|range| { - RCC.icscr().modify(|w| w.set_msirange(range)); - - RCC.cr().modify(|w| w.set_msion(true)); - while !RCC.cr().read().msirdy() {} - - Hertz(32_768 * (1 << (range as u8 + 1))) - }); - - let hsi = config.hsi.then(|| { - RCC.cr().modify(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - - HSI_FREQ - }); - - let hse = config.hse.map(|hse| { - RCC.cr().modify(|w| { - w.set_hsebyp(hse.mode == HseMode::Bypass); - w.set_hseon(true); - }); - while !RCC.cr().read().hserdy() {} - - hse.freq - }); - - let pll = config.pll.map(|pll| { - let freq = match pll.source { - PllSource::HSE => hse.unwrap(), - PllSource::HSI => hsi.unwrap(), - }; - - // Disable PLL - RCC.cr().modify(|w| w.set_pllon(false)); - while RCC.cr().read().pllrdy() {} - - let freq = freq * pll.mul / pll.div; - - assert!(freq <= Hertz(32_000_000)); - - RCC.cfgr().write(move |w| { - w.set_pllmul(pll.mul); - w.set_plldiv(pll.div); - w.set_pllsrc(pll.source); - }); - - // Enable PLL - RCC.cr().modify(|w| w.set_pllon(true)); - while !RCC.cr().read().pllrdy() {} - - freq - }); - - let sys_clk = match config.mux { - ClockSrc::HSE => hse.unwrap(), - ClockSrc::HSI => hsi.unwrap(), - ClockSrc::MSI => msi.unwrap(), - ClockSrc::PLL1_P => pll.unwrap(), - }; - - let wait_states = match (config.voltage_scale, sys_clk.0) { - (VoltageScale::RANGE1, ..=16_000_000) => 0, - (VoltageScale::RANGE2, ..=8_000_000) => 0, - (VoltageScale::RANGE3, ..=4_200_000) => 0, - _ => 1, - }; - - #[cfg(stm32l1)] - FLASH.acr().write(|w| w.set_acc64(true)); - FLASH.acr().modify(|w| w.set_prften(true)); - FLASH.acr().modify(|w| w.set_latency(wait_states != 0)); - - RCC.cfgr().modify(|w| { - w.set_sw(config.mux); - w.set_hpre(config.ahb_pre); - w.set_ppre1(config.apb1_pre); - w.set_ppre2(config.apb2_pre); - }); - - let hclk1 = sys_clk / config.ahb_pre; - let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk1, config.apb1_pre); - let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk1, config.apb2_pre); - - #[cfg(crs)] - let _hsi48 = config.hsi48.map(|config| { - // Select HSI48 as USB clock - RCC.ccipr().modify(|w| w.set_hsi48msel(true)); - super::init_hsi48(config) - }); - - set_freqs(Clocks { - sys: sys_clk, - hclk1, - pclk1, - pclk2, - pclk1_tim, - pclk2_tim, - rtc, - }); -} diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index e15f4fe4..debd16ca 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -23,8 +23,7 @@ pub use hsi48::*; #[cfg_attr(rcc_g0, path = "g0.rs")] #[cfg_attr(rcc_g4, path = "g4.rs")] #[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")] -#[cfg_attr(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")] -#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5, rcc_wl5, rcc_wle, rcc_wb), path = "l4l5.rs")] +#[cfg_attr(any(stm32l0, stm32l1, stm32l4, stm32l5, stm32wb, stm32wl), path = "l.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")] #[cfg_attr(rcc_wba, path = "wba.rs")] mod _version; diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 35f42d28..e7367d5e 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -466,7 +466,7 @@ pub fn config() -> Config { mul: PllMul::MUL4, div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) }); - config.rcc.mux = ClockSrc::PLL1_P; + config.rcc.mux = ClockSrc::PLL1_R; } #[cfg(any(feature = "stm32l152re"))] @@ -478,7 +478,7 @@ pub fn config() -> Config { mul: PllMul::MUL4, div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) }); - config.rcc.mux = ClockSrc::PLL1_P; + config.rcc.mux = ClockSrc::PLL1_R; } config