stm32/rcc: merge wb into l4/l5.

This commit is contained in:
Dario Nieuwenhuis 2023-10-23 01:09:36 +02:00
parent 64ab23d17d
commit 0ef1cb29f7
10 changed files with 146 additions and 292 deletions

View File

@ -58,7 +58,7 @@ rand_core = "0.6.3"
sdio-host = "0.5.0" sdio-host = "0.5.0"
embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
critical-section = "1.1" critical-section = "1.1"
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4ddcb77c9d213d11eebb048f40e112bc54163cdc" } stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-bcc9b6bf9fa195e91625849efc4ba473d9ace4e9" }
vcell = "0.1.3" vcell = "0.1.3"
bxcan = "0.7.0" bxcan = "0.7.0"
nb = "1.0.0" nb = "1.0.0"
@ -76,7 +76,7 @@ critical-section = { version = "1.1", features = ["std"] }
[build-dependencies] [build-dependencies]
proc-macro2 = "1.0.36" proc-macro2 = "1.0.36"
quote = "1.0.15" quote = "1.0.15"
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-4ddcb77c9d213d11eebb048f40e112bc54163cdc", default-features = false, features = ["metadata"]} stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-bcc9b6bf9fa195e91625849efc4ba473d9ace4e9", default-features = false, features = ["metadata"]}
[features] [features]

View File

@ -1,7 +1,8 @@
use crate::pac::rcc::regs::Cfgr; use crate::pac::rcc::regs::Cfgr;
#[cfg(not(stm32wl))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
pub use crate::pac::rcc::vals::Clk48sel as Clk48Src; pub use crate::pac::rcc::vals::Clk48sel as Clk48Src;
use crate::pac::rcc::vals::Msirgsel; #[cfg(any(stm32wb, stm32wl))]
pub use crate::pac::rcc::vals::Hsepre as HsePrescaler;
pub use crate::pac::rcc::vals::{ pub use crate::pac::rcc::vals::{
Hpre as AHBPrescaler, Msirange as MSIRange, Pllm as PllPreDiv, Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, 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, Pllr as PllRDiv, Pllsrc as PLLSource, Ppre as APBPrescaler, Sw as ClockSrc,
@ -27,6 +28,9 @@ pub struct Hse {
pub freq: Hertz, pub freq: Hertz,
/// HSE mode. /// HSE mode.
pub mode: HseMode, pub mode: HseMode,
/// HSE prescaler
#[cfg(any(stm32wb, stm32wl))]
pub prescaler: HsePrescaler,
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@ -54,12 +58,12 @@ pub struct Config {
pub msi: Option<MSIRange>, pub msi: Option<MSIRange>,
pub hsi: bool, pub hsi: bool,
pub hse: Option<Hse>, pub hse: Option<Hse>,
#[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))]
pub hsi48: bool, pub hsi48: bool,
// pll // pll
pub pll: Option<Pll>, pub pll: Option<Pll>,
#[cfg(any(stm32l4, stm32l5))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
pub pllsai1: Option<Pll>, pub pllsai1: Option<Pll>,
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
pub pllsai2: Option<Pll>, pub pllsai2: Option<Pll>,
@ -69,11 +73,13 @@ pub struct Config {
pub ahb_pre: AHBPrescaler, pub ahb_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler, pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler, pub apb2_pre: APBPrescaler,
#[cfg(stm32wl)] #[cfg(any(stm32wl5x, stm32wb))]
pub core2_ahb_pre: AHBPrescaler,
#[cfg(any(stm32wl, stm32wb))]
pub shared_ahb_pre: AHBPrescaler, pub shared_ahb_pre: AHBPrescaler,
// muxes // muxes
#[cfg(not(stm32wl))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
pub clk48_src: Clk48Src, pub clk48_src: Clk48Src,
// low speed LSI/LSE/RTC // low speed LSI/LSE/RTC
@ -91,28 +97,63 @@ impl Default for Config {
ahb_pre: AHBPrescaler::DIV1, ahb_pre: AHBPrescaler::DIV1,
apb1_pre: APBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1,
#[cfg(stm32wl)] #[cfg(any(stm32wl5x, stm32wb))]
core2_ahb_pre: AHBPrescaler::DIV1,
#[cfg(any(stm32wl, stm32wb))]
shared_ahb_pre: AHBPrescaler::DIV1, shared_ahb_pre: AHBPrescaler::DIV1,
pll: None, pll: None,
#[cfg(any(stm32l4, stm32l5))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
pllsai1: None, pllsai1: None,
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
pllsai2: None, pllsai2: None,
#[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))]
hsi48: true, hsi48: true,
#[cfg(not(stm32wl))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
clk48_src: Clk48Src::HSI48, clk48_src: Clk48Src::HSI48,
ls: Default::default(), ls: Default::default(),
} }
} }
} }
#[cfg(stm32wb)]
pub const WPAN_DEFAULT: Config = Config {
hse: Some(Hse {
freq: Hertz(32_000_000),
mode: HseMode::Oscillator,
prescaler: HsePrescaler::DIV1,
}),
mux: ClockSrc::PLL1_R,
hsi48: true,
msi: None,
hsi: false,
clk48_src: Clk48Src::PLL1_Q,
ls: super::LsConfig::default_lse(),
pll: Some(Pll {
source: PLLSource::HSE,
prediv: PllPreDiv::DIV2,
mul: PllMul::MUL12,
divp: Some(PllPDiv::DIV3), // 32 / 2 * 12 / 3 = 64Mhz
divq: Some(PllQDiv::DIV4), // 32 / 2 * 12 / 4 = 48Mhz
divr: Some(PllRDiv::DIV3), // 32 / 2 * 12 / 3 = 64Mhz
}),
pllsai1: None,
ahb_pre: AHBPrescaler::DIV1,
core2_ahb_pre: AHBPrescaler::DIV2,
shared_ahb_pre: AHBPrescaler::DIV1,
apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1,
};
pub(crate) unsafe fn init(config: Config) { pub(crate) unsafe fn init(config: Config) {
// Switch to MSI to prevent problems with PLL configuration. // Switch to MSI to prevent problems with PLL configuration.
if !RCC.cr().read().msion() { if !RCC.cr().read().msion() {
// Turn on MSI and configure it to 4MHz. // Turn on MSI and configure it to 4MHz.
RCC.cr().modify(|w| { RCC.cr().modify(|w| {
w.set_msirgsel(Msirgsel::CR); #[cfg(not(stm32wb))]
w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR);
w.set_msirange(MSIRange::RANGE4M); w.set_msirange(MSIRange::RANGE4M);
w.set_msipllen(false); w.set_msipllen(false);
w.set_msion(true) w.set_msion(true)
@ -138,8 +179,9 @@ pub(crate) unsafe fn init(config: Config) {
let msi = config.msi.map(|range| { let msi = config.msi.map(|range| {
// Enable MSI // Enable MSI
RCC.cr().modify(|w| { RCC.cr().modify(|w| {
#[cfg(not(stm32wb))]
w.set_msirgsel(crate::pac::rcc::vals::Msirgsel::CR);
w.set_msirange(range); w.set_msirange(range);
w.set_msirgsel(Msirgsel::CR);
w.set_msion(true); w.set_msion(true);
// If LSE is enabled, enable calibration of MSI // If LSE is enabled, enable calibration of MSI
@ -173,7 +215,7 @@ pub(crate) unsafe fn init(config: Config) {
hse.freq hse.freq
}); });
#[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5))] #[cfg(any(all(stm32l4, not(any(stm32l47x, stm32l48x))), stm32l5, stm32wb))]
let hsi48 = config.hsi48.then(|| { let hsi48 = config.hsi48.then(|| {
RCC.crrcr().modify(|w| w.set_hsi48on(true)); RCC.crrcr().modify(|w| w.set_hsi48on(true));
while !RCC.crrcr().read().hsi48rdy() {} while !RCC.crrcr().read().hsi48rdy() {}
@ -185,7 +227,7 @@ pub(crate) unsafe fn init(config: Config) {
let _plls = [ let _plls = [
&config.pll, &config.pll,
#[cfg(any(stm32l4, stm32l5))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
&config.pllsai1, &config.pllsai1,
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
&config.pllsai2, &config.pllsai2,
@ -214,7 +256,7 @@ pub(crate) unsafe fn init(config: Config) {
let pll_input = PllInput { hse, hsi, msi }; let pll_input = PllInput { hse, hsi, msi };
let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); let pll = init_pll(PllInstance::Pll, config.pll, &pll_input);
#[cfg(any(stm32l4, stm32l5))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input);
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input); let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input);
@ -230,7 +272,7 @@ pub(crate) unsafe fn init(config: Config) {
RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src)); RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src));
#[cfg(stm32l5)] #[cfg(stm32l5)]
RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src)); RCC.ccipr1().modify(|w| w.set_clk48sel(config.clk48_src));
#[cfg(not(stm32wl))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
let _clk48 = match config.clk48_src { let _clk48 = match config.clk48_src {
Clk48Src::HSI48 => hsi48, Clk48Src::HSI48 => hsi48,
Clk48Src::MSI => msi, Clk48Src::MSI => msi,
@ -261,7 +303,9 @@ pub(crate) unsafe fn init(config: Config) {
} }
}; };
#[cfg(stm32wl)] #[cfg(any(stm32wl5x, stm32wb))]
let _ahb2_freq = sys_clk / config.core2_ahb_pre;
#[cfg(any(stm32wl, stm32wb))]
let ahb3_freq = sys_clk / config.shared_ahb_pre; let ahb3_freq = sys_clk / config.shared_ahb_pre;
// Set flash wait states // Set flash wait states
@ -290,6 +334,15 @@ pub(crate) unsafe fn init(config: Config) {
..=36_000_000 => 1, ..=36_000_000 => 1,
_ => 2, _ => 2,
}; };
#[cfg(stm32wb)]
let latency = match ahb3_freq.0 {
// VOS RANGE1, others TODO.
..=18_000_000 => 0,
..=36_000_000 => 1,
..=54_000_000 => 2,
..=64_000_000 => 3,
_ => 4,
};
FLASH.acr().modify(|w| w.set_latency(latency)); FLASH.acr().modify(|w| w.set_latency(latency));
while FLASH.acr().read().latency() != latency {} while FLASH.acr().read().latency() != latency {}
@ -302,12 +355,16 @@ pub(crate) unsafe fn init(config: Config) {
}); });
while RCC.cfgr().read().sws() != config.mux {} while RCC.cfgr().read().sws() != config.mux {}
#[cfg(stm32wl)] #[cfg(any(stm32wl, stm32wb))]
{ {
RCC.extcfgr().modify(|w| { RCC.extcfgr().modify(|w| {
w.set_shdhpre(config.shared_ahb_pre); w.set_shdhpre(config.shared_ahb_pre);
#[cfg(any(stm32wl5x, stm32wb))]
w.set_c2hpre(config.core2_ahb_pre);
}); });
while !RCC.extcfgr().read().shdhpref() {} while !RCC.extcfgr().read().shdhpref() {}
#[cfg(any(stm32wl5x, stm32wb))]
while !RCC.extcfgr().read().c2hpref() {}
} }
set_freqs(Clocks { set_freqs(Clocks {
@ -387,7 +444,7 @@ struct PllOutput {
#[derive(PartialEq, Eq, Clone, Copy)] #[derive(PartialEq, Eq, Clone, Copy)]
enum PllInstance { enum PllInstance {
Pll, Pll,
#[cfg(any(stm32l4, stm32l5))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
Pllsai1, Pllsai1,
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
Pllsai2, Pllsai2,
@ -400,7 +457,7 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll
RCC.cr().modify(|w| w.set_pllon(false)); RCC.cr().modify(|w| w.set_pllon(false));
while RCC.cr().read().pllrdy() {} while RCC.cr().read().pllrdy() {}
} }
#[cfg(any(stm32l4, stm32l5))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
PllInstance::Pllsai1 => { PllInstance::Pllsai1 => {
RCC.cr().modify(|w| w.set_pllsai1on(false)); RCC.cr().modify(|w| w.set_pllsai1on(false));
while RCC.cr().read().pllsai1rdy() {} while RCC.cr().read().pllsai1rdy() {}
@ -459,7 +516,7 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll
w.set_pllsrc(pll.source); w.set_pllsrc(pll.source);
write_fields!(w); write_fields!(w);
}), }),
#[cfg(any(stm32l4, stm32l5))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| { PllInstance::Pllsai1 => RCC.pllsai1cfgr().write(|w| {
#[cfg(any(rcc_l4plus, stm32l5))] #[cfg(any(rcc_l4plus, stm32l5))]
w.set_pllm(pll.prediv); w.set_pllm(pll.prediv);
@ -483,7 +540,7 @@ fn init_pll(instance: PllInstance, config: Option<Pll>, input: &PllInput) -> Pll
RCC.cr().modify(|w| w.set_pllon(true)); RCC.cr().modify(|w| w.set_pllon(true));
while !RCC.cr().read().pllrdy() {} while !RCC.cr().read().pllrdy() {}
} }
#[cfg(any(stm32l4, stm32l5))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
PllInstance::Pllsai1 => { PllInstance::Pllsai1 => {
RCC.cr().modify(|w| w.set_pllsai1on(true)); RCC.cr().modify(|w| w.set_pllsai1on(true));
while !RCC.cr().read().pllsai1rdy() {} while !RCC.cr().read().pllsai1rdy() {}

View File

@ -19,9 +19,8 @@ pub use mco::*;
#[cfg_attr(rcc_g4, path = "g4.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_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_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")]
#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5, rcc_wl5, rcc_wle), path = "l4l5.rs")] #[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5, rcc_wl5, rcc_wle, rcc_wb), path = "l4l5.rs")]
#[cfg_attr(rcc_u5, path = "u5.rs")] #[cfg_attr(rcc_u5, path = "u5.rs")]
#[cfg_attr(rcc_wb, path = "wb.rs")]
#[cfg_attr(rcc_wba, path = "wba.rs")] #[cfg_attr(rcc_wba, path = "wba.rs")]
mod _version; mod _version;
#[cfg(feature = "low-power")] #[cfg(feature = "low-power")]

View File

@ -1,258 +0,0 @@
pub use crate::pac::rcc::vals::{
Hpre as AHBPrescaler, Hsepre as HsePrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Pllsrc as PllSource,
Ppre as APBPrescaler, Sw as Sysclk,
};
use crate::rcc::{set_freqs, Clocks};
use crate::time::{mhz, Hertz};
/// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
pub struct Hse {
pub prediv: HsePrescaler,
pub frequency: Hertz,
}
pub struct PllMux {
/// Source clock selection.
pub source: PllSource,
/// PLL pre-divider (DIVM). Must be between 1 and 63.
pub prediv: Pllm,
}
pub struct Pll {
/// PLL multiplication factor. Must be between 4 and 512.
pub mul: Plln,
/// PLL P division factor. If None, PLL P output is disabled. Must be between 1 and 128.
/// On PLL1, it must be even (in particular, it cannot be 1.)
pub divp: Option<Pllp>,
/// PLL Q division factor. If None, PLL Q output is disabled. Must be between 1 and 128.
pub divq: Option<Pllq>,
/// PLL R division factor. If None, PLL R output is disabled. Must be between 1 and 128.
pub divr: Option<Pllr>,
}
/// Clocks configutation
pub struct Config {
pub hse: Option<Hse>,
pub sys: Sysclk,
pub mux: Option<PllMux>,
pub hsi48: bool,
pub pll: Option<Pll>,
pub pllsai: Option<Pll>,
pub ahb1_pre: AHBPrescaler,
pub ahb2_pre: AHBPrescaler,
pub ahb3_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler,
pub ls: super::LsConfig,
}
pub const WPAN_DEFAULT: Config = Config {
hse: Some(Hse {
frequency: mhz(32),
prediv: HsePrescaler::DIV1,
}),
sys: Sysclk::PLL1_R,
mux: Some(PllMux {
source: PllSource::HSE,
prediv: Pllm::DIV2,
}),
hsi48: true,
ls: super::LsConfig::default_lse(),
pll: Some(Pll {
mul: Plln::MUL12,
divp: Some(Pllp::DIV3),
divq: Some(Pllq::DIV4),
divr: Some(Pllr::DIV3),
}),
pllsai: None,
ahb1_pre: AHBPrescaler::DIV1,
ahb2_pre: AHBPrescaler::DIV2,
ahb3_pre: AHBPrescaler::DIV1,
apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1,
};
impl Default for Config {
#[inline]
fn default() -> Config {
Config {
sys: Sysclk::HSI,
hse: None,
mux: None,
pll: None,
pllsai: None,
hsi48: true,
ls: Default::default(),
ahb1_pre: AHBPrescaler::DIV1,
ahb2_pre: AHBPrescaler::DIV1,
ahb3_pre: AHBPrescaler::DIV1,
apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1,
}
}
}
#[cfg(stm32wb)]
/// RCC initialization function
pub(crate) unsafe fn init(config: Config) {
let hse_clk = config.hse.as_ref().map(|hse| hse.frequency / hse.prediv);
let mux_clk = config.mux.as_ref().map(|pll_mux| {
(match pll_mux.source {
PllSource::HSE => hse_clk.unwrap(),
PllSource::HSI => HSI_FREQ,
_ => unreachable!(),
} / pll_mux.prediv)
});
let (pll_r, _pll_q, _pll_p) = match &config.pll {
Some(pll) => {
let pll_vco = mux_clk.unwrap() * pll.mul as u32;
(
pll.divr.map(|divr| pll_vco / divr),
pll.divq.map(|divq| pll_vco / divq),
pll.divp.map(|divp| pll_vco / divp),
)
}
None => (None, None, None),
};
let sys_clk = match config.sys {
Sysclk::HSE => hse_clk.unwrap(),
Sysclk::HSI => HSI_FREQ,
Sysclk::PLL1_R => pll_r.unwrap(),
_ => unreachable!(),
};
let ahb1_clk = sys_clk / config.ahb1_pre;
let ahb2_clk = sys_clk / config.ahb2_pre;
let ahb3_clk = sys_clk / config.ahb3_pre;
let (apb1_clk, apb1_tim_clk) = match config.apb1_pre {
APBPrescaler::DIV1 => (ahb1_clk, ahb1_clk),
pre => {
let freq = ahb1_clk / pre;
(freq, freq * 2u32)
}
};
let (apb2_clk, apb2_tim_clk) = match config.apb2_pre {
APBPrescaler::DIV1 => (ahb1_clk, ahb1_clk),
pre => {
let freq = ahb1_clk / pre;
(freq, freq * 2u32)
}
};
let rcc = crate::pac::RCC;
let needs_hsi = if let Some(pll_mux) = &config.mux {
pll_mux.source == PllSource::HSI
} else {
false
};
if needs_hsi || config.sys == Sysclk::HSI {
rcc.cr().modify(|w| {
w.set_hsion(true);
});
while !rcc.cr().read().hsirdy() {}
}
rcc.cfgr().modify(|w| w.set_stopwuck(true));
let rtc = config.ls.init();
match &config.hse {
Some(hse) => {
rcc.cr().modify(|w| {
w.set_hsepre(hse.prediv);
w.set_hseon(true);
});
while !rcc.cr().read().hserdy() {}
}
_ => {}
}
match &config.mux {
Some(pll_mux) => {
rcc.pllcfgr().modify(|w| {
w.set_pllm(pll_mux.prediv);
w.set_pllsrc(pll_mux.source.into());
});
}
_ => {}
};
match &config.pll {
Some(pll) => {
rcc.pllcfgr().modify(|w| {
w.set_plln(pll.mul);
pll.divp.map(|divp| {
w.set_pllpen(true);
w.set_pllp(divp)
});
pll.divq.map(|divq| {
w.set_pllqen(true);
w.set_pllq(divq)
});
pll.divr.map(|divr| {
w.set_pllren(true);
w.set_pllr(divr);
});
});
rcc.cr().modify(|w| w.set_pllon(true));
while !rcc.cr().read().pllrdy() {}
}
_ => {}
}
let _hsi48 = config.hsi48.then(|| {
rcc.crrcr().modify(|w| w.set_hsi48on(true));
while !rcc.crrcr().read().hsi48rdy() {}
Hertz(48_000_000)
});
rcc.cfgr().modify(|w| {
w.set_sw(config.sys.into());
w.set_hpre(config.ahb1_pre);
w.set_ppre1(config.apb1_pre);
w.set_ppre2(config.apb2_pre);
});
rcc.extcfgr().modify(|w| {
w.set_c2hpre(config.ahb2_pre);
w.set_shdhpre(config.ahb3_pre);
});
set_freqs(Clocks {
sys: sys_clk,
hclk1: ahb1_clk,
hclk2: ahb2_clk,
hclk3: ahb3_clk,
pclk1: apb1_clk,
pclk2: apb2_clk,
pclk1_tim: apb1_tim_clk,
pclk2_tim: apb2_tim_clk,
rtc,
})
}

View File

@ -39,6 +39,7 @@ async fn main(_spawner: Spawner) {
config.rcc.hse = Some(Hse { config.rcc.hse = Some(Hse {
freq: Hertz(32_000_000), freq: Hertz(32_000_000),
mode: HseMode::Bypass, mode: HseMode::Bypass,
prescaler: HsePrescaler::DIV1,
}); });
config.rcc.mux = ClockSrc::PLL1_R; config.rcc.mux = ClockSrc::PLL1_R;
config.rcc.pll = Some(Pll { config.rcc.pll = Some(Pll {

View File

@ -11,6 +11,7 @@ use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant};
use embassy_stm32::bind_interrupts; use embassy_stm32::bind_interrupts;
use embassy_stm32::gpio::{Level, Output, Pin, Speed}; use embassy_stm32::gpio::{Level, Output, Pin, Speed};
use embassy_stm32::spi::Spi; use embassy_stm32::spi::Spi;
use embassy_stm32::time::Hertz;
use embassy_time::{Delay, Timer}; use embassy_time::{Delay, Timer};
use lora_phy::mod_params::*; use lora_phy::mod_params::*;
use lora_phy::sx1261_2::SX1261_2; use lora_phy::sx1261_2::SX1261_2;
@ -26,7 +27,23 @@ bind_interrupts!(struct Irqs{
#[embassy_executor::main] #[embassy_executor::main]
async fn main(_spawner: Spawner) { async fn main(_spawner: Spawner) {
let mut config = embassy_stm32::Config::default(); 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,
prescaler: HsePrescaler::DIV1,
});
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); let p = embassy_stm32::init(config);
let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2); let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2);

View File

@ -11,6 +11,7 @@ use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant};
use embassy_stm32::bind_interrupts; use embassy_stm32::bind_interrupts;
use embassy_stm32::gpio::{Level, Output, Pin, Speed}; use embassy_stm32::gpio::{Level, Output, Pin, Speed};
use embassy_stm32::spi::Spi; use embassy_stm32::spi::Spi;
use embassy_stm32::time::Hertz;
use embassy_time::Delay; use embassy_time::Delay;
use lora_phy::mod_params::*; use lora_phy::mod_params::*;
use lora_phy::sx1261_2::SX1261_2; use lora_phy::sx1261_2::SX1261_2;
@ -26,7 +27,23 @@ bind_interrupts!(struct Irqs{
#[embassy_executor::main] #[embassy_executor::main]
async fn main(_spawner: Spawner) { async fn main(_spawner: Spawner) {
let mut config = embassy_stm32::Config::default(); 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,
prescaler: HsePrescaler::DIV1,
});
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); let p = embassy_stm32::init(config);
let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2); let spi = Spi::new_subghz(p.SUBGHZSPI, p.DMA1_CH1, p.DMA1_CH2);

View File

@ -21,6 +21,7 @@ async fn main(_spawner: Spawner) {
config.rcc.hse = Some(Hse { config.rcc.hse = Some(Hse {
freq: Hertz(32_000_000), freq: Hertz(32_000_000),
mode: HseMode::Bypass, mode: HseMode::Bypass,
prescaler: HsePrescaler::DIV1,
}); });
config.rcc.mux = ClockSrc::PLL1_R; config.rcc.mux = ClockSrc::PLL1_R;
config.rcc.pll = Some(Pll { config.rcc.pll = Some(Pll {

View File

@ -5,20 +5,34 @@
use chrono::{NaiveDate, NaiveDateTime}; use chrono::{NaiveDate, NaiveDateTime};
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::rcc::{ClockSrc, LsConfig};
use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::rtc::{Rtc, RtcConfig};
use embassy_stm32::time::Hertz;
use embassy_stm32::Config; use embassy_stm32::Config;
use embassy_time::Timer; use embassy_time::Timer;
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main] #[embassy_executor::main]
async fn main(_spawner: Spawner) { async fn main(_spawner: Spawner) {
let p = {
let mut config = Config::default(); let mut config = Config::default();
config.rcc.mux = ClockSrc::HSE; {
use embassy_stm32::rcc::*;
config.rcc.ls = LsConfig::default_lse(); config.rcc.ls = LsConfig::default_lse();
embassy_stm32::init(config) config.rcc.hse = Some(Hse {
}; freq: Hertz(32_000_000),
mode: HseMode::Bypass,
prescaler: HsePrescaler::DIV1,
});
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);
info!("Hello World!"); info!("Hello World!");
let now = NaiveDate::from_ymd_opt(2020, 5, 15) let now = NaiveDate::from_ymd_opt(2020, 5, 15)

View File

@ -227,6 +227,11 @@ pub fn config() -> Config {
#[allow(unused_mut)] #[allow(unused_mut)]
let mut config = Config::default(); let mut config = Config::default();
#[cfg(feature = "stm32wb55rg")]
{
config.rcc = embassy_stm32::rcc::WPAN_DEFAULT;
}
#[cfg(feature = "stm32f207zg")] #[cfg(feature = "stm32f207zg")]
{ {
use embassy_stm32::rcc::*; use embassy_stm32::rcc::*;
@ -405,6 +410,7 @@ pub fn config() -> Config {
config.rcc.hse = Some(Hse { config.rcc.hse = Some(Hse {
freq: Hertz(32_000_000), freq: Hertz(32_000_000),
mode: HseMode::Bypass, mode: HseMode::Bypass,
prescaler: HsePrescaler::DIV1,
}); });
config.rcc.mux = ClockSrc::PLL1_R; config.rcc.mux = ClockSrc::PLL1_R;
config.rcc.pll = Some(Pll { config.rcc.pll = Some(Pll {