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 }
critical-section = "1.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"
bxcan = "0.7.0"
nb = "1.0.0"
@ -77,7 +77,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-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]

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)]
#[derive(Clone, Copy)]
pub enum LseCfg {
pub enum LseMode {
Oscillator(LseDrive),
Bypass,
}
impl Default for LseCfg {
fn default() -> Self {
Self::Oscillator(Default::default())
}
pub struct LseConfig {
pub frequency: Hertz,
pub mode: LseMode,
}
#[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)))]
#[allow(dead_code)]
type Bdcr = crate::pac::rcc::regs::Bdcr;
#[cfg(any(rtc_v2l0, rtc_v2l1))]
#[allow(dead_code)]
type Bdcr = crate::pac::rcc::regs::Csr;
#[cfg(any(stm32c0))]
type Bdcr = crate::pac::rcc::regs::Csr1;
#[allow(dead_code)]
pub struct BackupDomain {}
#[cfg(any(stm32c0))]
fn unlock() {}
impl BackupDomain {
#[cfg(any(
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
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();
#[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
let cr = crate::pac::PWR.cr1();
#[cfg(not(any(stm32c0)))]
fn unlock() {
#[cfg(any(stm32f0, stm32f1, stm32f2, stm32f3, stm32l0, stm32l1))]
let cr = crate::pac::PWR.cr();
#[cfg(not(any(stm32f0, stm32f1, stm32f2, stm32f3, stm32l0, stm32l1, stm32u5, stm32h5, stm32wba)))]
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));
while !cr.read().dbp() {}
cr.modify(|w| w.set_dbp(true));
while !cr.read().dbp() {}
}
fn bdcr() -> Reg<Bdcr, RW> {
#[cfg(any(rtc_v2l0, rtc_v2l1))]
return crate::pac::RCC.csr();
#[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))]
return crate::pac::RCC.bdcr();
#[cfg(any(stm32c0))]
return crate::pac::RCC.csr1();
}
pub struct LsConfig {
pub rtc: RtcClockSource,
pub lsi: bool,
pub lse: Option<LseConfig>,
}
impl LsConfig {
pub const fn default_lse() -> Self {
Self {
rtc: RtcClockSource::LSE,
lse: Some(LseConfig {
frequency: Hertz(32_000),
mode: LseMode::Oscillator(LseDrive::MediumHigh),
}),
lsi: false,
}
#[cfg(any(rtc_v2l0, rtc_v2l1))]
let cr = crate::pac::RCC.csr();
#[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
let cr = crate::pac::RCC.bdcr();
cr.modify(|w| f(w))
}
#[cfg(any(
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
rtc_v3u5
))]
#[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
pub const fn default_lsi() -> Self {
Self {
rtc: RtcClockSource::LSI,
lsi: true,
lse: None,
}
}
#[cfg(any(
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
rtc_v3u5
))]
#[allow(dead_code, unused_variables)]
pub fn configure_ls(clock_source: RtcClockSource, lsi: bool, lse: Option<LseCfg>) {
use atomic_polyfill::{compiler_fence, Ordering};
pub const fn off() -> Self {
Self {
rtc: RtcClockSource::NOCLOCK,
lsi: false,
lse: None,
}
}
}
match clock_source {
RtcClockSource::LSI => assert!(lsi),
RtcClockSource::LSE => assert!(lse.is_some()),
_ => {}
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)),
Some(LseCfg::Bypass) => (true, true, None),
let (lse_en, lse_byp, lse_drv) = match &self.lse {
Some(c) => match c.mode {
LseMode::Oscillator(lse_drv) => (true, false, Some(lse_drv)),
LseMode::Bypass => (true, true, None),
},
None => (false, false, None),
};
_ = lse_drv; // not all chips have it.
if lsi {
#[cfg(rtc_v3u5)]
// Disable backup domain write protection
unlock();
if self.lsi {
#[cfg(any(stm32u5, stm32h5, stm32wba))]
let csr = crate::pac::RCC.bdcr();
#[cfg(not(rtc_v3u5))]
#[cfg(not(any(stm32u5, stm32h5, stm32wba, stm32c0)))]
let csr = crate::pac::RCC.csr();
// Disable backup domain write protection
Self::modify(|_| {});
#[cfg(any(stm32c0))]
let csr = crate::pac::RCC.csr2();
#[cfg(not(any(rcc_wb, rcc_wba)))]
csr.modify(|w| w.set_lsion(true));
@ -139,12 +175,12 @@ impl BackupDomain {
// first check if the configuration matches what 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;
ok &= reg.rtcsel() == clock_source;
ok &= reg.rtcsel() == self.rtc;
#[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.lsebyp() == lse_byp;
@ -155,22 +191,29 @@ impl BackupDomain {
// if configuration is OK, we're done.
if ok {
// RTC code assumes backup domain is unlocked
Self::modify(|w| {});
trace!("BDCR ok: {:08x}", Self::read().0);
return;
trace!("BDCR ok: {:08x}", bdcr().read().0);
return rtc_clk;
}
// 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));
Self::modify(|w| w.set_bdrst(false));
bdcr().modify(|w| w.set_bdrst(true));
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 {
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)))]
if let Some(lse_drv) = lse_drv {
w.set_lsedrv(lse_drv.into());
@ -179,22 +222,24 @@ impl BackupDomain {
w.set_lseon(true);
});
while !Self::read().lserdy() {}
while !bdcr().read().lserdy() {}
}
if clock_source != RtcClockSource::NOCLOCK {
Self::modify(|w| {
if self.rtc != RtcClockSource::NOCLOCK {
bdcr().modify(|w| {
#[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
assert!(!w.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
#[cfg(not(rcc_wba))]
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);
rtc_clk
}
}

View File

@ -8,9 +8,6 @@ use crate::time::Hertz;
/// HSI speed
pub const HSI_FREQ: Hertz = Hertz(48_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// System clock mux source
#[derive(Clone, Copy)]
pub enum ClockSrc {
@ -24,6 +21,7 @@ pub struct Config {
pub mux: ClockSrc,
pub ahb_pre: AHBPrescaler,
pub apb_pre: APBPrescaler,
pub ls: super::LsConfig,
}
impl Default for Config {
@ -33,6 +31,7 @@ impl Default for Config {
mux: ClockSrc::HSI(HSIPrescaler::DIV1),
ahb_pre: AHBPrescaler::DIV1,
apb_pre: APBPrescaler::DIV1,
ls: Default::default(),
}
}
}
@ -60,10 +59,12 @@ pub(crate) unsafe fn init(config: Config) {
// Enable LSI
RCC.csr2().write(|w| w.set_lsion(true));
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
// RM0454 § 3.3.4:
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,
apb1: apb_freq,
apb1_tim: apb_tim_freq,
rtc,
});
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,16 +1,12 @@
use crate::pac::pwr::vals::Vos;
use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllp, Pllq, Pllsrc, Ppre, Sw};
use crate::pac::{FLASH, PWR, RCC};
use crate::rcc::bd::{BackupDomain, RtcClockSource};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz;
/// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// Clocks configuration
#[non_exhaustive]
#[derive(Default)]
@ -23,9 +19,7 @@ pub struct Config {
pub pclk2: Option<Hertz>,
pub pll48: bool,
pub rtc: Option<RtcClockSource>,
pub lsi: bool,
pub lse: Option<Hertz>,
pub ls: super::LsConfig,
}
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(
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,
};
let rtc = config.ls.init();
set_freqs(Clocks {
sys: Hertz(sysclk),

View File

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

View File

@ -14,9 +14,6 @@ use crate::time::Hertz;
/// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// System clock mux source
#[derive(Clone, Copy)]
pub enum ClockSrc {
@ -101,6 +98,8 @@ pub struct Config {
pub clock_48mhz_src: Option<Clock48MhzSrc>,
pub adc12_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.
@ -122,6 +121,7 @@ impl Default for Config {
clock_48mhz_src: None,
adc12_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));
}
let rtc = config.ls.init();
set_freqs(Clocks {
sys: sys_clk,
ahb1: ahb_freq,
@ -354,5 +356,6 @@ pub(crate) unsafe fn init(config: Config) {
apb2_tim: apb2_tim_freq,
adc: adc12_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};
pub use crate::pac::rcc::vals::{Ckpersel as PerClockSource, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul};
use crate::pac::{FLASH, PWR, RCC};
#[cfg(stm32h7)]
use crate::rcc::bd::{BackupDomain, LseCfg, RtcClockSource};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz;
@ -23,9 +21,6 @@ pub const CSI_FREQ: Hertz = Hertz(4_000_000);
/// HSI48 speed
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);
#[cfg(any(stm32h5, pwr_h7rm0455))]
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 timer_prescaler: TimerPrescaler,
pub voltage_scale: VoltageScale,
#[cfg(stm32h7)]
pub rtc_mux: Option<RtcClockSource>,
pub ls: super::LsConfig,
}
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
timer_prescaler: TimerPrescaler::DefaultX2,
voltage_scale: VoltageScale::Scale0,
#[cfg(stm32h7)]
rtc_mux: None,
ls: Default::default(),
}
}
}
@ -471,18 +464,7 @@ pub(crate) unsafe fn init(config: Config) {
flash_setup(hclk, config.voltage_scale);
#[cfg(stm32h7)]
{
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);
}
let rtc = config.ls.init();
#[cfg(stm32h7)]
{
@ -548,17 +530,6 @@ pub(crate) unsafe fn init(config: Config) {
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 {
sys,
ahb1: hclk,
@ -573,10 +544,7 @@ pub(crate) unsafe fn init(config: Config) {
apb1_tim,
apb2_tim,
adc,
#[cfg(stm32h7)]
rtc: rtc_clk,
#[cfg(stm32h7)]
rtc_hse: None,
rtc,
});
}

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::rcc::vals::{
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
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// System clock mux source
#[derive(Clone, Copy)]
pub enum ClockSrc {
@ -50,9 +45,7 @@ pub struct Config {
pub apb2_pre: APBPrescaler,
#[cfg(crs)]
pub enable_hsi48: bool,
pub rtc: Option<RtcClockSource>,
pub lse: Option<Hertz>,
pub lsi: bool,
pub ls: super::LsConfig,
pub voltage_scale: VoltageScale,
}
@ -66,10 +59,8 @@ impl Default for Config {
apb2_pre: APBPrescaler::DIV1,
#[cfg(crs)]
enable_hsi48: false,
rtc: None,
lse: None,
lsi: false,
voltage_scale: VoltageScale::RANGE1,
ls: Default::default(),
}
}
}
@ -144,11 +135,7 @@ pub(crate) unsafe fn init(config: Config) {
}
};
BackupDomain::configure_ls(
config.rtc.unwrap_or(RtcClockSource::NOCLOCK),
config.lsi,
config.lse.map(|_| Default::default()),
);
let rtc = config.ls.init();
let wait_states = match (config.voltage_scale, sys_clk.0) {
(VoltageScale::RANGE1, ..=16_000_000) => 0,
@ -227,5 +214,6 @@ pub(crate) unsafe fn init(config: Config) {
apb2: apb2_freq,
apb1_tim: apb1_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::{FLASH, RCC};
use crate::rcc::bd::{BackupDomain, RtcClockSource};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz;
/// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// System clock mux source
#[derive(Clone, Copy)]
pub enum ClockSrc {
@ -51,9 +47,7 @@ pub struct Config {
pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>,
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
pub hsi48: bool,
pub rtc_mux: RtcClockSource,
pub lse: Option<Hertz>,
pub lsi: bool,
pub ls: super::LsConfig,
}
impl Default for Config {
@ -67,9 +61,7 @@ impl Default for Config {
pllsai1: None,
#[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
hsi48: false,
rtc_mux: RtcClockSource::LSI,
lsi: true,
lse: None,
ls: Default::default(),
}
}
}
@ -95,7 +87,7 @@ pub(crate) unsafe fn init(config: Config) {
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 {
ClockSrc::MSI(range) => {
@ -105,12 +97,8 @@ pub(crate) unsafe fn init(config: Config) {
w.set_msirgsel(true);
w.set_msion(true);
if config.rtc_mux == RtcClockSource::LSE {
// If LSE is enabled, enable calibration of MSI
w.set_msipllen(true);
} else {
w.set_msipllen(false);
}
// If LSE is enabled, enable calibration of MSI
w.set_msipllen(config.ls.lse.is_some());
});
while !RCC.cr().read().msirdy() {}
@ -285,6 +273,7 @@ pub(crate) unsafe fn init(config: Config) {
apb2: apb2_freq,
apb1_tim: apb1_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::{FLASH, PWR, RCC};
use crate::rcc::bd::RtcClockSource;
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz;
/// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// System clock mux source
#[derive(Clone, Copy)]
pub enum ClockSrc {
@ -50,9 +46,7 @@ pub struct Config {
pub apb2_pre: APBPrescaler,
pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>,
pub hsi48: bool,
pub rtc_mux: RtcClockSource,
pub lse: Option<Hertz>,
pub lsi: bool,
pub ls: super::LsConfig,
}
impl Default for Config {
@ -65,9 +59,7 @@ impl Default for Config {
apb2_pre: APBPrescaler::DIV1,
pllsai1: None,
hsi48: false,
rtc_mux: RtcClockSource::LSI,
lsi: true,
lse: None,
ls: Default::default(),
}
}
}
@ -93,7 +85,7 @@ pub(crate) unsafe fn init(config: Config) {
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));
let (sys_clk, sw) = match config.mux {
@ -104,12 +96,8 @@ pub(crate) unsafe fn init(config: Config) {
w.set_msirgsel(true);
w.set_msion(true);
if config.rtc_mux == RtcClockSource::LSE {
// If LSE is enabled, enable calibration of MSI
w.set_msipllen(true);
} else {
w.set_msipllen(false);
}
// If LSE is enabled, enable calibration of MSI
w.set_msipllen(config.ls.lse.is_some());
});
while !RCC.cr().read().msirdy() {}
@ -280,6 +268,7 @@ pub(crate) unsafe fn init(config: Config) {
apb2: apb2_freq,
apb1_tim: apb1_tim_freq,
apb2_tim: apb2_tim_freq,
rtc,
});
}

View File

@ -2,11 +2,11 @@
use core::mem::MaybeUninit;
pub use crate::rcc::bd::RtcClockSource;
use crate::time::Hertz;
pub(crate) mod bd;
mod bd;
mod mco;
pub use bd::*;
pub use mco::*;
#[cfg_attr(rcc_f0, path = "f0.rs")]
@ -132,13 +132,7 @@ pub struct Clocks {
#[cfg(stm32f334)]
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>,
#[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")]
@ -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
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
///
/// Safety: Sets a mutable global.

View File

@ -7,9 +7,6 @@ use crate::time::Hertz;
/// HSI speed
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;
#[derive(Copy, Clone)]
@ -111,7 +108,6 @@ impl Into<Sw> for ClockSrc {
}
}
#[derive(Copy, Clone)]
pub struct Config {
pub mux: ClockSrc,
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.
pub voltage_range: VoltageScale,
pub ls: super::LsConfig,
}
impl Config {
@ -193,6 +190,7 @@ impl Default for Config {
apb3_pre: APBPrescaler::DIV1,
hsi48: false,
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 {
sys: sys_clk,
ahb1: ahb_freq,
@ -444,6 +444,7 @@ pub(crate) unsafe fn init(config: Config) {
apb3: apb3_freq,
apb1_tim: apb1_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,
Ppre as APBPrescaler, Sw as Sysclk,
};
use crate::rcc::bd::{BackupDomain, RtcClockSource};
use crate::rcc::Clocks;
use crate::time::{khz, mhz, Hertz};
use crate::rcc::{set_freqs, Clocks};
use crate::time::{mhz, Hertz};
/// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
pub struct Hse {
pub prediv: HsePrescaler,
@ -42,11 +38,8 @@ pub struct Pll {
/// Clocks configutation
pub struct Config {
pub hse: Option<Hse>,
pub lse: Option<Hertz>,
pub lsi: bool,
pub sys: Sysclk,
pub mux: Option<PllMux>,
pub rtc: Option<RtcClockSource>,
pub pll: Option<Pll>,
pub pllsai: Option<Pll>,
@ -56,6 +49,8 @@ pub struct Config {
pub ahb3_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler,
pub ls: super::LsConfig,
}
pub const WPAN_DEFAULT: Config = Config {
@ -63,14 +58,13 @@ pub const WPAN_DEFAULT: Config = Config {
frequency: mhz(32),
prediv: HsePrescaler::DIV1,
}),
lse: Some(khz(32)),
sys: Sysclk::PLL,
mux: Some(PllMux {
source: PllSource::HSE,
prediv: Pllm::DIV2,
}),
rtc: Some(RtcClockSource::LSE),
lsi: false,
ls: super::LsConfig::default_lse(),
pll: Some(Pll {
mul: Plln::MUL12,
@ -92,13 +86,12 @@ impl Default for Config {
fn default() -> Config {
Config {
hse: None,
lse: None,
sys: Sysclk::HSI16,
mux: None,
pll: None,
pllsai: None,
rtc: None,
lsi: false,
ls: Default::default(),
ahb1_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 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 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));
BackupDomain::configure_ls(
config.rtc.unwrap_or(RtcClockSource::NOCLOCK),
config.lsi,
config.lse.map(|_| Default::default()),
);
let rtc = config.ls.init();
match &config.hse {
Some(hse) => {
@ -263,4 +233,16 @@ pub(crate) fn configure_clocks(config: &Config) {
w.set_c2hpre(config.ahb2_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
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::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
@ -43,13 +40,13 @@ impl Into<Sw> for ClockSrc {
}
}
#[derive(Copy, Clone)]
pub struct Config {
pub mux: ClockSrc,
pub ahb_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler,
pub apb7_pre: APBPrescaler,
pub ls: super::LsConfig,
}
impl Default for Config {
@ -60,6 +57,7 @@ impl Default for Config {
apb1_pre: APBPrescaler::DIV1,
apb2_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 {
sys: sys_clk,
ahb1: ahb_freq,
@ -150,5 +150,6 @@ pub(crate) unsafe fn init(config: Config) {
apb7: apb7_freq,
apb1_tim: apb1_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,
};
use crate::pac::{FLASH, RCC};
use crate::rcc::bd::{BackupDomain, RtcClockSource};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz;
/// HSI speed
pub const HSI_FREQ: Hertz = Hertz(16_000_000);
/// LSI speed
pub const LSI_FREQ: Hertz = Hertz(32_000);
/// HSE speed
pub const HSE_FREQ: Hertz = Hertz(32_000_000);
@ -33,10 +29,8 @@ pub struct Config {
pub shd_ahb_pre: AHBPrescaler,
pub apb1_pre: APBPrescaler,
pub apb2_pre: APBPrescaler,
pub rtc_mux: RtcClockSource,
pub lse: Option<Hertz>,
pub lsi: bool,
pub adc_clock_source: AdcClockSource,
pub ls: super::LsConfig,
}
impl Default for Config {
@ -48,10 +42,8 @@ impl Default for Config {
shd_ahb_pre: AHBPrescaler::DIV1,
apb1_pre: APBPrescaler::DIV1,
apb2_pre: APBPrescaler::DIV1,
rtc_mux: RtcClockSource::LSI,
lsi: true,
lse: None,
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 {}
// Enables the LSI if configured
BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default()));
match config.mux {
ClockSrc::HSI16 => {
// Enable HSI16
@ -129,12 +118,8 @@ pub(crate) unsafe fn init(config: Config) {
w.set_msirange(range);
w.set_msion(true);
if config.rtc_mux == RtcClockSource::LSE {
// If LSE is enabled, enable calibration of MSI
w.set_msipllen(true);
} else {
w.set_msipllen(false);
}
// If LSE is enabled, enable calibration of MSI
w.set_msipllen(config.ls.lse.is_some());
});
while !RCC.cr().read().msirdy() {}
}
@ -156,6 +141,8 @@ pub(crate) unsafe fn init(config: Config) {
// TODO: switch voltage range
let rtc = config.ls.init();
set_freqs(Clocks {
sys: sys_clk,
ahb1: ahb_freq,
@ -166,6 +153,7 @@ pub(crate) unsafe fn init(config: Config) {
apb3: shd_ahb_freq,
apb1_tim: apb1_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;
pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError};
pub use crate::rcc::RtcClockSource;
use crate::time::Hertz;
/// refer to AN4759 to compare features of RTC2 and RTC3
@ -184,7 +183,7 @@ impl Default for RtcCalibrationCyclePeriod {
impl Rtc {
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();
let mut this = Self {
@ -204,19 +203,8 @@ impl Rtc {
}
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() };
// 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)
freqs.rtc.unwrap()
}
/// Acquire a [`RtcTimeProvider`] instance.

View File

@ -5,16 +5,14 @@
use chrono::{NaiveDate, NaiveDateTime};
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig};
use embassy_stm32::rtc::{Rtc, RtcConfig};
use embassy_stm32::Config;
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let mut config = Config::default();
config.rcc.lsi = true;
config.rcc.rtc = Option::Some(RtcClockSource::LSI);
let config = Config::default();
let p = embassy_stm32::init(config);
info!("Hello World!");

View File

@ -5,20 +5,18 @@
use chrono::{NaiveDate, NaiveDateTime};
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::rcc::Lse;
use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig};
use embassy_stm32::rcc::LsConfig;
use embassy_stm32::rtc::{Rtc, RtcConfig};
use embassy_stm32::Config;
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = {
let mut config = Config::default();
config.rcc.lse = Some(Lse::Oscillator);
config.rcc.rtc_mux = Some(RtcClockSource::LSE);
embassy_stm32::init(config)
};
let mut config = Config::default();
config.rcc.ls = LsConfig::default_lse();
let p = embassy_stm32::init(config);
info!("Hello World!");
let now = NaiveDate::from_ymd_opt(2020, 5, 15)

View File

@ -5,7 +5,7 @@
use chrono::{NaiveDate, NaiveDateTime};
use defmt::*;
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::time::Hertz;
use embassy_stm32::Config;
@ -23,8 +23,7 @@ async fn main(_spawner: Spawner) {
PllMul::MUL20,
None,
);
config.rcc.lse = Some(Hertz(32_768));
config.rcc.rtc_mux = rcc::RtcClockSource::LSE;
config.rcc.ls = LsConfig::default_lse();
embassy_stm32::init(config)
};
info!("Hello World!");

View File

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

View File

@ -34,7 +34,6 @@ bind_interrupts!(struct Irqs{
async fn main(_spawner: Spawner) {
let mut config = embassy_stm32::Config::default();
config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE;
config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI;
let p = embassy_stm32::init(config);
pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01));

View File

@ -16,7 +16,6 @@ bind_interrupts!(struct Irqs{
async fn main(_spawner: Spawner) {
let mut config = embassy_stm32::Config::default();
config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE;
config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI;
let p = embassy_stm32::init(config);
pac::RCC.ccipr().modify(|w| {

View File

@ -5,9 +5,8 @@
use chrono::{NaiveDate, NaiveDateTime};
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::rcc::ClockSrc;
use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig};
use embassy_stm32::time::Hertz;
use embassy_stm32::rcc::{ClockSrc, LsConfig};
use embassy_stm32::rtc::{Rtc, RtcConfig};
use embassy_stm32::Config;
use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _};
@ -17,8 +16,7 @@ async fn main(_spawner: Spawner) {
let p = {
let mut config = Config::default();
config.rcc.mux = ClockSrc::HSE;
config.rcc.lse = Some(Hertz(32_768));
config.rcc.rtc_mux = RtcClockSource::LSE;
config.rcc.ls = LsConfig::default_lse();
embassy_stm32::init(config)
};
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"
stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # 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
stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo
stm32h563zi = ["embassy-stm32/stm32h563zi", "eth"] # Nucleo
stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board
stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" ] # Nucleo
stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth"] # Nucleo
stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono"] # IoT board
stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma"] # Nucleo
stm32l152re = ["embassy-stm32/stm32l152re", "not-gpdma"] # Nucleo
stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "not-gpdma"] # Nucleo
stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "not-gpdma"] # Nucleo
stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] # Nucleo
stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma"] # Nucleo
stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma"] # Nucleo
stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma"] # Nucleo
stm32f767zi = ["embassy-stm32/stm32f767zi", "not-gpdma", "eth"] # Nucleo
stm32f207zg = ["embassy-stm32/stm32f207zg", "not-gpdma", "eth"] # Nucleo
stm32f303ze = ["embassy-stm32/stm32f303ze", "not-gpdma"] # Nucleo
stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth"] # Nucleo
stm32f207zg = ["embassy-stm32/stm32f207zg", "chrono", "not-gpdma", "eth"] # Nucleo
stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] # Nucleo
stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma"] # Nucleo
eth = []

View File

@ -10,26 +10,14 @@ use chrono::{NaiveDate, NaiveDateTime};
use common::*;
use defmt::assert;
use embassy_executor::Spawner;
use embassy_stm32::rcc::RtcClockSource;
use embassy_stm32::rcc::LsConfig;
use embassy_stm32::rtc::{Rtc, RtcConfig};
use embassy_time::{Duration, Timer};
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let mut config = config();
#[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);
}
config.rcc.ls = LsConfig::default_lse();
let p = embassy_stm32::init(config);
info!("Hello World!");

View File

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