diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 2d694267a..568a7eeb9 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-ee64389697d9234af374a89788aa52bb93d59284" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4ddcb77c9d213d11eebb048f40e112bc54163cdc" } 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-ee64389697d9234af374a89788aa52bb93d59284", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4ddcb77c9d213d11eebb048f40e112bc54163cdc", default-features = false, features = ["metadata"]} [features] diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index 1b1e182f0..4006dee19 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs @@ -5,6 +5,7 @@ use core::task::Poll; use self::sealed::Instance; use crate::interrupt; use crate::interrupt::typelevel::Interrupt; +use crate::pac::rcc::vals::{Lptim1sel, Lptim2sel}; use crate::peripherals::IPCC; use crate::rcc::sealed::RccPeripheral; @@ -273,7 +274,7 @@ fn _configure_pwr() { // set LPTIM1 & LPTIM2 clock source rcc.ccipr().modify(|w| { - w.set_lptim1sel(0b00); // PCLK - w.set_lptim2sel(0b00); // PCLK + w.set_lptim1sel(Lptim1sel::PCLK1); + w.set_lptim2sel(Lptim2sel::PCLK1); }); } diff --git a/embassy-stm32/src/rcc/l4l5.rs b/embassy-stm32/src/rcc/l4l5.rs index 8cf284d1e..b56962270 100644 --- a/embassy-stm32/src/rcc/l4l5.rs +++ b/embassy-stm32/src/rcc/l4l5.rs @@ -1,8 +1,10 @@ use crate::pac::rcc::regs::Cfgr; +#[cfg(not(stm32wl))] +pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; use crate::pac::rcc::vals::Msirgsel; pub use crate::pac::rcc::vals::{ - Clk48sel as Clk48Src, 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, + 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, }; use crate::pac::{FLASH, RCC}; use crate::rcc::{set_freqs, Clocks}; @@ -11,6 +13,22 @@ 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 @@ -35,12 +53,13 @@ pub struct Config { // base clock sources pub msi: Option, pub hsi: bool, - pub hse: Option, - #[cfg(not(any(stm32l47x, stm32l48x)))] + pub hse: Option, + #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] pub hsi48: bool, // pll pub pll: Option, + #[cfg(any(stm32l4, stm32l5))] pub pllsai1: Option, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] pub pllsai2: Option, @@ -50,8 +69,11 @@ pub struct Config { pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, + #[cfg(stm32wl)] + pub shared_ahb_pre: AHBPrescaler, // muxes + #[cfg(not(stm32wl))] pub clk48_src: Clk48Src, // low speed LSI/LSE/RTC @@ -69,12 +91,16 @@ impl Default for Config { ahb_pre: AHBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1, + #[cfg(stm32wl)] + shared_ahb_pre: AHBPrescaler::DIV1, pll: None, + #[cfg(any(stm32l4, stm32l5))] pllsai1: None, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] pllsai2: None, - #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] + #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] hsi48: true, + #[cfg(not(stm32wl))] clk48_src: Clk48Src::HSI48, ls: Default::default(), } @@ -111,7 +137,7 @@ pub(crate) unsafe fn init(config: Config) { let msi = config.msi.map(|range| { // Enable MSI - RCC.cr().write(|w| { + RCC.cr().modify(|w| { w.set_msirange(range); w.set_msirgsel(Msirgsel::CR); w.set_msion(true); @@ -128,20 +154,26 @@ pub(crate) unsafe fn init(config: Config) { }); let hsi = config.hsi.then(|| { - RCC.cr().write(|w| w.set_hsion(true)); + RCC.cr().modify(|w| w.set_hsion(true)); while !RCC.cr().read().hsirdy() {} HSI_FREQ }); - let hse = config.hse.map(|freq| { - RCC.cr().write(|w| w.set_hseon(true)); + let hse = config.hse.map(|hse| { + RCC.cr().modify(|w| { + #[cfg(stm32wl)] + w.set_hsebyppwr(hse.mode == HseMode::Bypass); + #[cfg(not(stm32wl))] + w.set_hsebyp(hse.mode == HseMode::Bypass); + w.set_hseon(true); + }); while !RCC.cr().read().hserdy() {} - freq + hse.freq }); - #[cfg(not(any(stm32l47x, stm32l48x)))] + #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] let hsi48 = config.hsi48.then(|| { RCC.crrcr().modify(|w| w.set_hsi48on(true)); while !RCC.crrcr().read().hsi48rdy() {} @@ -153,6 +185,7 @@ pub(crate) unsafe fn init(config: Config) { let _plls = [ &config.pll, + #[cfg(any(stm32l4, stm32l5))] &config.pllsai1, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] &config.pllsai2, @@ -169,8 +202,8 @@ pub(crate) unsafe fn init(config: Config) { }), }; - // L4+ has shared PLLSRC, check it's equal in all PLLs. - #[cfg(any(rcc_l4plus))] + // L4+, WL has shared PLLSRC, check it's equal in all PLLs. + #[cfg(any(rcc_l4plus, stm32wl))] match get_equal(_plls.into_iter().flatten().map(|p| p.source)) { Err(()) => panic!("Source must be equal across all enabled PLLs."), Ok(None) => {} @@ -181,6 +214,7 @@ pub(crate) unsafe fn init(config: Config) { let pll_input = PllInput { hse, hsi, msi }; let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); + #[cfg(any(stm32l4, stm32l5))] let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input); @@ -196,6 +230,7 @@ pub(crate) unsafe fn init(config: Config) { RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src)); #[cfg(stm32l5)] RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src)); + #[cfg(not(stm32wl))] let _clk48 = match config.clk48_src { Clk48Src::HSI48 => hsi48, Clk48Src::MSI => msi, @@ -208,38 +243,6 @@ pub(crate) unsafe fn init(config: Config) { #[cfg(all(stm32l4, not(rcc_l4plus)))] assert!(sys_clk.0 <= 80_000_000); - // Set flash wait states - #[cfg(stm32l4)] - FLASH.acr().modify(|w| { - w.set_latency(match sys_clk.0 { - 0..=16_000_000 => 0, - 0..=32_000_000 => 1, - 0..=48_000_000 => 2, - 0..=64_000_000 => 3, - _ => 4, - }) - }); - // VCORE Range 0 (performance), others TODO - #[cfg(stm32l5)] - FLASH.acr().modify(|w| { - w.set_latency(match sys_clk.0 { - 0..=20_000_000 => 0, - 0..=40_000_000 => 1, - 0..=60_000_000 => 2, - 0..=80_000_000 => 3, - 0..=100_000_000 => 4, - _ => 5, - }) - }); - - 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); - }); - while RCC.cfgr().read().sws() != config.mux {} - let ahb_freq = sys_clk / config.ahb_pre; let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { @@ -258,15 +261,69 @@ pub(crate) unsafe fn init(config: Config) { } }; + #[cfg(stm32wl)] + let ahb3_freq = sys_clk / config.shared_ahb_pre; + + // Set flash wait states + #[cfg(stm32l4)] + let latency = match sys_clk.0 { + 0..=16_000_000 => 0, + 0..=32_000_000 => 1, + 0..=48_000_000 => 2, + 0..=64_000_000 => 3, + _ => 4, + }; + #[cfg(stm32l5)] + let latency = match sys_clk.0 { + // VCORE Range 0 (performance), others TODO + 0..=20_000_000 => 0, + 0..=40_000_000 => 1, + 0..=60_000_000 => 2, + 0..=80_000_000 => 3, + 0..=100_000_000 => 4, + _ => 5, + }; + #[cfg(stm32wl)] + let latency = match ahb3_freq.0 { + // VOS RANGE1, others TODO. + ..=18_000_000 => 0, + ..=36_000_000 => 1, + _ => 2, + }; + + FLASH.acr().modify(|w| w.set_latency(latency)); + while FLASH.acr().read().latency() != latency {} + + 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); + }); + while RCC.cfgr().read().sws() != config.mux {} + + #[cfg(stm32wl)] + { + RCC.extcfgr().modify(|w| { + w.set_shdhpre(config.shared_ahb_pre); + }); + while !RCC.extcfgr().read().shdhpref() {} + } + set_freqs(Clocks { sys: sys_clk, hclk1: ahb_freq, hclk2: ahb_freq, + #[cfg(not(stm32wl))] hclk3: ahb_freq, pclk1: apb1_freq, pclk2: apb2_freq, pclk1_tim: apb1_tim_freq, pclk2_tim: apb2_tim_freq, + #[cfg(stm32wl)] + hclk3: ahb3_freq, + #[cfg(stm32wl)] + pclk3: ahb3_freq, #[cfg(rcc_l4)] hsi: None, #[cfg(rcc_l4)] @@ -330,6 +387,7 @@ struct PllOutput { #[derive(PartialEq, Eq, Clone, Copy)] enum PllInstance { Pll, + #[cfg(any(stm32l4, stm32l5))] Pllsai1, #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] Pllsai2, @@ -342,6 +400,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll RCC.cr().modify(|w| w.set_pllon(false)); while RCC.cr().read().pllrdy() {} } + #[cfg(any(stm32l4, stm32l5))] PllInstance::Pllsai1 => { RCC.cr().modify(|w| w.set_pllsai1on(false)); while RCC.cr().read().pllsai1rdy() {} @@ -356,7 +415,7 @@ 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::NONE => panic!("must not select PLL source as NONE"), + PLLSource::DISABLE => panic!("must not select PLL source as NONE"), PLLSource::HSE => input.hse, PLLSource::HSI => input.hsi, PLLSource::MSI => input.msi, @@ -400,6 +459,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll w.set_pllsrc(pll.source); write_fields!(w); }), + #[cfg(any(stm32l4, stm32l5))] PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { #[cfg(any(rcc_l4plus, stm32l5))] w.set_pllm(pll.prediv); @@ -423,6 +483,7 @@ fn init_pll(instance: PllInstance, config: Option, input: &PllInput) -> Pll RCC.cr().modify(|w| w.set_pllon(true)); while !RCC.cr().read().pllrdy() {} } + #[cfg(any(stm32l4, stm32l5))] PllInstance::Pllsai1 => { RCC.cr().modify(|w| w.set_pllsai1on(true)); while !RCC.cr().read().pllsai1rdy() {} diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 49174b27f..78d54f803 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -19,11 +19,10 @@ pub use mco::*; #[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), path = "l4l5.rs")] +#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5, rcc_wl5, rcc_wle), path = "l4l5.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")] #[cfg_attr(rcc_wb, path = "wb.rs")] #[cfg_attr(rcc_wba, path = "wba.rs")] -#[cfg_attr(any(rcc_wl5, rcc_wle), path = "wl.rs")] mod _version; #[cfg(feature = "low-power")] use core::sync::atomic::{AtomicU32, Ordering}; diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index 7664557e9..2bbacbbdc 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs @@ -170,7 +170,7 @@ impl Config { RCC.icscr1().modify(|w| { w.set_msisrange(range); - w.set_msirgsel(Msirgsel::RCC_ICSCR1); + w.set_msirgsel(Msirgsel::ICSCR1); }); RCC.cr().write(|w| { w.set_msipllen(false); diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs deleted file mode 100644 index 4d68b55c2..000000000 --- a/embassy-stm32/src/rcc/wl.rs +++ /dev/null @@ -1,184 +0,0 @@ -pub use crate::pac::pwr::vals::Vos as VoltageScale; -use crate::pac::rcc::vals::Sw; -pub use crate::pac::rcc::vals::{ - Adcsel as AdcClockSource, Hpre as AHBPrescaler, Msirange as MSIRange, Pllm, Plln, Pllp, Pllq, Pllr, - Pllsrc as PllSource, Ppre as APBPrescaler, -}; -use crate::pac::{FLASH, RCC}; -use crate::rcc::{set_freqs, Clocks}; -use crate::time::Hertz; - -/// HSI speed -pub const HSI_FREQ: Hertz = Hertz(16_000_000); - -/// HSE speed -pub const HSE_FREQ: Hertz = Hertz(32_000_000); - -/// System clock mux source -#[derive(Clone, Copy)] -pub enum ClockSrc { - MSI(MSIRange), - HSE, - HSI, -} - -/// Clocks configutation -pub struct Config { - pub mux: ClockSrc, - pub ahb_pre: AHBPrescaler, - pub shd_ahb_pre: AHBPrescaler, - pub apb1_pre: APBPrescaler, - pub apb2_pre: APBPrescaler, - pub adc_clock_source: AdcClockSource, - pub ls: super::LsConfig, -} - -impl Default for Config { - #[inline] - fn default() -> Config { - Config { - mux: ClockSrc::MSI(MSIRange::RANGE4M), - ahb_pre: AHBPrescaler::DIV1, - shd_ahb_pre: AHBPrescaler::DIV1, - apb1_pre: APBPrescaler::DIV1, - apb2_pre: APBPrescaler::DIV1, - adc_clock_source: AdcClockSource::HSI, - ls: Default::default(), - } - } -} - -pub(crate) unsafe fn init(config: Config) { - let (sys_clk, sw, vos) = match config.mux { - ClockSrc::HSI => (HSI_FREQ, Sw::HSI, VoltageScale::RANGE2), - ClockSrc::HSE => (HSE_FREQ, Sw::HSE, VoltageScale::RANGE1), - ClockSrc::MSI(range) => (msirange_to_hertz(range), Sw::MSI, msirange_to_vos(range)), - }; - - let ahb_freq = sys_clk / config.ahb_pre; - let shd_ahb_freq = sys_clk / config.shd_ahb_pre; - - let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, freq * 2u32) - } - }; - - let (apb2_freq, apb2_tim_freq) = match config.apb2_pre { - APBPrescaler::DIV1 => (ahb_freq, ahb_freq), - pre => { - let freq = ahb_freq / pre; - (freq, freq * 2u32) - } - }; - - // Adjust flash latency - let flash_clk_src_freq = shd_ahb_freq; - let ws = match vos { - VoltageScale::RANGE1 => match flash_clk_src_freq.0 { - 0..=18_000_000 => 0b000, - 18_000_001..=36_000_000 => 0b001, - _ => 0b010, - }, - VoltageScale::RANGE2 => match flash_clk_src_freq.0 { - 0..=6_000_000 => 0b000, - 6_000_001..=12_000_000 => 0b001, - _ => 0b010, - }, - _ => unreachable!(), - }; - - FLASH.acr().modify(|w| { - w.set_latency(ws); - }); - - while FLASH.acr().read().latency() != ws {} - - match config.mux { - ClockSrc::HSI => { - // Enable HSI - RCC.cr().write(|w| w.set_hsion(true)); - while !RCC.cr().read().hsirdy() {} - } - ClockSrc::HSE => { - // Enable HSE - RCC.cr().write(|w| { - w.set_hsebyppwr(true); - w.set_hseon(true); - }); - while !RCC.cr().read().hserdy() {} - } - ClockSrc::MSI(range) => { - let cr = RCC.cr().read(); - assert!(!cr.msion() || cr.msirdy()); - RCC.cr().write(|w| { - w.set_msirgsel(true); - 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() {} - } - } - - RCC.extcfgr().modify(|w| { - w.set_shdhpre(config.shd_ahb_pre); - }); - - RCC.cfgr().modify(|w| { - w.set_sw(sw.into()); - w.set_hpre(config.ahb_pre); - w.set_ppre1(config.apb1_pre); - w.set_ppre2(config.apb2_pre); - }); - - // ADC clock MUX - RCC.ccipr().modify(|w| w.set_adcsel(config.adc_clock_source)); - - // TODO: switch voltage range - - let rtc = config.ls.init(); - - set_freqs(Clocks { - sys: sys_clk, - hclk1: ahb_freq, - hclk2: ahb_freq, - hclk3: shd_ahb_freq, - pclk1: apb1_freq, - pclk2: apb2_freq, - pclk3: shd_ahb_freq, - pclk1_tim: apb1_tim_freq, - pclk2_tim: apb2_tim_freq, - rtc, - }); -} - -fn msirange_to_hertz(range: MSIRange) -> Hertz { - match range { - MSIRange::RANGE100K => Hertz(100_000), - MSIRange::RANGE200K => Hertz(200_000), - MSIRange::RANGE400K => Hertz(400_000), - MSIRange::RANGE800K => Hertz(800_000), - MSIRange::RANGE1M => Hertz(1_000_000), - MSIRange::RANGE2M => Hertz(2_000_000), - MSIRange::RANGE4M => Hertz(4_000_000), - MSIRange::RANGE8M => Hertz(8_000_000), - MSIRange::RANGE16M => Hertz(16_000_000), - MSIRange::RANGE24M => Hertz(24_000_000), - MSIRange::RANGE32M => Hertz(32_000_000), - MSIRange::RANGE48M => Hertz(48_000_000), - _ => unreachable!(), - } -} - -fn msirange_to_vos(range: MSIRange) -> VoltageScale { - if range.to_bits() > MSIRange::RANGE16M.to_bits() { - VoltageScale::RANGE1 - } else { - VoltageScale::RANGE2 - } -} diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index fec0a349d..69527c9ad 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs @@ -5,7 +5,6 @@ use chrono::{NaiveDate, NaiveDateTime}; use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, LsConfig, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv}; use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::time::Hertz; use embassy_stm32::Config; @@ -15,17 +14,23 @@ use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); - config.rcc.mux = ClockSrc::PLL1_R; - config.rcc.hse = Some(Hertz::mhz(8)); - config.rcc.pll = Some(Pll { - source: PLLSource::HSE, - prediv: PllPreDiv::DIV1, - mul: PllMul::MUL20, - divp: None, - divq: None, - divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) - }); - config.rcc.ls = LsConfig::default_lse(); + { + use embassy_stm32::rcc::*; + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.hse = Some(Hse { + freq: Hertz::mhz(8), + mode: HseMode::Oscillator, + }); + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL20, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) + }); + config.rcc.ls = LsConfig::default_lse(); + } let p = embassy_stm32::init(config); info!("Hello World!"); diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 3c9d2cfc0..f76b504a7 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs @@ -48,7 +48,6 @@ use embassy_net_adin1110::{self, Device, Runner, ADIN1110}; use embedded_hal_bus::spi::ExclusiveDevice; use hal::gpio::Pull; use hal::i2c::Config as I2C_Config; -use hal::rcc::{ClockSrc, PLLSource, Pll, PllMul, PllPreDiv, PllRDiv}; use hal::spi::{Config as SPI_Config, Spi}; use hal::time::Hertz; @@ -74,20 +73,25 @@ async fn main(spawner: Spawner) { defmt::println!("Start main()"); let mut config = embassy_stm32::Config::default(); - - // 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(Hertz::mhz(8)); - config.rcc.pll = Some(Pll { - source: PLLSource::HSE, - prediv: PllPreDiv::DIV1, - mul: PllMul::MUL20, - divp: None, - divq: None, - divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) - }); - config.rcc.hsi48 = true; // needed for rng + { + use embassy_stm32::rcc::*; + // 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 { + freq: Hertz::mhz(8), + mode: HseMode::Oscillator, + }); + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV1, + mul: PllMul::MUL20, + divp: None, + divq: None, + divr: Some(PllRDiv::DIV2), // sysclk 80Mhz clock (8 / 1 * 20 / 2) + }); + config.rcc.hsi48 = true; // needed for rng + } let dp = embassy_stm32::init(config); diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs index 8c789afbc..e26c274ad 100644 --- a/examples/stm32wl/src/bin/lora_lorawan.rs +++ b/examples/stm32wl/src/bin/lora_lorawan.rs @@ -12,7 +12,8 @@ use embassy_lora::LoraTimer; use embassy_stm32::gpio::{Level, Output, Pin, Speed}; use embassy_stm32::rng::{self, Rng}; use embassy_stm32::spi::Spi; -use embassy_stm32::{bind_interrupts, pac, peripherals}; +use embassy_stm32::time::Hertz; +use embassy_stm32::{bind_interrupts, peripherals}; use embassy_time::Delay; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; @@ -33,11 +34,24 @@ bind_interrupts!(struct Irqs{ #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); + } let p = embassy_stm32::init(config); - pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01)); - let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2); // Set CTRL1 and CTRL3 for high-power transmission, while CTRL2 acts as an RF switch between tx and rx diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs index 70676c704..2cf7ef9d0 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs @@ -4,9 +4,9 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::rcc::{ClockSrc, MSIRange}; use embassy_stm32::rng::{self, Rng}; -use embassy_stm32::{bind_interrupts, pac, peripherals}; +use embassy_stm32::time::Hertz; +use embassy_stm32::{bind_interrupts, peripherals}; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs{ @@ -16,11 +16,24 @@ bind_interrupts!(struct Irqs{ #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); - config.rcc.mux = ClockSrc::MSI(MSIRange::RANGE32M); + { + use embassy_stm32::rcc::*; + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) + }); + } let p = embassy_stm32::init(config); - pac::RCC.ccipr().modify(|w| w.set_rngsel(0b11)); // msi - info!("Hello World!"); let mut rng = Rng::new(p.RNG, Irqs); diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 0a70e6a7e..cb1738154 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs @@ -402,9 +402,18 @@ pub fn config() -> Config { #[cfg(feature = "stm32wl55jc")] { use embassy_stm32::rcc::*; - config.rcc.mux = ClockSrc::MSI(MSIRange::RANGE32M); - embassy_stm32::pac::RCC.ccipr().modify(|w| { - w.set_rngsel(0b11); // msi + config.rcc.hse = Some(Hse { + freq: Hertz(32_000_000), + mode: HseMode::Bypass, + }); + config.rcc.mux = ClockSrc::PLL1_R; + config.rcc.pll = Some(Pll { + source: PLLSource::HSE, + prediv: PllPreDiv::DIV2, + mul: PllMul::MUL6, + divp: None, + divq: Some(PllQDiv::DIV2), // PLL1_Q clock (32 / 2 * 6 / 2), used for RNG + divr: Some(PllRDiv::DIV2), // sysclk 48Mhz clock (32 / 2 * 6 / 2) }); }