Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add rcc bd lsi/lse abstraction #1869

Merged
merged 5 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 74 additions & 2 deletions embassy-stm32/src/rcc/bd.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,34 @@
#[allow(dead_code)]
#[derive(Default)]
pub enum LseDrive {
#[cfg(any(rtc_v2f7, rtc_v2l4))]
Low = 0,
MediumLow = 0x01,
#[default]
MediumHigh = 0x02,
#[cfg(any(rtc_v2f7, rtc_v2l4))]
High = 0x03,
}

#[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))]
impl From<LseDrive> for crate::pac::rcc::vals::Lsedrv {
fn from(value: LseDrive) -> Self {
use crate::pac::rcc::vals::Lsedrv;

match value {
#[cfg(any(rtc_v2f7, rtc_v2l4))]
LseDrive::Low => Lsedrv::LOW,
LseDrive::MediumLow => Lsedrv::MEDIUMLOW,
LseDrive::MediumHigh => Lsedrv::MEDIUMHIGH,
#[cfg(any(rtc_v2f7, rtc_v2l4))]
LseDrive::High => Lsedrv::HIGH,
}
}
}

#[allow(dead_code)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(u8)]
#[allow(dead_code)]
pub enum RtcClockSource {
/// 00: No clock
NoClock = 0b00,
Expand Down Expand Up @@ -66,6 +94,38 @@ impl BackupDomain {
r
}

#[allow(dead_code, unused_variables)]
#[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3))]
pub fn enable_lse(lse_drive: LseDrive) {
Self::modify(|w| {
#[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))]
w.set_lsedrv(lse_drive.into());
w.set_lseon(true);
});

while !Self::read().lserdy() {}
}

#[allow(dead_code)]
#[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3))]
pub fn enable_lsi() {
let csr = crate::pac::RCC.csr();

Self::modify(|_| {
#[cfg(not(rtc_v2wb))]
csr.modify(|w| w.set_lsion(true));

#[cfg(rtc_v2wb)]
csr.modify(|w| w.set_lsi1on(true));
});

#[cfg(not(rtc_v2wb))]
while !csr.read().lsirdy() {}

#[cfg(rtc_v2wb)]
while !csr.read().lsi1rdy() {}
}

#[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
Expand All @@ -74,7 +134,7 @@ impl BackupDomain {
pub fn set_rtc_clock_source(clock_source: RtcClockSource) {
let clock_source = clock_source as u8;
#[cfg(any(
all(not(any(rtc_v3, rtc_v3u5)), not(rtc_v2wb)),
not(any(rtc_v3, rtc_v3u5, rtc_v2wb)),
all(any(rtc_v3, rtc_v3u5), not(any(rcc_wl5, rcc_wle)))
))]
let clock_source = crate::pac::rcc::vals::Rtcsel::from_bits(clock_source);
Expand All @@ -86,6 +146,18 @@ impl BackupDomain {
});
}

#[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3))]
#[allow(dead_code, unused_variables)]
pub fn configure_rtc(clock_source: RtcClockSource, lse_drive: Option<LseDrive>) {
match clock_source {
RtcClockSource::LSI => Self::enable_lsi(),
RtcClockSource::LSE => Self::enable_lse(lse_drive.unwrap_or_default()),
_ => {}
};

Self::set_rtc_clock_source(clock_source);
}

#[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
Expand Down
35 changes: 3 additions & 32 deletions embassy-stm32/src/rcc/l4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use core::marker::PhantomData;

use embassy_hal_internal::into_ref;
use stm32_metapac::rcc::regs::Cfgr;
use stm32_metapac::rcc::vals::{Lsedrv, Mcopre, Mcosel};
use stm32_metapac::rcc::vals::{Mcopre, Mcosel};

pub use super::bus::{AHBPrescaler, APBPrescaler};
use crate::gpio::sealed::AFType;
use crate::gpio::Speed;
use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw};
use crate::pac::{FLASH, PWR, RCC};
use crate::pac::{FLASH, RCC};
use crate::rcc::bd::{BackupDomain, RtcClockSource};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz;
Expand Down Expand Up @@ -407,36 +407,7 @@ pub(crate) unsafe fn init(config: Config) {

RCC.apb1enr1().modify(|w| w.set_pwren(true));

match config.rtc_mux {
RtcClockSource::LSE => {
// 1. Unlock the backup domain
PWR.cr1().modify(|w| w.set_dbp(true));

// 2. Setup the LSE
RCC.bdcr().modify(|w| {
// Enable LSE
w.set_lseon(true);
// Max drive strength
// TODO: should probably be settable
w.set_lsedrv(Lsedrv::HIGH);
});

// Wait until LSE is running
while !RCC.bdcr().read().lserdy() {}

BackupDomain::set_rtc_clock_source(RtcClockSource::LSE);
}
RtcClockSource::LSI => {
// Turn on the internal 32 kHz LSI oscillator
RCC.csr().modify(|w| w.set_lsion(true));

// Wait until LSI is running
while !RCC.csr().read().lsirdy() {}

BackupDomain::set_rtc_clock_source(RtcClockSource::LSI);
}
_ => unreachable!(),
}
BackupDomain::configure_rtc(config.rtc_mux, None);

let (sys_clk, sw) = match config.mux {
ClockSrc::MSI(range) => {
Expand Down
14 changes: 1 addition & 13 deletions embassy-stm32/src/rcc/wb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,18 +293,6 @@ pub(crate) fn configure_clocks(config: &Config) {
while !rcc.cr().read().hsirdy() {}
}

let needs_lsi = if let Some(rtc_mux) = &config.rtc {
*rtc_mux == RtcClockSource::LSI
} else {
false
};

if needs_lsi {
rcc.csr().modify(|w| w.set_lsi1on(true));

while !rcc.csr().read().lsi1rdy() {}
}

match &config.lse {
Some(_) => {
rcc.cfgr().modify(|w| w.set_stopwuck(true));
Expand Down Expand Up @@ -378,5 +366,5 @@ pub(crate) fn configure_clocks(config: &Config) {

config
.rtc
.map(|clock_source| BackupDomain::set_rtc_clock_source(clock_source));
.map(|clock_source| BackupDomain::configure_rtc(clock_source, None));
}
33 changes: 2 additions & 31 deletions embassy-stm32/src/rcc/wl.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale};
use crate::pac::rcc::vals::Adcsel;
use crate::pac::{FLASH, PWR, RCC};
use crate::pac::{FLASH, RCC};
use crate::rcc::bd::{BackupDomain, RtcClockSource};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz;
Expand Down Expand Up @@ -234,36 +234,7 @@ pub(crate) unsafe fn init(config: Config) {

while FLASH.acr().read().latency() != ws {}

match config.rtc_mux {
RtcClockSource::LSE => {
// 1. Unlock the backup domain
PWR.cr1().modify(|w| w.set_dbp(true));

// 2. Setup the LSE
RCC.bdcr().modify(|w| {
// Enable LSE
w.set_lseon(true);
// Max drive strength
// TODO: should probably be settable
w.set_lsedrv(Lsedrv::High as u8); //---// PAM - should not be commented
});

// Wait until LSE is running
while !RCC.bdcr().read().lserdy() {}

BackupDomain::set_rtc_clock_source(RtcClockSource::LSE);
}
RtcClockSource::LSI => {
// Turn on the internal 32 kHz LSI oscillator
RCC.csr().modify(|w| w.set_lsion(true));

// Wait until LSI is running
while !RCC.csr().read().lsirdy() {}

BackupDomain::set_rtc_clock_source(RtcClockSource::LSI);
}
_ => unreachable!(),
}
BackupDomain::configure_rtc(config.rtc_mux, None);

match config.mux {
ClockSrc::HSI16 => {
Expand Down