stm32/rcc: add LSE/LSI to all chips, add RTC to more chips.
This commit is contained in:
parent
5a19d18b9c
commit
b91d1eaca0
@ -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]
|
||||||
|
@ -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
|
let cr = crate::pac::PWR.cr();
|
||||||
))]
|
#[cfg(not(any(stm32f0, stm32f1, stm32f2, stm32f3, stm32l0, stm32l1, stm32u5, stm32h5, stm32wba)))]
|
||||||
#[allow(dead_code, unused_variables)]
|
let cr = crate::pac::PWR.cr1();
|
||||||
fn modify<R>(f: impl FnOnce(&mut Bdcr) -> R) -> R {
|
#[cfg(any(stm32u5, stm32h5, stm32wba))]
|
||||||
#[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1, rtc_v2l0))]
|
let cr = crate::pac::PWR.dbpcr();
|
||||||
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();
|
|
||||||
|
|
||||||
// TODO: Missing from PAC for l0 and f0?
|
cr.modify(|w| w.set_dbp(true));
|
||||||
#[cfg(not(any(rtc_v2f0, rtc_v3u5)))]
|
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(
|
pub const fn default_lsi() -> Self {
|
||||||
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
|
Self {
|
||||||
rtc_v3u5
|
rtc: RtcClockSource::LSI,
|
||||||
))]
|
lsi: true,
|
||||||
#[allow(dead_code)]
|
lse: None,
|
||||||
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(
|
pub const fn off() -> Self {
|
||||||
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
|
Self {
|
||||||
rtc_v3u5
|
rtc: RtcClockSource::NOCLOCK,
|
||||||
))]
|
lsi: false,
|
||||||
#[allow(dead_code, unused_variables)]
|
lse: None,
|
||||||
pub fn configure_ls(clock_source: RtcClockSource, lsi: bool, lse: Option<LseCfg>) {
|
}
|
||||||
use atomic_polyfill::{compiler_fence, Ordering};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match clock_source {
|
impl Default for LsConfig {
|
||||||
RtcClockSource::LSI => assert!(lsi),
|
fn default() -> Self {
|
||||||
RtcClockSource::LSE => assert!(lse.is_some()),
|
// 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 {
|
// Disable backup domain write protection
|
||||||
#[cfg(rtc_v3u5)]
|
unlock();
|
||||||
|
|
||||||
|
if self.lsi {
|
||||||
|
#[cfg(any(stm32u5, stm32h5, stm32wba))]
|
||||||
let csr = crate::pac::RCC.bdcr();
|
let csr = crate::pac::RCC.bdcr();
|
||||||
|
#[cfg(not(any(stm32u5, stm32h5, stm32wba, stm32c0)))]
|
||||||
#[cfg(not(rtc_v3u5))]
|
|
||||||
let csr = crate::pac::RCC.csr();
|
let csr = crate::pac::RCC.csr();
|
||||||
|
#[cfg(any(stm32c0))]
|
||||||
// Disable backup domain write protection
|
let csr = crate::pac::RCC.csr2();
|
||||||
Self::modify(|_| {});
|
|
||||||
|
|
||||||
#[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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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),
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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(config.ls.lse.is_some());
|
||||||
w.set_msipllen(true);
|
|
||||||
} 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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(config.ls.lse.is_some());
|
||||||
w.set_msipllen(true);
|
|
||||||
} 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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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(config.ls.lse.is_some());
|
||||||
w.set_msipllen(true);
|
|
||||||
} 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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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!");
|
||||||
|
@ -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.ls = LsConfig::default_lse();
|
||||||
config.rcc.lse = Some(Lse::Oscillator);
|
|
||||||
config.rcc.rtc_mux = Some(RtcClockSource::LSE);
|
let p = embassy_stm32::init(config);
|
||||||
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)
|
||||||
|
@ -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!");
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
@ -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| {
|
||||||
|
@ -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!");
|
||||||
|
@ -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 = []
|
||||||
|
@ -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!");
|
||||||
|
@ -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!");
|
||||||
|
Loading…
Reference in New Issue
Block a user