stm32/rcc: add LSE/LSI to all chips, add RTC to more chips.

This commit is contained in:
Dario Nieuwenhuis 2023-10-11 03:53:27 +02:00
parent 5a19d18b9c
commit b91d1eaca0
31 changed files with 267 additions and 403 deletions

View File

@ -59,7 +59,7 @@ 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"
atomic-polyfill = "1.0.1" atomic-polyfill = "1.0.1"
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9f45b0c48cc3de71ec6a66fe7e871b21aef0940c" } stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6bfa5a0dcec6a9bd42cea94ba11eeae1a17a7f2c" }
vcell = "0.1.3" vcell = "0.1.3"
bxcan = "0.7.0" bxcan = "0.7.0"
nb = "1.0.0" nb = "1.0.0"
@ -77,7 +77,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-9f45b0c48cc3de71ec6a66fe7e871b21aef0940c", default-features = false, features = ["metadata"]} stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6bfa5a0dcec6a9bd42cea94ba11eeae1a17a7f2c", default-features = false, features = ["metadata"]}
[features] [features]

View File

@ -1,14 +1,24 @@
use core::sync::atomic::{compiler_fence, Ordering};
use crate::pac::common::{Reg, RW};
pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource;
use crate::time::Hertz;
#[cfg(any(stm32f0, stm32f1, stm32f3))]
pub const LSI_FREQ: Hertz = Hertz(40_000);
#[cfg(not(any(stm32f0, stm32f1, stm32f3)))]
pub const LSI_FREQ: Hertz = Hertz(32_000);
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum LseCfg { pub enum LseMode {
Oscillator(LseDrive), Oscillator(LseDrive),
Bypass, Bypass,
} }
impl Default for LseCfg { pub struct LseConfig {
fn default() -> Self { pub frequency: Hertz,
Self::Oscillator(Default::default()) pub mode: LseMode,
}
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -36,90 +46,116 @@ impl From<LseDrive> for crate::pac::rcc::vals::Lsedrv {
} }
} }
pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource;
#[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))] #[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))]
#[allow(dead_code)]
type Bdcr = crate::pac::rcc::regs::Bdcr; type Bdcr = crate::pac::rcc::regs::Bdcr;
#[cfg(any(rtc_v2l0, rtc_v2l1))] #[cfg(any(rtc_v2l0, rtc_v2l1))]
#[allow(dead_code)]
type Bdcr = crate::pac::rcc::regs::Csr; type Bdcr = crate::pac::rcc::regs::Csr;
#[cfg(any(stm32c0))]
type Bdcr = crate::pac::rcc::regs::Csr1;
#[allow(dead_code)] #[cfg(any(stm32c0))]
pub struct BackupDomain {} fn unlock() {}
impl BackupDomain { #[cfg(not(any(stm32c0)))]
#[cfg(any( fn unlock() {
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, #[cfg(any(stm32f0, stm32f1, stm32f2, stm32f3, stm32l0, stm32l1))]
rtc_v3u5
))]
#[allow(dead_code, unused_variables)]
fn modify<R>(f: impl FnOnce(&mut Bdcr) -> R) -> R {
#[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1, rtc_v2l0))]
let cr = crate::pac::PWR.cr(); let cr = crate::pac::PWR.cr();
#[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] #[cfg(not(any(stm32f0, stm32f1, stm32f2, stm32f3, stm32l0, stm32l1, stm32u5, stm32h5, stm32wba)))]
let cr = crate::pac::PWR.cr1(); let cr = crate::pac::PWR.cr1();
#[cfg(any(stm32u5, stm32h5, stm32wba))]
let cr = crate::pac::PWR.dbpcr();
// TODO: Missing from PAC for l0 and f0?
#[cfg(not(any(rtc_v2f0, rtc_v3u5)))]
{
cr.modify(|w| w.set_dbp(true)); cr.modify(|w| w.set_dbp(true));
while !cr.read().dbp() {} while !cr.read().dbp() {}
} }
fn bdcr() -> Reg<Bdcr, RW> {
#[cfg(any(rtc_v2l0, rtc_v2l1))] #[cfg(any(rtc_v2l0, rtc_v2l1))]
let cr = crate::pac::RCC.csr(); return crate::pac::RCC.csr();
#[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))]
#[cfg(not(any(rtc_v2l0, rtc_v2l1)))] return crate::pac::RCC.bdcr();
let cr = crate::pac::RCC.bdcr(); #[cfg(any(stm32c0))]
return crate::pac::RCC.csr1();
cr.modify(|w| f(w))
} }
#[cfg(any( pub struct LsConfig {
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, pub rtc: RtcClockSource,
rtc_v3u5 pub lsi: bool,
))] pub lse: Option<LseConfig>,
#[allow(dead_code)]
fn read() -> Bdcr {
#[cfg(any(rtc_v2l0, rtc_v2l1))]
let r = crate::pac::RCC.csr().read();
#[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
let r = crate::pac::RCC.bdcr().read();
r
} }
#[cfg(any( impl LsConfig {
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, pub const fn default_lse() -> Self {
rtc_v3u5 Self {
))] rtc: RtcClockSource::LSE,
#[allow(dead_code, unused_variables)] lse: Some(LseConfig {
pub fn configure_ls(clock_source: RtcClockSource, lsi: bool, lse: Option<LseCfg>) { frequency: Hertz(32_000),
use atomic_polyfill::{compiler_fence, Ordering}; mode: LseMode::Oscillator(LseDrive::MediumHigh),
}),
lsi: false,
}
}
match clock_source { pub const fn default_lsi() -> Self {
RtcClockSource::LSI => assert!(lsi), Self {
RtcClockSource::LSE => assert!(lse.is_some()), rtc: RtcClockSource::LSI,
_ => {} lsi: true,
lse: None,
}
}
pub const fn off() -> Self {
Self {
rtc: RtcClockSource::NOCLOCK,
lsi: false,
lse: None,
}
}
}
impl Default for LsConfig {
fn default() -> Self {
// on L5, just the fact that LSI is enabled makes things crash.
// TODO: investigate.
#[cfg(not(stm32l5))]
return Self::default_lsi();
#[cfg(stm32l5)]
return Self::off();
}
}
impl LsConfig {
pub(crate) fn init(&self) -> Option<Hertz> {
let rtc_clk = match self.rtc {
RtcClockSource::LSI => {
assert!(self.lsi);
Some(LSI_FREQ)
}
RtcClockSource::LSE => Some(self.lse.as_ref().unwrap().frequency),
RtcClockSource::NOCLOCK => None,
_ => todo!(),
}; };
let (lse_en, lse_byp, lse_drv) = match lse {
Some(LseCfg::Oscillator(lse_drv)) => (true, false, Some(lse_drv)), let (lse_en, lse_byp, lse_drv) = match &self.lse {
Some(LseCfg::Bypass) => (true, true, None), Some(c) => match c.mode {
LseMode::Oscillator(lse_drv) => (true, false, Some(lse_drv)),
LseMode::Bypass => (true, true, None),
},
None => (false, false, None), None => (false, false, None),
}; };
_ = lse_drv; // not all chips have it.
if lsi {
#[cfg(rtc_v3u5)]
let csr = crate::pac::RCC.bdcr();
#[cfg(not(rtc_v3u5))]
let csr = crate::pac::RCC.csr();
// Disable backup domain write protection // Disable backup domain write protection
Self::modify(|_| {}); unlock();
if self.lsi {
#[cfg(any(stm32u5, stm32h5, stm32wba))]
let csr = crate::pac::RCC.bdcr();
#[cfg(not(any(stm32u5, stm32h5, stm32wba, stm32c0)))]
let csr = crate::pac::RCC.csr();
#[cfg(any(stm32c0))]
let csr = crate::pac::RCC.csr2();
#[cfg(not(any(rcc_wb, rcc_wba)))] #[cfg(not(any(rcc_wb, rcc_wba)))]
csr.modify(|w| w.set_lsion(true)); csr.modify(|w| w.set_lsion(true));
@ -139,12 +175,12 @@ impl BackupDomain {
// first check if the configuration matches what we want. // first check if the configuration matches what we want.
// check if it's already enabled and in the source we want. // check if it's already enabled and in the source we want.
let reg = Self::read(); let reg = bdcr().read();
let mut ok = true; let mut ok = true;
ok &= reg.rtcsel() == clock_source; ok &= reg.rtcsel() == self.rtc;
#[cfg(not(rcc_wba))] #[cfg(not(rcc_wba))]
{ {
ok &= reg.rtcen() == (clock_source != RtcClockSource::NOCLOCK); ok &= reg.rtcen() == (self.rtc != RtcClockSource::NOCLOCK);
} }
ok &= reg.lseon() == lse_en; ok &= reg.lseon() == lse_en;
ok &= reg.lsebyp() == lse_byp; ok &= reg.lsebyp() == lse_byp;
@ -155,22 +191,29 @@ impl BackupDomain {
// if configuration is OK, we're done. // if configuration is OK, we're done.
if ok { if ok {
// RTC code assumes backup domain is unlocked trace!("BDCR ok: {:08x}", bdcr().read().0);
Self::modify(|w| {}); return rtc_clk;
trace!("BDCR ok: {:08x}", Self::read().0);
return;
} }
// If not OK, reset backup domain and configure it. // If not OK, reset backup domain and configure it.
#[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1)))] #[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1, stm32h5, stm32c0)))]
{ {
Self::modify(|w| w.set_bdrst(true)); bdcr().modify(|w| w.set_bdrst(true));
Self::modify(|w| w.set_bdrst(false)); bdcr().modify(|w| w.set_bdrst(false));
}
#[cfg(any(stm32h5))]
{
bdcr().modify(|w| w.set_vswrst(true));
bdcr().modify(|w| w.set_vswrst(false));
}
#[cfg(any(stm32c0))]
{
bdcr().modify(|w| w.set_rtcrst(true));
bdcr().modify(|w| w.set_rtcrst(false));
} }
if lse_en { if lse_en {
Self::modify(|w| { bdcr().modify(|w| {
#[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))] #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))]
if let Some(lse_drv) = lse_drv { if let Some(lse_drv) = lse_drv {
w.set_lsedrv(lse_drv.into()); w.set_lsedrv(lse_drv.into());
@ -179,22 +222,24 @@ impl BackupDomain {
w.set_lseon(true); w.set_lseon(true);
}); });
while !Self::read().lserdy() {} while !bdcr().read().lserdy() {}
} }
if clock_source != RtcClockSource::NOCLOCK { if self.rtc != RtcClockSource::NOCLOCK {
Self::modify(|w| { bdcr().modify(|w| {
#[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
assert!(!w.lsecsson(), "RTC is not compatible with LSE CSS, yet."); assert!(!w.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
#[cfg(not(rcc_wba))] #[cfg(not(rcc_wba))]
w.set_rtcen(true); w.set_rtcen(true);
w.set_rtcsel(clock_source); w.set_rtcsel(self.rtc);
}); });
} }
trace!("BDCR configured: {:08x}", Self::read().0); trace!("BDCR configured: {:08x}", bdcr().read().0);
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
rtc_clk
} }
} }

View File

@ -8,9 +8,6 @@ use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(48_000_000); pub const HSI_FREQ: Hertz = Hertz(48_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// System clock mux source /// System clock mux source
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum ClockSrc { pub enum ClockSrc {
@ -24,6 +21,7 @@ pub struct Config {
pub mux: ClockSrc, pub mux: ClockSrc,
pub ahb_pre: AHBPrescaler, pub ahb_pre: AHBPrescaler,
pub apb_pre: APBPrescaler, pub apb_pre: APBPrescaler,
pub ls: super::LsConfig,
} }
impl Default for Config { impl Default for Config {
@ -33,6 +31,7 @@ impl Default for Config {
mux: ClockSrc::HSI(HSIPrescaler::DIV1), mux: ClockSrc::HSI(HSIPrescaler::DIV1),
ahb_pre: AHBPrescaler::DIV1, ahb_pre: AHBPrescaler::DIV1,
apb_pre: APBPrescaler::DIV1, apb_pre: APBPrescaler::DIV1,
ls: Default::default(),
} }
} }
} }
@ -60,10 +59,12 @@ pub(crate) unsafe fn init(config: Config) {
// Enable LSI // Enable LSI
RCC.csr2().write(|w| w.set_lsion(true)); RCC.csr2().write(|w| w.set_lsion(true));
while !RCC.csr2().read().lsirdy() {} while !RCC.csr2().read().lsirdy() {}
(LSI_FREQ, Sw::LSI) (super::LSI_FREQ, Sw::LSI)
} }
}; };
let rtc = config.ls.init();
// Determine the flash latency implied by the target clock speed // Determine the flash latency implied by the target clock speed
// RM0454 § 3.3.4: // RM0454 § 3.3.4:
let target_flash_latency = if sys_clk <= Hertz(24_000_000) { let target_flash_latency = if sys_clk <= Hertz(24_000_000) {
@ -137,5 +138,6 @@ pub(crate) unsafe fn init(config: Config) {
ahb1: ahb_freq, ahb1: ahb_freq,
apb1: apb_freq, apb1: apb_freq,
apb1_tim: apb_tim_freq, apb1_tim: apb_tim_freq,
rtc,
}); });
} }

View File

@ -8,9 +8,6 @@ use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(8_000_000); pub const HSI_FREQ: Hertz = Hertz(8_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(40_000);
/// Configuration of the clocks /// Configuration of the clocks
/// ///
/// hse takes precedence over hsi48 if both are enabled /// hse takes precedence over hsi48 if both are enabled
@ -27,6 +24,8 @@ pub struct Config {
pub sys_ck: Option<Hertz>, pub sys_ck: Option<Hertz>,
pub hclk: Option<Hertz>, pub hclk: Option<Hertz>,
pub pclk: Option<Hertz>, pub pclk: Option<Hertz>,
pub ls: super::LsConfig,
} }
pub(crate) unsafe fn init(config: Config) { pub(crate) unsafe fn init(config: Config) {
@ -159,6 +158,8 @@ pub(crate) unsafe fn init(config: Config) {
}) })
} }
let rtc = config.ls.init();
set_freqs(Clocks { set_freqs(Clocks {
sys: Hertz(real_sysclk), sys: Hertz(real_sysclk),
apb1: Hertz(pclk), apb1: Hertz(pclk),
@ -166,5 +167,6 @@ pub(crate) unsafe fn init(config: Config) {
apb1_tim: Hertz(pclk * timer_mul), apb1_tim: Hertz(pclk * timer_mul),
apb2_tim: Hertz(pclk * timer_mul), apb2_tim: Hertz(pclk * timer_mul),
ahb1: Hertz(hclk), ahb1: Hertz(hclk),
rtc,
}); });
} }

View File

@ -9,9 +9,6 @@ use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(8_000_000); pub const HSI_FREQ: Hertz = Hertz(8_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(40_000);
/// Configuration of the clocks /// Configuration of the clocks
/// ///
#[non_exhaustive] #[non_exhaustive]
@ -25,6 +22,8 @@ pub struct Config {
pub pclk2: Option<Hertz>, pub pclk2: Option<Hertz>,
pub adcclk: Option<Hertz>, pub adcclk: Option<Hertz>,
pub pllxtpre: bool, pub pllxtpre: bool,
pub ls: super::LsConfig,
} }
pub(crate) unsafe fn init(config: Config) { pub(crate) unsafe fn init(config: Config) {
@ -177,6 +176,8 @@ pub(crate) unsafe fn init(config: Config) {
}); });
}); });
let rtc = config.ls.init();
set_freqs(Clocks { set_freqs(Clocks {
sys: Hertz(real_sysclk), sys: Hertz(real_sysclk),
apb1: Hertz(pclk1), apb1: Hertz(pclk1),
@ -185,5 +186,6 @@ pub(crate) unsafe fn init(config: Config) {
apb2_tim: Hertz(pclk2 * timer_mul2), apb2_tim: Hertz(pclk2 * timer_mul2),
ahb1: Hertz(hclk), ahb1: Hertz(hclk),
adc: Some(Hertz(adcclk)), adc: Some(Hertz(adcclk)),
rtc,
}); });
} }

View File

@ -5,17 +5,12 @@ pub use crate::pac::rcc::vals::{
Ppre as APBPrescaler, Ppre as APBPrescaler,
}; };
use crate::pac::{FLASH, RCC}; use crate::pac::{FLASH, RCC};
use crate::rcc::bd::BackupDomain;
use crate::rcc::{set_freqs, Clocks}; use crate::rcc::{set_freqs, Clocks};
use crate::rtc::RtcClockSource;
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct HSEConfig { pub struct HSEConfig {
pub frequency: Hertz, pub frequency: Hertz,
@ -180,13 +175,11 @@ pub struct Config {
pub pll_mux: PLLSrc, pub pll_mux: PLLSrc,
pub pll: PLLConfig, pub pll: PLLConfig,
pub mux: ClockSrc, pub mux: ClockSrc,
pub rtc: Option<RtcClockSource>,
pub lsi: bool,
pub lse: Option<Hertz>,
pub voltage: VoltageScale, pub voltage: VoltageScale,
pub ahb_pre: AHBPrescaler, pub ahb_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler, pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler, pub apb2_pre: APBPrescaler,
pub ls: super::LsConfig,
} }
impl Default for Config { impl Default for Config {
@ -199,12 +192,10 @@ impl Default for Config {
pll: PLLConfig::default(), pll: PLLConfig::default(),
voltage: VoltageScale::Range3, voltage: VoltageScale::Range3,
mux: ClockSrc::HSI, mux: ClockSrc::HSI,
rtc: None,
lsi: false,
lse: None,
ahb_pre: AHBPrescaler::DIV1, ahb_pre: AHBPrescaler::DIV1,
apb1_pre: APBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1,
ls: Default::default(),
} }
} }
} }
@ -312,11 +303,7 @@ pub(crate) unsafe fn init(config: Config) {
RCC.cr().modify(|w| w.set_hsion(false)); RCC.cr().modify(|w| w.set_hsion(false));
} }
BackupDomain::configure_ls( let rtc = config.ls.init();
config.rtc.unwrap_or(RtcClockSource::NOCLOCK),
config.lsi,
config.lse.map(|_| Default::default()),
);
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
@ -328,5 +315,6 @@ pub(crate) unsafe fn init(config: Config) {
apb2: apb2_freq, apb2: apb2_freq,
apb2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
pll48: Some(pll_clocks.pll48_freq), pll48: Some(pll_clocks.pll48_freq),
rtc,
}); });
} }

View File

@ -10,9 +10,6 @@ use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(8_000_000); pub const HSI_FREQ: Hertz = Hertz(8_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(40_000);
#[cfg(rcc_f3)] #[cfg(rcc_f3)]
impl From<AdcClockSource> for Ckmode { impl From<AdcClockSource> for Ckmode {
fn from(value: AdcClockSource) -> Self { fn from(value: AdcClockSource) -> Self {
@ -87,6 +84,7 @@ pub struct Config {
pub adc34: Option<AdcClockSource>, pub adc34: Option<AdcClockSource>,
#[cfg(stm32f334)] #[cfg(stm32f334)]
pub hrtim: HrtimClockSource, pub hrtim: HrtimClockSource,
pub ls: super::LsConfig,
} }
// Information required to setup the PLL clock // Information required to setup the PLL clock
@ -279,6 +277,8 @@ pub(crate) unsafe fn init(config: Config) {
} }
}; };
let rtc = config.ls.init();
set_freqs(Clocks { set_freqs(Clocks {
sys: sysclk, sys: sysclk,
apb1: pclk1, apb1: pclk1,
@ -294,6 +294,7 @@ pub(crate) unsafe fn init(config: Config) {
adc34: None, adc34: None,
#[cfg(stm32f334)] #[cfg(stm32f334)]
hrtim: hrtim, hrtim: hrtim,
rtc,
}); });
} }

View File

@ -1,17 +1,11 @@
use stm32_metapac::rcc::vals::{Pllm, Plln, Pllq, Pllr}; use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllq, Pllr, Ppre, Sw};
use crate::pac::rcc::vals::{Hpre, Ppre, Sw};
use crate::pac::{FLASH, PWR, RCC}; use crate::pac::{FLASH, PWR, RCC};
use crate::rcc::bd::{BackupDomain, RtcClockSource};
use crate::rcc::{set_freqs, Clocks}; use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// Clocks configuration /// Clocks configuration
#[non_exhaustive] #[non_exhaustive]
#[derive(Default)] #[derive(Default)]
@ -30,9 +24,7 @@ pub struct Config {
pub pllsai: Option<Hertz>, pub pllsai: Option<Hertz>,
pub pll48: bool, pub pll48: bool,
pub rtc: Option<RtcClockSource>, pub ls: super::LsConfig,
pub lsi: bool,
pub lse: Option<Hertz>,
} }
#[cfg(stm32f410)] #[cfg(stm32f410)]
@ -344,17 +336,7 @@ pub(crate) unsafe fn init(config: Config) {
}) })
}); });
BackupDomain::configure_ls( let rtc = config.ls.init();
config.rtc.unwrap_or(RtcClockSource::NOCLOCK),
config.lsi,
config.lse.map(|_| Default::default()),
);
let rtc = match config.rtc {
Some(RtcClockSource::LSI) => Some(LSI_FREQ),
Some(RtcClockSource::LSE) => Some(config.lse.unwrap()),
_ => None,
};
set_freqs(Clocks { set_freqs(Clocks {
sys: Hertz(sysclk), sys: Hertz(sysclk),
@ -377,7 +359,6 @@ pub(crate) unsafe fn init(config: Config) {
pllsai: plls.pllsaiclk.map(Hertz), pllsai: plls.pllsaiclk.map(Hertz),
rtc, rtc,
rtc_hse: None,
}); });
} }

View File

@ -1,16 +1,12 @@
use crate::pac::pwr::vals::Vos; use crate::pac::pwr::vals::Vos;
use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllp, Pllq, Pllsrc, Ppre, Sw}; use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllp, Pllq, Pllsrc, Ppre, Sw};
use crate::pac::{FLASH, PWR, RCC}; use crate::pac::{FLASH, PWR, RCC};
use crate::rcc::bd::{BackupDomain, RtcClockSource};
use crate::rcc::{set_freqs, Clocks}; use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// Clocks configuration /// Clocks configuration
#[non_exhaustive] #[non_exhaustive]
#[derive(Default)] #[derive(Default)]
@ -23,9 +19,7 @@ pub struct Config {
pub pclk2: Option<Hertz>, pub pclk2: Option<Hertz>,
pub pll48: bool, pub pll48: bool,
pub rtc: Option<RtcClockSource>, pub ls: super::LsConfig,
pub lsi: bool,
pub lse: Option<Hertz>,
} }
fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48clk: bool) -> PllResults { fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48clk: bool) -> PllResults {
@ -261,17 +255,7 @@ pub(crate) unsafe fn init(config: Config) {
}) })
}); });
BackupDomain::configure_ls( let rtc = config.ls.init();
config.rtc.unwrap_or(RtcClockSource::NOCLOCK),
config.lsi,
config.lse.map(|_| Default::default()),
);
let rtc = match config.rtc {
Some(RtcClockSource::LSI) => Some(LSI_FREQ),
Some(RtcClockSource::LSE) => Some(config.lse.unwrap()),
_ => None,
};
set_freqs(Clocks { set_freqs(Clocks {
sys: Hertz(sysclk), sys: Hertz(sysclk),

View File

@ -10,9 +10,6 @@ use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// System clock mux source /// System clock mux source
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum ClockSrc { pub enum ClockSrc {
@ -73,6 +70,7 @@ pub struct Config {
pub ahb_pre: AHBPrescaler, pub ahb_pre: AHBPrescaler,
pub apb_pre: APBPrescaler, pub apb_pre: APBPrescaler,
pub low_power_run: bool, pub low_power_run: bool,
pub ls: super::LsConfig,
} }
impl Default for Config { impl Default for Config {
@ -83,6 +81,7 @@ impl Default for Config {
ahb_pre: AHBPrescaler::DIV1, ahb_pre: AHBPrescaler::DIV1,
apb_pre: APBPrescaler::DIV1, apb_pre: APBPrescaler::DIV1,
low_power_run: false, low_power_run: false,
ls: Default::default(),
} }
} }
} }
@ -193,7 +192,7 @@ pub(crate) unsafe fn init(config: Config) {
// Enable LSI // Enable LSI
RCC.csr().write(|w| w.set_lsion(true)); RCC.csr().write(|w| w.set_lsion(true));
while !RCC.csr().read().lsirdy() {} while !RCC.csr().read().lsirdy() {}
(LSI_FREQ, Sw::LSI) (super::LSI_FREQ, Sw::LSI)
} }
}; };
@ -272,10 +271,13 @@ pub(crate) unsafe fn init(config: Config) {
PWR.cr1().modify(|w| w.set_lpr(true)); PWR.cr1().modify(|w| w.set_lpr(true));
} }
let rtc = config.ls.init();
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
ahb1: ahb_freq, ahb1: ahb_freq,
apb1: apb_freq, apb1: apb_freq,
apb1_tim: apb_tim_freq, apb1_tim: apb_tim_freq,
rtc,
}); });
} }

View File

@ -14,9 +14,6 @@ use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// System clock mux source /// System clock mux source
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum ClockSrc { pub enum ClockSrc {
@ -101,6 +98,8 @@ pub struct Config {
pub clock_48mhz_src: Option<Clock48MhzSrc>, pub clock_48mhz_src: Option<Clock48MhzSrc>,
pub adc12_clock_source: AdcClockSource, pub adc12_clock_source: AdcClockSource,
pub adc345_clock_source: AdcClockSource, pub adc345_clock_source: AdcClockSource,
pub ls: super::LsConfig,
} }
/// Configuration for the Clock Recovery System (CRS) used to trim the HSI48 oscillator. /// Configuration for the Clock Recovery System (CRS) used to trim the HSI48 oscillator.
@ -122,6 +121,7 @@ impl Default for Config {
clock_48mhz_src: None, clock_48mhz_src: None,
adc12_clock_source: Adcsel::NOCLK, adc12_clock_source: Adcsel::NOCLK,
adc345_clock_source: Adcsel::NOCLK, adc345_clock_source: Adcsel::NOCLK,
ls: Default::default(),
} }
} }
} }
@ -344,6 +344,8 @@ pub(crate) unsafe fn init(config: Config) {
PWR.cr1().modify(|w| w.set_lpr(true)); PWR.cr1().modify(|w| w.set_lpr(true));
} }
let rtc = config.ls.init();
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
ahb1: ahb_freq, ahb1: ahb_freq,
@ -354,5 +356,6 @@ pub(crate) unsafe fn init(config: Config) {
apb2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
adc: adc12_ck, adc: adc12_ck,
adc34: adc345_ck, adc34: adc345_ck,
rtc,
}); });
} }

View File

@ -9,8 +9,6 @@ pub use crate::pac::rcc::vals::Adcsel as AdcClockSource;
use crate::pac::rcc::vals::{Ckpersel, Hsidiv, Pllrge, Pllsrc, Pllvcosel, Sw, Timpre}; use crate::pac::rcc::vals::{Ckpersel, Hsidiv, Pllrge, Pllsrc, Pllvcosel, Sw, Timpre};
pub use crate::pac::rcc::vals::{Ckpersel as PerClockSource, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul}; pub use crate::pac::rcc::vals::{Ckpersel as PerClockSource, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul};
use crate::pac::{FLASH, PWR, RCC}; use crate::pac::{FLASH, PWR, RCC};
#[cfg(stm32h7)]
use crate::rcc::bd::{BackupDomain, LseCfg, RtcClockSource};
use crate::rcc::{set_freqs, Clocks}; use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
@ -23,9 +21,6 @@ pub const CSI_FREQ: Hertz = Hertz(4_000_000);
/// HSI48 speed /// HSI48 speed
pub const HSI48_FREQ: Hertz = Hertz(48_000_000); pub const HSI48_FREQ: Hertz = Hertz(48_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
const VCO_RANGE: RangeInclusive<Hertz> = Hertz(150_000_000)..=Hertz(420_000_000); const VCO_RANGE: RangeInclusive<Hertz> = Hertz(150_000_000)..=Hertz(420_000_000);
#[cfg(any(stm32h5, pwr_h7rm0455))] #[cfg(any(stm32h5, pwr_h7rm0455))]
const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(128_000_000)..=Hertz(560_000_000); const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(128_000_000)..=Hertz(560_000_000);
@ -196,8 +191,7 @@ pub struct Config {
pub adc_clock_source: AdcClockSource, pub adc_clock_source: AdcClockSource,
pub timer_prescaler: TimerPrescaler, pub timer_prescaler: TimerPrescaler,
pub voltage_scale: VoltageScale, pub voltage_scale: VoltageScale,
#[cfg(stm32h7)] pub ls: super::LsConfig,
pub rtc_mux: Option<RtcClockSource>,
} }
impl Default for Config { impl Default for Config {
@ -231,8 +225,7 @@ impl Default for Config {
adc_clock_source: AdcClockSource::from_bits(0), // PLL2_P on H7, HCLK on H5 adc_clock_source: AdcClockSource::from_bits(0), // PLL2_P on H7, HCLK on H5
timer_prescaler: TimerPrescaler::DefaultX2, timer_prescaler: TimerPrescaler::DefaultX2,
voltage_scale: VoltageScale::Scale0, voltage_scale: VoltageScale::Scale0,
#[cfg(stm32h7)] ls: Default::default(),
rtc_mux: None,
} }
} }
} }
@ -471,18 +464,7 @@ pub(crate) unsafe fn init(config: Config) {
flash_setup(hclk, config.voltage_scale); flash_setup(hclk, config.voltage_scale);
#[cfg(stm32h7)] let rtc = config.ls.init();
{
let lsecfg = config.lse.map(|lse| match lse {
Lse::Bypass(freq) => {
assert!(freq <= Hertz(1_000_000));
LseCfg::Bypass
}
Lse::Oscillator => LseCfg::Oscillator(Default::default()),
});
BackupDomain::configure_ls(config.rtc_mux.unwrap_or(RtcClockSource::NOCLOCK), config.lsi, lsecfg);
}
#[cfg(stm32h7)] #[cfg(stm32h7)]
{ {
@ -548,17 +530,6 @@ pub(crate) unsafe fn init(config: Config) {
while !pac::SYSCFG.cccsr().read().ready() {} while !pac::SYSCFG.cccsr().read().ready() {}
} }
#[cfg(stm32h7)]
let rtc_clk = match config.rtc_mux {
Some(RtcClockSource::LSI) => Some(LSI_FREQ),
Some(RtcClockSource::LSE) => Some(match config.lse {
Some(Lse::Oscillator) => Hertz(32768),
Some(Lse::Bypass(freq)) => freq,
None => panic!("LSE not configured"),
}),
_ => None,
};
set_freqs(Clocks { set_freqs(Clocks {
sys, sys,
ahb1: hclk, ahb1: hclk,
@ -573,10 +544,7 @@ pub(crate) unsafe fn init(config: Config) {
apb1_tim, apb1_tim,
apb2_tim, apb2_tim,
adc, adc,
#[cfg(stm32h7)] rtc,
rtc: rtc_clk,
#[cfg(stm32h7)]
rtc_hse: None,
}); });
} }

View File

@ -1,5 +1,3 @@
use super::bd::BackupDomain;
use super::RtcClockSource;
pub use crate::pac::pwr::vals::Vos as VoltageScale; pub use crate::pac::pwr::vals::Vos as VoltageScale;
pub use crate::pac::rcc::vals::{ pub use crate::pac::rcc::vals::{
Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Pllmul as PLLMul, Ppre as APBPrescaler, Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Pllmul as PLLMul, Ppre as APBPrescaler,
@ -14,9 +12,6 @@ use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// System clock mux source /// System clock mux source
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum ClockSrc { pub enum ClockSrc {
@ -50,9 +45,7 @@ pub struct Config {
pub apb2_pre: APBPrescaler, pub apb2_pre: APBPrescaler,
#[cfg(crs)] #[cfg(crs)]
pub enable_hsi48: bool, pub enable_hsi48: bool,
pub rtc: Option<RtcClockSource>, pub ls: super::LsConfig,
pub lse: Option<Hertz>,
pub lsi: bool,
pub voltage_scale: VoltageScale, pub voltage_scale: VoltageScale,
} }
@ -66,10 +59,8 @@ impl Default for Config {
apb2_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1,
#[cfg(crs)] #[cfg(crs)]
enable_hsi48: false, enable_hsi48: false,
rtc: None,
lse: None,
lsi: false,
voltage_scale: VoltageScale::RANGE1, voltage_scale: VoltageScale::RANGE1,
ls: Default::default(),
} }
} }
} }
@ -144,11 +135,7 @@ pub(crate) unsafe fn init(config: Config) {
} }
}; };
BackupDomain::configure_ls( let rtc = config.ls.init();
config.rtc.unwrap_or(RtcClockSource::NOCLOCK),
config.lsi,
config.lse.map(|_| Default::default()),
);
let wait_states = match (config.voltage_scale, sys_clk.0) { let wait_states = match (config.voltage_scale, sys_clk.0) {
(VoltageScale::RANGE1, ..=16_000_000) => 0, (VoltageScale::RANGE1, ..=16_000_000) => 0,
@ -227,5 +214,6 @@ pub(crate) unsafe fn init(config: Config) {
apb2: apb2_freq, apb2: apb2_freq,
apb1_tim: apb1_tim_freq, apb1_tim: apb1_tim_freq,
apb2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
rtc,
}); });
} }

View File

@ -5,16 +5,12 @@ pub use crate::pac::rcc::vals::{
}; };
use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw}; use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw};
use crate::pac::{FLASH, RCC}; use crate::pac::{FLASH, RCC};
use crate::rcc::bd::{BackupDomain, RtcClockSource};
use crate::rcc::{set_freqs, Clocks}; use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// System clock mux source /// System clock mux source
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum ClockSrc { pub enum ClockSrc {
@ -51,9 +47,7 @@ pub struct Config {
pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>, pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>,
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
pub hsi48: bool, pub hsi48: bool,
pub rtc_mux: RtcClockSource, pub ls: super::LsConfig,
pub lse: Option<Hertz>,
pub lsi: bool,
} }
impl Default for Config { impl Default for Config {
@ -67,9 +61,7 @@ impl Default for Config {
pllsai1: None, pllsai1: None,
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
hsi48: false, hsi48: false,
rtc_mux: RtcClockSource::LSI, ls: Default::default(),
lsi: true,
lse: None,
} }
} }
} }
@ -95,7 +87,7 @@ pub(crate) unsafe fn init(config: Config) {
while RCC.cfgr().read().sws() != Sw::MSI {} while RCC.cfgr().read().sws() != Sw::MSI {}
} }
BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default())); let rtc = config.ls.init();
let (sys_clk, sw) = match config.mux { let (sys_clk, sw) = match config.mux {
ClockSrc::MSI(range) => { ClockSrc::MSI(range) => {
@ -105,12 +97,8 @@ pub(crate) unsafe fn init(config: Config) {
w.set_msirgsel(true); w.set_msirgsel(true);
w.set_msion(true); w.set_msion(true);
if config.rtc_mux == RtcClockSource::LSE {
// If LSE is enabled, enable calibration of MSI // If LSE is enabled, enable calibration of MSI
w.set_msipllen(true); w.set_msipllen(config.ls.lse.is_some());
} else {
w.set_msipllen(false);
}
}); });
while !RCC.cr().read().msirdy() {} while !RCC.cr().read().msirdy() {}
@ -285,6 +273,7 @@ pub(crate) unsafe fn init(config: Config) {
apb2: apb2_freq, apb2: apb2_freq,
apb1_tim: apb1_tim_freq, apb1_tim: apb1_tim_freq,
apb2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
rtc,
}); });
} }

View File

@ -5,16 +5,12 @@ pub use crate::pac::rcc::vals::{
}; };
use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw}; use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw};
use crate::pac::{FLASH, PWR, RCC}; use crate::pac::{FLASH, PWR, RCC};
use crate::rcc::bd::RtcClockSource;
use crate::rcc::{set_freqs, Clocks}; use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// System clock mux source /// System clock mux source
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum ClockSrc { pub enum ClockSrc {
@ -50,9 +46,7 @@ pub struct Config {
pub apb2_pre: APBPrescaler, pub apb2_pre: APBPrescaler,
pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>, pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>,
pub hsi48: bool, pub hsi48: bool,
pub rtc_mux: RtcClockSource, pub ls: super::LsConfig,
pub lse: Option<Hertz>,
pub lsi: bool,
} }
impl Default for Config { impl Default for Config {
@ -65,9 +59,7 @@ impl Default for Config {
apb2_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1,
pllsai1: None, pllsai1: None,
hsi48: false, hsi48: false,
rtc_mux: RtcClockSource::LSI, ls: Default::default(),
lsi: true,
lse: None,
} }
} }
} }
@ -93,7 +85,7 @@ pub(crate) unsafe fn init(config: Config) {
while RCC.cfgr().read().sws() != Sw::MSI {} while RCC.cfgr().read().sws() != Sw::MSI {}
} }
//BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default())); let rtc = config.ls.init();
PWR.cr1().modify(|w| w.set_vos(stm32_metapac::pwr::vals::Vos::RANGE0)); PWR.cr1().modify(|w| w.set_vos(stm32_metapac::pwr::vals::Vos::RANGE0));
let (sys_clk, sw) = match config.mux { let (sys_clk, sw) = match config.mux {
@ -104,12 +96,8 @@ pub(crate) unsafe fn init(config: Config) {
w.set_msirgsel(true); w.set_msirgsel(true);
w.set_msion(true); w.set_msion(true);
if config.rtc_mux == RtcClockSource::LSE {
// If LSE is enabled, enable calibration of MSI // If LSE is enabled, enable calibration of MSI
w.set_msipllen(true); w.set_msipllen(config.ls.lse.is_some());
} else {
w.set_msipllen(false);
}
}); });
while !RCC.cr().read().msirdy() {} while !RCC.cr().read().msirdy() {}
@ -280,6 +268,7 @@ pub(crate) unsafe fn init(config: Config) {
apb2: apb2_freq, apb2: apb2_freq,
apb1_tim: apb1_tim_freq, apb1_tim: apb1_tim_freq,
apb2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
rtc,
}); });
} }

View File

@ -2,11 +2,11 @@
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
pub use crate::rcc::bd::RtcClockSource;
use crate::time::Hertz; use crate::time::Hertz;
pub(crate) mod bd; mod bd;
mod mco; mod mco;
pub use bd::*;
pub use mco::*; pub use mco::*;
#[cfg_attr(rcc_f0, path = "f0.rs")] #[cfg_attr(rcc_f0, path = "f0.rs")]
@ -132,13 +132,7 @@ pub struct Clocks {
#[cfg(stm32f334)] #[cfg(stm32f334)]
pub hrtim: Option<Hertz>, pub hrtim: Option<Hertz>,
#[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_f7, rcc_h7, rcc_h7rm0433, rcc_h7ab))]
/// Set only if the lsi or lse is configured, indicates stop is supported
pub rtc: Option<Hertz>, pub rtc: Option<Hertz>,
#[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h7, rcc_h7rm0433, rcc_h7ab))]
/// Set if the hse is configured, indicates stop is not supported
pub rtc_hse: Option<Hertz>,
} }
#[cfg(feature = "low-power")] #[cfg(feature = "low-power")]
@ -166,14 +160,6 @@ pub(crate) fn clock_refcount_sub() {
/// The existence of this value indicates that the clock configuration can no longer be changed /// The existence of this value indicates that the clock configuration can no longer be changed
static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit(); static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit();
#[cfg(stm32wb)]
/// RCC initialization function
pub(crate) unsafe fn init(config: Config) {
set_freqs(compute_clocks(&config));
configure_clocks(&config);
}
/// Sets the clock frequencies /// Sets the clock frequencies
/// ///
/// Safety: Sets a mutable global. /// Safety: Sets a mutable global.

View File

@ -7,9 +7,6 @@ use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
pub use crate::pac::pwr::vals::Vos as VoltageScale; pub use crate::pac::pwr::vals::Vos as VoltageScale;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -111,7 +108,6 @@ impl Into<Sw> for ClockSrc {
} }
} }
#[derive(Copy, Clone)]
pub struct Config { pub struct Config {
pub mux: ClockSrc, pub mux: ClockSrc,
pub ahb_pre: AHBPrescaler, pub ahb_pre: AHBPrescaler,
@ -125,6 +121,7 @@ pub struct Config {
/// ///
/// See RM0456 § 10.5.4 for a general overview and § 11.4.10 for clock source frequency limits. /// See RM0456 § 10.5.4 for a general overview and § 11.4.10 for clock source frequency limits.
pub voltage_range: VoltageScale, pub voltage_range: VoltageScale,
pub ls: super::LsConfig,
} }
impl Config { impl Config {
@ -193,6 +190,7 @@ impl Default for Config {
apb3_pre: APBPrescaler::DIV1, apb3_pre: APBPrescaler::DIV1,
hsi48: false, hsi48: false,
voltage_range: VoltageScale::RANGE3, voltage_range: VoltageScale::RANGE3,
ls: Default::default(),
} }
} }
} }
@ -434,6 +432,8 @@ pub(crate) unsafe fn init(config: Config) {
} }
}; };
let rtc = config.ls.init();
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
ahb1: ahb_freq, ahb1: ahb_freq,
@ -444,6 +444,7 @@ pub(crate) unsafe fn init(config: Config) {
apb3: apb3_freq, apb3: apb3_freq,
apb1_tim: apb1_tim_freq, apb1_tim: apb1_tim_freq,
apb2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
rtc,
}); });
} }

View File

@ -2,16 +2,12 @@ pub use crate::pac::rcc::vals::{
Hpre as AHBPrescaler, Hsepre as HsePrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Pllsrc as PllSource, Hpre as AHBPrescaler, Hsepre as HsePrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Pllsrc as PllSource,
Ppre as APBPrescaler, Sw as Sysclk, Ppre as APBPrescaler, Sw as Sysclk,
}; };
use crate::rcc::bd::{BackupDomain, RtcClockSource}; use crate::rcc::{set_freqs, Clocks};
use crate::rcc::Clocks; use crate::time::{mhz, Hertz};
use crate::time::{khz, mhz, Hertz};
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
pub struct Hse { pub struct Hse {
pub prediv: HsePrescaler, pub prediv: HsePrescaler,
@ -42,11 +38,8 @@ pub struct Pll {
/// Clocks configutation /// Clocks configutation
pub struct Config { pub struct Config {
pub hse: Option<Hse>, pub hse: Option<Hse>,
pub lse: Option<Hertz>,
pub lsi: bool,
pub sys: Sysclk, pub sys: Sysclk,
pub mux: Option<PllMux>, pub mux: Option<PllMux>,
pub rtc: Option<RtcClockSource>,
pub pll: Option<Pll>, pub pll: Option<Pll>,
pub pllsai: Option<Pll>, pub pllsai: Option<Pll>,
@ -56,6 +49,8 @@ pub struct Config {
pub ahb3_pre: AHBPrescaler, pub ahb3_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler, pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler, pub apb2_pre: APBPrescaler,
pub ls: super::LsConfig,
} }
pub const WPAN_DEFAULT: Config = Config { pub const WPAN_DEFAULT: Config = Config {
@ -63,14 +58,13 @@ pub const WPAN_DEFAULT: Config = Config {
frequency: mhz(32), frequency: mhz(32),
prediv: HsePrescaler::DIV1, prediv: HsePrescaler::DIV1,
}), }),
lse: Some(khz(32)),
sys: Sysclk::PLL, sys: Sysclk::PLL,
mux: Some(PllMux { mux: Some(PllMux {
source: PllSource::HSE, source: PllSource::HSE,
prediv: Pllm::DIV2, prediv: Pllm::DIV2,
}), }),
rtc: Some(RtcClockSource::LSE),
lsi: false, ls: super::LsConfig::default_lse(),
pll: Some(Pll { pll: Some(Pll {
mul: Plln::MUL12, mul: Plln::MUL12,
@ -92,13 +86,12 @@ impl Default for Config {
fn default() -> Config { fn default() -> Config {
Config { Config {
hse: None, hse: None,
lse: None,
sys: Sysclk::HSI16, sys: Sysclk::HSI16,
mux: None, mux: None,
pll: None, pll: None,
pllsai: None, pllsai: None,
rtc: None,
lsi: false, ls: Default::default(),
ahb1_pre: AHBPrescaler::DIV1, ahb1_pre: AHBPrescaler::DIV1,
ahb2_pre: AHBPrescaler::DIV1, ahb2_pre: AHBPrescaler::DIV1,
@ -109,7 +102,9 @@ impl Default for Config {
} }
} }
pub(crate) fn compute_clocks(config: &Config) -> Clocks { #[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 hse_clk = config.hse.as_ref().map(|hse| hse.frequency / hse.prediv);
let mux_clk = config.mux.as_ref().map(|pll_mux| { let mux_clk = config.mux.as_ref().map(|pll_mux| {
@ -160,27 +155,6 @@ pub(crate) fn compute_clocks(config: &Config) -> Clocks {
} }
}; };
let rtc_clk = match config.rtc {
Some(RtcClockSource::LSI) => Some(LSI_FREQ),
Some(RtcClockSource::LSE) => Some(config.lse.unwrap()),
_ => None,
};
Clocks {
sys: sys_clk,
ahb1: ahb1_clk,
ahb2: ahb2_clk,
ahb3: ahb3_clk,
apb1: apb1_clk,
apb2: apb2_clk,
apb1_tim: apb1_tim_clk,
apb2_tim: apb2_tim_clk,
rtc: rtc_clk,
rtc_hse: None,
}
}
pub(crate) fn configure_clocks(config: &Config) {
let rcc = crate::pac::RCC; let rcc = crate::pac::RCC;
let needs_hsi = if let Some(pll_mux) = &config.mux { let needs_hsi = if let Some(pll_mux) = &config.mux {
@ -199,11 +173,7 @@ pub(crate) fn configure_clocks(config: &Config) {
rcc.cfgr().modify(|w| w.set_stopwuck(true)); rcc.cfgr().modify(|w| w.set_stopwuck(true));
BackupDomain::configure_ls( let rtc = config.ls.init();
config.rtc.unwrap_or(RtcClockSource::NOCLOCK),
config.lsi,
config.lse.map(|_| Default::default()),
);
match &config.hse { match &config.hse {
Some(hse) => { Some(hse) => {
@ -263,4 +233,16 @@ pub(crate) fn configure_clocks(config: &Config) {
w.set_c2hpre(config.ahb2_pre); w.set_c2hpre(config.ahb2_pre);
w.set_shdhpre(config.ahb3_pre); w.set_shdhpre(config.ahb3_pre);
}); });
set_freqs(Clocks {
sys: sys_clk,
ahb1: ahb1_clk,
ahb2: ahb2_clk,
ahb3: ahb3_clk,
apb1: apb1_clk,
apb2: apb2_clk,
apb1_tim: apb1_tim_clk,
apb2_tim: apb2_tim_clk,
rtc,
})
} }

View File

@ -7,9 +7,6 @@ use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
pub use crate::pac::pwr::vals::Vos as VoltageScale; pub use crate::pac::pwr::vals::Vos as VoltageScale;
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
@ -43,13 +40,13 @@ impl Into<Sw> for ClockSrc {
} }
} }
#[derive(Copy, Clone)]
pub struct Config { pub struct Config {
pub mux: ClockSrc, pub mux: ClockSrc,
pub ahb_pre: AHBPrescaler, pub ahb_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler, pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler, pub apb2_pre: APBPrescaler,
pub apb7_pre: APBPrescaler, pub apb7_pre: APBPrescaler,
pub ls: super::LsConfig,
} }
impl Default for Config { impl Default for Config {
@ -60,6 +57,7 @@ impl Default for Config {
apb1_pre: APBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1,
apb7_pre: APBPrescaler::DIV1, apb7_pre: APBPrescaler::DIV1,
ls: Default::default(),
} }
} }
} }
@ -140,6 +138,8 @@ pub(crate) unsafe fn init(config: Config) {
} }
}; };
let rtc = config.ls.init();
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
ahb1: ahb_freq, ahb1: ahb_freq,
@ -150,5 +150,6 @@ pub(crate) unsafe fn init(config: Config) {
apb7: apb7_freq, apb7: apb7_freq,
apb1_tim: apb1_tim_freq, apb1_tim: apb1_tim_freq,
apb2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
rtc,
}); });
} }

View File

@ -5,16 +5,12 @@ pub use crate::pac::rcc::vals::{
Pllsrc as PllSource, Ppre as APBPrescaler, Pllsrc as PllSource, Ppre as APBPrescaler,
}; };
use crate::pac::{FLASH, RCC}; use crate::pac::{FLASH, RCC};
use crate::rcc::bd::{BackupDomain, RtcClockSource};
use crate::rcc::{set_freqs, Clocks}; use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000); pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// HSE speed /// HSE speed
pub const HSE_FREQ: Hertz = Hertz(32_000_000); pub const HSE_FREQ: Hertz = Hertz(32_000_000);
@ -33,10 +29,8 @@ pub struct Config {
pub shd_ahb_pre: AHBPrescaler, pub shd_ahb_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler, pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler, pub apb2_pre: APBPrescaler,
pub rtc_mux: RtcClockSource,
pub lse: Option<Hertz>,
pub lsi: bool,
pub adc_clock_source: AdcClockSource, pub adc_clock_source: AdcClockSource,
pub ls: super::LsConfig,
} }
impl Default for Config { impl Default for Config {
@ -48,10 +42,8 @@ impl Default for Config {
shd_ahb_pre: AHBPrescaler::DIV1, shd_ahb_pre: AHBPrescaler::DIV1,
apb1_pre: APBPrescaler::DIV1, apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1, apb2_pre: APBPrescaler::DIV1,
rtc_mux: RtcClockSource::LSI,
lsi: true,
lse: None,
adc_clock_source: AdcClockSource::HSI16, adc_clock_source: AdcClockSource::HSI16,
ls: Default::default(),
} }
} }
} }
@ -104,9 +96,6 @@ pub(crate) unsafe fn init(config: Config) {
while FLASH.acr().read().latency() != ws {} while FLASH.acr().read().latency() != ws {}
// Enables the LSI if configured
BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default()));
match config.mux { match config.mux {
ClockSrc::HSI16 => { ClockSrc::HSI16 => {
// Enable HSI16 // Enable HSI16
@ -129,12 +118,8 @@ pub(crate) unsafe fn init(config: Config) {
w.set_msirange(range); w.set_msirange(range);
w.set_msion(true); w.set_msion(true);
if config.rtc_mux == RtcClockSource::LSE {
// If LSE is enabled, enable calibration of MSI // If LSE is enabled, enable calibration of MSI
w.set_msipllen(true); w.set_msipllen(config.ls.lse.is_some());
} else {
w.set_msipllen(false);
}
}); });
while !RCC.cr().read().msirdy() {} while !RCC.cr().read().msirdy() {}
} }
@ -156,6 +141,8 @@ pub(crate) unsafe fn init(config: Config) {
// TODO: switch voltage range // TODO: switch voltage range
let rtc = config.ls.init();
set_freqs(Clocks { set_freqs(Clocks {
sys: sys_clk, sys: sys_clk,
ahb1: ahb_freq, ahb1: ahb_freq,
@ -166,6 +153,7 @@ pub(crate) unsafe fn init(config: Config) {
apb3: shd_ahb_freq, apb3: shd_ahb_freq,
apb1_tim: apb1_tim_freq, apb1_tim: apb1_tim_freq,
apb2_tim: apb2_tim_freq, apb2_tim: apb2_tim_freq,
rtc,
}); });
} }

View File

@ -10,7 +10,6 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::blocking_mutex::Mutex; use embassy_sync::blocking_mutex::Mutex;
pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError};
pub use crate::rcc::RtcClockSource;
use crate::time::Hertz; use crate::time::Hertz;
/// refer to AN4759 to compare features of RTC2 and RTC3 /// refer to AN4759 to compare features of RTC2 and RTC3
@ -184,7 +183,7 @@ impl Default for RtcCalibrationCyclePeriod {
impl Rtc { impl Rtc {
pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
#[cfg(any(rcc_wle, rcc_wl5, rcc_g4, rcc_g0, rtc_v2l4, rtc_v2wb))] #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))]
<RTC as crate::rcc::sealed::RccPeripheral>::enable(); <RTC as crate::rcc::sealed::RccPeripheral>::enable();
let mut this = Self { let mut this = Self {
@ -204,19 +203,8 @@ impl Rtc {
} }
fn frequency() -> Hertz { fn frequency() -> Hertz {
#[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab))]
let freqs = unsafe { crate::rcc::get_freqs() }; let freqs = unsafe { crate::rcc::get_freqs() };
freqs.rtc.unwrap()
// Load the clock frequency from the rcc mod, if supported
#[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab))]
match freqs.rtc {
Some(hertz) => hertz,
None => freqs.rtc_hse.unwrap(),
}
// Assume the default value, if not supported
#[cfg(not(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab)))]
Hertz(32_768)
} }
/// Acquire a [`RtcTimeProvider`] instance. /// Acquire a [`RtcTimeProvider`] instance.

View File

@ -5,16 +5,14 @@
use chrono::{NaiveDate, NaiveDateTime}; use chrono::{NaiveDate, NaiveDateTime};
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; use embassy_stm32::rtc::{Rtc, RtcConfig};
use embassy_stm32::Config; use embassy_stm32::Config;
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, 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 mut config = Config::default(); let config = Config::default();
config.rcc.lsi = true;
config.rcc.rtc = Option::Some(RtcClockSource::LSI);
let p = embassy_stm32::init(config); let p = embassy_stm32::init(config);
info!("Hello World!"); info!("Hello World!");

View File

@ -5,20 +5,18 @@
use chrono::{NaiveDate, NaiveDateTime}; use chrono::{NaiveDate, NaiveDateTime};
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::rcc::Lse; use embassy_stm32::rcc::LsConfig;
use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; use embassy_stm32::rtc::{Rtc, RtcConfig};
use embassy_stm32::Config; use embassy_stm32::Config;
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, 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.lse = Some(Lse::Oscillator); config.rcc.ls = LsConfig::default_lse();
config.rcc.rtc_mux = Some(RtcClockSource::LSE);
embassy_stm32::init(config) 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

@ -5,7 +5,7 @@
use chrono::{NaiveDate, NaiveDateTime}; use chrono::{NaiveDate, NaiveDateTime};
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::rcc::{self, ClockSrc, PLLSource, PllMul, PllPreDiv, PllRDiv}; use embassy_stm32::rcc::{ClockSrc, LsConfig, PLLSource, PllMul, PllPreDiv, PllRDiv};
use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::rtc::{Rtc, RtcConfig};
use embassy_stm32::time::Hertz; use embassy_stm32::time::Hertz;
use embassy_stm32::Config; use embassy_stm32::Config;
@ -23,8 +23,7 @@ async fn main(_spawner: Spawner) {
PllMul::MUL20, PllMul::MUL20,
None, None,
); );
config.rcc.lse = Some(Hertz(32_768)); config.rcc.ls = LsConfig::default_lse();
config.rcc.rtc_mux = rcc::RtcClockSource::LSE;
embassy_stm32::init(config) embassy_stm32::init(config)
}; };
info!("Hello World!"); info!("Hello World!");

View File

@ -32,7 +32,6 @@ use embedded_io::Write as bWrite;
use embedded_io_async::Write; use embedded_io_async::Write;
use hal::gpio::{Input, Level, Output, Speed}; use hal::gpio::{Input, Level, Output, Speed};
use hal::i2c::{self, I2c}; use hal::i2c::{self, I2c};
use hal::rcc::{self};
use hal::rng::{self, Rng}; use hal::rng::{self, Rng};
use hal::{bind_interrupts, exti, pac, peripherals}; use hal::{bind_interrupts, exti, pac, peripherals};
use heapless::Vec; use heapless::Vec;
@ -86,7 +85,6 @@ async fn main(spawner: Spawner) {
None, None,
); );
config.rcc.hsi48 = true; // needed for rng config.rcc.hsi48 = true; // needed for rng
config.rcc.rtc_mux = rcc::RtcClockSource::LSI;
let dp = embassy_stm32::init(config); let dp = embassy_stm32::init(config);

View File

@ -34,7 +34,6 @@ bind_interrupts!(struct Irqs{
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; config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE;
config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI;
let p = embassy_stm32::init(config); let p = embassy_stm32::init(config);
pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01)); pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01));

View File

@ -16,7 +16,6 @@ bind_interrupts!(struct Irqs{
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; config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE;
config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI;
let p = embassy_stm32::init(config); let p = embassy_stm32::init(config);
pac::RCC.ccipr().modify(|w| { pac::RCC.ccipr().modify(|w| {

View File

@ -5,9 +5,8 @@
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; use embassy_stm32::rcc::{ClockSrc, LsConfig};
use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; use embassy_stm32::rtc::{Rtc, RtcConfig};
use embassy_stm32::time::Hertz;
use embassy_stm32::Config; use embassy_stm32::Config;
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
@ -17,8 +16,7 @@ async fn main(_spawner: Spawner) {
let p = { let p = {
let mut config = Config::default(); let mut config = Config::default();
config.rcc.mux = ClockSrc::HSE; config.rcc.mux = ClockSrc::HSE;
config.rcc.lse = Some(Hertz(32_768)); config.rcc.ls = LsConfig::default_lse();
config.rcc.rtc_mux = RtcClockSource::LSE;
embassy_stm32::init(config) embassy_stm32::init(config)
}; };
info!("Hello World!"); info!("Hello World!");

View File

@ -10,19 +10,19 @@ stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill
stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc" stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc"
stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo
stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo
stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "not-gpdma"] # Nucleo
stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin"] # Nucleo stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin"] # Nucleo
stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" ] # Nucleo
stm32h563zi = ["embassy-stm32/stm32h563zi", "eth"] # Nucleo stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth"] # Nucleo
stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono"] # IoT board
stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma"] # Nucleo stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma"] # Nucleo
stm32l152re = ["embassy-stm32/stm32l152re", "not-gpdma"] # Nucleo stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] # Nucleo
stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "not-gpdma"] # Nucleo stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma"] # Nucleo
stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "not-gpdma"] # Nucleo stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma"] # Nucleo
stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma"] # Nucleo stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma"] # Nucleo
stm32f767zi = ["embassy-stm32/stm32f767zi", "not-gpdma", "eth"] # Nucleo stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth"] # Nucleo
stm32f207zg = ["embassy-stm32/stm32f207zg", "not-gpdma", "eth"] # Nucleo stm32f207zg = ["embassy-stm32/stm32f207zg", "chrono", "not-gpdma", "eth"] # Nucleo
stm32f303ze = ["embassy-stm32/stm32f303ze", "not-gpdma"] # Nucleo stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] # Nucleo
stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma"] # Nucleo stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma"] # Nucleo
eth = [] eth = []

View File

@ -10,26 +10,14 @@ use chrono::{NaiveDate, NaiveDateTime};
use common::*; use common::*;
use defmt::assert; use defmt::assert;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::rcc::RtcClockSource; use embassy_stm32::rcc::LsConfig;
use embassy_stm32::rtc::{Rtc, RtcConfig}; use embassy_stm32::rtc::{Rtc, RtcConfig};
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, Timer};
#[embassy_executor::main] #[embassy_executor::main]
async fn main(_spawner: Spawner) { async fn main(_spawner: Spawner) {
let mut config = config(); let mut config = config();
config.rcc.ls = LsConfig::default_lse();
#[cfg(feature = "stm32h755zi")]
{
use embassy_stm32::rcc::Lse;
config.rcc.lse = Some(Lse::Oscillator);
config.rcc.rtc_mux = Some(RtcClockSource::LSE);
}
#[cfg(not(feature = "stm32h755zi"))]
{
use embassy_stm32::time::Hertz;
config.rcc.lse = Some(Hertz(32_768));
config.rcc.rtc = Some(RtcClockSource::LSE);
}
let p = embassy_stm32::init(config); let p = embassy_stm32::init(config);
info!("Hello World!"); info!("Hello World!");

View File

@ -11,9 +11,8 @@ use common::*;
use cortex_m_rt::entry; use cortex_m_rt::entry;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::low_power::{stop_with_rtc, Executor}; use embassy_stm32::low_power::{stop_with_rtc, Executor};
use embassy_stm32::rcc::RtcClockSource; use embassy_stm32::rcc::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::{Duration, Timer}; use embassy_time::{Duration, Timer};
use static_cell::make_static; use static_cell::make_static;
@ -49,9 +48,7 @@ async fn async_main(spawner: Spawner) {
let _ = config(); let _ = config();
let mut config = Config::default(); let mut config = Config::default();
config.rcc.ls = LsConfig::default_lse();
config.rcc.lse = Some(Hertz(32_768));
config.rcc.rtc = Some(RtcClockSource::LSE);
let p = embassy_stm32::init(config); let p = embassy_stm32::init(config);
info!("Hello World!"); info!("Hello World!");