diff options
| -rw-r--r-- | embassy-stm32/src/rcc/bd.rs | 76 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/l4.rs | 35 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/wb.rs | 14 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/wl.rs | 33 |
4 files changed, 80 insertions, 78 deletions
diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index 4d8ed82aa..34b88458f 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs | |||
| @@ -1,6 +1,34 @@ | |||
| 1 | #[allow(dead_code)] | ||
| 2 | #[derive(Default)] | ||
| 3 | pub enum LseDrive { | ||
| 4 | #[cfg(any(rtc_v2f7, rtc_v2l4))] | ||
| 5 | Low = 0, | ||
| 6 | MediumLow = 0x01, | ||
| 7 | #[default] | ||
| 8 | MediumHigh = 0x02, | ||
| 9 | #[cfg(any(rtc_v2f7, rtc_v2l4))] | ||
| 10 | High = 0x03, | ||
| 11 | } | ||
| 12 | |||
| 13 | #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))] | ||
| 14 | impl From<LseDrive> for crate::pac::rcc::vals::Lsedrv { | ||
| 15 | fn from(value: LseDrive) -> Self { | ||
| 16 | use crate::pac::rcc::vals::Lsedrv; | ||
| 17 | |||
| 18 | match value { | ||
| 19 | #[cfg(any(rtc_v2f7, rtc_v2l4))] | ||
| 20 | LseDrive::Low => Lsedrv::LOW, | ||
| 21 | LseDrive::MediumLow => Lsedrv::MEDIUMLOW, | ||
| 22 | LseDrive::MediumHigh => Lsedrv::MEDIUMHIGH, | ||
| 23 | #[cfg(any(rtc_v2f7, rtc_v2l4))] | ||
| 24 | LseDrive::High => Lsedrv::HIGH, | ||
| 25 | } | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | #[allow(dead_code)] | ||
| 1 | #[derive(Copy, Clone, Debug, PartialEq)] | 30 | #[derive(Copy, Clone, Debug, PartialEq)] |
| 2 | #[repr(u8)] | 31 | #[repr(u8)] |
| 3 | #[allow(dead_code)] | ||
| 4 | pub enum RtcClockSource { | 32 | pub enum RtcClockSource { |
| 5 | /// 00: No clock | 33 | /// 00: No clock |
| 6 | NoClock = 0b00, | 34 | NoClock = 0b00, |
| @@ -66,6 +94,38 @@ impl BackupDomain { | |||
| 66 | r | 94 | r |
| 67 | } | 95 | } |
| 68 | 96 | ||
| 97 | #[allow(dead_code, unused_variables)] | ||
| 98 | #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3))] | ||
| 99 | pub fn enable_lse(lse_drive: LseDrive) { | ||
| 100 | Self::modify(|w| { | ||
| 101 | #[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))] | ||
| 102 | w.set_lsedrv(lse_drive.into()); | ||
| 103 | w.set_lseon(true); | ||
| 104 | }); | ||
| 105 | |||
| 106 | while !Self::read().lserdy() {} | ||
| 107 | } | ||
| 108 | |||
| 109 | #[allow(dead_code)] | ||
| 110 | #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3))] | ||
| 111 | pub fn enable_lsi() { | ||
| 112 | let csr = crate::pac::RCC.csr(); | ||
| 113 | |||
| 114 | Self::modify(|_| { | ||
| 115 | #[cfg(not(rtc_v2wb))] | ||
| 116 | csr.modify(|w| w.set_lsion(true)); | ||
| 117 | |||
| 118 | #[cfg(rtc_v2wb)] | ||
| 119 | csr.modify(|w| w.set_lsi1on(true)); | ||
| 120 | }); | ||
| 121 | |||
| 122 | #[cfg(not(rtc_v2wb))] | ||
| 123 | while !csr.read().lsirdy() {} | ||
| 124 | |||
| 125 | #[cfg(rtc_v2wb)] | ||
| 126 | while !csr.read().lsi1rdy() {} | ||
| 127 | } | ||
| 128 | |||
| 69 | #[cfg(any( | 129 | #[cfg(any( |
| 70 | rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, | 130 | rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, |
| 71 | rtc_v3u5 | 131 | rtc_v3u5 |
| @@ -74,7 +134,7 @@ impl BackupDomain { | |||
| 74 | pub fn set_rtc_clock_source(clock_source: RtcClockSource) { | 134 | pub fn set_rtc_clock_source(clock_source: RtcClockSource) { |
| 75 | let clock_source = clock_source as u8; | 135 | let clock_source = clock_source as u8; |
| 76 | #[cfg(any( | 136 | #[cfg(any( |
| 77 | all(not(any(rtc_v3, rtc_v3u5)), not(rtc_v2wb)), | 137 | not(any(rtc_v3, rtc_v3u5, rtc_v2wb)), |
| 78 | all(any(rtc_v3, rtc_v3u5), not(any(rcc_wl5, rcc_wle))) | 138 | all(any(rtc_v3, rtc_v3u5), not(any(rcc_wl5, rcc_wle))) |
| 79 | ))] | 139 | ))] |
| 80 | let clock_source = crate::pac::rcc::vals::Rtcsel::from_bits(clock_source); | 140 | let clock_source = crate::pac::rcc::vals::Rtcsel::from_bits(clock_source); |
| @@ -86,6 +146,18 @@ impl BackupDomain { | |||
| 86 | }); | 146 | }); |
| 87 | } | 147 | } |
| 88 | 148 | ||
| 149 | #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3))] | ||
| 150 | #[allow(dead_code, unused_variables)] | ||
| 151 | pub fn configure_rtc(clock_source: RtcClockSource, lse_drive: Option<LseDrive>) { | ||
| 152 | match clock_source { | ||
| 153 | RtcClockSource::LSI => Self::enable_lsi(), | ||
| 154 | RtcClockSource::LSE => Self::enable_lse(lse_drive.unwrap_or_default()), | ||
| 155 | _ => {} | ||
| 156 | }; | ||
| 157 | |||
| 158 | Self::set_rtc_clock_source(clock_source); | ||
| 159 | } | ||
| 160 | |||
| 89 | #[cfg(any( | 161 | #[cfg(any( |
| 90 | rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, | 162 | rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, |
| 91 | rtc_v3u5 | 163 | rtc_v3u5 |
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index c6bccfd26..0083ae5bb 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs | |||
| @@ -2,13 +2,13 @@ use core::marker::PhantomData; | |||
| 2 | 2 | ||
| 3 | use embassy_hal_internal::into_ref; | 3 | use embassy_hal_internal::into_ref; |
| 4 | use stm32_metapac::rcc::regs::Cfgr; | 4 | use stm32_metapac::rcc::regs::Cfgr; |
| 5 | use stm32_metapac::rcc::vals::{Lsedrv, Mcopre, Mcosel}; | 5 | use stm32_metapac::rcc::vals::{Mcopre, Mcosel}; |
| 6 | 6 | ||
| 7 | pub use super::bus::{AHBPrescaler, APBPrescaler}; | 7 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 8 | use crate::gpio::sealed::AFType; | 8 | use crate::gpio::sealed::AFType; |
| 9 | use crate::gpio::Speed; | 9 | use crate::gpio::Speed; |
| 10 | use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; | 10 | use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; |
| 11 | use crate::pac::{FLASH, PWR, RCC}; | 11 | use crate::pac::{FLASH, RCC}; |
| 12 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; | 12 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; |
| 13 | use crate::rcc::{set_freqs, Clocks}; | 13 | use crate::rcc::{set_freqs, Clocks}; |
| 14 | use crate::time::Hertz; | 14 | use crate::time::Hertz; |
| @@ -407,36 +407,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 407 | 407 | ||
| 408 | RCC.apb1enr1().modify(|w| w.set_pwren(true)); | 408 | RCC.apb1enr1().modify(|w| w.set_pwren(true)); |
| 409 | 409 | ||
| 410 | match config.rtc_mux { | 410 | BackupDomain::configure_rtc(config.rtc_mux, None); |
| 411 | RtcClockSource::LSE => { | ||
| 412 | // 1. Unlock the backup domain | ||
| 413 | PWR.cr1().modify(|w| w.set_dbp(true)); | ||
| 414 | |||
| 415 | // 2. Setup the LSE | ||
| 416 | RCC.bdcr().modify(|w| { | ||
| 417 | // Enable LSE | ||
| 418 | w.set_lseon(true); | ||
| 419 | // Max drive strength | ||
| 420 | // TODO: should probably be settable | ||
| 421 | w.set_lsedrv(Lsedrv::HIGH); | ||
| 422 | }); | ||
| 423 | |||
| 424 | // Wait until LSE is running | ||
| 425 | while !RCC.bdcr().read().lserdy() {} | ||
| 426 | |||
| 427 | BackupDomain::set_rtc_clock_source(RtcClockSource::LSE); | ||
| 428 | } | ||
| 429 | RtcClockSource::LSI => { | ||
| 430 | // Turn on the internal 32 kHz LSI oscillator | ||
| 431 | RCC.csr().modify(|w| w.set_lsion(true)); | ||
| 432 | |||
| 433 | // Wait until LSI is running | ||
| 434 | while !RCC.csr().read().lsirdy() {} | ||
| 435 | |||
| 436 | BackupDomain::set_rtc_clock_source(RtcClockSource::LSI); | ||
| 437 | } | ||
| 438 | _ => unreachable!(), | ||
| 439 | } | ||
| 440 | 411 | ||
| 441 | let (sys_clk, sw) = match config.mux { | 412 | let (sys_clk, sw) = match config.mux { |
| 442 | ClockSrc::MSI(range) => { | 413 | ClockSrc::MSI(range) => { |
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index 6496b41e1..efd964642 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs | |||
| @@ -293,18 +293,6 @@ pub(crate) fn configure_clocks(config: &Config) { | |||
| 293 | while !rcc.cr().read().hsirdy() {} | 293 | while !rcc.cr().read().hsirdy() {} |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | let needs_lsi = if let Some(rtc_mux) = &config.rtc { | ||
| 297 | *rtc_mux == RtcClockSource::LSI | ||
| 298 | } else { | ||
| 299 | false | ||
| 300 | }; | ||
| 301 | |||
| 302 | if needs_lsi { | ||
| 303 | rcc.csr().modify(|w| w.set_lsi1on(true)); | ||
| 304 | |||
| 305 | while !rcc.csr().read().lsi1rdy() {} | ||
| 306 | } | ||
| 307 | |||
| 308 | match &config.lse { | 296 | match &config.lse { |
| 309 | Some(_) => { | 297 | Some(_) => { |
| 310 | rcc.cfgr().modify(|w| w.set_stopwuck(true)); | 298 | rcc.cfgr().modify(|w| w.set_stopwuck(true)); |
| @@ -378,5 +366,5 @@ pub(crate) fn configure_clocks(config: &Config) { | |||
| 378 | 366 | ||
| 379 | config | 367 | config |
| 380 | .rtc | 368 | .rtc |
| 381 | .map(|clock_source| BackupDomain::set_rtc_clock_source(clock_source)); | 369 | .map(|clock_source| BackupDomain::configure_rtc(clock_source, None)); |
| 382 | } | 370 | } |
diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index 47be00ad8..7a03d9060 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; | 1 | pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; |
| 2 | use crate::pac::rcc::vals::Adcsel; | 2 | use crate::pac::rcc::vals::Adcsel; |
| 3 | use crate::pac::{FLASH, PWR, RCC}; | 3 | use crate::pac::{FLASH, RCC}; |
| 4 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; | 4 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; |
| 5 | use crate::rcc::{set_freqs, Clocks}; | 5 | use crate::rcc::{set_freqs, Clocks}; |
| 6 | use crate::time::Hertz; | 6 | use crate::time::Hertz; |
| @@ -234,36 +234,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 234 | 234 | ||
| 235 | while FLASH.acr().read().latency() != ws {} | 235 | while FLASH.acr().read().latency() != ws {} |
| 236 | 236 | ||
| 237 | match config.rtc_mux { | 237 | BackupDomain::configure_rtc(config.rtc_mux, None); |
| 238 | RtcClockSource::LSE => { | ||
| 239 | // 1. Unlock the backup domain | ||
| 240 | PWR.cr1().modify(|w| w.set_dbp(true)); | ||
| 241 | |||
| 242 | // 2. Setup the LSE | ||
| 243 | RCC.bdcr().modify(|w| { | ||
| 244 | // Enable LSE | ||
| 245 | w.set_lseon(true); | ||
| 246 | // Max drive strength | ||
| 247 | // TODO: should probably be settable | ||
| 248 | w.set_lsedrv(Lsedrv::High as u8); //---// PAM - should not be commented | ||
| 249 | }); | ||
| 250 | |||
| 251 | // Wait until LSE is running | ||
| 252 | while !RCC.bdcr().read().lserdy() {} | ||
| 253 | |||
| 254 | BackupDomain::set_rtc_clock_source(RtcClockSource::LSE); | ||
| 255 | } | ||
| 256 | RtcClockSource::LSI => { | ||
| 257 | // Turn on the internal 32 kHz LSI oscillator | ||
| 258 | RCC.csr().modify(|w| w.set_lsion(true)); | ||
| 259 | |||
| 260 | // Wait until LSI is running | ||
| 261 | while !RCC.csr().read().lsirdy() {} | ||
| 262 | |||
| 263 | BackupDomain::set_rtc_clock_source(RtcClockSource::LSI); | ||
| 264 | } | ||
| 265 | _ => unreachable!(), | ||
| 266 | } | ||
| 267 | 238 | ||
| 268 | match config.mux { | 239 | match config.mux { |
| 269 | ClockSrc::HSI16 => { | 240 | ClockSrc::HSI16 => { |
