diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index 8fcc088fd..835d9c704 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - feat: Allow OSPI DMA writes larger than 64kB using chunking - feat: More ADC enums for g0 PAC, API change for oversampling, allow separate sample times - feat: Add USB CRS sync support for STM32C071 +- fix: RTC register definition for STM32L4P5 and L4Q5 as they use v3 register map. +- fix: Cut down the capabilities of the STM32L412 and L422 RTC as those are missing binary timer mode and underflow interrupt. ## 0.4.0 - 2025-08-26 diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 369fabc50..82bc73708 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -66,6 +66,10 @@ build = [ {target = "thumbv7em-none-eabi", features = ["defmt", "exti", "stm32l431cb", "time", "time-driver-any"]}, {target = "thumbv7em-none-eabi", features = ["defmt", "exti", "stm32l476vg", "time", "time-driver-any"]}, {target = "thumbv7em-none-eabi", features = ["defmt", "exti", "stm32l422cb", "time", "time-driver-any"]}, + {target = "thumbv7em-none-eabi", features = ["defmt", "exti", "stm32l4p5ae", "time", "time-driver-any", "single-bank"]}, + {target = "thumbv7em-none-eabi", features = ["defmt", "exti", "stm32l4q5zg", "time", "time-driver-any", "single-bank"]}, + {target = "thumbv7em-none-eabi", features = ["defmt", "exti", "stm32l4r9vi", "time", "time-driver-any", "dual-bank"]}, + {target = "thumbv7em-none-eabi", features = ["defmt", "exti", "stm32l4s7vi", "time", "time-driver-any", "dual-bank"]}, {target = "thumbv7em-none-eabi", features = ["defmt", "exti", "stm32wb15cc", "time", "time-driver-any"]}, {target = "thumbv6m-none-eabi", features = ["defmt", "exti", "stm32l072cz", "time", "time-driver-any"]}, {target = "thumbv6m-none-eabi", features = ["defmt", "exti", "stm32l041f6", "time", "time-driver-any"]}, @@ -174,7 +178,7 @@ futures-util = { version = "0.3.30", default-features = false } sdio-host = "0.9.0" critical-section = "1.1" #stm32-metapac = { version = "18" } -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-3cf72eac610259fd78ef16f1c63be69a144d75f7" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-b9f6b0c542d85ee695d71c35ced195e0cef51ac0" } vcell = "0.1.3" nb = "1.0.0" @@ -204,7 +208,7 @@ proc-macro2 = "1.0.36" quote = "1.0.15" #stm32-metapac = { version = "18", default-features = false, features = ["metadata"]} -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-3cf72eac610259fd78ef16f1c63be69a144d75f7", default-features = false, features = ["metadata"] } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-b9f6b0c542d85ee695d71c35ced195e0cef51ac0", default-features = false, features = ["metadata"] } [features] default = ["rt"] diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs index e2c704405..63fc195dd 100644 --- a/embassy-stm32/src/rcc/bd.rs +++ b/embassy-stm32/src/rcc/bd.rs @@ -52,9 +52,9 @@ impl From for crate::pac::rcc::vals::Lsedrv { } } -#[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))] +#[cfg(not(any(rtc_v2_l0, rtc_v2_l1, stm32c0)))] type Bdcr = crate::pac::rcc::regs::Bdcr; -#[cfg(any(rtc_v2l0, rtc_v2l1))] +#[cfg(any(rtc_v2_l0, rtc_v2_l1))] type Bdcr = crate::pac::rcc::regs::Csr; #[cfg(any(stm32c0))] type Bdcr = crate::pac::rcc::regs::Csr1; @@ -76,9 +76,9 @@ fn unlock() { } fn bdcr() -> Reg { - #[cfg(any(rtc_v2l0, rtc_v2l1))] + #[cfg(any(rtc_v2_l0, rtc_v2_l1))] return crate::pac::RCC.csr(); - #[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))] + #[cfg(not(any(rtc_v2_l0, rtc_v2_l1, stm32c0)))] return crate::pac::RCC.bdcr(); #[cfg(any(stm32c0))] return crate::pac::RCC.csr1(); @@ -273,7 +273,7 @@ impl LsConfig { if self.rtc != RtcClockSource::DISABLE { bdcr().modify(|w| { - #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] + #[cfg(any(rtc_v2_h7, rtc_v2_l4, rtc_v2_wb, rtc_v3_base, rtc_v3_u5))] assert!(!w.lsecsson(), "RTC is not compatible with LSE CSS, yet."); #[cfg(not(rcc_wba))] diff --git a/embassy-stm32/src/rtc/low_power.rs b/embassy-stm32/src/rtc/low_power.rs index 78ccd3e6c..a81ac6746 100644 --- a/embassy-stm32/src/rtc/low_power.rs +++ b/embassy-stm32/src/rtc/low_power.rs @@ -1,4 +1,8 @@ +#[cfg(feature = "time")] +use embassy_time::{Duration, TICK_HZ}; + use super::{bcd2_to_byte, DateTimeError, Rtc, RtcError}; +use crate::interrupt::typelevel::Interrupt; use crate::peripherals::RTC; use crate::rtc::SealedInstance; @@ -11,7 +15,7 @@ pub(super) struct RtcInstant { } impl RtcInstant { - #[cfg(not(rtc_v2f2))] + #[cfg(not(rtc_v2_f2))] const fn from(second: u8, subsecond: u16) -> Result { if second > 59 { Err(DateTimeError::InvalidSecond) @@ -38,8 +42,6 @@ impl core::ops::Sub for RtcInstant { type Output = embassy_time::Duration; fn sub(self, rhs: Self) -> Self::Output { - use embassy_time::{Duration, TICK_HZ}; - let second = if self.second < rhs.second { self.second + 60 } else { @@ -129,11 +131,6 @@ impl Rtc { requested_duration: embassy_time::Duration, cs: critical_section::CriticalSection, ) { - use embassy_time::{Duration, TICK_HZ}; - - #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))] - use crate::pac::rtc::vals::Calrf; - // Panic if the rcc mod knows we're not using low-power rtc #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] unsafe { crate::rcc::get_freqs() }.rtc.to_hertz().unwrap(); @@ -150,17 +147,15 @@ impl Rtc { self.write(false, |regs| { regs.cr().modify(|w| w.set_wute(false)); - #[cfg(any( - rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb - ))] + #[cfg(rtc_v2)] { regs.isr().modify(|w| w.set_wutf(false)); while !regs.isr().read().wutwf() {} } - #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))] + #[cfg(rtc_v3)] { - regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR)); + regs.scr().write(|w| w.set_cwutf(crate::pac::rtc::vals::Calrf::CLEAR)); while !regs.icsr().read().wutwf() {} } @@ -185,10 +180,6 @@ impl Rtc { /// stop the wakeup alarm and return the time elapsed since `start_wakeup_alarm` /// was called, otherwise none pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option { - use crate::interrupt::typelevel::Interrupt; - #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))] - use crate::pac::rtc::vals::Calrf; - let instant = self.instant().unwrap(); if RTC::regs().cr().read().wute() { trace!("rtc: stop wakeup alarm at {}", instant); @@ -197,13 +188,10 @@ impl Rtc { regs.cr().modify(|w| w.set_wutie(false)); regs.cr().modify(|w| w.set_wute(false)); - #[cfg(any( - rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb - ))] + #[cfg(rtc_v2)] regs.isr().modify(|w| w.set_wutf(false)); - - #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))] - regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR)); + #[cfg(rtc_v3)] + regs.scr().write(|w| w.set_cwutf(crate::pac::rtc::vals::Calrf::CLEAR)); // Check RM for EXTI and/or NVIC section, "Event event input mapping" or "EXTI interrupt/event mapping" or something similar, // there is a table for every "Event input" / "EXTI Line". @@ -222,8 +210,6 @@ impl Rtc { } pub(crate) fn enable_wakeup_line(&self) { - use crate::interrupt::typelevel::Interrupt; - ::WakeupInterrupt::unpend(); unsafe { ::WakeupInterrupt::enable() }; diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 449f3008a..92dec0960 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs @@ -18,14 +18,9 @@ use crate::pac::rtc::regs::{Dr, Tr}; use crate::time::Hertz; /// refer to AN4759 to compare features of RTC2 and RTC3 -#[cfg_attr(any(rtc_v1), path = "v1.rs")] -#[cfg_attr( - any( - rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb - ), - path = "v2.rs" -)] -#[cfg_attr(any(rtc_v3, rtc_v3u5, rtc_v3l5, rtc_v3h7rs, rtc_v3c0), path = "v3.rs")] +#[cfg_attr(rtc_v1, path = "v1.rs")] +#[cfg_attr(rtc_v2, path = "v2.rs")] +#[cfg_attr(rtc_v3, path = "v3.rs")] mod _version; #[allow(unused_imports)] pub use _version::*; @@ -72,12 +67,12 @@ impl RtcTimeProvider { // Calculate second fraction and multiply to microseconds // Formula from RM0410 - #[cfg(not(rtc_v2f2))] + #[cfg(not(rtc_v2_f2))] let us = { let prediv = RTC::regs().prer().read().prediv_s() as f32; (((prediv - _ss as f32) / (prediv + 1.0)) * 1e6).min(999_999.0) as u32 }; - #[cfg(rtc_v2f2)] + #[cfg(rtc_v2_f2)] let us = 0; DateTime::from(year, month, day, weekday, hour, minute, second, us).map_err(RtcError::InvalidDateTime) @@ -87,9 +82,9 @@ impl RtcTimeProvider { fn read(&self, mut f: impl FnMut(Dr, Tr, u16) -> Result) -> Result { let r = RTC::regs(); - #[cfg(not(rtc_v2f2))] + #[cfg(not(rtc_v2_f2))] let read_ss = || r.ssr().read().ss(); - #[cfg(rtc_v2f2)] + #[cfg(rtc_v2_f2)] let read_ss = || 0; let mut ss = read_ss(); @@ -168,7 +163,7 @@ impl Rtc { this.configure(async_psc, sync_psc); // Wait for the clock to update after initialization - #[cfg(not(rtc_v2f2))] + #[cfg(not(rtc_v2_f2))] { let now = this.time_provider().read(|_, _, ss| Ok(ss)).unwrap(); while now == this.time_provider().read(|_, _, ss| Ok(ss)).unwrap() {} diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index 28380a3c0..23f6ccb0c 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs @@ -11,11 +11,11 @@ impl super::Rtc { pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) { self.write(true, |rtc| { rtc.cr().modify(|w| { - #[cfg(not(rtc_v2f2))] + #[cfg(not(rtc_v2_f2))] w.set_bypshad(true); - #[cfg(rtc_v2f2)] + #[cfg(rtc_v2_f2)] w.set_fmt(false); - #[cfg(not(rtc_v2f2))] + #[cfg(not(rtc_v2_f2))] w.set_fmt(stm32_metapac::rtc::vals::Fmt::TWENTY_FOUR_HOUR); w.set_osel(Osel::DISABLED); w.set_pol(Pol::HIGH); @@ -36,7 +36,7 @@ impl super::Rtc { /// /// To perform a calibration when `async_prescaler` is less then 3, `sync_prescaler` /// has to be reduced accordingly (see RM0351 Rev 9, sec 38.3.12). - #[cfg(not(rtc_v2f2))] + #[cfg(not(rtc_v2_f2))] pub fn calibrate(&mut self, mut clock_drift: f32, period: super::RtcCalibrationCyclePeriod) { const RTC_CALR_MIN_PPM: f32 = -487.1; const RTC_CALR_MAX_PPM: f32 = 488.5;