Merge pull request #1830 from xoviat/rtc
stm32: move backup domain in rcc mod
This commit is contained in:
		| @@ -58,7 +58,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-2b87e34c661e19ff6dc603fabfe7fe99ab7261f7" } | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9a61a1f090462df8bd1751f89951f04934fdceb3" } | ||||||
| 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-2b87e34c661e19ff6dc603fabfe7fe99ab7261f7", default-features = false, features = ["metadata"]} | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9a61a1f090462df8bd1751f89951f04934fdceb3", default-features = false, features = ["metadata"]} | ||||||
|  |  | ||||||
| [features] | [features] | ||||||
| default = ["rt"] | default = ["rt"] | ||||||
|   | |||||||
							
								
								
									
										151
									
								
								embassy-stm32/src/rcc/bd.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								embassy-stm32/src/rcc/bd.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,151 @@ | |||||||
|  | #[derive(Copy, Clone, Debug, PartialEq)] | ||||||
|  | #[repr(u8)] | ||||||
|  | #[allow(dead_code)] | ||||||
|  | pub enum RtcClockSource { | ||||||
|  |     /// 00: No clock | ||||||
|  |     NoClock = 0b00, | ||||||
|  |     /// 01: LSE oscillator clock used as RTC clock | ||||||
|  |     LSE = 0b01, | ||||||
|  |     /// 10: LSI oscillator clock used as RTC clock | ||||||
|  |     LSI = 0b10, | ||||||
|  |     /// 11: HSE oscillator clock divided by 32 used as RTC clock | ||||||
|  |     HSE = 0b11, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))] | ||||||
|  | #[allow(dead_code)] | ||||||
|  | type Bdcr = crate::pac::rcc::regs::Bdcr; | ||||||
|  |  | ||||||
|  | #[cfg(any(rtc_v2l0, rtc_v2l1))] | ||||||
|  | #[allow(dead_code)] | ||||||
|  | type Bdcr = crate::pac::rcc::regs::Csr; | ||||||
|  |  | ||||||
|  | #[allow(dead_code)] | ||||||
|  | pub struct BackupDomain {} | ||||||
|  |  | ||||||
|  | impl BackupDomain { | ||||||
|  |     #[cfg(any( | ||||||
|  |         rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, | ||||||
|  |         rtc_v3u5 | ||||||
|  |     ))] | ||||||
|  |     #[allow(dead_code, unused_variables)] | ||||||
|  |     fn modify<R>(f: impl FnOnce(&mut Bdcr) -> R) -> R { | ||||||
|  |         #[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1))] | ||||||
|  |         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? | ||||||
|  |         #[cfg(not(any(rtc_v2f0, rtc_v2l0, rtc_v3u5)))] | ||||||
|  |         { | ||||||
|  |             cr.modify(|w| w.set_dbp(true)); | ||||||
|  |             while !cr.read().dbp() {} | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         #[cfg(any(rtc_v2l0, rtc_v2l1))] | ||||||
|  |         let cr = crate::pac::RCC.csr(); | ||||||
|  |  | ||||||
|  |         #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | ||||||
|  |         let cr = crate::pac::RCC.bdcr(); | ||||||
|  |  | ||||||
|  |         cr.modify(|w| f(w)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #[cfg(any( | ||||||
|  |         rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, | ||||||
|  |         rtc_v3u5 | ||||||
|  |     ))] | ||||||
|  |     #[allow(dead_code)] | ||||||
|  |     fn read() -> Bdcr { | ||||||
|  |         #[cfg(any(rtc_v2l0, rtc_v2l1))] | ||||||
|  |         let r = crate::pac::RCC.csr().read(); | ||||||
|  |  | ||||||
|  |         #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | ||||||
|  |         let r = crate::pac::RCC.bdcr().read(); | ||||||
|  |  | ||||||
|  |         r | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #[cfg(any( | ||||||
|  |         rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, | ||||||
|  |         rtc_v3u5 | ||||||
|  |     ))] | ||||||
|  |     #[allow(dead_code, unused_variables)] | ||||||
|  |     pub fn 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)), | ||||||
|  |             all(any(rtc_v3, rtc_v3u5), not(any(rcc_wl5, rcc_wle))) | ||||||
|  |         ))] | ||||||
|  |         let clock_source = crate::pac::rcc::vals::Rtcsel::from_bits(clock_source); | ||||||
|  |  | ||||||
|  |         #[cfg(not(rtc_v2wb))] | ||||||
|  |         Self::modify(|w| { | ||||||
|  |             // Select RTC source | ||||||
|  |             w.set_rtcsel(clock_source); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #[cfg(any( | ||||||
|  |         rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb | ||||||
|  |     ))] | ||||||
|  |     #[allow(dead_code)] | ||||||
|  |     pub fn enable_rtc() { | ||||||
|  |         let reg = Self::read(); | ||||||
|  |  | ||||||
|  |         #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb))] | ||||||
|  |         assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); | ||||||
|  |  | ||||||
|  |         if !reg.rtcen() { | ||||||
|  |             #[cfg(not(any(rtc_v2l0, rtc_v2l1, rtc_v2f2)))] | ||||||
|  |             Self::modify(|w| w.set_bdrst(true)); | ||||||
|  |  | ||||||
|  |             Self::modify(|w| { | ||||||
|  |                 // Reset | ||||||
|  |                 #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | ||||||
|  |                 w.set_bdrst(false); | ||||||
|  |  | ||||||
|  |                 w.set_rtcen(true); | ||||||
|  |                 w.set_rtcsel(reg.rtcsel()); | ||||||
|  |  | ||||||
|  |                 // Restore bcdr | ||||||
|  |                 #[cfg(any(rtc_v2l4, rtc_v2wb))] | ||||||
|  |                 w.set_lscosel(reg.lscosel()); | ||||||
|  |                 #[cfg(any(rtc_v2l4, rtc_v2wb))] | ||||||
|  |                 w.set_lscoen(reg.lscoen()); | ||||||
|  |  | ||||||
|  |                 w.set_lseon(reg.lseon()); | ||||||
|  |  | ||||||
|  |                 #[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))] | ||||||
|  |                 w.set_lsedrv(reg.lsedrv()); | ||||||
|  |                 w.set_lsebyp(reg.lsebyp()); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #[cfg(any(rtc_v3, rtc_v3u5))] | ||||||
|  |     #[allow(dead_code)] | ||||||
|  |     pub fn enable_rtc() { | ||||||
|  |         let reg = Self::read(); | ||||||
|  |         assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); | ||||||
|  |  | ||||||
|  |         if !reg.rtcen() { | ||||||
|  |             Self::modify(|w| w.set_bdrst(true)); | ||||||
|  |  | ||||||
|  |             Self::modify(|w| { | ||||||
|  |                 w.set_bdrst(false); | ||||||
|  |  | ||||||
|  |                 w.set_rtcen(true); | ||||||
|  |                 w.set_rtcsel(reg.rtcsel()); | ||||||
|  |  | ||||||
|  |                 // Restore bcdr | ||||||
|  |                 w.set_lscosel(reg.lscosel()); | ||||||
|  |                 w.set_lscoen(reg.lscoen()); | ||||||
|  |  | ||||||
|  |                 w.set_lseon(reg.lseon()); | ||||||
|  |                 w.set_lsedrv(reg.lsedrv()); | ||||||
|  |                 w.set_lsebyp(reg.lsebyp()); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| pub use super::common::{AHBPrescaler, APBPrescaler}; | pub use super::bus::{AHBPrescaler, APBPrescaler}; | ||||||
| use crate::pac::flash::vals::Latency; | use crate::pac::flash::vals::Latency; | ||||||
| use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw}; | use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw}; | ||||||
| use crate::pac::{FLASH, RCC}; | use crate::pac::{FLASH, RCC}; | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| use core::convert::TryFrom; | use core::convert::TryFrom; | ||||||
| use core::ops::{Div, Mul}; | use core::ops::{Div, Mul}; | ||||||
|  |  | ||||||
| pub use super::common::{AHBPrescaler, APBPrescaler}; | pub use super::bus::{AHBPrescaler, APBPrescaler}; | ||||||
| use crate::pac::flash::vals::Latency; | use crate::pac::flash::vals::Latency; | ||||||
| use crate::pac::rcc::vals::{Pllp, Pllsrc, Sw}; | use crate::pac::rcc::vals::{Pllp, Pllsrc, Sw}; | ||||||
| use crate::pac::{FLASH, RCC}; | use crate::pac::{FLASH, RCC}; | ||||||
| @@ -201,7 +201,7 @@ pub struct PLLClocks { | |||||||
|     pub pll48_freq: Hertz, |     pub pll48_freq: Hertz, | ||||||
| } | } | ||||||
|  |  | ||||||
| pub use super::common::VoltageScale; | pub use super::bus::VoltageScale; | ||||||
|  |  | ||||||
| impl VoltageScale { | impl VoltageScale { | ||||||
|     const fn wait_states(&self, ahb_freq: Hertz) -> Option<Latency> { |     const fn wait_states(&self, ahb_freq: Hertz) -> Option<Latency> { | ||||||
|   | |||||||
| @@ -201,9 +201,9 @@ fn calc_pll(config: &Config, Hertz(sysclk): Hertz) -> (Hertz, PllConfig) { | |||||||
|     // Calculates the Multiplier and the Divisor to arrive at |     // Calculates the Multiplier and the Divisor to arrive at | ||||||
|     // the required System clock from PLL source frequency |     // the required System clock from PLL source frequency | ||||||
|     let get_mul_div = |sysclk, pllsrcclk| { |     let get_mul_div = |sysclk, pllsrcclk| { | ||||||
|         let common_div = gcd(sysclk, pllsrcclk); |         let bus_div = gcd(sysclk, pllsrcclk); | ||||||
|         let mut multiplier = sysclk / common_div; |         let mut multiplier = sysclk / bus_div; | ||||||
|         let mut divisor = pllsrcclk / common_div; |         let mut divisor = pllsrcclk / bus_div; | ||||||
|         // Minimum PLL multiplier is two |         // Minimum PLL multiplier is two | ||||||
|         if multiplier == 1 { |         if multiplier == 1 { | ||||||
|             multiplier *= 2; |             multiplier *= 2; | ||||||
|   | |||||||
| @@ -8,8 +8,8 @@ use crate::gpio::sealed::AFType; | |||||||
| use crate::gpio::Speed; | use crate::gpio::Speed; | ||||||
| use crate::pac::rcc::vals::{Hpre, 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::rtc::{Rtc, RtcClockSource}; |  | ||||||
| use crate::time::Hertz; | use crate::time::Hertz; | ||||||
| use crate::{peripherals, Peripheral}; | use crate::{peripherals, Peripheral}; | ||||||
|  |  | ||||||
| @@ -470,7 +470,7 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     config.rtc.map(|clock_source| { |     config.rtc.map(|clock_source| { | ||||||
|         Rtc::set_clock_source(clock_source); |         BackupDomain::set_rtc_clock_source(clock_source); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     let rtc = match config.rtc { |     let rtc = match config.rtc { | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| pub use super::common::{AHBPrescaler, APBPrescaler}; | pub use super::bus::{AHBPrescaler, APBPrescaler}; | ||||||
| use crate::pac::flash::vals::Latency; | use crate::pac::flash::vals::Latency; | ||||||
| use crate::pac::rcc::vals::{self, Hsidiv, Ppre, Sw}; | use crate::pac::rcc::vals::{self, Hsidiv, Ppre, Sw}; | ||||||
| use crate::pac::{FLASH, PWR, RCC}; | use crate::pac::{FLASH, PWR, RCC}; | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ use stm32_metapac::flash::vals::Latency; | |||||||
| use stm32_metapac::rcc::vals::{Hpre, Pllsrc, Ppre, Sw}; | use stm32_metapac::rcc::vals::{Hpre, Pllsrc, Ppre, Sw}; | ||||||
| use stm32_metapac::FLASH; | use stm32_metapac::FLASH; | ||||||
|  |  | ||||||
| pub use super::common::{AHBPrescaler, APBPrescaler}; | pub use super::bus::{AHBPrescaler, APBPrescaler}; | ||||||
| use crate::pac::{PWR, RCC}; | use crate::pac::{PWR, RCC}; | ||||||
| use crate::rcc::sealed::RccPeripheral; | use crate::rcc::sealed::RccPeripheral; | ||||||
| use crate::rcc::{set_freqs, Clocks}; | use crate::rcc::{set_freqs, Clocks}; | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ const VCO_MAX: u32 = 420_000_000; | |||||||
| const VCO_WIDE_MIN: u32 = 128_000_000; | const VCO_WIDE_MIN: u32 = 128_000_000; | ||||||
| const VCO_WIDE_MAX: u32 = 560_000_000; | const VCO_WIDE_MAX: u32 = 560_000_000; | ||||||
|  |  | ||||||
| pub use super::common::{AHBPrescaler, APBPrescaler, VoltageScale}; | pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; | ||||||
|  |  | ||||||
| pub enum HseMode { | pub enum HseMode { | ||||||
|     /// crystal/ceramic oscillator (HSEBYP=0) |     /// crystal/ceramic oscillator (HSEBYP=0) | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ pub const HSI48_FREQ: Hertz = Hertz(48_000_000); | |||||||
| /// LSI speed | /// LSI speed | ||||||
| pub const LSI_FREQ: Hertz = Hertz(32_000); | pub const LSI_FREQ: Hertz = Hertz(32_000); | ||||||
|  |  | ||||||
| pub use super::common::VoltageScale; | pub use super::bus::VoltageScale; | ||||||
|  |  | ||||||
| #[derive(Clone, Copy)] | #[derive(Clone, Copy)] | ||||||
| pub enum AdcClockSource { | pub enum AdcClockSource { | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| pub use super::common::{AHBPrescaler, APBPrescaler}; | pub use super::bus::{AHBPrescaler, APBPrescaler}; | ||||||
| use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; | ||||||
| use crate::pac::RCC; | use crate::pac::RCC; | ||||||
| #[cfg(crs)] | #[cfg(crs)] | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| pub use super::common::{AHBPrescaler, APBPrescaler}; | pub use super::bus::{AHBPrescaler, APBPrescaler}; | ||||||
| use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; | ||||||
| use crate::pac::{FLASH, RCC}; | use crate::pac::{FLASH, RCC}; | ||||||
| use crate::rcc::{set_freqs, Clocks}; | use crate::rcc::{set_freqs, Clocks}; | ||||||
|   | |||||||
| @@ -4,13 +4,13 @@ use embassy_hal_internal::into_ref; | |||||||
| use stm32_metapac::rcc::regs::Cfgr; | use stm32_metapac::rcc::regs::Cfgr; | ||||||
| use stm32_metapac::rcc::vals::{Lsedrv, Mcopre, Mcosel}; | use stm32_metapac::rcc::vals::{Lsedrv, Mcopre, Mcosel}; | ||||||
|  |  | ||||||
| pub use super::common::{AHBPrescaler, APBPrescaler}; | pub use super::bus::{AHBPrescaler, APBPrescaler}; | ||||||
| use crate::gpio::sealed::AFType; | use crate::gpio::sealed::AFType; | ||||||
| use crate::gpio::Speed; | use crate::gpio::Speed; | ||||||
| use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; | use crate::pac::rcc::vals::{Hpre, Msirange, 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::rtc::{Rtc, RtcClockSource as RCS}; |  | ||||||
| use crate::time::Hertz; | use crate::time::Hertz; | ||||||
| use crate::{peripherals, Peripheral}; | use crate::{peripherals, Peripheral}; | ||||||
|  |  | ||||||
| @@ -254,16 +254,11 @@ 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::LSI32, |             rtc_mux: RtcClockSource::LSI, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| pub enum RtcClockSource { |  | ||||||
|     LSE32, |  | ||||||
|     LSI32, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| pub enum McoClock { | pub enum McoClock { | ||||||
|     DIV1, |     DIV1, | ||||||
|     DIV2, |     DIV2, | ||||||
| @@ -413,7 +408,7 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|     RCC.apb1enr1().modify(|w| w.set_pwren(true)); |     RCC.apb1enr1().modify(|w| w.set_pwren(true)); | ||||||
|  |  | ||||||
|     match config.rtc_mux { |     match config.rtc_mux { | ||||||
|         RtcClockSource::LSE32 => { |         RtcClockSource::LSE => { | ||||||
|             // 1. Unlock the backup domain |             // 1. Unlock the backup domain | ||||||
|             PWR.cr1().modify(|w| w.set_dbp(true)); |             PWR.cr1().modify(|w| w.set_dbp(true)); | ||||||
|  |  | ||||||
| @@ -429,17 +424,18 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|             // Wait until LSE is running |             // Wait until LSE is running | ||||||
|             while !RCC.bdcr().read().lserdy() {} |             while !RCC.bdcr().read().lserdy() {} | ||||||
|  |  | ||||||
|             Rtc::set_clock_source(RCS::LSE); |             BackupDomain::set_rtc_clock_source(RtcClockSource::LSE); | ||||||
|         } |         } | ||||||
|         RtcClockSource::LSI32 => { |         RtcClockSource::LSI => { | ||||||
|             // Turn on the internal 32 kHz LSI oscillator |             // Turn on the internal 32 kHz LSI oscillator | ||||||
|             RCC.csr().modify(|w| w.set_lsion(true)); |             RCC.csr().modify(|w| w.set_lsion(true)); | ||||||
|  |  | ||||||
|             // Wait until LSI is running |             // Wait until LSI is running | ||||||
|             while !RCC.csr().read().lsirdy() {} |             while !RCC.csr().read().lsirdy() {} | ||||||
|  |  | ||||||
|             Rtc::set_clock_source(RCS::LSI); |             BackupDomain::set_rtc_clock_source(RtcClockSource::LSI); | ||||||
|         } |         } | ||||||
|  |         _ => unreachable!(), | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     let (sys_clk, sw) = match config.mux { |     let (sys_clk, sw) = match config.mux { | ||||||
| @@ -451,7 +447,7 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|                 w.set_msirgsel(true); |                 w.set_msirgsel(true); | ||||||
|                 w.set_msion(true); |                 w.set_msion(true); | ||||||
|  |  | ||||||
|                 if let RtcClockSource::LSE32 = config.rtc_mux { |                 if let RtcClockSource::LSE = config.rtc_mux { | ||||||
|                     // If LSE is enabled, enable calibration of MSI |                     // If LSE is enabled, enable calibration of MSI | ||||||
|                     w.set_msipllen(true); |                     w.set_msipllen(true); | ||||||
|                 } else { |                 } else { | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| use stm32_metapac::PWR; | use stm32_metapac::PWR; | ||||||
|  |  | ||||||
| pub use super::common::{AHBPrescaler, APBPrescaler}; | pub use super::bus::{AHBPrescaler, APBPrescaler}; | ||||||
| use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; | use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; | ||||||
| use crate::pac::{FLASH, RCC}; | use crate::pac::{FLASH, RCC}; | ||||||
| use crate::rcc::{set_freqs, Clocks}; | use crate::rcc::{set_freqs, Clocks}; | ||||||
|   | |||||||
| @@ -1,9 +1,10 @@ | |||||||
| #![macro_use] | #![macro_use] | ||||||
|  |  | ||||||
| pub mod common; | pub(crate) mod bd; | ||||||
|  | pub mod bus; | ||||||
| use core::mem::MaybeUninit; | use core::mem::MaybeUninit; | ||||||
|  |  | ||||||
|  | pub use crate::rcc::bd::RtcClockSource; | ||||||
| use crate::time::Hertz; | use crate::time::Hertz; | ||||||
|  |  | ||||||
| #[cfg_attr(rcc_f0, path = "f0.rs")] | #[cfg_attr(rcc_f0, path = "f0.rs")] | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| use stm32_metapac::rcc::vals::{Msirange, Msirgsel, Pllm, Pllsrc, Sw}; | use stm32_metapac::rcc::vals::{Msirange, Msirgsel, Pllm, Pllsrc, Sw}; | ||||||
|  |  | ||||||
| pub use super::common::{AHBPrescaler, APBPrescaler}; | pub use super::bus::{AHBPrescaler, APBPrescaler}; | ||||||
| use crate::pac::{FLASH, RCC}; | use crate::pac::{FLASH, RCC}; | ||||||
| use crate::rcc::{set_freqs, Clocks}; | use crate::rcc::{set_freqs, Clocks}; | ||||||
| use crate::time::Hertz; | use crate::time::Hertz; | ||||||
| @@ -11,7 +11,7 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); | |||||||
| /// LSI speed | /// LSI speed | ||||||
| pub const LSI_FREQ: Hertz = Hertz(32_000); | pub const LSI_FREQ: Hertz = Hertz(32_000); | ||||||
|  |  | ||||||
| pub use super::common::VoltageScale; | pub use super::bus::VoltageScale; | ||||||
|  |  | ||||||
| #[derive(Copy, Clone)] | #[derive(Copy, Clone)] | ||||||
| pub enum ClockSrc { | pub enum ClockSrc { | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| pub use super::common::{AHBPrescaler, APBPrescaler}; | pub use super::bus::{AHBPrescaler, APBPrescaler}; | ||||||
|  | use crate::rcc::bd::{BackupDomain, RtcClockSource}; | ||||||
| use crate::rcc::Clocks; | use crate::rcc::Clocks; | ||||||
| use crate::rtc::{Rtc, RtcClockSource}; |  | ||||||
| use crate::time::{khz, mhz, Hertz}; | use crate::time::{khz, mhz, Hertz}; | ||||||
|  |  | ||||||
| /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, | ||||||
| @@ -375,5 +375,7 @@ pub(crate) fn configure_clocks(config: &Config) { | |||||||
|         w.set_shdhpre(config.ahb3_pre.into()); |         w.set_shdhpre(config.ahb3_pre.into()); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     config.rtc.map(|clock_source| Rtc::set_clock_source(clock_source)); |     config | ||||||
|  |         .rtc | ||||||
|  |         .map(|clock_source| BackupDomain::set_rtc_clock_source(clock_source)); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| pub use super::common::{AHBPrescaler, APBPrescaler, VoltageScale}; | pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; | ||||||
| use crate::pac::pwr::vals::Dbp; |  | ||||||
| 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::rtc::{Rtc, RtcClockSource as RCS}; |  | ||||||
| use crate::time::Hertz; | use crate::time::Hertz; | ||||||
|  |  | ||||||
| /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, | ||||||
| @@ -130,16 +129,11 @@ impl Default for Config { | |||||||
|             apb2_pre: APBPrescaler::NotDivided, |             apb2_pre: APBPrescaler::NotDivided, | ||||||
|             enable_lsi: false, |             enable_lsi: false, | ||||||
|             enable_rtc_apb: false, |             enable_rtc_apb: false, | ||||||
|             rtc_mux: RtcClockSource::LSI32, |             rtc_mux: RtcClockSource::LSI, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| pub enum RtcClockSource { |  | ||||||
|     LSE32, |  | ||||||
|     LSI32, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[repr(u8)] | #[repr(u8)] | ||||||
| pub enum Lsedrv { | pub enum Lsedrv { | ||||||
|     Low = 0, |     Low = 0, | ||||||
| @@ -215,9 +209,9 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|     while FLASH.acr().read().latency() != ws {} |     while FLASH.acr().read().latency() != ws {} | ||||||
|  |  | ||||||
|     match config.rtc_mux { |     match config.rtc_mux { | ||||||
|         RtcClockSource::LSE32 => { |         RtcClockSource::LSE => { | ||||||
|             // 1. Unlock the backup domain |             // 1. Unlock the backup domain | ||||||
|             PWR.cr1().modify(|w| w.set_dbp(Dbp::ENABLED)); |             PWR.cr1().modify(|w| w.set_dbp(true)); | ||||||
|  |  | ||||||
|             // 2. Setup the LSE |             // 2. Setup the LSE | ||||||
|             RCC.bdcr().modify(|w| { |             RCC.bdcr().modify(|w| { | ||||||
| @@ -231,17 +225,18 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|             // Wait until LSE is running |             // Wait until LSE is running | ||||||
|             while !RCC.bdcr().read().lserdy() {} |             while !RCC.bdcr().read().lserdy() {} | ||||||
|  |  | ||||||
|             Rtc::set_clock_source(RCS::LSE); |             BackupDomain::set_rtc_clock_source(RtcClockSource::LSE); | ||||||
|         } |         } | ||||||
|         RtcClockSource::LSI32 => { |         RtcClockSource::LSI => { | ||||||
|             // Turn on the internal 32 kHz LSI oscillator |             // Turn on the internal 32 kHz LSI oscillator | ||||||
|             RCC.csr().modify(|w| w.set_lsion(true)); |             RCC.csr().modify(|w| w.set_lsion(true)); | ||||||
|  |  | ||||||
|             // Wait until LSI is running |             // Wait until LSI is running | ||||||
|             while !RCC.csr().read().lsirdy() {} |             while !RCC.csr().read().lsirdy() {} | ||||||
|  |  | ||||||
|             Rtc::set_clock_source(RCS::LSI); |             BackupDomain::set_rtc_clock_source(RtcClockSource::LSI); | ||||||
|         } |         } | ||||||
|  |         _ => unreachable!(), | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     match config.mux { |     match config.mux { | ||||||
| @@ -266,7 +261,7 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|                 w.set_msirange(range.into()); |                 w.set_msirange(range.into()); | ||||||
|                 w.set_msion(true); |                 w.set_msion(true); | ||||||
|  |  | ||||||
|                 if let RtcClockSource::LSE32 = config.rtc_mux { |                 if let RtcClockSource::LSE = config.rtc_mux { | ||||||
|                     // If LSE is enabled, enable calibration of MSI |                     // If LSE is enabled, enable calibration of MSI | ||||||
|                     w.set_msipllen(true); |                     w.set_msipllen(true); | ||||||
|                 } else { |                 } else { | ||||||
|   | |||||||
| @@ -89,7 +89,7 @@ pub enum DayOfWeek { | |||||||
| #[cfg(feature = "chrono")] | #[cfg(feature = "chrono")] | ||||||
| impl From<chrono::Weekday> for DayOfWeek { | impl From<chrono::Weekday> for DayOfWeek { | ||||||
|     fn from(weekday: Weekday) -> Self { |     fn from(weekday: Weekday) -> Self { | ||||||
|         day_of_week_from_u8(weekday.number_from_monday() as u8).unwrap() |         day_of_week_from_u8(weekday.num_days_from_monday() as u8).unwrap() | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,6 +10,8 @@ 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}; | ||||||
|  | use crate::rcc::bd::BackupDomain; | ||||||
|  | pub use crate::rcc::RtcClockSource; | ||||||
|  |  | ||||||
| /// refer to AN4759 to compare features of RTC2 and RTC3 | /// refer to AN4759 to compare features of RTC2 and RTC3 | ||||||
| #[cfg_attr(any(rtc_v1), path = "v1.rs")] | #[cfg_attr(any(rtc_v1), path = "v1.rs")] | ||||||
| @@ -107,19 +109,6 @@ pub struct Rtc { | |||||||
|     stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<RtcInstant>>>, |     stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<RtcInstant>>>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Copy, Clone, Debug, PartialEq)] |  | ||||||
| #[repr(u8)] |  | ||||||
| pub enum RtcClockSource { |  | ||||||
|     /// 00: No clock |  | ||||||
|     NoClock = 0b00, |  | ||||||
|     /// 01: LSE oscillator clock used as RTC clock |  | ||||||
|     LSE = 0b01, |  | ||||||
|     /// 10: LSI oscillator clock used as RTC clock |  | ||||||
|     LSI = 0b10, |  | ||||||
|     /// 11: HSE oscillator clock divided by 32 used as RTC clock |  | ||||||
|     HSE = 0b11, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[derive(Copy, Clone, PartialEq)] | #[derive(Copy, Clone, PartialEq)] | ||||||
| pub struct RtcConfig { | pub struct RtcConfig { | ||||||
|     /// Asynchronous prescaler factor |     /// Asynchronous prescaler factor | ||||||
| @@ -189,7 +178,7 @@ impl Rtc { | |||||||
|             stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), |             stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         Self::enable(); |         BackupDomain::enable_rtc(); | ||||||
|  |  | ||||||
|         rtc_struct.configure(rtc_config); |         rtc_struct.configure(rtc_config); | ||||||
|         rtc_struct.rtc_config = rtc_config; |         rtc_struct.rtc_config = rtc_config; | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ use stm32_metapac::rtc::vals::{Init, Osel, Pol}; | |||||||
|  |  | ||||||
| #[cfg(feature = "low-power")] | #[cfg(feature = "low-power")] | ||||||
| use super::RtcInstant; | use super::RtcInstant; | ||||||
| use super::{sealed, RtcClockSource, RtcConfig}; | use super::{sealed, RtcConfig}; | ||||||
| use crate::pac::rtc::Rtc; | use crate::pac::rtc::Rtc; | ||||||
| use crate::peripherals::RTC; | use crate::peripherals::RTC; | ||||||
| use crate::rtc::sealed::Instance; | use crate::rtc::sealed::Instance; | ||||||
| @@ -73,22 +73,6 @@ impl WakeupPrescaler { | |||||||
| } | } | ||||||
|  |  | ||||||
| impl super::Rtc { | impl super::Rtc { | ||||||
|     fn unlock_registers() { |  | ||||||
|         #[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1))] |  | ||||||
|         let cr = crate::pac::PWR.cr(); |  | ||||||
|         #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))] |  | ||||||
|         let cr = crate::pac::PWR.cr1(); |  | ||||||
|  |  | ||||||
|         // TODO: Missing from PAC for l0 and f0? |  | ||||||
|         #[cfg(not(any(rtc_v2f0, rtc_v2l0)))] |  | ||||||
|         { |  | ||||||
|             if !cr.read().dbp() { |  | ||||||
|                 cr.modify(|w| w.set_dbp(true)); |  | ||||||
|                 while !cr.read().dbp() {} |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[cfg(feature = "low-power")] |     #[cfg(feature = "low-power")] | ||||||
|     /// start the wakeup alarm and wtih a duration that is as close to but less than |     /// start the wakeup alarm and wtih a duration that is as close to but less than | ||||||
|     /// the requested duration, and record the instant the wakeup alarm was started |     /// the requested duration, and record the instant the wakeup alarm was started | ||||||
| @@ -155,69 +139,6 @@ impl super::Rtc { | |||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[allow(dead_code)] |  | ||||||
|     pub(crate) fn set_clock_source(clock_source: RtcClockSource) { |  | ||||||
|         #[cfg(not(rtc_v2wb))] |  | ||||||
|         use stm32_metapac::rcc::vals::Rtcsel; |  | ||||||
|  |  | ||||||
|         #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] |  | ||||||
|         let cr = crate::pac::RCC.bdcr(); |  | ||||||
|         #[cfg(any(rtc_v2l0, rtc_v2l1))] |  | ||||||
|         let cr = crate::pac::RCC.csr(); |  | ||||||
|  |  | ||||||
|         Self::unlock_registers(); |  | ||||||
|  |  | ||||||
|         cr.modify(|w| { |  | ||||||
|             // Select RTC source |  | ||||||
|             #[cfg(not(rtc_v2wb))] |  | ||||||
|             w.set_rtcsel(Rtcsel::from_bits(clock_source as u8)); |  | ||||||
|             #[cfg(rtc_v2wb)] |  | ||||||
|             w.set_rtcsel(clock_source as u8); |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     pub(super) fn enable() { |  | ||||||
|         #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] |  | ||||||
|         let reg = crate::pac::RCC.bdcr().read(); |  | ||||||
|         #[cfg(any(rtc_v2l0, rtc_v2l1))] |  | ||||||
|         let reg = crate::pac::RCC.csr().read(); |  | ||||||
|  |  | ||||||
|         #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb))] |  | ||||||
|         assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); |  | ||||||
|  |  | ||||||
|         if !reg.rtcen() { |  | ||||||
|             Self::unlock_registers(); |  | ||||||
|  |  | ||||||
|             #[cfg(not(any(rtc_v2l0, rtc_v2l1, rtc_v2f2)))] |  | ||||||
|             crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true)); |  | ||||||
|             #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] |  | ||||||
|             let cr = crate::pac::RCC.bdcr(); |  | ||||||
|             #[cfg(any(rtc_v2l0, rtc_v2l1))] |  | ||||||
|             let cr = crate::pac::RCC.csr(); |  | ||||||
|  |  | ||||||
|             cr.modify(|w| { |  | ||||||
|                 // Reset |  | ||||||
|                 #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] |  | ||||||
|                 w.set_bdrst(false); |  | ||||||
|  |  | ||||||
|                 w.set_rtcen(true); |  | ||||||
|                 w.set_rtcsel(reg.rtcsel()); |  | ||||||
|  |  | ||||||
|                 // Restore bcdr |  | ||||||
|                 #[cfg(any(rtc_v2l4, rtc_v2wb))] |  | ||||||
|                 w.set_lscosel(reg.lscosel()); |  | ||||||
|                 #[cfg(any(rtc_v2l4, rtc_v2wb))] |  | ||||||
|                 w.set_lscoen(reg.lscoen()); |  | ||||||
|  |  | ||||||
|                 w.set_lseon(reg.lseon()); |  | ||||||
|  |  | ||||||
|                 #[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))] |  | ||||||
|                 w.set_lsedrv(reg.lsedrv()); |  | ||||||
|                 w.set_lsebyp(reg.lsebyp()); |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// Applies the RTC config |     /// Applies the RTC config | ||||||
|     /// It this changes the RTC clock source the time will be reset |     /// It this changes the RTC clock source the time will be reset | ||||||
|     pub(super) fn configure(&mut self, rtc_config: RtcConfig) { |     pub(super) fn configure(&mut self, rtc_config: RtcConfig) { | ||||||
|   | |||||||
| @@ -1,74 +1,11 @@ | |||||||
| use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Init, Key, Osel, Pol, TampalrmPu, TampalrmType}; | use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Init, Key, Osel, Pol, TampalrmPu, TampalrmType}; | ||||||
|  |  | ||||||
| use super::{sealed, RtcCalibrationCyclePeriod, RtcClockSource, RtcConfig}; | use super::{sealed, RtcCalibrationCyclePeriod, RtcConfig}; | ||||||
| use crate::pac::rtc::Rtc; | use crate::pac::rtc::Rtc; | ||||||
| use crate::peripherals::RTC; | use crate::peripherals::RTC; | ||||||
| use crate::rtc::sealed::Instance; | use crate::rtc::sealed::Instance; | ||||||
|  |  | ||||||
| impl super::Rtc { | impl super::Rtc { | ||||||
|     fn unlock_registers() { |  | ||||||
|         // Unlock the backup domain |  | ||||||
|         #[cfg(not(any(rtc_v3u5, rcc_wl5, rcc_wle)))] |  | ||||||
|         { |  | ||||||
|             if !crate::pac::PWR.cr1().read().dbp() { |  | ||||||
|                 crate::pac::PWR.cr1().modify(|w| w.set_dbp(true)); |  | ||||||
|                 while !crate::pac::PWR.cr1().read().dbp() {} |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         #[cfg(any(rcc_wl5, rcc_wle))] |  | ||||||
|         { |  | ||||||
|             use crate::pac::pwr::vals::Dbp; |  | ||||||
|  |  | ||||||
|             if crate::pac::PWR.cr1().read().dbp() != Dbp::ENABLED { |  | ||||||
|                 crate::pac::PWR.cr1().modify(|w| w.set_dbp(Dbp::ENABLED)); |  | ||||||
|                 while crate::pac::PWR.cr1().read().dbp() != Dbp::ENABLED {} |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[allow(dead_code)] |  | ||||||
|     pub(crate) fn set_clock_source(clock_source: RtcClockSource) { |  | ||||||
|         let clock_source = clock_source as u8; |  | ||||||
|         #[cfg(not(any(rcc_wl5, rcc_wle)))] |  | ||||||
|         let clock_source = crate::pac::rcc::vals::Rtcsel::from_bits(clock_source); |  | ||||||
|  |  | ||||||
|         Self::unlock_registers(); |  | ||||||
|  |  | ||||||
|         crate::pac::RCC.bdcr().modify(|w| { |  | ||||||
|             // Select RTC source |  | ||||||
|             w.set_rtcsel(clock_source); |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     pub(super) fn enable() { |  | ||||||
|         let bdcr = crate::pac::RCC.bdcr(); |  | ||||||
|  |  | ||||||
|         let reg = bdcr.read(); |  | ||||||
|         assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); |  | ||||||
|  |  | ||||||
|         if !reg.rtcen() { |  | ||||||
|             Self::unlock_registers(); |  | ||||||
|  |  | ||||||
|             bdcr.modify(|w| w.set_bdrst(true)); |  | ||||||
|  |  | ||||||
|             bdcr.modify(|w| { |  | ||||||
|                 // Reset |  | ||||||
|                 w.set_bdrst(false); |  | ||||||
|  |  | ||||||
|                 w.set_rtcen(true); |  | ||||||
|                 w.set_rtcsel(reg.rtcsel()); |  | ||||||
|  |  | ||||||
|                 // Restore bcdr |  | ||||||
|                 w.set_lscosel(reg.lscosel()); |  | ||||||
|                 w.set_lscoen(reg.lscoen()); |  | ||||||
|  |  | ||||||
|                 w.set_lseon(reg.lseon()); |  | ||||||
|                 w.set_lsedrv(reg.lsedrv()); |  | ||||||
|                 w.set_lsebyp(reg.lsebyp()); |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// Applies the RTC config |     /// Applies the RTC config | ||||||
|     /// It this changes the RTC clock source the time will be reset |     /// It this changes the RTC clock source the time will be reset | ||||||
|     pub(super) fn configure(&mut self, rtc_config: RtcConfig) { |     pub(super) fn configure(&mut self, rtc_config: RtcConfig) { | ||||||
|   | |||||||
| @@ -5,13 +5,17 @@ | |||||||
| 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, RtcConfig}; | use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; | ||||||
|  | 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 = embassy_stm32::init(Default::default()); |     let mut config = Config::default(); | ||||||
|  |     config.rcc.rtc = Option::Some(RtcClockSource::LSI); | ||||||
|  |     let p = 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) | ||||||
| @@ -23,8 +27,11 @@ async fn main(_spawner: Spawner) { | |||||||
|  |  | ||||||
|     rtc.set_datetime(now.into()).expect("datetime not set"); |     rtc.set_datetime(now.into()).expect("datetime not set"); | ||||||
|  |  | ||||||
|     // In reality the delay would be much longer |     loop { | ||||||
|     Timer::after(Duration::from_millis(20000)).await; |         let now: NaiveDateTime = rtc.now().unwrap().into(); | ||||||
|  |  | ||||||
|     let _then: NaiveDateTime = rtc.now().unwrap().into(); |         info!("{}", now.timestamp()); | ||||||
|  |  | ||||||
|  |         Timer::after(Duration::from_millis(1000)).await; | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { | |||||||
|             PLLMul::Mul20, |             PLLMul::Mul20, | ||||||
|             None, |             None, | ||||||
|         ); |         ); | ||||||
|         config.rcc.rtc_mux = rcc::RtcClockSource::LSE32; |         config.rcc.rtc_mux = rcc::RtcClockSource::LSE; | ||||||
|         embassy_stm32::init(config) |         embassy_stm32::init(config) | ||||||
|     }; |     }; | ||||||
|     info!("Hello World!"); |     info!("Hello World!"); | ||||||
|   | |||||||
| @@ -84,7 +84,7 @@ 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::LSI32; |     config.rcc.rtc_mux = rcc::RtcClockSource::LSI; | ||||||
|  |  | ||||||
|     let dp = embassy_stm32::init(config); |     let dp = embassy_stm32::init(config); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,8 +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::{self, ClockSrc}; | use embassy_stm32::rcc::ClockSrc; | ||||||
| use embassy_stm32::rtc::{Rtc, RtcConfig}; | use embassy_stm32::rtc::{Rtc, RtcClockSource, 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 _}; | ||||||
| @@ -16,7 +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::HSE32; |         config.rcc.mux = ClockSrc::HSE32; | ||||||
|         config.rcc.rtc_mux = rcc::RtcClockSource::LSE32; |         config.rcc.rtc_mux = RtcClockSource::LSE; | ||||||
|         config.rcc.enable_rtc_apb = true; |         config.rcc.enable_rtc_apb = true; | ||||||
|         embassy_stm32::init(config) |         embassy_stm32::init(config) | ||||||
|     }; |     }; | ||||||
|   | |||||||
| @@ -10,7 +10,8 @@ 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::rtc::{Rtc, RtcClockSource, RtcConfig}; | use embassy_stm32::rcc::RtcClockSource; | ||||||
|  | use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||||||
| use embassy_time::{Duration, Timer}; | use embassy_time::{Duration, Timer}; | ||||||
|  |  | ||||||
| #[embassy_executor::main] | #[embassy_executor::main] | ||||||
|   | |||||||
| @@ -11,7 +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::rtc::{Rtc, RtcClockSource, RtcConfig}; | use embassy_stm32::rcc::RtcClockSource; | ||||||
|  | use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||||||
| use embassy_time::{Duration, Timer}; | use embassy_time::{Duration, Timer}; | ||||||
| use static_cell::make_static; | use static_cell::make_static; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user