diff options
| author | xoviat <[email protected]> | 2023-08-27 20:26:41 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-08-27 20:26:41 +0000 |
| commit | 88146eb53e40ea2ab43c2db77f3f62c6d08c9b36 (patch) | |
| tree | 39e00c267d61fde8c6caf47da6658f4e533a0b98 | |
| parent | 13f050167346ce262ea33c0757496b832c90fa58 (diff) | |
| parent | 326e78757b6b69ba598fb89030defd62e081af64 (diff) | |
Merge pull request #1830 from xoviat/rtc
stm32: move backup domain in rcc mod
29 files changed, 224 insertions, 223 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 150014afe..d0ada97a3 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml | |||
| @@ -58,7 +58,7 @@ sdio-host = "0.5.0" | |||
| 58 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } | 58 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } |
| 59 | critical-section = "1.1" | 59 | critical-section = "1.1" |
| 60 | atomic-polyfill = "1.0.1" | 60 | atomic-polyfill = "1.0.1" |
| 61 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2b87e34c661e19ff6dc603fabfe7fe99ab7261f7" } | 61 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9a61a1f090462df8bd1751f89951f04934fdceb3" } |
| 62 | vcell = "0.1.3" | 62 | vcell = "0.1.3" |
| 63 | bxcan = "0.7.0" | 63 | bxcan = "0.7.0" |
| 64 | nb = "1.0.0" | 64 | nb = "1.0.0" |
| @@ -77,7 +77,7 @@ critical-section = { version = "1.1", features = ["std"] } | |||
| 77 | [build-dependencies] | 77 | [build-dependencies] |
| 78 | proc-macro2 = "1.0.36" | 78 | proc-macro2 = "1.0.36" |
| 79 | quote = "1.0.15" | 79 | quote = "1.0.15" |
| 80 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-2b87e34c661e19ff6dc603fabfe7fe99ab7261f7", default-features = false, features = ["metadata"]} | 80 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9a61a1f090462df8bd1751f89951f04934fdceb3", default-features = false, features = ["metadata"]} |
| 81 | 81 | ||
| 82 | [features] | 82 | [features] |
| 83 | default = ["rt"] | 83 | default = ["rt"] |
diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs new file mode 100644 index 000000000..0fc116ed8 --- /dev/null +++ b/embassy-stm32/src/rcc/bd.rs | |||
| @@ -0,0 +1,151 @@ | |||
| 1 | #[derive(Copy, Clone, Debug, PartialEq)] | ||
| 2 | #[repr(u8)] | ||
| 3 | #[allow(dead_code)] | ||
| 4 | pub enum RtcClockSource { | ||
| 5 | /// 00: No clock | ||
| 6 | NoClock = 0b00, | ||
| 7 | /// 01: LSE oscillator clock used as RTC clock | ||
| 8 | LSE = 0b01, | ||
| 9 | /// 10: LSI oscillator clock used as RTC clock | ||
| 10 | LSI = 0b10, | ||
| 11 | /// 11: HSE oscillator clock divided by 32 used as RTC clock | ||
| 12 | HSE = 0b11, | ||
| 13 | } | ||
| 14 | |||
| 15 | #[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))] | ||
| 16 | #[allow(dead_code)] | ||
| 17 | type Bdcr = crate::pac::rcc::regs::Bdcr; | ||
| 18 | |||
| 19 | #[cfg(any(rtc_v2l0, rtc_v2l1))] | ||
| 20 | #[allow(dead_code)] | ||
| 21 | type Bdcr = crate::pac::rcc::regs::Csr; | ||
| 22 | |||
| 23 | #[allow(dead_code)] | ||
| 24 | pub struct BackupDomain {} | ||
| 25 | |||
| 26 | impl BackupDomain { | ||
| 27 | #[cfg(any( | ||
| 28 | rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, | ||
| 29 | rtc_v3u5 | ||
| 30 | ))] | ||
| 31 | #[allow(dead_code, unused_variables)] | ||
| 32 | fn modify<R>(f: impl FnOnce(&mut Bdcr) -> R) -> R { | ||
| 33 | #[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1))] | ||
| 34 | let cr = crate::pac::PWR.cr(); | ||
| 35 | #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] | ||
| 36 | let cr = crate::pac::PWR.cr1(); | ||
| 37 | |||
| 38 | // TODO: Missing from PAC for l0 and f0? | ||
| 39 | #[cfg(not(any(rtc_v2f0, rtc_v2l0, rtc_v3u5)))] | ||
| 40 | { | ||
| 41 | cr.modify(|w| w.set_dbp(true)); | ||
| 42 | while !cr.read().dbp() {} | ||
| 43 | } | ||
| 44 | |||
| 45 | #[cfg(any(rtc_v2l0, rtc_v2l1))] | ||
| 46 | let cr = crate::pac::RCC.csr(); | ||
| 47 | |||
| 48 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | ||
| 49 | let cr = crate::pac::RCC.bdcr(); | ||
| 50 | |||
| 51 | cr.modify(|w| f(w)) | ||
| 52 | } | ||
| 53 | |||
| 54 | #[cfg(any( | ||
| 55 | rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, | ||
| 56 | rtc_v3u5 | ||
| 57 | ))] | ||
| 58 | #[allow(dead_code)] | ||
| 59 | fn read() -> Bdcr { | ||
| 60 | #[cfg(any(rtc_v2l0, rtc_v2l1))] | ||
| 61 | let r = crate::pac::RCC.csr().read(); | ||
| 62 | |||
| 63 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | ||
| 64 | let r = crate::pac::RCC.bdcr().read(); | ||
| 65 | |||
| 66 | r | ||
| 67 | } | ||
| 68 | |||
| 69 | #[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, | ||
| 71 | rtc_v3u5 | ||
| 72 | ))] | ||
| 73 | #[allow(dead_code, unused_variables)] | ||
| 74 | pub fn set_rtc_clock_source(clock_source: RtcClockSource) { | ||
| 75 | let clock_source = clock_source as u8; | ||
| 76 | #[cfg(any( | ||
| 77 | all(not(any(rtc_v3, rtc_v3u5)), not(rtc_v2wb)), | ||
| 78 | all(any(rtc_v3, rtc_v3u5), not(any(rcc_wl5, rcc_wle))) | ||
| 79 | ))] | ||
| 80 | let clock_source = crate::pac::rcc::vals::Rtcsel::from_bits(clock_source); | ||
| 81 | |||
| 82 | #[cfg(not(rtc_v2wb))] | ||
| 83 | Self::modify(|w| { | ||
| 84 | // Select RTC source | ||
| 85 | w.set_rtcsel(clock_source); | ||
| 86 | }); | ||
| 87 | } | ||
| 88 | |||
| 89 | #[cfg(any( | ||
| 90 | rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb | ||
| 91 | ))] | ||
| 92 | #[allow(dead_code)] | ||
| 93 | pub fn enable_rtc() { | ||
| 94 | let reg = Self::read(); | ||
| 95 | |||
| 96 | #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb))] | ||
| 97 | assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); | ||
| 98 | |||
| 99 | if !reg.rtcen() { | ||
| 100 | #[cfg(not(any(rtc_v2l0, rtc_v2l1, rtc_v2f2)))] | ||
| 101 | Self::modify(|w| w.set_bdrst(true)); | ||
| 102 | |||
| 103 | Self::modify(|w| { | ||
| 104 | // Reset | ||
| 105 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | ||
| 106 | w.set_bdrst(false); | ||
| 107 | |||
| 108 | w.set_rtcen(true); | ||
| 109 | w.set_rtcsel(reg.rtcsel()); | ||
| 110 | |||
| 111 | // Restore bcdr | ||
| 112 | #[cfg(any(rtc_v2l4, rtc_v2wb))] | ||
| 113 | w.set_lscosel(reg.lscosel()); | ||
| 114 | #[cfg(any(rtc_v2l4, rtc_v2wb))] | ||
| 115 | w.set_lscoen(reg.lscoen()); | ||
| 116 | |||
| 117 | w.set_lseon(reg.lseon()); | ||
| 118 | |||
| 119 | #[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))] | ||
| 120 | w.set_lsedrv(reg.lsedrv()); | ||
| 121 | w.set_lsebyp(reg.lsebyp()); | ||
| 122 | }); | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | #[cfg(any(rtc_v3, rtc_v3u5))] | ||
| 127 | #[allow(dead_code)] | ||
| 128 | pub fn enable_rtc() { | ||
| 129 | let reg = Self::read(); | ||
| 130 | assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); | ||
| 131 | |||
| 132 | if !reg.rtcen() { | ||
| 133 | Self::modify(|w| w.set_bdrst(true)); | ||
| 134 | |||
| 135 | Self::modify(|w| { | ||
| 136 | w.set_bdrst(false); | ||
| 137 | |||
| 138 | w.set_rtcen(true); | ||
| 139 | w.set_rtcsel(reg.rtcsel()); | ||
| 140 | |||
| 141 | // Restore bcdr | ||
| 142 | w.set_lscosel(reg.lscosel()); | ||
| 143 | w.set_lscoen(reg.lscoen()); | ||
| 144 | |||
| 145 | w.set_lseon(reg.lseon()); | ||
| 146 | w.set_lsedrv(reg.lsedrv()); | ||
| 147 | w.set_lsebyp(reg.lsebyp()); | ||
| 148 | }); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | } | ||
diff --git a/embassy-stm32/src/rcc/common.rs b/embassy-stm32/src/rcc/bus.rs index 62736a43a..62736a43a 100644 --- a/embassy-stm32/src/rcc/common.rs +++ b/embassy-stm32/src/rcc/bus.rs | |||
diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs index 6a9326347..d85790797 100644 --- a/embassy-stm32/src/rcc/c0.rs +++ b/embassy-stm32/src/rcc/c0.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler}; | 1 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 2 | use crate::pac::flash::vals::Latency; | 2 | use crate::pac::flash::vals::Latency; |
| 3 | use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw}; | 3 | use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw}; |
| 4 | use crate::pac::{FLASH, RCC}; | 4 | use crate::pac::{FLASH, RCC}; |
diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs index ec4ed99b8..9d9bc59fd 100644 --- a/embassy-stm32/src/rcc/f2.rs +++ b/embassy-stm32/src/rcc/f2.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | use core::convert::TryFrom; | 1 | use core::convert::TryFrom; |
| 2 | use core::ops::{Div, Mul}; | 2 | use core::ops::{Div, Mul}; |
| 3 | 3 | ||
| 4 | pub use super::common::{AHBPrescaler, APBPrescaler}; | 4 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 5 | use crate::pac::flash::vals::Latency; | 5 | use crate::pac::flash::vals::Latency; |
| 6 | use crate::pac::rcc::vals::{Pllp, Pllsrc, Sw}; | 6 | use crate::pac::rcc::vals::{Pllp, Pllsrc, Sw}; |
| 7 | use crate::pac::{FLASH, RCC}; | 7 | use crate::pac::{FLASH, RCC}; |
| @@ -201,7 +201,7 @@ pub struct PLLClocks { | |||
| 201 | pub pll48_freq: Hertz, | 201 | pub pll48_freq: Hertz, |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | pub use super::common::VoltageScale; | 204 | pub use super::bus::VoltageScale; |
| 205 | 205 | ||
| 206 | impl VoltageScale { | 206 | impl VoltageScale { |
| 207 | const fn wait_states(&self, ahb_freq: Hertz) -> Option<Latency> { | 207 | const fn wait_states(&self, ahb_freq: Hertz) -> Option<Latency> { |
diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index 321270a70..7480c0393 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs | |||
| @@ -201,9 +201,9 @@ fn calc_pll(config: &Config, Hertz(sysclk): Hertz) -> (Hertz, PllConfig) { | |||
| 201 | // Calculates the Multiplier and the Divisor to arrive at | 201 | // Calculates the Multiplier and the Divisor to arrive at |
| 202 | // the required System clock from PLL source frequency | 202 | // the required System clock from PLL source frequency |
| 203 | let get_mul_div = |sysclk, pllsrcclk| { | 203 | let get_mul_div = |sysclk, pllsrcclk| { |
| 204 | let common_div = gcd(sysclk, pllsrcclk); | 204 | let bus_div = gcd(sysclk, pllsrcclk); |
| 205 | let mut multiplier = sysclk / common_div; | 205 | let mut multiplier = sysclk / bus_div; |
| 206 | let mut divisor = pllsrcclk / common_div; | 206 | let mut divisor = pllsrcclk / bus_div; |
| 207 | // Minimum PLL multiplier is two | 207 | // Minimum PLL multiplier is two |
| 208 | if multiplier == 1 { | 208 | if multiplier == 1 { |
| 209 | multiplier *= 2; | 209 | multiplier *= 2; |
diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs index ee9cb2897..10d3322aa 100644 --- a/embassy-stm32/src/rcc/f4.rs +++ b/embassy-stm32/src/rcc/f4.rs | |||
| @@ -8,8 +8,8 @@ use crate::gpio::sealed::AFType; | |||
| 8 | use crate::gpio::Speed; | 8 | use crate::gpio::Speed; |
| 9 | use crate::pac::rcc::vals::{Hpre, Ppre, Sw}; | 9 | use crate::pac::rcc::vals::{Hpre, Ppre, Sw}; |
| 10 | use crate::pac::{FLASH, PWR, RCC}; | 10 | use crate::pac::{FLASH, PWR, RCC}; |
| 11 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; | ||
| 11 | use crate::rcc::{set_freqs, Clocks}; | 12 | use crate::rcc::{set_freqs, Clocks}; |
| 12 | use crate::rtc::{Rtc, RtcClockSource}; | ||
| 13 | use crate::time::Hertz; | 13 | use crate::time::Hertz; |
| 14 | use crate::{peripherals, Peripheral}; | 14 | use crate::{peripherals, Peripheral}; |
| 15 | 15 | ||
| @@ -470,7 +470,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | config.rtc.map(|clock_source| { | 472 | config.rtc.map(|clock_source| { |
| 473 | Rtc::set_clock_source(clock_source); | 473 | BackupDomain::set_rtc_clock_source(clock_source); |
| 474 | }); | 474 | }); |
| 475 | 475 | ||
| 476 | let rtc = match config.rtc { | 476 | let rtc = match config.rtc { |
diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs index bf2d5199e..7fdbcb00c 100644 --- a/embassy-stm32/src/rcc/g0.rs +++ b/embassy-stm32/src/rcc/g0.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler}; | 1 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 2 | use crate::pac::flash::vals::Latency; | 2 | use crate::pac::flash::vals::Latency; |
| 3 | use crate::pac::rcc::vals::{self, Hsidiv, Ppre, Sw}; | 3 | use crate::pac::rcc::vals::{self, Hsidiv, Ppre, Sw}; |
| 4 | use crate::pac::{FLASH, PWR, RCC}; | 4 | use crate::pac::{FLASH, PWR, RCC}; |
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs index dff04023e..3b044cd11 100644 --- a/embassy-stm32/src/rcc/g4.rs +++ b/embassy-stm32/src/rcc/g4.rs | |||
| @@ -2,7 +2,7 @@ use stm32_metapac::flash::vals::Latency; | |||
| 2 | use stm32_metapac::rcc::vals::{Hpre, Pllsrc, Ppre, Sw}; | 2 | use stm32_metapac::rcc::vals::{Hpre, Pllsrc, Ppre, Sw}; |
| 3 | use stm32_metapac::FLASH; | 3 | use stm32_metapac::FLASH; |
| 4 | 4 | ||
| 5 | pub use super::common::{AHBPrescaler, APBPrescaler}; | 5 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 6 | use crate::pac::{PWR, RCC}; | 6 | use crate::pac::{PWR, RCC}; |
| 7 | use crate::rcc::sealed::RccPeripheral; | 7 | use crate::rcc::sealed::RccPeripheral; |
| 8 | use crate::rcc::{set_freqs, Clocks}; | 8 | use crate::rcc::{set_freqs, Clocks}; |
diff --git a/embassy-stm32/src/rcc/h5.rs b/embassy-stm32/src/rcc/h5.rs index 2e72b1931..5741cdf92 100644 --- a/embassy-stm32/src/rcc/h5.rs +++ b/embassy-stm32/src/rcc/h5.rs | |||
| @@ -26,7 +26,7 @@ const VCO_MAX: u32 = 420_000_000; | |||
| 26 | const VCO_WIDE_MIN: u32 = 128_000_000; | 26 | const VCO_WIDE_MIN: u32 = 128_000_000; |
| 27 | const VCO_WIDE_MAX: u32 = 560_000_000; | 27 | const VCO_WIDE_MAX: u32 = 560_000_000; |
| 28 | 28 | ||
| 29 | pub use super::common::{AHBPrescaler, APBPrescaler, VoltageScale}; | 29 | pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; |
| 30 | 30 | ||
| 31 | pub enum HseMode { | 31 | pub enum HseMode { |
| 32 | /// crystal/ceramic oscillator (HSEBYP=0) | 32 | /// crystal/ceramic oscillator (HSEBYP=0) |
diff --git a/embassy-stm32/src/rcc/h7.rs b/embassy-stm32/src/rcc/h7.rs index 7fb4fb95b..a6e694618 100644 --- a/embassy-stm32/src/rcc/h7.rs +++ b/embassy-stm32/src/rcc/h7.rs | |||
| @@ -24,7 +24,7 @@ pub const HSI48_FREQ: Hertz = Hertz(48_000_000); | |||
| 24 | /// LSI speed | 24 | /// LSI speed |
| 25 | pub const LSI_FREQ: Hertz = Hertz(32_000); | 25 | pub const LSI_FREQ: Hertz = Hertz(32_000); |
| 26 | 26 | ||
| 27 | pub use super::common::VoltageScale; | 27 | pub use super::bus::VoltageScale; |
| 28 | 28 | ||
| 29 | #[derive(Clone, Copy)] | 29 | #[derive(Clone, Copy)] |
| 30 | pub enum AdcClockSource { | 30 | pub enum AdcClockSource { |
diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0.rs index 46b58ca7c..7f9ab01f1 100644 --- a/embassy-stm32/src/rcc/l0.rs +++ b/embassy-stm32/src/rcc/l0.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler}; | 1 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 2 | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; | 2 | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; |
| 3 | use crate::pac::RCC; | 3 | use crate::pac::RCC; |
| 4 | #[cfg(crs)] | 4 | #[cfg(crs)] |
diff --git a/embassy-stm32/src/rcc/l1.rs b/embassy-stm32/src/rcc/l1.rs index bdfc5b87a..ed949ea6f 100644 --- a/embassy-stm32/src/rcc/l1.rs +++ b/embassy-stm32/src/rcc/l1.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler}; | 1 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 2 | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; | 2 | use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; |
| 3 | use crate::pac::{FLASH, RCC}; | 3 | use crate::pac::{FLASH, RCC}; |
| 4 | use crate::rcc::{set_freqs, Clocks}; | 4 | use crate::rcc::{set_freqs, Clocks}; |
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs index b34b8caab..c6bccfd26 100644 --- a/embassy-stm32/src/rcc/l4.rs +++ b/embassy-stm32/src/rcc/l4.rs | |||
| @@ -4,13 +4,13 @@ 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::{Lsedrv, Mcopre, Mcosel}; |
| 6 | 6 | ||
| 7 | pub use super::common::{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, PWR, RCC}; |
| 12 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; | ||
| 12 | use crate::rcc::{set_freqs, Clocks}; | 13 | use crate::rcc::{set_freqs, Clocks}; |
| 13 | use crate::rtc::{Rtc, RtcClockSource as RCS}; | ||
| 14 | use crate::time::Hertz; | 14 | use crate::time::Hertz; |
| 15 | use crate::{peripherals, Peripheral}; | 15 | use crate::{peripherals, Peripheral}; |
| 16 | 16 | ||
| @@ -254,16 +254,11 @@ impl Default for Config { | |||
| 254 | pllsai1: None, | 254 | pllsai1: None, |
| 255 | #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] | 255 | #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] |
| 256 | hsi48: false, | 256 | hsi48: false, |
| 257 | rtc_mux: RtcClockSource::LSI32, | 257 | rtc_mux: RtcClockSource::LSI, |
| 258 | } | 258 | } |
| 259 | } | 259 | } |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | pub enum RtcClockSource { | ||
| 263 | LSE32, | ||
| 264 | LSI32, | ||
| 265 | } | ||
| 266 | |||
| 267 | pub enum McoClock { | 262 | pub enum McoClock { |
| 268 | DIV1, | 263 | DIV1, |
| 269 | DIV2, | 264 | DIV2, |
| @@ -413,7 +408,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 413 | RCC.apb1enr1().modify(|w| w.set_pwren(true)); | 408 | RCC.apb1enr1().modify(|w| w.set_pwren(true)); |
| 414 | 409 | ||
| 415 | match config.rtc_mux { | 410 | match config.rtc_mux { |
| 416 | RtcClockSource::LSE32 => { | 411 | RtcClockSource::LSE => { |
| 417 | // 1. Unlock the backup domain | 412 | // 1. Unlock the backup domain |
| 418 | PWR.cr1().modify(|w| w.set_dbp(true)); | 413 | PWR.cr1().modify(|w| w.set_dbp(true)); |
| 419 | 414 | ||
| @@ -429,17 +424,18 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 429 | // Wait until LSE is running | 424 | // Wait until LSE is running |
| 430 | while !RCC.bdcr().read().lserdy() {} | 425 | while !RCC.bdcr().read().lserdy() {} |
| 431 | 426 | ||
| 432 | Rtc::set_clock_source(RCS::LSE); | 427 | BackupDomain::set_rtc_clock_source(RtcClockSource::LSE); |
| 433 | } | 428 | } |
| 434 | RtcClockSource::LSI32 => { | 429 | RtcClockSource::LSI => { |
| 435 | // Turn on the internal 32 kHz LSI oscillator | 430 | // Turn on the internal 32 kHz LSI oscillator |
| 436 | RCC.csr().modify(|w| w.set_lsion(true)); | 431 | RCC.csr().modify(|w| w.set_lsion(true)); |
| 437 | 432 | ||
| 438 | // Wait until LSI is running | 433 | // Wait until LSI is running |
| 439 | while !RCC.csr().read().lsirdy() {} | 434 | while !RCC.csr().read().lsirdy() {} |
| 440 | 435 | ||
| 441 | Rtc::set_clock_source(RCS::LSI); | 436 | BackupDomain::set_rtc_clock_source(RtcClockSource::LSI); |
| 442 | } | 437 | } |
| 438 | _ => unreachable!(), | ||
| 443 | } | 439 | } |
| 444 | 440 | ||
| 445 | let (sys_clk, sw) = match config.mux { | 441 | let (sys_clk, sw) = match config.mux { |
| @@ -451,7 +447,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 451 | w.set_msirgsel(true); | 447 | w.set_msirgsel(true); |
| 452 | w.set_msion(true); | 448 | w.set_msion(true); |
| 453 | 449 | ||
| 454 | if let RtcClockSource::LSE32 = config.rtc_mux { | 450 | if let RtcClockSource::LSE = config.rtc_mux { |
| 455 | // If LSE is enabled, enable calibration of MSI | 451 | // If LSE is enabled, enable calibration of MSI |
| 456 | w.set_msipllen(true); | 452 | w.set_msipllen(true); |
| 457 | } else { | 453 | } else { |
diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs index a85e14889..9e4e0fc75 100644 --- a/embassy-stm32/src/rcc/l5.rs +++ b/embassy-stm32/src/rcc/l5.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use stm32_metapac::PWR; | 1 | use stm32_metapac::PWR; |
| 2 | 2 | ||
| 3 | pub use super::common::{AHBPrescaler, APBPrescaler}; | 3 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 4 | use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; | 4 | use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw}; |
| 5 | use crate::pac::{FLASH, RCC}; | 5 | use crate::pac::{FLASH, RCC}; |
| 6 | use crate::rcc::{set_freqs, Clocks}; | 6 | use crate::rcc::{set_freqs, Clocks}; |
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 45a4d880d..9f1b3b663 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | pub mod common; | 3 | pub(crate) mod bd; |
| 4 | 4 | pub mod bus; | |
| 5 | use core::mem::MaybeUninit; | 5 | use core::mem::MaybeUninit; |
| 6 | 6 | ||
| 7 | pub use crate::rcc::bd::RtcClockSource; | ||
| 7 | use crate::time::Hertz; | 8 | use crate::time::Hertz; |
| 8 | 9 | ||
| 9 | #[cfg_attr(rcc_f0, path = "f0.rs")] | 10 | #[cfg_attr(rcc_f0, path = "f0.rs")] |
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs index b5feeb0c4..4aca9cd3d 100644 --- a/embassy-stm32/src/rcc/u5.rs +++ b/embassy-stm32/src/rcc/u5.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use stm32_metapac::rcc::vals::{Msirange, Msirgsel, Pllm, Pllsrc, Sw}; | 1 | use stm32_metapac::rcc::vals::{Msirange, Msirgsel, Pllm, Pllsrc, Sw}; |
| 2 | 2 | ||
| 3 | pub use super::common::{AHBPrescaler, APBPrescaler}; | 3 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 4 | use crate::pac::{FLASH, RCC}; | 4 | use crate::pac::{FLASH, RCC}; |
| 5 | use crate::rcc::{set_freqs, Clocks}; | 5 | use crate::rcc::{set_freqs, Clocks}; |
| 6 | use crate::time::Hertz; | 6 | use crate::time::Hertz; |
| @@ -11,7 +11,7 @@ pub const HSI_FREQ: Hertz = Hertz(16_000_000); | |||
| 11 | /// LSI speed | 11 | /// LSI speed |
| 12 | pub const LSI_FREQ: Hertz = Hertz(32_000); | 12 | pub const LSI_FREQ: Hertz = Hertz(32_000); |
| 13 | 13 | ||
| 14 | pub use super::common::VoltageScale; | 14 | pub use super::bus::VoltageScale; |
| 15 | 15 | ||
| 16 | #[derive(Copy, Clone)] | 16 | #[derive(Copy, Clone)] |
| 17 | pub enum ClockSrc { | 17 | pub enum ClockSrc { |
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs index ae708b37f..6a3eab707 100644 --- a/embassy-stm32/src/rcc/wb.rs +++ b/embassy-stm32/src/rcc/wb.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler}; | 1 | pub use super::bus::{AHBPrescaler, APBPrescaler}; |
| 2 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; | ||
| 2 | use crate::rcc::Clocks; | 3 | use crate::rcc::Clocks; |
| 3 | use crate::rtc::{Rtc, RtcClockSource}; | ||
| 4 | use crate::time::{khz, mhz, Hertz}; | 4 | use crate::time::{khz, mhz, Hertz}; |
| 5 | 5 | ||
| 6 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, | 6 | /// 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) { | |||
| 375 | w.set_shdhpre(config.ahb3_pre.into()); | 375 | w.set_shdhpre(config.ahb3_pre.into()); |
| 376 | }); | 376 | }); |
| 377 | 377 | ||
| 378 | config.rtc.map(|clock_source| Rtc::set_clock_source(clock_source)); | 378 | config |
| 379 | .rtc | ||
| 380 | .map(|clock_source| BackupDomain::set_rtc_clock_source(clock_source)); | ||
| 379 | } | 381 | } |
diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs index f1dd2bd7e..e33690d10 100644 --- a/embassy-stm32/src/rcc/wl.rs +++ b/embassy-stm32/src/rcc/wl.rs | |||
| @@ -1,8 +1,7 @@ | |||
| 1 | pub use super::common::{AHBPrescaler, APBPrescaler, VoltageScale}; | 1 | pub use super::bus::{AHBPrescaler, APBPrescaler, VoltageScale}; |
| 2 | use crate::pac::pwr::vals::Dbp; | ||
| 3 | use crate::pac::{FLASH, PWR, RCC}; | 2 | use crate::pac::{FLASH, PWR, RCC}; |
| 3 | use crate::rcc::bd::{BackupDomain, RtcClockSource}; | ||
| 4 | use crate::rcc::{set_freqs, Clocks}; | 4 | use crate::rcc::{set_freqs, Clocks}; |
| 5 | use crate::rtc::{Rtc, RtcClockSource as RCS}; | ||
| 6 | use crate::time::Hertz; | 5 | use crate::time::Hertz; |
| 7 | 6 | ||
| 8 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, | 7 | /// Most of clock setup is copied from stm32l0xx-hal, and adopted to the generated PAC, |
| @@ -130,16 +129,11 @@ impl Default for Config { | |||
| 130 | apb2_pre: APBPrescaler::NotDivided, | 129 | apb2_pre: APBPrescaler::NotDivided, |
| 131 | enable_lsi: false, | 130 | enable_lsi: false, |
| 132 | enable_rtc_apb: false, | 131 | enable_rtc_apb: false, |
| 133 | rtc_mux: RtcClockSource::LSI32, | 132 | rtc_mux: RtcClockSource::LSI, |
| 134 | } | 133 | } |
| 135 | } | 134 | } |
| 136 | } | 135 | } |
| 137 | 136 | ||
| 138 | pub enum RtcClockSource { | ||
| 139 | LSE32, | ||
| 140 | LSI32, | ||
| 141 | } | ||
| 142 | |||
| 143 | #[repr(u8)] | 137 | #[repr(u8)] |
| 144 | pub enum Lsedrv { | 138 | pub enum Lsedrv { |
| 145 | Low = 0, | 139 | Low = 0, |
| @@ -215,9 +209,9 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 215 | while FLASH.acr().read().latency() != ws {} | 209 | while FLASH.acr().read().latency() != ws {} |
| 216 | 210 | ||
| 217 | match config.rtc_mux { | 211 | match config.rtc_mux { |
| 218 | RtcClockSource::LSE32 => { | 212 | RtcClockSource::LSE => { |
| 219 | // 1. Unlock the backup domain | 213 | // 1. Unlock the backup domain |
| 220 | PWR.cr1().modify(|w| w.set_dbp(Dbp::ENABLED)); | 214 | PWR.cr1().modify(|w| w.set_dbp(true)); |
| 221 | 215 | ||
| 222 | // 2. Setup the LSE | 216 | // 2. Setup the LSE |
| 223 | RCC.bdcr().modify(|w| { | 217 | RCC.bdcr().modify(|w| { |
| @@ -231,17 +225,18 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 231 | // Wait until LSE is running | 225 | // Wait until LSE is running |
| 232 | while !RCC.bdcr().read().lserdy() {} | 226 | while !RCC.bdcr().read().lserdy() {} |
| 233 | 227 | ||
| 234 | Rtc::set_clock_source(RCS::LSE); | 228 | BackupDomain::set_rtc_clock_source(RtcClockSource::LSE); |
| 235 | } | 229 | } |
| 236 | RtcClockSource::LSI32 => { | 230 | RtcClockSource::LSI => { |
| 237 | // Turn on the internal 32 kHz LSI oscillator | 231 | // Turn on the internal 32 kHz LSI oscillator |
| 238 | RCC.csr().modify(|w| w.set_lsion(true)); | 232 | RCC.csr().modify(|w| w.set_lsion(true)); |
| 239 | 233 | ||
| 240 | // Wait until LSI is running | 234 | // Wait until LSI is running |
| 241 | while !RCC.csr().read().lsirdy() {} | 235 | while !RCC.csr().read().lsirdy() {} |
| 242 | 236 | ||
| 243 | Rtc::set_clock_source(RCS::LSI); | 237 | BackupDomain::set_rtc_clock_source(RtcClockSource::LSI); |
| 244 | } | 238 | } |
| 239 | _ => unreachable!(), | ||
| 245 | } | 240 | } |
| 246 | 241 | ||
| 247 | match config.mux { | 242 | match config.mux { |
| @@ -266,7 +261,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 266 | w.set_msirange(range.into()); | 261 | w.set_msirange(range.into()); |
| 267 | w.set_msion(true); | 262 | w.set_msion(true); |
| 268 | 263 | ||
| 269 | if let RtcClockSource::LSE32 = config.rtc_mux { | 264 | if let RtcClockSource::LSE = config.rtc_mux { |
| 270 | // If LSE is enabled, enable calibration of MSI | 265 | // If LSE is enabled, enable calibration of MSI |
| 271 | w.set_msipllen(true); | 266 | w.set_msipllen(true); |
| 272 | } else { | 267 | } else { |
diff --git a/embassy-stm32/src/rtc/datetime.rs b/embassy-stm32/src/rtc/datetime.rs index a9c48d88d..3efe9be5d 100644 --- a/embassy-stm32/src/rtc/datetime.rs +++ b/embassy-stm32/src/rtc/datetime.rs | |||
| @@ -89,7 +89,7 @@ pub enum DayOfWeek { | |||
| 89 | #[cfg(feature = "chrono")] | 89 | #[cfg(feature = "chrono")] |
| 90 | impl From<chrono::Weekday> for DayOfWeek { | 90 | impl From<chrono::Weekday> for DayOfWeek { |
| 91 | fn from(weekday: Weekday) -> Self { | 91 | fn from(weekday: Weekday) -> Self { |
| 92 | day_of_week_from_u8(weekday.number_from_monday() as u8).unwrap() | 92 | day_of_week_from_u8(weekday.num_days_from_monday() as u8).unwrap() |
| 93 | } | 93 | } |
| 94 | } | 94 | } |
| 95 | 95 | ||
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs index 1f1abb78d..c408b2d61 100644 --- a/embassy-stm32/src/rtc/mod.rs +++ b/embassy-stm32/src/rtc/mod.rs | |||
| @@ -10,6 +10,8 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | |||
| 10 | use embassy_sync::blocking_mutex::Mutex; | 10 | use embassy_sync::blocking_mutex::Mutex; |
| 11 | 11 | ||
| 12 | pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; | 12 | pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; |
| 13 | use crate::rcc::bd::BackupDomain; | ||
| 14 | pub use crate::rcc::RtcClockSource; | ||
| 13 | 15 | ||
| 14 | /// refer to AN4759 to compare features of RTC2 and RTC3 | 16 | /// refer to AN4759 to compare features of RTC2 and RTC3 |
| 15 | #[cfg_attr(any(rtc_v1), path = "v1.rs")] | 17 | #[cfg_attr(any(rtc_v1), path = "v1.rs")] |
| @@ -107,19 +109,6 @@ pub struct Rtc { | |||
| 107 | stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<RtcInstant>>>, | 109 | stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<RtcInstant>>>, |
| 108 | } | 110 | } |
| 109 | 111 | ||
| 110 | #[derive(Copy, Clone, Debug, PartialEq)] | ||
| 111 | #[repr(u8)] | ||
| 112 | pub enum RtcClockSource { | ||
| 113 | /// 00: No clock | ||
| 114 | NoClock = 0b00, | ||
| 115 | /// 01: LSE oscillator clock used as RTC clock | ||
| 116 | LSE = 0b01, | ||
| 117 | /// 10: LSI oscillator clock used as RTC clock | ||
| 118 | LSI = 0b10, | ||
| 119 | /// 11: HSE oscillator clock divided by 32 used as RTC clock | ||
| 120 | HSE = 0b11, | ||
| 121 | } | ||
| 122 | |||
| 123 | #[derive(Copy, Clone, PartialEq)] | 112 | #[derive(Copy, Clone, PartialEq)] |
| 124 | pub struct RtcConfig { | 113 | pub struct RtcConfig { |
| 125 | /// Asynchronous prescaler factor | 114 | /// Asynchronous prescaler factor |
| @@ -189,7 +178,7 @@ impl Rtc { | |||
| 189 | stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), | 178 | stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), |
| 190 | }; | 179 | }; |
| 191 | 180 | ||
| 192 | Self::enable(); | 181 | BackupDomain::enable_rtc(); |
| 193 | 182 | ||
| 194 | rtc_struct.configure(rtc_config); | 183 | rtc_struct.configure(rtc_config); |
| 195 | rtc_struct.rtc_config = rtc_config; | 184 | rtc_struct.rtc_config = rtc_config; |
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs index bf926f986..1e0ca9b48 100644 --- a/embassy-stm32/src/rtc/v2.rs +++ b/embassy-stm32/src/rtc/v2.rs | |||
| @@ -2,7 +2,7 @@ use stm32_metapac::rtc::vals::{Init, Osel, Pol}; | |||
| 2 | 2 | ||
| 3 | #[cfg(feature = "low-power")] | 3 | #[cfg(feature = "low-power")] |
| 4 | use super::RtcInstant; | 4 | use super::RtcInstant; |
| 5 | use super::{sealed, RtcClockSource, RtcConfig}; | 5 | use super::{sealed, RtcConfig}; |
| 6 | use crate::pac::rtc::Rtc; | 6 | use crate::pac::rtc::Rtc; |
| 7 | use crate::peripherals::RTC; | 7 | use crate::peripherals::RTC; |
| 8 | use crate::rtc::sealed::Instance; | 8 | use crate::rtc::sealed::Instance; |
| @@ -73,22 +73,6 @@ impl WakeupPrescaler { | |||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | impl super::Rtc { | 75 | impl super::Rtc { |
| 76 | fn unlock_registers() { | ||
| 77 | #[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1))] | ||
| 78 | let cr = crate::pac::PWR.cr(); | ||
| 79 | #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))] | ||
| 80 | let cr = crate::pac::PWR.cr1(); | ||
| 81 | |||
| 82 | // TODO: Missing from PAC for l0 and f0? | ||
| 83 | #[cfg(not(any(rtc_v2f0, rtc_v2l0)))] | ||
| 84 | { | ||
| 85 | if !cr.read().dbp() { | ||
| 86 | cr.modify(|w| w.set_dbp(true)); | ||
| 87 | while !cr.read().dbp() {} | ||
| 88 | } | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | #[cfg(feature = "low-power")] | 76 | #[cfg(feature = "low-power")] |
| 93 | /// start the wakeup alarm and wtih a duration that is as close to but less than | 77 | /// start the wakeup alarm and wtih a duration that is as close to but less than |
| 94 | /// the requested duration, and record the instant the wakeup alarm was started | 78 | /// the requested duration, and record the instant the wakeup alarm was started |
| @@ -155,69 +139,6 @@ impl super::Rtc { | |||
| 155 | }) | 139 | }) |
| 156 | } | 140 | } |
| 157 | 141 | ||
| 158 | #[allow(dead_code)] | ||
| 159 | pub(crate) fn set_clock_source(clock_source: RtcClockSource) { | ||
| 160 | #[cfg(not(rtc_v2wb))] | ||
| 161 | use stm32_metapac::rcc::vals::Rtcsel; | ||
| 162 | |||
| 163 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | ||
| 164 | let cr = crate::pac::RCC.bdcr(); | ||
| 165 | #[cfg(any(rtc_v2l0, rtc_v2l1))] | ||
| 166 | let cr = crate::pac::RCC.csr(); | ||
| 167 | |||
| 168 | Self::unlock_registers(); | ||
| 169 | |||
| 170 | cr.modify(|w| { | ||
| 171 | // Select RTC source | ||
| 172 | #[cfg(not(rtc_v2wb))] | ||
| 173 | w.set_rtcsel(Rtcsel::from_bits(clock_source as u8)); | ||
| 174 | #[cfg(rtc_v2wb)] | ||
| 175 | w.set_rtcsel(clock_source as u8); | ||
| 176 | }); | ||
| 177 | } | ||
| 178 | |||
| 179 | pub(super) fn enable() { | ||
| 180 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | ||
| 181 | let reg = crate::pac::RCC.bdcr().read(); | ||
| 182 | #[cfg(any(rtc_v2l0, rtc_v2l1))] | ||
| 183 | let reg = crate::pac::RCC.csr().read(); | ||
| 184 | |||
| 185 | #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb))] | ||
| 186 | assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); | ||
| 187 | |||
| 188 | if !reg.rtcen() { | ||
| 189 | Self::unlock_registers(); | ||
| 190 | |||
| 191 | #[cfg(not(any(rtc_v2l0, rtc_v2l1, rtc_v2f2)))] | ||
| 192 | crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true)); | ||
| 193 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | ||
| 194 | let cr = crate::pac::RCC.bdcr(); | ||
| 195 | #[cfg(any(rtc_v2l0, rtc_v2l1))] | ||
| 196 | let cr = crate::pac::RCC.csr(); | ||
| 197 | |||
| 198 | cr.modify(|w| { | ||
| 199 | // Reset | ||
| 200 | #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] | ||
| 201 | w.set_bdrst(false); | ||
| 202 | |||
| 203 | w.set_rtcen(true); | ||
| 204 | w.set_rtcsel(reg.rtcsel()); | ||
| 205 | |||
| 206 | // Restore bcdr | ||
| 207 | #[cfg(any(rtc_v2l4, rtc_v2wb))] | ||
| 208 | w.set_lscosel(reg.lscosel()); | ||
| 209 | #[cfg(any(rtc_v2l4, rtc_v2wb))] | ||
| 210 | w.set_lscoen(reg.lscoen()); | ||
| 211 | |||
| 212 | w.set_lseon(reg.lseon()); | ||
| 213 | |||
| 214 | #[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))] | ||
| 215 | w.set_lsedrv(reg.lsedrv()); | ||
| 216 | w.set_lsebyp(reg.lsebyp()); | ||
| 217 | }); | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | /// Applies the RTC config | 142 | /// Applies the RTC config |
| 222 | /// It this changes the RTC clock source the time will be reset | 143 | /// It this changes the RTC clock source the time will be reset |
| 223 | pub(super) fn configure(&mut self, rtc_config: RtcConfig) { | 144 | pub(super) fn configure(&mut self, rtc_config: RtcConfig) { |
diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs index 3297303ee..12952b15a 100644 --- a/embassy-stm32/src/rtc/v3.rs +++ b/embassy-stm32/src/rtc/v3.rs | |||
| @@ -1,74 +1,11 @@ | |||
| 1 | use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Init, Key, Osel, Pol, TampalrmPu, TampalrmType}; | 1 | use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Init, Key, Osel, Pol, TampalrmPu, TampalrmType}; |
| 2 | 2 | ||
| 3 | use super::{sealed, RtcCalibrationCyclePeriod, RtcClockSource, RtcConfig}; | 3 | use super::{sealed, RtcCalibrationCyclePeriod, RtcConfig}; |
| 4 | use crate::pac::rtc::Rtc; | 4 | use crate::pac::rtc::Rtc; |
| 5 | use crate::peripherals::RTC; | 5 | use crate::peripherals::RTC; |
| 6 | use crate::rtc::sealed::Instance; | 6 | use crate::rtc::sealed::Instance; |
| 7 | 7 | ||
| 8 | impl super::Rtc { | 8 | impl super::Rtc { |
| 9 | fn unlock_registers() { | ||
| 10 | // Unlock the backup domain | ||
| 11 | #[cfg(not(any(rtc_v3u5, rcc_wl5, rcc_wle)))] | ||
| 12 | { | ||
| 13 | if !crate::pac::PWR.cr1().read().dbp() { | ||
| 14 | crate::pac::PWR.cr1().modify(|w| w.set_dbp(true)); | ||
| 15 | while !crate::pac::PWR.cr1().read().dbp() {} | ||
| 16 | } | ||
| 17 | } | ||
| 18 | #[cfg(any(rcc_wl5, rcc_wle))] | ||
| 19 | { | ||
| 20 | use crate::pac::pwr::vals::Dbp; | ||
| 21 | |||
| 22 | if crate::pac::PWR.cr1().read().dbp() != Dbp::ENABLED { | ||
| 23 | crate::pac::PWR.cr1().modify(|w| w.set_dbp(Dbp::ENABLED)); | ||
| 24 | while crate::pac::PWR.cr1().read().dbp() != Dbp::ENABLED {} | ||
| 25 | } | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | #[allow(dead_code)] | ||
| 30 | pub(crate) fn set_clock_source(clock_source: RtcClockSource) { | ||
| 31 | let clock_source = clock_source as u8; | ||
| 32 | #[cfg(not(any(rcc_wl5, rcc_wle)))] | ||
| 33 | let clock_source = crate::pac::rcc::vals::Rtcsel::from_bits(clock_source); | ||
| 34 | |||
| 35 | Self::unlock_registers(); | ||
| 36 | |||
| 37 | crate::pac::RCC.bdcr().modify(|w| { | ||
| 38 | // Select RTC source | ||
| 39 | w.set_rtcsel(clock_source); | ||
| 40 | }); | ||
| 41 | } | ||
| 42 | |||
| 43 | pub(super) fn enable() { | ||
| 44 | let bdcr = crate::pac::RCC.bdcr(); | ||
| 45 | |||
| 46 | let reg = bdcr.read(); | ||
| 47 | assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet."); | ||
| 48 | |||
| 49 | if !reg.rtcen() { | ||
| 50 | Self::unlock_registers(); | ||
| 51 | |||
| 52 | bdcr.modify(|w| w.set_bdrst(true)); | ||
| 53 | |||
| 54 | bdcr.modify(|w| { | ||
| 55 | // Reset | ||
| 56 | w.set_bdrst(false); | ||
| 57 | |||
| 58 | w.set_rtcen(true); | ||
| 59 | w.set_rtcsel(reg.rtcsel()); | ||
| 60 | |||
| 61 | // Restore bcdr | ||
| 62 | w.set_lscosel(reg.lscosel()); | ||
| 63 | w.set_lscoen(reg.lscoen()); | ||
| 64 | |||
| 65 | w.set_lseon(reg.lseon()); | ||
| 66 | w.set_lsedrv(reg.lsedrv()); | ||
| 67 | w.set_lsebyp(reg.lsebyp()); | ||
| 68 | }); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | /// Applies the RTC config | 9 | /// Applies the RTC config |
| 73 | /// It this changes the RTC clock source the time will be reset | 10 | /// It this changes the RTC clock source the time will be reset |
| 74 | pub(super) fn configure(&mut self, rtc_config: RtcConfig) { | 11 | pub(super) fn configure(&mut self, rtc_config: RtcConfig) { |
diff --git a/examples/stm32f4/src/bin/rtc.rs b/examples/stm32f4/src/bin/rtc.rs index 0eca58203..23ff8ac47 100644 --- a/examples/stm32f4/src/bin/rtc.rs +++ b/examples/stm32f4/src/bin/rtc.rs | |||
| @@ -5,13 +5,17 @@ | |||
| 5 | use chrono::{NaiveDate, NaiveDateTime}; | 5 | use chrono::{NaiveDate, NaiveDateTime}; |
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | 8 | use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; |
| 9 | use embassy_stm32::Config; | ||
| 9 | use embassy_time::{Duration, Timer}; | 10 | use embassy_time::{Duration, Timer}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 11 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 12 | ||
| 12 | #[embassy_executor::main] | 13 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) { | 14 | async fn main(_spawner: Spawner) { |
| 14 | let p = embassy_stm32::init(Default::default()); | 15 | let mut config = Config::default(); |
| 16 | config.rcc.rtc = Option::Some(RtcClockSource::LSI); | ||
| 17 | let p = embassy_stm32::init(config); | ||
| 18 | |||
| 15 | info!("Hello World!"); | 19 | info!("Hello World!"); |
| 16 | 20 | ||
| 17 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) | 21 | let now = NaiveDate::from_ymd_opt(2020, 5, 15) |
| @@ -23,8 +27,11 @@ async fn main(_spawner: Spawner) { | |||
| 23 | 27 | ||
| 24 | rtc.set_datetime(now.into()).expect("datetime not set"); | 28 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| 25 | 29 | ||
| 26 | // In reality the delay would be much longer | 30 | loop { |
| 27 | Timer::after(Duration::from_millis(20000)).await; | 31 | let now: NaiveDateTime = rtc.now().unwrap().into(); |
| 32 | |||
| 33 | info!("{}", now.timestamp()); | ||
| 28 | 34 | ||
| 29 | let _then: NaiveDateTime = rtc.now().unwrap().into(); | 35 | Timer::after(Duration::from_millis(1000)).await; |
| 36 | } | ||
| 30 | } | 37 | } |
diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs index 294ea456c..f3f8aa46f 100644 --- a/examples/stm32l4/src/bin/rtc.rs +++ b/examples/stm32l4/src/bin/rtc.rs | |||
| @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { | |||
| 23 | PLLMul::Mul20, | 23 | PLLMul::Mul20, |
| 24 | None, | 24 | None, |
| 25 | ); | 25 | ); |
| 26 | config.rcc.rtc_mux = rcc::RtcClockSource::LSE32; | 26 | config.rcc.rtc_mux = rcc::RtcClockSource::LSE; |
| 27 | embassy_stm32::init(config) | 27 | embassy_stm32::init(config) |
| 28 | }; | 28 | }; |
| 29 | info!("Hello World!"); | 29 | info!("Hello World!"); |
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 148c58771..0a677be76 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs | |||
| @@ -84,7 +84,7 @@ async fn main(spawner: Spawner) { | |||
| 84 | None, | 84 | None, |
| 85 | ); | 85 | ); |
| 86 | config.rcc.hsi48 = true; // needed for rng | 86 | config.rcc.hsi48 = true; // needed for rng |
| 87 | config.rcc.rtc_mux = rcc::RtcClockSource::LSI32; | 87 | config.rcc.rtc_mux = rcc::RtcClockSource::LSI; |
| 88 | 88 | ||
| 89 | let dp = embassy_stm32::init(config); | 89 | let dp = embassy_stm32::init(config); |
| 90 | 90 | ||
diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs index fb1bc6e3d..2be6c7b93 100644 --- a/examples/stm32wl/src/bin/rtc.rs +++ b/examples/stm32wl/src/bin/rtc.rs | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | use chrono::{NaiveDate, NaiveDateTime}; | 5 | use chrono::{NaiveDate, NaiveDateTime}; |
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_stm32::rcc::{self, ClockSrc}; | 8 | use embassy_stm32::rcc::ClockSrc; |
| 9 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | 9 | use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; |
| 10 | use embassy_stm32::Config; | 10 | use embassy_stm32::Config; |
| 11 | use embassy_time::{Duration, Timer}; | 11 | use embassy_time::{Duration, Timer}; |
| 12 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -16,7 +16,7 @@ async fn main(_spawner: Spawner) { | |||
| 16 | let p = { | 16 | let p = { |
| 17 | let mut config = Config::default(); | 17 | let mut config = Config::default(); |
| 18 | config.rcc.mux = ClockSrc::HSE32; | 18 | config.rcc.mux = ClockSrc::HSE32; |
| 19 | config.rcc.rtc_mux = rcc::RtcClockSource::LSE32; | 19 | config.rcc.rtc_mux = RtcClockSource::LSE; |
| 20 | config.rcc.enable_rtc_apb = true; | 20 | config.rcc.enable_rtc_apb = true; |
| 21 | embassy_stm32::init(config) | 21 | embassy_stm32::init(config) |
| 22 | }; | 22 | }; |
diff --git a/tests/stm32/src/bin/rtc.rs b/tests/stm32/src/bin/rtc.rs index 7df415b44..1a64dd387 100644 --- a/tests/stm32/src/bin/rtc.rs +++ b/tests/stm32/src/bin/rtc.rs | |||
| @@ -10,7 +10,8 @@ use chrono::{NaiveDate, NaiveDateTime}; | |||
| 10 | use common::*; | 10 | use common::*; |
| 11 | use defmt::assert; | 11 | use defmt::assert; |
| 12 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
| 13 | use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; | 13 | use embassy_stm32::rcc::RtcClockSource; |
| 14 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||
| 14 | use embassy_time::{Duration, Timer}; | 15 | use embassy_time::{Duration, Timer}; |
| 15 | 16 | ||
| 16 | #[embassy_executor::main] | 17 | #[embassy_executor::main] |
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index 4a49bde9d..0b3f4a300 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs | |||
| @@ -11,7 +11,8 @@ use common::*; | |||
| 11 | use cortex_m_rt::entry; | 11 | use cortex_m_rt::entry; |
| 12 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
| 13 | use embassy_stm32::low_power::{stop_with_rtc, Executor}; | 13 | use embassy_stm32::low_power::{stop_with_rtc, Executor}; |
| 14 | use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; | 14 | use embassy_stm32::rcc::RtcClockSource; |
| 15 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | ||
| 15 | use embassy_time::{Duration, Timer}; | 16 | use embassy_time::{Duration, Timer}; |
| 16 | use static_cell::make_static; | 17 | use static_cell::make_static; |
| 17 | 18 | ||
