aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-10-11 03:53:27 +0200
committerDario Nieuwenhuis <[email protected]>2023-10-11 04:12:38 +0200
commitb91d1eaca07a65e8d4b688a3f9059c5578e92836 (patch)
treeaad9328bfb463033cd8c64a6550b816f1bc9dd77
parent5a19d18b9cd2027d0b3864cf6c09d4648fed569b (diff)
stm32/rcc: add LSE/LSI to all chips, add RTC to more chips.
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/src/rcc/bd.rs217
-rw-r--r--embassy-stm32/src/rcc/c0.rs10
-rw-r--r--embassy-stm32/src/rcc/f0.rs8
-rw-r--r--embassy-stm32/src/rcc/f1.rs8
-rw-r--r--embassy-stm32/src/rcc/f2.rs20
-rw-r--r--embassy-stm32/src/rcc/f3.rs7
-rw-r--r--embassy-stm32/src/rcc/f4.rs25
-rw-r--r--embassy-stm32/src/rcc/f7.rs20
-rw-r--r--embassy-stm32/src/rcc/g0.rs10
-rw-r--r--embassy-stm32/src/rcc/g4.rs9
-rw-r--r--embassy-stm32/src/rcc/h.rs40
-rw-r--r--embassy-stm32/src/rcc/l0l1.rs20
-rw-r--r--embassy-stm32/src/rcc/l4.rs23
-rw-r--r--embassy-stm32/src/rcc/l5.rs23
-rw-r--r--embassy-stm32/src/rcc/mod.rs18
-rw-r--r--embassy-stm32/src/rcc/u5.rs9
-rw-r--r--embassy-stm32/src/rcc/wb.rs66
-rw-r--r--embassy-stm32/src/rcc/wba.rs9
-rw-r--r--embassy-stm32/src/rcc/wl.rs26
-rw-r--r--embassy-stm32/src/rtc/mod.rs16
-rw-r--r--examples/stm32f4/src/bin/rtc.rs6
-rw-r--r--examples/stm32h7/src/bin/rtc.rs14
-rw-r--r--examples/stm32l4/src/bin/rtc.rs5
-rw-r--r--examples/stm32l4/src/bin/spe_adin1110_http_server.rs2
-rw-r--r--examples/stm32wl/src/bin/lora_lorawan.rs1
-rw-r--r--examples/stm32wl/src/bin/random.rs1
-rw-r--r--examples/stm32wl/src/bin/rtc.rs8
-rw-r--r--tests/stm32/Cargo.toml20
-rw-r--r--tests/stm32/src/bin/rtc.rs16
-rw-r--r--tests/stm32/src/bin/stop.rs7
31 files changed, 266 insertions, 402 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 6137e3c02..33583d22b 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -59,7 +59,7 @@ sdio-host = "0.5.0"
59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } 59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
60critical-section = "1.1" 60critical-section = "1.1"
61atomic-polyfill = "1.0.1" 61atomic-polyfill = "1.0.1"
62stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9f45b0c48cc3de71ec6a66fe7e871b21aef0940c" } 62stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6bfa5a0dcec6a9bd42cea94ba11eeae1a17a7f2c" }
63vcell = "0.1.3" 63vcell = "0.1.3"
64bxcan = "0.7.0" 64bxcan = "0.7.0"
65nb = "1.0.0" 65nb = "1.0.0"
@@ -77,7 +77,7 @@ critical-section = { version = "1.1", features = ["std"] }
77[build-dependencies] 77[build-dependencies]
78proc-macro2 = "1.0.36" 78proc-macro2 = "1.0.36"
79quote = "1.0.15" 79quote = "1.0.15"
80stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-9f45b0c48cc3de71ec6a66fe7e871b21aef0940c", default-features = false, features = ["metadata"]} 80stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-6bfa5a0dcec6a9bd42cea94ba11eeae1a17a7f2c", default-features = false, features = ["metadata"]}
81 81
82 82
83[features] 83[features]
diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs
index c18e92bc8..66ca65f80 100644
--- a/embassy-stm32/src/rcc/bd.rs
+++ b/embassy-stm32/src/rcc/bd.rs
@@ -1,14 +1,24 @@
1use core::sync::atomic::{compiler_fence, Ordering};
2
3use crate::pac::common::{Reg, RW};
4pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource;
5use crate::time::Hertz;
6
7#[cfg(any(stm32f0, stm32f1, stm32f3))]
8pub const LSI_FREQ: Hertz = Hertz(40_000);
9#[cfg(not(any(stm32f0, stm32f1, stm32f3)))]
10pub const LSI_FREQ: Hertz = Hertz(32_000);
11
1#[allow(dead_code)] 12#[allow(dead_code)]
2#[derive(Clone, Copy)] 13#[derive(Clone, Copy)]
3pub enum LseCfg { 14pub enum LseMode {
4 Oscillator(LseDrive), 15 Oscillator(LseDrive),
5 Bypass, 16 Bypass,
6} 17}
7 18
8impl Default for LseCfg { 19pub struct LseConfig {
9 fn default() -> Self { 20 pub frequency: Hertz,
10 Self::Oscillator(Default::default()) 21 pub mode: LseMode,
11 }
12} 22}
13 23
14#[allow(dead_code)] 24#[allow(dead_code)]
@@ -36,90 +46,116 @@ impl From<LseDrive> for crate::pac::rcc::vals::Lsedrv {
36 } 46 }
37} 47}
38 48
39pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource;
40
41#[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))] 49#[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))]
42#[allow(dead_code)]
43type Bdcr = crate::pac::rcc::regs::Bdcr; 50type Bdcr = crate::pac::rcc::regs::Bdcr;
44
45#[cfg(any(rtc_v2l0, rtc_v2l1))] 51#[cfg(any(rtc_v2l0, rtc_v2l1))]
46#[allow(dead_code)]
47type Bdcr = crate::pac::rcc::regs::Csr; 52type Bdcr = crate::pac::rcc::regs::Csr;
53#[cfg(any(stm32c0))]
54type Bdcr = crate::pac::rcc::regs::Csr1;
55
56#[cfg(any(stm32c0))]
57fn unlock() {}
58
59#[cfg(not(any(stm32c0)))]
60fn unlock() {
61 #[cfg(any(stm32f0, stm32f1, stm32f2, stm32f3, stm32l0, stm32l1))]
62 let cr = crate::pac::PWR.cr();
63 #[cfg(not(any(stm32f0, stm32f1, stm32f2, stm32f3, stm32l0, stm32l1, stm32u5, stm32h5, stm32wba)))]
64 let cr = crate::pac::PWR.cr1();
65 #[cfg(any(stm32u5, stm32h5, stm32wba))]
66 let cr = crate::pac::PWR.dbpcr();
67
68 cr.modify(|w| w.set_dbp(true));
69 while !cr.read().dbp() {}
70}
48 71
49#[allow(dead_code)] 72fn bdcr() -> Reg<Bdcr, RW> {
50pub struct BackupDomain {} 73 #[cfg(any(rtc_v2l0, rtc_v2l1))]
51 74 return crate::pac::RCC.csr();
52impl BackupDomain { 75 #[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))]
53 #[cfg(any( 76 return crate::pac::RCC.bdcr();
54 rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, 77 #[cfg(any(stm32c0))]
55 rtc_v3u5 78 return crate::pac::RCC.csr1();
56 ))] 79}
57 #[allow(dead_code, unused_variables)]
58 fn modify<R>(f: impl FnOnce(&mut Bdcr) -> R) -> R {
59 #[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1, rtc_v2l0))]
60 let cr = crate::pac::PWR.cr();
61 #[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
62 let cr = crate::pac::PWR.cr1();
63
64 // TODO: Missing from PAC for l0 and f0?
65 #[cfg(not(any(rtc_v2f0, rtc_v3u5)))]
66 {
67 cr.modify(|w| w.set_dbp(true));
68 while !cr.read().dbp() {}
69 }
70 80
71 #[cfg(any(rtc_v2l0, rtc_v2l1))] 81pub struct LsConfig {
72 let cr = crate::pac::RCC.csr(); 82 pub rtc: RtcClockSource,
83 pub lsi: bool,
84 pub lse: Option<LseConfig>,
85}
73 86
74 #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] 87impl LsConfig {
75 let cr = crate::pac::RCC.bdcr(); 88 pub const fn default_lse() -> Self {
89 Self {
90 rtc: RtcClockSource::LSE,
91 lse: Some(LseConfig {
92 frequency: Hertz(32_000),
93 mode: LseMode::Oscillator(LseDrive::MediumHigh),
94 }),
95 lsi: false,
96 }
97 }
76 98
77 cr.modify(|w| f(w)) 99 pub const fn default_lsi() -> Self {
100 Self {
101 rtc: RtcClockSource::LSI,
102 lsi: true,
103 lse: None,
104 }
78 } 105 }
79 106
80 #[cfg(any( 107 pub const fn off() -> Self {
81 rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, 108 Self {
82 rtc_v3u5 109 rtc: RtcClockSource::NOCLOCK,
83 ))] 110 lsi: false,
84 #[allow(dead_code)] 111 lse: None,
85 fn read() -> Bdcr { 112 }
86 #[cfg(any(rtc_v2l0, rtc_v2l1))] 113 }
87 let r = crate::pac::RCC.csr().read(); 114}
88 115
89 #[cfg(not(any(rtc_v2l0, rtc_v2l1)))] 116impl Default for LsConfig {
90 let r = crate::pac::RCC.bdcr().read(); 117 fn default() -> Self {
118 // on L5, just the fact that LSI is enabled makes things crash.
119 // TODO: investigate.
91 120
92 r 121 #[cfg(not(stm32l5))]
122 return Self::default_lsi();
123 #[cfg(stm32l5)]
124 return Self::off();
93 } 125 }
126}
94 127
95 #[cfg(any( 128impl LsConfig {
96 rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3, 129 pub(crate) fn init(&self) -> Option<Hertz> {
97 rtc_v3u5 130 let rtc_clk = match self.rtc {
98 ))] 131 RtcClockSource::LSI => {
99 #[allow(dead_code, unused_variables)] 132 assert!(self.lsi);
100 pub fn configure_ls(clock_source: RtcClockSource, lsi: bool, lse: Option<LseCfg>) { 133 Some(LSI_FREQ)
101 use atomic_polyfill::{compiler_fence, Ordering}; 134 }
102 135 RtcClockSource::LSE => Some(self.lse.as_ref().unwrap().frequency),
103 match clock_source { 136 RtcClockSource::NOCLOCK => None,
104 RtcClockSource::LSI => assert!(lsi), 137 _ => todo!(),
105 RtcClockSource::LSE => assert!(lse.is_some()),
106 _ => {}
107 }; 138 };
108 let (lse_en, lse_byp, lse_drv) = match lse { 139
109 Some(LseCfg::Oscillator(lse_drv)) => (true, false, Some(lse_drv)), 140 let (lse_en, lse_byp, lse_drv) = match &self.lse {
110 Some(LseCfg::Bypass) => (true, true, None), 141 Some(c) => match c.mode {
142 LseMode::Oscillator(lse_drv) => (true, false, Some(lse_drv)),
143 LseMode::Bypass => (true, true, None),
144 },
111 None => (false, false, None), 145 None => (false, false, None),
112 }; 146 };
147 _ = lse_drv; // not all chips have it.
113 148
114 if lsi { 149 // Disable backup domain write protection
115 #[cfg(rtc_v3u5)] 150 unlock();
116 let csr = crate::pac::RCC.bdcr();
117 151
118 #[cfg(not(rtc_v3u5))] 152 if self.lsi {
153 #[cfg(any(stm32u5, stm32h5, stm32wba))]
154 let csr = crate::pac::RCC.bdcr();
155 #[cfg(not(any(stm32u5, stm32h5, stm32wba, stm32c0)))]
119 let csr = crate::pac::RCC.csr(); 156 let csr = crate::pac::RCC.csr();
120 157 #[cfg(any(stm32c0))]
121 // Disable backup domain write protection 158 let csr = crate::pac::RCC.csr2();
122 Self::modify(|_| {});
123 159
124 #[cfg(not(any(rcc_wb, rcc_wba)))] 160 #[cfg(not(any(rcc_wb, rcc_wba)))]
125 csr.modify(|w| w.set_lsion(true)); 161 csr.modify(|w| w.set_lsion(true));
@@ -139,12 +175,12 @@ impl BackupDomain {
139 // first check if the configuration matches what we want. 175 // first check if the configuration matches what we want.
140 176
141 // check if it's already enabled and in the source we want. 177 // check if it's already enabled and in the source we want.
142 let reg = Self::read(); 178 let reg = bdcr().read();
143 let mut ok = true; 179 let mut ok = true;
144 ok &= reg.rtcsel() == clock_source; 180 ok &= reg.rtcsel() == self.rtc;
145 #[cfg(not(rcc_wba))] 181 #[cfg(not(rcc_wba))]
146 { 182 {
147 ok &= reg.rtcen() == (clock_source != RtcClockSource::NOCLOCK); 183 ok &= reg.rtcen() == (self.rtc != RtcClockSource::NOCLOCK);
148 } 184 }
149 ok &= reg.lseon() == lse_en; 185 ok &= reg.lseon() == lse_en;
150 ok &= reg.lsebyp() == lse_byp; 186 ok &= reg.lsebyp() == lse_byp;
@@ -155,22 +191,29 @@ impl BackupDomain {
155 191
156 // if configuration is OK, we're done. 192 // if configuration is OK, we're done.
157 if ok { 193 if ok {
158 // RTC code assumes backup domain is unlocked 194 trace!("BDCR ok: {:08x}", bdcr().read().0);
159 Self::modify(|w| {}); 195 return rtc_clk;
160
161 trace!("BDCR ok: {:08x}", Self::read().0);
162 return;
163 } 196 }
164 197
165 // If not OK, reset backup domain and configure it. 198 // If not OK, reset backup domain and configure it.
166 #[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1)))] 199 #[cfg(not(any(rcc_l0, rcc_l0_v2, rcc_l1, stm32h5, stm32c0)))]
200 {
201 bdcr().modify(|w| w.set_bdrst(true));
202 bdcr().modify(|w| w.set_bdrst(false));
203 }
204 #[cfg(any(stm32h5))]
205 {
206 bdcr().modify(|w| w.set_vswrst(true));
207 bdcr().modify(|w| w.set_vswrst(false));
208 }
209 #[cfg(any(stm32c0))]
167 { 210 {
168 Self::modify(|w| w.set_bdrst(true)); 211 bdcr().modify(|w| w.set_rtcrst(true));
169 Self::modify(|w| w.set_bdrst(false)); 212 bdcr().modify(|w| w.set_rtcrst(false));
170 } 213 }
171 214
172 if lse_en { 215 if lse_en {
173 Self::modify(|w| { 216 bdcr().modify(|w| {
174 #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))] 217 #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))]
175 if let Some(lse_drv) = lse_drv { 218 if let Some(lse_drv) = lse_drv {
176 w.set_lsedrv(lse_drv.into()); 219 w.set_lsedrv(lse_drv.into());
@@ -179,22 +222,24 @@ impl BackupDomain {
179 w.set_lseon(true); 222 w.set_lseon(true);
180 }); 223 });
181 224
182 while !Self::read().lserdy() {} 225 while !bdcr().read().lserdy() {}
183 } 226 }
184 227
185 if clock_source != RtcClockSource::NOCLOCK { 228 if self.rtc != RtcClockSource::NOCLOCK {
186 Self::modify(|w| { 229 bdcr().modify(|w| {
187 #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))] 230 #[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
188 assert!(!w.lsecsson(), "RTC is not compatible with LSE CSS, yet."); 231 assert!(!w.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
189 232
190 #[cfg(not(rcc_wba))] 233 #[cfg(not(rcc_wba))]
191 w.set_rtcen(true); 234 w.set_rtcen(true);
192 w.set_rtcsel(clock_source); 235 w.set_rtcsel(self.rtc);
193 }); 236 });
194 } 237 }
195 238
196 trace!("BDCR configured: {:08x}", Self::read().0); 239 trace!("BDCR configured: {:08x}", bdcr().read().0);
197 240
198 compiler_fence(Ordering::SeqCst); 241 compiler_fence(Ordering::SeqCst);
242
243 rtc_clk
199 } 244 }
200} 245}
diff --git a/embassy-stm32/src/rcc/c0.rs b/embassy-stm32/src/rcc/c0.rs
index 34d339a78..eeb6418ae 100644
--- a/embassy-stm32/src/rcc/c0.rs
+++ b/embassy-stm32/src/rcc/c0.rs
@@ -8,9 +8,6 @@ use crate::time::Hertz;
8/// HSI speed 8/// HSI speed
9pub const HSI_FREQ: Hertz = Hertz(48_000_000); 9pub const HSI_FREQ: Hertz = Hertz(48_000_000);
10 10
11/// LSI speed
12pub const LSI_FREQ: Hertz = Hertz(32_000);
13
14/// System clock mux source 11/// System clock mux source
15#[derive(Clone, Copy)] 12#[derive(Clone, Copy)]
16pub enum ClockSrc { 13pub enum ClockSrc {
@@ -24,6 +21,7 @@ pub struct Config {
24 pub mux: ClockSrc, 21 pub mux: ClockSrc,
25 pub ahb_pre: AHBPrescaler, 22 pub ahb_pre: AHBPrescaler,
26 pub apb_pre: APBPrescaler, 23 pub apb_pre: APBPrescaler,
24 pub ls: super::LsConfig,
27} 25}
28 26
29impl Default for Config { 27impl Default for Config {
@@ -33,6 +31,7 @@ impl Default for Config {
33 mux: ClockSrc::HSI(HSIPrescaler::DIV1), 31 mux: ClockSrc::HSI(HSIPrescaler::DIV1),
34 ahb_pre: AHBPrescaler::DIV1, 32 ahb_pre: AHBPrescaler::DIV1,
35 apb_pre: APBPrescaler::DIV1, 33 apb_pre: APBPrescaler::DIV1,
34 ls: Default::default(),
36 } 35 }
37 } 36 }
38} 37}
@@ -60,10 +59,12 @@ pub(crate) unsafe fn init(config: Config) {
60 // Enable LSI 59 // Enable LSI
61 RCC.csr2().write(|w| w.set_lsion(true)); 60 RCC.csr2().write(|w| w.set_lsion(true));
62 while !RCC.csr2().read().lsirdy() {} 61 while !RCC.csr2().read().lsirdy() {}
63 (LSI_FREQ, Sw::LSI) 62 (super::LSI_FREQ, Sw::LSI)
64 } 63 }
65 }; 64 };
66 65
66 let rtc = config.ls.init();
67
67 // Determine the flash latency implied by the target clock speed 68 // Determine the flash latency implied by the target clock speed
68 // RM0454 § 3.3.4: 69 // RM0454 § 3.3.4:
69 let target_flash_latency = if sys_clk <= Hertz(24_000_000) { 70 let target_flash_latency = if sys_clk <= Hertz(24_000_000) {
@@ -137,5 +138,6 @@ pub(crate) unsafe fn init(config: Config) {
137 ahb1: ahb_freq, 138 ahb1: ahb_freq,
138 apb1: apb_freq, 139 apb1: apb_freq,
139 apb1_tim: apb_tim_freq, 140 apb1_tim: apb_tim_freq,
141 rtc,
140 }); 142 });
141} 143}
diff --git a/embassy-stm32/src/rcc/f0.rs b/embassy-stm32/src/rcc/f0.rs
index ca6eed284..cc712e87a 100644
--- a/embassy-stm32/src/rcc/f0.rs
+++ b/embassy-stm32/src/rcc/f0.rs
@@ -8,9 +8,6 @@ use crate::time::Hertz;
8/// HSI speed 8/// HSI speed
9pub const HSI_FREQ: Hertz = Hertz(8_000_000); 9pub const HSI_FREQ: Hertz = Hertz(8_000_000);
10 10
11/// LSI speed
12pub const LSI_FREQ: Hertz = Hertz(40_000);
13
14/// Configuration of the clocks 11/// Configuration of the clocks
15/// 12///
16/// hse takes precedence over hsi48 if both are enabled 13/// hse takes precedence over hsi48 if both are enabled
@@ -27,6 +24,8 @@ pub struct Config {
27 pub sys_ck: Option<Hertz>, 24 pub sys_ck: Option<Hertz>,
28 pub hclk: Option<Hertz>, 25 pub hclk: Option<Hertz>,
29 pub pclk: Option<Hertz>, 26 pub pclk: Option<Hertz>,
27
28 pub ls: super::LsConfig,
30} 29}
31 30
32pub(crate) unsafe fn init(config: Config) { 31pub(crate) unsafe fn init(config: Config) {
@@ -159,6 +158,8 @@ pub(crate) unsafe fn init(config: Config) {
159 }) 158 })
160 } 159 }
161 160
161 let rtc = config.ls.init();
162
162 set_freqs(Clocks { 163 set_freqs(Clocks {
163 sys: Hertz(real_sysclk), 164 sys: Hertz(real_sysclk),
164 apb1: Hertz(pclk), 165 apb1: Hertz(pclk),
@@ -166,5 +167,6 @@ pub(crate) unsafe fn init(config: Config) {
166 apb1_tim: Hertz(pclk * timer_mul), 167 apb1_tim: Hertz(pclk * timer_mul),
167 apb2_tim: Hertz(pclk * timer_mul), 168 apb2_tim: Hertz(pclk * timer_mul),
168 ahb1: Hertz(hclk), 169 ahb1: Hertz(hclk),
170 rtc,
169 }); 171 });
170} 172}
diff --git a/embassy-stm32/src/rcc/f1.rs b/embassy-stm32/src/rcc/f1.rs
index 081c0c767..56c49cd8e 100644
--- a/embassy-stm32/src/rcc/f1.rs
+++ b/embassy-stm32/src/rcc/f1.rs
@@ -9,9 +9,6 @@ use crate::time::Hertz;
9/// HSI speed 9/// HSI speed
10pub const HSI_FREQ: Hertz = Hertz(8_000_000); 10pub const HSI_FREQ: Hertz = Hertz(8_000_000);
11 11
12/// LSI speed
13pub const LSI_FREQ: Hertz = Hertz(40_000);
14
15/// Configuration of the clocks 12/// Configuration of the clocks
16/// 13///
17#[non_exhaustive] 14#[non_exhaustive]
@@ -25,6 +22,8 @@ pub struct Config {
25 pub pclk2: Option<Hertz>, 22 pub pclk2: Option<Hertz>,
26 pub adcclk: Option<Hertz>, 23 pub adcclk: Option<Hertz>,
27 pub pllxtpre: bool, 24 pub pllxtpre: bool,
25
26 pub ls: super::LsConfig,
28} 27}
29 28
30pub(crate) unsafe fn init(config: Config) { 29pub(crate) unsafe fn init(config: Config) {
@@ -177,6 +176,8 @@ pub(crate) unsafe fn init(config: Config) {
177 }); 176 });
178 }); 177 });
179 178
179 let rtc = config.ls.init();
180
180 set_freqs(Clocks { 181 set_freqs(Clocks {
181 sys: Hertz(real_sysclk), 182 sys: Hertz(real_sysclk),
182 apb1: Hertz(pclk1), 183 apb1: Hertz(pclk1),
@@ -185,5 +186,6 @@ pub(crate) unsafe fn init(config: Config) {
185 apb2_tim: Hertz(pclk2 * timer_mul2), 186 apb2_tim: Hertz(pclk2 * timer_mul2),
186 ahb1: Hertz(hclk), 187 ahb1: Hertz(hclk),
187 adc: Some(Hertz(adcclk)), 188 adc: Some(Hertz(adcclk)),
189 rtc,
188 }); 190 });
189} 191}
diff --git a/embassy-stm32/src/rcc/f2.rs b/embassy-stm32/src/rcc/f2.rs
index 478d8894f..ab588233f 100644
--- a/embassy-stm32/src/rcc/f2.rs
+++ b/embassy-stm32/src/rcc/f2.rs
@@ -5,17 +5,12 @@ pub use crate::pac::rcc::vals::{
5 Ppre as APBPrescaler, 5 Ppre as APBPrescaler,
6}; 6};
7use crate::pac::{FLASH, RCC}; 7use crate::pac::{FLASH, RCC};
8use crate::rcc::bd::BackupDomain;
9use crate::rcc::{set_freqs, Clocks}; 8use crate::rcc::{set_freqs, Clocks};
10use crate::rtc::RtcClockSource;
11use crate::time::Hertz; 9use crate::time::Hertz;
12 10
13/// HSI speed 11/// HSI speed
14pub const HSI_FREQ: Hertz = Hertz(16_000_000); 12pub const HSI_FREQ: Hertz = Hertz(16_000_000);
15 13
16/// LSI speed
17pub const LSI_FREQ: Hertz = Hertz(32_000);
18
19#[derive(Clone, Copy)] 14#[derive(Clone, Copy)]
20pub struct HSEConfig { 15pub struct HSEConfig {
21 pub frequency: Hertz, 16 pub frequency: Hertz,
@@ -180,13 +175,11 @@ pub struct Config {
180 pub pll_mux: PLLSrc, 175 pub pll_mux: PLLSrc,
181 pub pll: PLLConfig, 176 pub pll: PLLConfig,
182 pub mux: ClockSrc, 177 pub mux: ClockSrc,
183 pub rtc: Option<RtcClockSource>,
184 pub lsi: bool,
185 pub lse: Option<Hertz>,
186 pub voltage: VoltageScale, 178 pub voltage: VoltageScale,
187 pub ahb_pre: AHBPrescaler, 179 pub ahb_pre: AHBPrescaler,
188 pub apb1_pre: APBPrescaler, 180 pub apb1_pre: APBPrescaler,
189 pub apb2_pre: APBPrescaler, 181 pub apb2_pre: APBPrescaler,
182 pub ls: super::LsConfig,
190} 183}
191 184
192impl Default for Config { 185impl Default for Config {
@@ -199,12 +192,10 @@ impl Default for Config {
199 pll: PLLConfig::default(), 192 pll: PLLConfig::default(),
200 voltage: VoltageScale::Range3, 193 voltage: VoltageScale::Range3,
201 mux: ClockSrc::HSI, 194 mux: ClockSrc::HSI,
202 rtc: None,
203 lsi: false,
204 lse: None,
205 ahb_pre: AHBPrescaler::DIV1, 195 ahb_pre: AHBPrescaler::DIV1,
206 apb1_pre: APBPrescaler::DIV1, 196 apb1_pre: APBPrescaler::DIV1,
207 apb2_pre: APBPrescaler::DIV1, 197 apb2_pre: APBPrescaler::DIV1,
198 ls: Default::default(),
208 } 199 }
209 } 200 }
210} 201}
@@ -312,11 +303,7 @@ pub(crate) unsafe fn init(config: Config) {
312 RCC.cr().modify(|w| w.set_hsion(false)); 303 RCC.cr().modify(|w| w.set_hsion(false));
313 } 304 }
314 305
315 BackupDomain::configure_ls( 306 let rtc = config.ls.init();
316 config.rtc.unwrap_or(RtcClockSource::NOCLOCK),
317 config.lsi,
318 config.lse.map(|_| Default::default()),
319 );
320 307
321 set_freqs(Clocks { 308 set_freqs(Clocks {
322 sys: sys_clk, 309 sys: sys_clk,
@@ -328,5 +315,6 @@ pub(crate) unsafe fn init(config: Config) {
328 apb2: apb2_freq, 315 apb2: apb2_freq,
329 apb2_tim: apb2_tim_freq, 316 apb2_tim: apb2_tim_freq,
330 pll48: Some(pll_clocks.pll48_freq), 317 pll48: Some(pll_clocks.pll48_freq),
318 rtc,
331 }); 319 });
332} 320}
diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs
index a11eeee54..2aa79cec7 100644
--- a/embassy-stm32/src/rcc/f3.rs
+++ b/embassy-stm32/src/rcc/f3.rs
@@ -10,9 +10,6 @@ use crate::time::Hertz;
10/// HSI speed 10/// HSI speed
11pub const HSI_FREQ: Hertz = Hertz(8_000_000); 11pub const HSI_FREQ: Hertz = Hertz(8_000_000);
12 12
13/// LSI speed
14pub const LSI_FREQ: Hertz = Hertz(40_000);
15
16#[cfg(rcc_f3)] 13#[cfg(rcc_f3)]
17impl From<AdcClockSource> for Ckmode { 14impl From<AdcClockSource> for Ckmode {
18 fn from(value: AdcClockSource) -> Self { 15 fn from(value: AdcClockSource) -> Self {
@@ -87,6 +84,7 @@ pub struct Config {
87 pub adc34: Option<AdcClockSource>, 84 pub adc34: Option<AdcClockSource>,
88 #[cfg(stm32f334)] 85 #[cfg(stm32f334)]
89 pub hrtim: HrtimClockSource, 86 pub hrtim: HrtimClockSource,
87 pub ls: super::LsConfig,
90} 88}
91 89
92// Information required to setup the PLL clock 90// Information required to setup the PLL clock
@@ -279,6 +277,8 @@ pub(crate) unsafe fn init(config: Config) {
279 } 277 }
280 }; 278 };
281 279
280 let rtc = config.ls.init();
281
282 set_freqs(Clocks { 282 set_freqs(Clocks {
283 sys: sysclk, 283 sys: sysclk,
284 apb1: pclk1, 284 apb1: pclk1,
@@ -294,6 +294,7 @@ pub(crate) unsafe fn init(config: Config) {
294 adc34: None, 294 adc34: None,
295 #[cfg(stm32f334)] 295 #[cfg(stm32f334)]
296 hrtim: hrtim, 296 hrtim: hrtim,
297 rtc,
297 }); 298 });
298} 299}
299 300
diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs
index 754a0d570..79c2d2f66 100644
--- a/embassy-stm32/src/rcc/f4.rs
+++ b/embassy-stm32/src/rcc/f4.rs
@@ -1,17 +1,11 @@
1use stm32_metapac::rcc::vals::{Pllm, Plln, Pllq, Pllr}; 1use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllq, Pllr, Ppre, Sw};
2
3use crate::pac::rcc::vals::{Hpre, Ppre, Sw};
4use crate::pac::{FLASH, PWR, RCC}; 2use crate::pac::{FLASH, PWR, RCC};
5use crate::rcc::bd::{BackupDomain, RtcClockSource};
6use crate::rcc::{set_freqs, Clocks}; 3use crate::rcc::{set_freqs, Clocks};
7use crate::time::Hertz; 4use crate::time::Hertz;
8 5
9/// HSI speed 6/// HSI speed
10pub const HSI_FREQ: Hertz = Hertz(16_000_000); 7pub const HSI_FREQ: Hertz = Hertz(16_000_000);
11 8
12/// LSI speed
13pub const LSI_FREQ: Hertz = Hertz(32_000);
14
15/// Clocks configuration 9/// Clocks configuration
16#[non_exhaustive] 10#[non_exhaustive]
17#[derive(Default)] 11#[derive(Default)]
@@ -30,9 +24,7 @@ pub struct Config {
30 pub pllsai: Option<Hertz>, 24 pub pllsai: Option<Hertz>,
31 25
32 pub pll48: bool, 26 pub pll48: bool,
33 pub rtc: Option<RtcClockSource>, 27 pub ls: super::LsConfig,
34 pub lsi: bool,
35 pub lse: Option<Hertz>,
36} 28}
37 29
38#[cfg(stm32f410)] 30#[cfg(stm32f410)]
@@ -344,17 +336,7 @@ pub(crate) unsafe fn init(config: Config) {
344 }) 336 })
345 }); 337 });
346 338
347 BackupDomain::configure_ls( 339 let rtc = config.ls.init();
348 config.rtc.unwrap_or(RtcClockSource::NOCLOCK),
349 config.lsi,
350 config.lse.map(|_| Default::default()),
351 );
352
353 let rtc = match config.rtc {
354 Some(RtcClockSource::LSI) => Some(LSI_FREQ),
355 Some(RtcClockSource::LSE) => Some(config.lse.unwrap()),
356 _ => None,
357 };
358 340
359 set_freqs(Clocks { 341 set_freqs(Clocks {
360 sys: Hertz(sysclk), 342 sys: Hertz(sysclk),
@@ -377,7 +359,6 @@ pub(crate) unsafe fn init(config: Config) {
377 pllsai: plls.pllsaiclk.map(Hertz), 359 pllsai: plls.pllsaiclk.map(Hertz),
378 360
379 rtc, 361 rtc,
380 rtc_hse: None,
381 }); 362 });
382} 363}
383 364
diff --git a/embassy-stm32/src/rcc/f7.rs b/embassy-stm32/src/rcc/f7.rs
index 565f6aa9f..0a0a1cf28 100644
--- a/embassy-stm32/src/rcc/f7.rs
+++ b/embassy-stm32/src/rcc/f7.rs
@@ -1,16 +1,12 @@
1use crate::pac::pwr::vals::Vos; 1use crate::pac::pwr::vals::Vos;
2use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllp, Pllq, Pllsrc, Ppre, Sw}; 2use crate::pac::rcc::vals::{Hpre, Pllm, Plln, Pllp, Pllq, Pllsrc, Ppre, Sw};
3use crate::pac::{FLASH, PWR, RCC}; 3use crate::pac::{FLASH, PWR, RCC};
4use crate::rcc::bd::{BackupDomain, RtcClockSource};
5use crate::rcc::{set_freqs, Clocks}; 4use crate::rcc::{set_freqs, Clocks};
6use crate::time::Hertz; 5use crate::time::Hertz;
7 6
8/// HSI speed 7/// HSI speed
9pub const HSI_FREQ: Hertz = Hertz(16_000_000); 8pub const HSI_FREQ: Hertz = Hertz(16_000_000);
10 9
11/// LSI speed
12pub const LSI_FREQ: Hertz = Hertz(32_000);
13
14/// Clocks configuration 10/// Clocks configuration
15#[non_exhaustive] 11#[non_exhaustive]
16#[derive(Default)] 12#[derive(Default)]
@@ -23,9 +19,7 @@ pub struct Config {
23 pub pclk2: Option<Hertz>, 19 pub pclk2: Option<Hertz>,
24 20
25 pub pll48: bool, 21 pub pll48: bool,
26 pub rtc: Option<RtcClockSource>, 22 pub ls: super::LsConfig,
27 pub lsi: bool,
28 pub lse: Option<Hertz>,
29} 23}
30 24
31fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48clk: bool) -> PllResults { 25fn setup_pll(pllsrcclk: u32, use_hse: bool, pllsysclk: Option<u32>, pll48clk: bool) -> PllResults {
@@ -261,17 +255,7 @@ pub(crate) unsafe fn init(config: Config) {
261 }) 255 })
262 }); 256 });
263 257
264 BackupDomain::configure_ls( 258 let rtc = config.ls.init();
265 config.rtc.unwrap_or(RtcClockSource::NOCLOCK),
266 config.lsi,
267 config.lse.map(|_| Default::default()),
268 );
269
270 let rtc = match config.rtc {
271 Some(RtcClockSource::LSI) => Some(LSI_FREQ),
272 Some(RtcClockSource::LSE) => Some(config.lse.unwrap()),
273 _ => None,
274 };
275 259
276 set_freqs(Clocks { 260 set_freqs(Clocks {
277 sys: Hertz(sysclk), 261 sys: Hertz(sysclk),
diff --git a/embassy-stm32/src/rcc/g0.rs b/embassy-stm32/src/rcc/g0.rs
index 823836af7..962b1dc0d 100644
--- a/embassy-stm32/src/rcc/g0.rs
+++ b/embassy-stm32/src/rcc/g0.rs
@@ -10,9 +10,6 @@ use crate::time::Hertz;
10/// HSI speed 10/// HSI speed
11pub const HSI_FREQ: Hertz = Hertz(16_000_000); 11pub const HSI_FREQ: Hertz = Hertz(16_000_000);
12 12
13/// LSI speed
14pub const LSI_FREQ: Hertz = Hertz(32_000);
15
16/// System clock mux source 13/// System clock mux source
17#[derive(Clone, Copy)] 14#[derive(Clone, Copy)]
18pub enum ClockSrc { 15pub enum ClockSrc {
@@ -73,6 +70,7 @@ pub struct Config {
73 pub ahb_pre: AHBPrescaler, 70 pub ahb_pre: AHBPrescaler,
74 pub apb_pre: APBPrescaler, 71 pub apb_pre: APBPrescaler,
75 pub low_power_run: bool, 72 pub low_power_run: bool,
73 pub ls: super::LsConfig,
76} 74}
77 75
78impl Default for Config { 76impl Default for Config {
@@ -83,6 +81,7 @@ impl Default for Config {
83 ahb_pre: AHBPrescaler::DIV1, 81 ahb_pre: AHBPrescaler::DIV1,
84 apb_pre: APBPrescaler::DIV1, 82 apb_pre: APBPrescaler::DIV1,
85 low_power_run: false, 83 low_power_run: false,
84 ls: Default::default(),
86 } 85 }
87 } 86 }
88} 87}
@@ -193,7 +192,7 @@ pub(crate) unsafe fn init(config: Config) {
193 // Enable LSI 192 // Enable LSI
194 RCC.csr().write(|w| w.set_lsion(true)); 193 RCC.csr().write(|w| w.set_lsion(true));
195 while !RCC.csr().read().lsirdy() {} 194 while !RCC.csr().read().lsirdy() {}
196 (LSI_FREQ, Sw::LSI) 195 (super::LSI_FREQ, Sw::LSI)
197 } 196 }
198 }; 197 };
199 198
@@ -272,10 +271,13 @@ pub(crate) unsafe fn init(config: Config) {
272 PWR.cr1().modify(|w| w.set_lpr(true)); 271 PWR.cr1().modify(|w| w.set_lpr(true));
273 } 272 }
274 273
274 let rtc = config.ls.init();
275
275 set_freqs(Clocks { 276 set_freqs(Clocks {
276 sys: sys_clk, 277 sys: sys_clk,
277 ahb1: ahb_freq, 278 ahb1: ahb_freq,
278 apb1: apb_freq, 279 apb1: apb_freq,
279 apb1_tim: apb_tim_freq, 280 apb1_tim: apb_tim_freq,
281 rtc,
280 }); 282 });
281} 283}
diff --git a/embassy-stm32/src/rcc/g4.rs b/embassy-stm32/src/rcc/g4.rs
index 43256524d..a4078e38b 100644
--- a/embassy-stm32/src/rcc/g4.rs
+++ b/embassy-stm32/src/rcc/g4.rs
@@ -14,9 +14,6 @@ use crate::time::Hertz;
14/// HSI speed 14/// HSI speed
15pub const HSI_FREQ: Hertz = Hertz(16_000_000); 15pub const HSI_FREQ: Hertz = Hertz(16_000_000);
16 16
17/// LSI speed
18pub const LSI_FREQ: Hertz = Hertz(32_000);
19
20/// System clock mux source 17/// System clock mux source
21#[derive(Clone, Copy)] 18#[derive(Clone, Copy)]
22pub enum ClockSrc { 19pub enum ClockSrc {
@@ -101,6 +98,8 @@ pub struct Config {
101 pub clock_48mhz_src: Option<Clock48MhzSrc>, 98 pub clock_48mhz_src: Option<Clock48MhzSrc>,
102 pub adc12_clock_source: AdcClockSource, 99 pub adc12_clock_source: AdcClockSource,
103 pub adc345_clock_source: AdcClockSource, 100 pub adc345_clock_source: AdcClockSource,
101
102 pub ls: super::LsConfig,
104} 103}
105 104
106/// Configuration for the Clock Recovery System (CRS) used to trim the HSI48 oscillator. 105/// Configuration for the Clock Recovery System (CRS) used to trim the HSI48 oscillator.
@@ -122,6 +121,7 @@ impl Default for Config {
122 clock_48mhz_src: None, 121 clock_48mhz_src: None,
123 adc12_clock_source: Adcsel::NOCLK, 122 adc12_clock_source: Adcsel::NOCLK,
124 adc345_clock_source: Adcsel::NOCLK, 123 adc345_clock_source: Adcsel::NOCLK,
124 ls: Default::default(),
125 } 125 }
126 } 126 }
127} 127}
@@ -344,6 +344,8 @@ pub(crate) unsafe fn init(config: Config) {
344 PWR.cr1().modify(|w| w.set_lpr(true)); 344 PWR.cr1().modify(|w| w.set_lpr(true));
345 } 345 }
346 346
347 let rtc = config.ls.init();
348
347 set_freqs(Clocks { 349 set_freqs(Clocks {
348 sys: sys_clk, 350 sys: sys_clk,
349 ahb1: ahb_freq, 351 ahb1: ahb_freq,
@@ -354,5 +356,6 @@ pub(crate) unsafe fn init(config: Config) {
354 apb2_tim: apb2_tim_freq, 356 apb2_tim: apb2_tim_freq,
355 adc: adc12_ck, 357 adc: adc12_ck,
356 adc34: adc345_ck, 358 adc34: adc345_ck,
359 rtc,
357 }); 360 });
358} 361}
diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs
index d29064996..7236d82ff 100644
--- a/embassy-stm32/src/rcc/h.rs
+++ b/embassy-stm32/src/rcc/h.rs
@@ -9,8 +9,6 @@ pub use crate::pac::rcc::vals::Adcsel as AdcClockSource;
9use crate::pac::rcc::vals::{Ckpersel, Hsidiv, Pllrge, Pllsrc, Pllvcosel, Sw, Timpre}; 9use crate::pac::rcc::vals::{Ckpersel, Hsidiv, Pllrge, Pllsrc, Pllvcosel, Sw, Timpre};
10pub use crate::pac::rcc::vals::{Ckpersel as PerClockSource, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul}; 10pub use crate::pac::rcc::vals::{Ckpersel as PerClockSource, Plldiv as PllDiv, Pllm as PllPreDiv, Plln as PllMul};
11use crate::pac::{FLASH, PWR, RCC}; 11use crate::pac::{FLASH, PWR, RCC};
12#[cfg(stm32h7)]
13use crate::rcc::bd::{BackupDomain, LseCfg, RtcClockSource};
14use crate::rcc::{set_freqs, Clocks}; 12use crate::rcc::{set_freqs, Clocks};
15use crate::time::Hertz; 13use crate::time::Hertz;
16 14
@@ -23,9 +21,6 @@ pub const CSI_FREQ: Hertz = Hertz(4_000_000);
23/// HSI48 speed 21/// HSI48 speed
24pub const HSI48_FREQ: Hertz = Hertz(48_000_000); 22pub const HSI48_FREQ: Hertz = Hertz(48_000_000);
25 23
26/// LSI speed
27pub const LSI_FREQ: Hertz = Hertz(32_000);
28
29const VCO_RANGE: RangeInclusive<Hertz> = Hertz(150_000_000)..=Hertz(420_000_000); 24const VCO_RANGE: RangeInclusive<Hertz> = Hertz(150_000_000)..=Hertz(420_000_000);
30#[cfg(any(stm32h5, pwr_h7rm0455))] 25#[cfg(any(stm32h5, pwr_h7rm0455))]
31const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(128_000_000)..=Hertz(560_000_000); 26const VCO_WIDE_RANGE: RangeInclusive<Hertz> = Hertz(128_000_000)..=Hertz(560_000_000);
@@ -196,8 +191,7 @@ pub struct Config {
196 pub adc_clock_source: AdcClockSource, 191 pub adc_clock_source: AdcClockSource,
197 pub timer_prescaler: TimerPrescaler, 192 pub timer_prescaler: TimerPrescaler,
198 pub voltage_scale: VoltageScale, 193 pub voltage_scale: VoltageScale,
199 #[cfg(stm32h7)] 194 pub ls: super::LsConfig,
200 pub rtc_mux: Option<RtcClockSource>,
201} 195}
202 196
203impl Default for Config { 197impl Default for Config {
@@ -231,8 +225,7 @@ impl Default for Config {
231 adc_clock_source: AdcClockSource::from_bits(0), // PLL2_P on H7, HCLK on H5 225 adc_clock_source: AdcClockSource::from_bits(0), // PLL2_P on H7, HCLK on H5
232 timer_prescaler: TimerPrescaler::DefaultX2, 226 timer_prescaler: TimerPrescaler::DefaultX2,
233 voltage_scale: VoltageScale::Scale0, 227 voltage_scale: VoltageScale::Scale0,
234 #[cfg(stm32h7)] 228 ls: Default::default(),
235 rtc_mux: None,
236 } 229 }
237 } 230 }
238} 231}
@@ -471,18 +464,7 @@ pub(crate) unsafe fn init(config: Config) {
471 464
472 flash_setup(hclk, config.voltage_scale); 465 flash_setup(hclk, config.voltage_scale);
473 466
474 #[cfg(stm32h7)] 467 let rtc = config.ls.init();
475 {
476 let lsecfg = config.lse.map(|lse| match lse {
477 Lse::Bypass(freq) => {
478 assert!(freq <= Hertz(1_000_000));
479 LseCfg::Bypass
480 }
481 Lse::Oscillator => LseCfg::Oscillator(Default::default()),
482 });
483
484 BackupDomain::configure_ls(config.rtc_mux.unwrap_or(RtcClockSource::NOCLOCK), config.lsi, lsecfg);
485 }
486 468
487 #[cfg(stm32h7)] 469 #[cfg(stm32h7)]
488 { 470 {
@@ -548,17 +530,6 @@ pub(crate) unsafe fn init(config: Config) {
548 while !pac::SYSCFG.cccsr().read().ready() {} 530 while !pac::SYSCFG.cccsr().read().ready() {}
549 } 531 }
550 532
551 #[cfg(stm32h7)]
552 let rtc_clk = match config.rtc_mux {
553 Some(RtcClockSource::LSI) => Some(LSI_FREQ),
554 Some(RtcClockSource::LSE) => Some(match config.lse {
555 Some(Lse::Oscillator) => Hertz(32768),
556 Some(Lse::Bypass(freq)) => freq,
557 None => panic!("LSE not configured"),
558 }),
559 _ => None,
560 };
561
562 set_freqs(Clocks { 533 set_freqs(Clocks {
563 sys, 534 sys,
564 ahb1: hclk, 535 ahb1: hclk,
@@ -573,10 +544,7 @@ pub(crate) unsafe fn init(config: Config) {
573 apb1_tim, 544 apb1_tim,
574 apb2_tim, 545 apb2_tim,
575 adc, 546 adc,
576 #[cfg(stm32h7)] 547 rtc,
577 rtc: rtc_clk,
578 #[cfg(stm32h7)]
579 rtc_hse: None,
580 }); 548 });
581} 549}
582 550
diff --git a/embassy-stm32/src/rcc/l0l1.rs b/embassy-stm32/src/rcc/l0l1.rs
index 4b1acae5d..d8a1fc10c 100644
--- a/embassy-stm32/src/rcc/l0l1.rs
+++ b/embassy-stm32/src/rcc/l0l1.rs
@@ -1,5 +1,3 @@
1use super::bd::BackupDomain;
2use super::RtcClockSource;
3pub use crate::pac::pwr::vals::Vos as VoltageScale; 1pub use crate::pac::pwr::vals::Vos as VoltageScale;
4pub use crate::pac::rcc::vals::{ 2pub use crate::pac::rcc::vals::{
5 Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Pllmul as PLLMul, Ppre as APBPrescaler, 3 Hpre as AHBPrescaler, Msirange as MSIRange, Plldiv as PLLDiv, Pllmul as PLLMul, Ppre as APBPrescaler,
@@ -14,9 +12,6 @@ use crate::time::Hertz;
14/// HSI speed 12/// HSI speed
15pub const HSI_FREQ: Hertz = Hertz(16_000_000); 13pub const HSI_FREQ: Hertz = Hertz(16_000_000);
16 14
17/// LSI speed
18pub const LSI_FREQ: Hertz = Hertz(32_000);
19
20/// System clock mux source 15/// System clock mux source
21#[derive(Clone, Copy)] 16#[derive(Clone, Copy)]
22pub enum ClockSrc { 17pub enum ClockSrc {
@@ -50,9 +45,7 @@ pub struct Config {
50 pub apb2_pre: APBPrescaler, 45 pub apb2_pre: APBPrescaler,
51 #[cfg(crs)] 46 #[cfg(crs)]
52 pub enable_hsi48: bool, 47 pub enable_hsi48: bool,
53 pub rtc: Option<RtcClockSource>, 48 pub ls: super::LsConfig,
54 pub lse: Option<Hertz>,
55 pub lsi: bool,
56 pub voltage_scale: VoltageScale, 49 pub voltage_scale: VoltageScale,
57} 50}
58 51
@@ -66,10 +59,8 @@ impl Default for Config {
66 apb2_pre: APBPrescaler::DIV1, 59 apb2_pre: APBPrescaler::DIV1,
67 #[cfg(crs)] 60 #[cfg(crs)]
68 enable_hsi48: false, 61 enable_hsi48: false,
69 rtc: None,
70 lse: None,
71 lsi: false,
72 voltage_scale: VoltageScale::RANGE1, 62 voltage_scale: VoltageScale::RANGE1,
63 ls: Default::default(),
73 } 64 }
74 } 65 }
75} 66}
@@ -144,11 +135,7 @@ pub(crate) unsafe fn init(config: Config) {
144 } 135 }
145 }; 136 };
146 137
147 BackupDomain::configure_ls( 138 let rtc = config.ls.init();
148 config.rtc.unwrap_or(RtcClockSource::NOCLOCK),
149 config.lsi,
150 config.lse.map(|_| Default::default()),
151 );
152 139
153 let wait_states = match (config.voltage_scale, sys_clk.0) { 140 let wait_states = match (config.voltage_scale, sys_clk.0) {
154 (VoltageScale::RANGE1, ..=16_000_000) => 0, 141 (VoltageScale::RANGE1, ..=16_000_000) => 0,
@@ -227,5 +214,6 @@ pub(crate) unsafe fn init(config: Config) {
227 apb2: apb2_freq, 214 apb2: apb2_freq,
228 apb1_tim: apb1_tim_freq, 215 apb1_tim: apb1_tim_freq,
229 apb2_tim: apb2_tim_freq, 216 apb2_tim: apb2_tim_freq,
217 rtc,
230 }); 218 });
231} 219}
diff --git a/embassy-stm32/src/rcc/l4.rs b/embassy-stm32/src/rcc/l4.rs
index 686bbd4ee..1e5733d31 100644
--- a/embassy-stm32/src/rcc/l4.rs
+++ b/embassy-stm32/src/rcc/l4.rs
@@ -5,16 +5,12 @@ pub use crate::pac::rcc::vals::{
5}; 5};
6use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw}; 6use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw};
7use crate::pac::{FLASH, RCC}; 7use crate::pac::{FLASH, RCC};
8use crate::rcc::bd::{BackupDomain, RtcClockSource};
9use crate::rcc::{set_freqs, Clocks}; 8use crate::rcc::{set_freqs, Clocks};
10use crate::time::Hertz; 9use crate::time::Hertz;
11 10
12/// HSI speed 11/// HSI speed
13pub const HSI_FREQ: Hertz = Hertz(16_000_000); 12pub const HSI_FREQ: Hertz = Hertz(16_000_000);
14 13
15/// LSI speed
16pub const LSI_FREQ: Hertz = Hertz(32_000);
17
18/// System clock mux source 14/// System clock mux source
19#[derive(Clone, Copy)] 15#[derive(Clone, Copy)]
20pub enum ClockSrc { 16pub enum ClockSrc {
@@ -51,9 +47,7 @@ pub struct Config {
51 pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>, 47 pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>,
52 #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] 48 #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
53 pub hsi48: bool, 49 pub hsi48: bool,
54 pub rtc_mux: RtcClockSource, 50 pub ls: super::LsConfig,
55 pub lse: Option<Hertz>,
56 pub lsi: bool,
57} 51}
58 52
59impl Default for Config { 53impl Default for Config {
@@ -67,9 +61,7 @@ impl Default for Config {
67 pllsai1: None, 61 pllsai1: None,
68 #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))] 62 #[cfg(not(any(stm32l471, stm32l475, stm32l476, stm32l486)))]
69 hsi48: false, 63 hsi48: false,
70 rtc_mux: RtcClockSource::LSI, 64 ls: Default::default(),
71 lsi: true,
72 lse: None,
73 } 65 }
74 } 66 }
75} 67}
@@ -95,7 +87,7 @@ pub(crate) unsafe fn init(config: Config) {
95 while RCC.cfgr().read().sws() != Sw::MSI {} 87 while RCC.cfgr().read().sws() != Sw::MSI {}
96 } 88 }
97 89
98 BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default())); 90 let rtc = config.ls.init();
99 91
100 let (sys_clk, sw) = match config.mux { 92 let (sys_clk, sw) = match config.mux {
101 ClockSrc::MSI(range) => { 93 ClockSrc::MSI(range) => {
@@ -105,12 +97,8 @@ pub(crate) unsafe fn init(config: Config) {
105 w.set_msirgsel(true); 97 w.set_msirgsel(true);
106 w.set_msion(true); 98 w.set_msion(true);
107 99
108 if config.rtc_mux == RtcClockSource::LSE { 100 // If LSE is enabled, enable calibration of MSI
109 // If LSE is enabled, enable calibration of MSI 101 w.set_msipllen(config.ls.lse.is_some());
110 w.set_msipllen(true);
111 } else {
112 w.set_msipllen(false);
113 }
114 }); 102 });
115 while !RCC.cr().read().msirdy() {} 103 while !RCC.cr().read().msirdy() {}
116 104
@@ -285,6 +273,7 @@ pub(crate) unsafe fn init(config: Config) {
285 apb2: apb2_freq, 273 apb2: apb2_freq,
286 apb1_tim: apb1_tim_freq, 274 apb1_tim: apb1_tim_freq,
287 apb2_tim: apb2_tim_freq, 275 apb2_tim: apb2_tim_freq,
276 rtc,
288 }); 277 });
289} 278}
290 279
diff --git a/embassy-stm32/src/rcc/l5.rs b/embassy-stm32/src/rcc/l5.rs
index ac4804d4f..1f4e00344 100644
--- a/embassy-stm32/src/rcc/l5.rs
+++ b/embassy-stm32/src/rcc/l5.rs
@@ -5,16 +5,12 @@ pub use crate::pac::rcc::vals::{
5}; 5};
6use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw}; 6use crate::pac::rcc::vals::{Msirange, Pllsrc, Sw};
7use crate::pac::{FLASH, PWR, RCC}; 7use crate::pac::{FLASH, PWR, RCC};
8use crate::rcc::bd::RtcClockSource;
9use crate::rcc::{set_freqs, Clocks}; 8use crate::rcc::{set_freqs, Clocks};
10use crate::time::Hertz; 9use crate::time::Hertz;
11 10
12/// HSI speed 11/// HSI speed
13pub const HSI_FREQ: Hertz = Hertz(16_000_000); 12pub const HSI_FREQ: Hertz = Hertz(16_000_000);
14 13
15/// LSI speed
16pub const LSI_FREQ: Hertz = Hertz(32_000);
17
18/// System clock mux source 14/// System clock mux source
19#[derive(Clone, Copy)] 15#[derive(Clone, Copy)]
20pub enum ClockSrc { 16pub enum ClockSrc {
@@ -50,9 +46,7 @@ pub struct Config {
50 pub apb2_pre: APBPrescaler, 46 pub apb2_pre: APBPrescaler,
51 pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>, 47 pub pllsai1: Option<(PllMul, PllPreDiv, Option<PllRDiv>, Option<PllQDiv>, Option<PllPDiv>)>,
52 pub hsi48: bool, 48 pub hsi48: bool,
53 pub rtc_mux: RtcClockSource, 49 pub ls: super::LsConfig,
54 pub lse: Option<Hertz>,
55 pub lsi: bool,
56} 50}
57 51
58impl Default for Config { 52impl Default for Config {
@@ -65,9 +59,7 @@ impl Default for Config {
65 apb2_pre: APBPrescaler::DIV1, 59 apb2_pre: APBPrescaler::DIV1,
66 pllsai1: None, 60 pllsai1: None,
67 hsi48: false, 61 hsi48: false,
68 rtc_mux: RtcClockSource::LSI, 62 ls: Default::default(),
69 lsi: true,
70 lse: None,
71 } 63 }
72 } 64 }
73} 65}
@@ -93,7 +85,7 @@ pub(crate) unsafe fn init(config: Config) {
93 while RCC.cfgr().read().sws() != Sw::MSI {} 85 while RCC.cfgr().read().sws() != Sw::MSI {}
94 } 86 }
95 87
96 //BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default())); 88 let rtc = config.ls.init();
97 89
98 PWR.cr1().modify(|w| w.set_vos(stm32_metapac::pwr::vals::Vos::RANGE0)); 90 PWR.cr1().modify(|w| w.set_vos(stm32_metapac::pwr::vals::Vos::RANGE0));
99 let (sys_clk, sw) = match config.mux { 91 let (sys_clk, sw) = match config.mux {
@@ -104,12 +96,8 @@ pub(crate) unsafe fn init(config: Config) {
104 w.set_msirgsel(true); 96 w.set_msirgsel(true);
105 w.set_msion(true); 97 w.set_msion(true);
106 98
107 if config.rtc_mux == RtcClockSource::LSE { 99 // If LSE is enabled, enable calibration of MSI
108 // If LSE is enabled, enable calibration of MSI 100 w.set_msipllen(config.ls.lse.is_some());
109 w.set_msipllen(true);
110 } else {
111 w.set_msipllen(false);
112 }
113 }); 101 });
114 while !RCC.cr().read().msirdy() {} 102 while !RCC.cr().read().msirdy() {}
115 103
@@ -280,6 +268,7 @@ pub(crate) unsafe fn init(config: Config) {
280 apb2: apb2_freq, 268 apb2: apb2_freq,
281 apb1_tim: apb1_tim_freq, 269 apb1_tim: apb1_tim_freq,
282 apb2_tim: apb2_tim_freq, 270 apb2_tim: apb2_tim_freq,
271 rtc,
283 }); 272 });
284} 273}
285 274
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 3d4de0e6e..a9e53d424 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -2,11 +2,11 @@
2 2
3use core::mem::MaybeUninit; 3use core::mem::MaybeUninit;
4 4
5pub use crate::rcc::bd::RtcClockSource;
6use crate::time::Hertz; 5use crate::time::Hertz;
7 6
8pub(crate) mod bd; 7mod bd;
9mod mco; 8mod mco;
9pub use bd::*;
10pub use mco::*; 10pub use mco::*;
11 11
12#[cfg_attr(rcc_f0, path = "f0.rs")] 12#[cfg_attr(rcc_f0, path = "f0.rs")]
@@ -132,13 +132,7 @@ pub struct Clocks {
132 #[cfg(stm32f334)] 132 #[cfg(stm32f334)]
133 pub hrtim: Option<Hertz>, 133 pub hrtim: Option<Hertz>,
134 134
135 #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_f7, rcc_h7, rcc_h7rm0433, rcc_h7ab))]
136 /// Set only if the lsi or lse is configured, indicates stop is supported
137 pub rtc: Option<Hertz>, 135 pub rtc: Option<Hertz>,
138
139 #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h7, rcc_h7rm0433, rcc_h7ab))]
140 /// Set if the hse is configured, indicates stop is not supported
141 pub rtc_hse: Option<Hertz>,
142} 136}
143 137
144#[cfg(feature = "low-power")] 138#[cfg(feature = "low-power")]
@@ -166,14 +160,6 @@ pub(crate) fn clock_refcount_sub() {
166/// The existence of this value indicates that the clock configuration can no longer be changed 160/// The existence of this value indicates that the clock configuration can no longer be changed
167static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit(); 161static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit();
168 162
169#[cfg(stm32wb)]
170/// RCC initialization function
171pub(crate) unsafe fn init(config: Config) {
172 set_freqs(compute_clocks(&config));
173
174 configure_clocks(&config);
175}
176
177/// Sets the clock frequencies 163/// Sets the clock frequencies
178/// 164///
179/// Safety: Sets a mutable global. 165/// Safety: Sets a mutable global.
diff --git a/embassy-stm32/src/rcc/u5.rs b/embassy-stm32/src/rcc/u5.rs
index d8fb17301..68a8d3a35 100644
--- a/embassy-stm32/src/rcc/u5.rs
+++ b/embassy-stm32/src/rcc/u5.rs
@@ -7,9 +7,6 @@ use crate::time::Hertz;
7/// HSI speed 7/// HSI speed
8pub const HSI_FREQ: Hertz = Hertz(16_000_000); 8pub const HSI_FREQ: Hertz = Hertz(16_000_000);
9 9
10/// LSI speed
11pub const LSI_FREQ: Hertz = Hertz(32_000);
12
13pub use crate::pac::pwr::vals::Vos as VoltageScale; 10pub use crate::pac::pwr::vals::Vos as VoltageScale;
14 11
15#[derive(Copy, Clone)] 12#[derive(Copy, Clone)]
@@ -111,7 +108,6 @@ impl Into<Sw> for ClockSrc {
111 } 108 }
112} 109}
113 110
114#[derive(Copy, Clone)]
115pub struct Config { 111pub struct Config {
116 pub mux: ClockSrc, 112 pub mux: ClockSrc,
117 pub ahb_pre: AHBPrescaler, 113 pub ahb_pre: AHBPrescaler,
@@ -125,6 +121,7 @@ pub struct Config {
125 /// 121 ///
126 /// See RM0456 § 10.5.4 for a general overview and § 11.4.10 for clock source frequency limits. 122 /// See RM0456 § 10.5.4 for a general overview and § 11.4.10 for clock source frequency limits.
127 pub voltage_range: VoltageScale, 123 pub voltage_range: VoltageScale,
124 pub ls: super::LsConfig,
128} 125}
129 126
130impl Config { 127impl Config {
@@ -193,6 +190,7 @@ impl Default for Config {
193 apb3_pre: APBPrescaler::DIV1, 190 apb3_pre: APBPrescaler::DIV1,
194 hsi48: false, 191 hsi48: false,
195 voltage_range: VoltageScale::RANGE3, 192 voltage_range: VoltageScale::RANGE3,
193 ls: Default::default(),
196 } 194 }
197 } 195 }
198} 196}
@@ -434,6 +432,8 @@ pub(crate) unsafe fn init(config: Config) {
434 } 432 }
435 }; 433 };
436 434
435 let rtc = config.ls.init();
436
437 set_freqs(Clocks { 437 set_freqs(Clocks {
438 sys: sys_clk, 438 sys: sys_clk,
439 ahb1: ahb_freq, 439 ahb1: ahb_freq,
@@ -444,6 +444,7 @@ pub(crate) unsafe fn init(config: Config) {
444 apb3: apb3_freq, 444 apb3: apb3_freq,
445 apb1_tim: apb1_tim_freq, 445 apb1_tim: apb1_tim_freq,
446 apb2_tim: apb2_tim_freq, 446 apb2_tim: apb2_tim_freq,
447 rtc,
447 }); 448 });
448} 449}
449 450
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs
index f8eeaa953..181e6bb5b 100644
--- a/embassy-stm32/src/rcc/wb.rs
+++ b/embassy-stm32/src/rcc/wb.rs
@@ -2,16 +2,12 @@ pub use crate::pac::rcc::vals::{
2 Hpre as AHBPrescaler, Hsepre as HsePrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Pllsrc as PllSource, 2 Hpre as AHBPrescaler, Hsepre as HsePrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Pllsrc as PllSource,
3 Ppre as APBPrescaler, Sw as Sysclk, 3 Ppre as APBPrescaler, Sw as Sysclk,
4}; 4};
5use crate::rcc::bd::{BackupDomain, RtcClockSource}; 5use crate::rcc::{set_freqs, Clocks};
6use crate::rcc::Clocks; 6use crate::time::{mhz, Hertz};
7use crate::time::{khz, mhz, Hertz};
8 7
9/// HSI speed 8/// HSI speed
10pub const HSI_FREQ: Hertz = Hertz(16_000_000); 9pub const HSI_FREQ: Hertz = Hertz(16_000_000);
11 10
12/// LSI speed
13pub const LSI_FREQ: Hertz = Hertz(32_000);
14
15pub struct Hse { 11pub struct Hse {
16 pub prediv: HsePrescaler, 12 pub prediv: HsePrescaler,
17 13
@@ -42,11 +38,8 @@ pub struct Pll {
42/// Clocks configutation 38/// Clocks configutation
43pub struct Config { 39pub struct Config {
44 pub hse: Option<Hse>, 40 pub hse: Option<Hse>,
45 pub lse: Option<Hertz>,
46 pub lsi: bool,
47 pub sys: Sysclk, 41 pub sys: Sysclk,
48 pub mux: Option<PllMux>, 42 pub mux: Option<PllMux>,
49 pub rtc: Option<RtcClockSource>,
50 43
51 pub pll: Option<Pll>, 44 pub pll: Option<Pll>,
52 pub pllsai: Option<Pll>, 45 pub pllsai: Option<Pll>,
@@ -56,6 +49,8 @@ pub struct Config {
56 pub ahb3_pre: AHBPrescaler, 49 pub ahb3_pre: AHBPrescaler,
57 pub apb1_pre: APBPrescaler, 50 pub apb1_pre: APBPrescaler,
58 pub apb2_pre: APBPrescaler, 51 pub apb2_pre: APBPrescaler,
52
53 pub ls: super::LsConfig,
59} 54}
60 55
61pub const WPAN_DEFAULT: Config = Config { 56pub const WPAN_DEFAULT: Config = Config {
@@ -63,14 +58,13 @@ pub const WPAN_DEFAULT: Config = Config {
63 frequency: mhz(32), 58 frequency: mhz(32),
64 prediv: HsePrescaler::DIV1, 59 prediv: HsePrescaler::DIV1,
65 }), 60 }),
66 lse: Some(khz(32)),
67 sys: Sysclk::PLL, 61 sys: Sysclk::PLL,
68 mux: Some(PllMux { 62 mux: Some(PllMux {
69 source: PllSource::HSE, 63 source: PllSource::HSE,
70 prediv: Pllm::DIV2, 64 prediv: Pllm::DIV2,
71 }), 65 }),
72 rtc: Some(RtcClockSource::LSE), 66
73 lsi: false, 67 ls: super::LsConfig::default_lse(),
74 68
75 pll: Some(Pll { 69 pll: Some(Pll {
76 mul: Plln::MUL12, 70 mul: Plln::MUL12,
@@ -92,13 +86,12 @@ impl Default for Config {
92 fn default() -> Config { 86 fn default() -> Config {
93 Config { 87 Config {
94 hse: None, 88 hse: None,
95 lse: None,
96 sys: Sysclk::HSI16, 89 sys: Sysclk::HSI16,
97 mux: None, 90 mux: None,
98 pll: None, 91 pll: None,
99 pllsai: None, 92 pllsai: None,
100 rtc: None, 93
101 lsi: false, 94 ls: Default::default(),
102 95
103 ahb1_pre: AHBPrescaler::DIV1, 96 ahb1_pre: AHBPrescaler::DIV1,
104 ahb2_pre: AHBPrescaler::DIV1, 97 ahb2_pre: AHBPrescaler::DIV1,
@@ -109,7 +102,9 @@ impl Default for Config {
109 } 102 }
110} 103}
111 104
112pub(crate) fn compute_clocks(config: &Config) -> Clocks { 105#[cfg(stm32wb)]
106/// RCC initialization function
107pub(crate) unsafe fn init(config: Config) {
113 let hse_clk = config.hse.as_ref().map(|hse| hse.frequency / hse.prediv); 108 let hse_clk = config.hse.as_ref().map(|hse| hse.frequency / hse.prediv);
114 109
115 let mux_clk = config.mux.as_ref().map(|pll_mux| { 110 let mux_clk = config.mux.as_ref().map(|pll_mux| {
@@ -160,27 +155,6 @@ pub(crate) fn compute_clocks(config: &Config) -> Clocks {
160 } 155 }
161 }; 156 };
162 157
163 let rtc_clk = match config.rtc {
164 Some(RtcClockSource::LSI) => Some(LSI_FREQ),
165 Some(RtcClockSource::LSE) => Some(config.lse.unwrap()),
166 _ => None,
167 };
168
169 Clocks {
170 sys: sys_clk,
171 ahb1: ahb1_clk,
172 ahb2: ahb2_clk,
173 ahb3: ahb3_clk,
174 apb1: apb1_clk,
175 apb2: apb2_clk,
176 apb1_tim: apb1_tim_clk,
177 apb2_tim: apb2_tim_clk,
178 rtc: rtc_clk,
179 rtc_hse: None,
180 }
181}
182
183pub(crate) fn configure_clocks(config: &Config) {
184 let rcc = crate::pac::RCC; 158 let rcc = crate::pac::RCC;
185 159
186 let needs_hsi = if let Some(pll_mux) = &config.mux { 160 let needs_hsi = if let Some(pll_mux) = &config.mux {
@@ -199,11 +173,7 @@ pub(crate) fn configure_clocks(config: &Config) {
199 173
200 rcc.cfgr().modify(|w| w.set_stopwuck(true)); 174 rcc.cfgr().modify(|w| w.set_stopwuck(true));
201 175
202 BackupDomain::configure_ls( 176 let rtc = config.ls.init();
203 config.rtc.unwrap_or(RtcClockSource::NOCLOCK),
204 config.lsi,
205 config.lse.map(|_| Default::default()),
206 );
207 177
208 match &config.hse { 178 match &config.hse {
209 Some(hse) => { 179 Some(hse) => {
@@ -263,4 +233,16 @@ pub(crate) fn configure_clocks(config: &Config) {
263 w.set_c2hpre(config.ahb2_pre); 233 w.set_c2hpre(config.ahb2_pre);
264 w.set_shdhpre(config.ahb3_pre); 234 w.set_shdhpre(config.ahb3_pre);
265 }); 235 });
236
237 set_freqs(Clocks {
238 sys: sys_clk,
239 ahb1: ahb1_clk,
240 ahb2: ahb2_clk,
241 ahb3: ahb3_clk,
242 apb1: apb1_clk,
243 apb2: apb2_clk,
244 apb1_tim: apb1_tim_clk,
245 apb2_tim: apb2_tim_clk,
246 rtc,
247 })
266} 248}
diff --git a/embassy-stm32/src/rcc/wba.rs b/embassy-stm32/src/rcc/wba.rs
index d79b3063e..ff5669ec5 100644
--- a/embassy-stm32/src/rcc/wba.rs
+++ b/embassy-stm32/src/rcc/wba.rs
@@ -7,9 +7,6 @@ use crate::time::Hertz;
7/// HSI speed 7/// HSI speed
8pub const HSI_FREQ: Hertz = Hertz(16_000_000); 8pub const HSI_FREQ: Hertz = Hertz(16_000_000);
9 9
10/// LSI speed
11pub const LSI_FREQ: Hertz = Hertz(32_000);
12
13pub use crate::pac::pwr::vals::Vos as VoltageScale; 10pub use crate::pac::pwr::vals::Vos as VoltageScale;
14pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler}; 11pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
15 12
@@ -43,13 +40,13 @@ impl Into<Sw> for ClockSrc {
43 } 40 }
44} 41}
45 42
46#[derive(Copy, Clone)]
47pub struct Config { 43pub struct Config {
48 pub mux: ClockSrc, 44 pub mux: ClockSrc,
49 pub ahb_pre: AHBPrescaler, 45 pub ahb_pre: AHBPrescaler,
50 pub apb1_pre: APBPrescaler, 46 pub apb1_pre: APBPrescaler,
51 pub apb2_pre: APBPrescaler, 47 pub apb2_pre: APBPrescaler,
52 pub apb7_pre: APBPrescaler, 48 pub apb7_pre: APBPrescaler,
49 pub ls: super::LsConfig,
53} 50}
54 51
55impl Default for Config { 52impl Default for Config {
@@ -60,6 +57,7 @@ impl Default for Config {
60 apb1_pre: APBPrescaler::DIV1, 57 apb1_pre: APBPrescaler::DIV1,
61 apb2_pre: APBPrescaler::DIV1, 58 apb2_pre: APBPrescaler::DIV1,
62 apb7_pre: APBPrescaler::DIV1, 59 apb7_pre: APBPrescaler::DIV1,
60 ls: Default::default(),
63 } 61 }
64 } 62 }
65} 63}
@@ -140,6 +138,8 @@ pub(crate) unsafe fn init(config: Config) {
140 } 138 }
141 }; 139 };
142 140
141 let rtc = config.ls.init();
142
143 set_freqs(Clocks { 143 set_freqs(Clocks {
144 sys: sys_clk, 144 sys: sys_clk,
145 ahb1: ahb_freq, 145 ahb1: ahb_freq,
@@ -150,5 +150,6 @@ pub(crate) unsafe fn init(config: Config) {
150 apb7: apb7_freq, 150 apb7: apb7_freq,
151 apb1_tim: apb1_tim_freq, 151 apb1_tim: apb1_tim_freq,
152 apb2_tim: apb2_tim_freq, 152 apb2_tim: apb2_tim_freq,
153 rtc,
153 }); 154 });
154} 155}
diff --git a/embassy-stm32/src/rcc/wl.rs b/embassy-stm32/src/rcc/wl.rs
index 4c3fe5051..366ca1369 100644
--- a/embassy-stm32/src/rcc/wl.rs
+++ b/embassy-stm32/src/rcc/wl.rs
@@ -5,16 +5,12 @@ pub use crate::pac::rcc::vals::{
5 Pllsrc as PllSource, Ppre as APBPrescaler, 5 Pllsrc as PllSource, Ppre as APBPrescaler,
6}; 6};
7use crate::pac::{FLASH, RCC}; 7use crate::pac::{FLASH, RCC};
8use crate::rcc::bd::{BackupDomain, RtcClockSource};
9use crate::rcc::{set_freqs, Clocks}; 8use crate::rcc::{set_freqs, Clocks};
10use crate::time::Hertz; 9use crate::time::Hertz;
11 10
12/// HSI speed 11/// HSI speed
13pub const HSI_FREQ: Hertz = Hertz(16_000_000); 12pub const HSI_FREQ: Hertz = Hertz(16_000_000);
14 13
15/// LSI speed
16pub const LSI_FREQ: Hertz = Hertz(32_000);
17
18/// HSE speed 14/// HSE speed
19pub const HSE_FREQ: Hertz = Hertz(32_000_000); 15pub const HSE_FREQ: Hertz = Hertz(32_000_000);
20 16
@@ -33,10 +29,8 @@ pub struct Config {
33 pub shd_ahb_pre: AHBPrescaler, 29 pub shd_ahb_pre: AHBPrescaler,
34 pub apb1_pre: APBPrescaler, 30 pub apb1_pre: APBPrescaler,
35 pub apb2_pre: APBPrescaler, 31 pub apb2_pre: APBPrescaler,
36 pub rtc_mux: RtcClockSource,
37 pub lse: Option<Hertz>,
38 pub lsi: bool,
39 pub adc_clock_source: AdcClockSource, 32 pub adc_clock_source: AdcClockSource,
33 pub ls: super::LsConfig,
40} 34}
41 35
42impl Default for Config { 36impl Default for Config {
@@ -48,10 +42,8 @@ impl Default for Config {
48 shd_ahb_pre: AHBPrescaler::DIV1, 42 shd_ahb_pre: AHBPrescaler::DIV1,
49 apb1_pre: APBPrescaler::DIV1, 43 apb1_pre: APBPrescaler::DIV1,
50 apb2_pre: APBPrescaler::DIV1, 44 apb2_pre: APBPrescaler::DIV1,
51 rtc_mux: RtcClockSource::LSI,
52 lsi: true,
53 lse: None,
54 adc_clock_source: AdcClockSource::HSI16, 45 adc_clock_source: AdcClockSource::HSI16,
46 ls: Default::default(),
55 } 47 }
56 } 48 }
57} 49}
@@ -104,9 +96,6 @@ pub(crate) unsafe fn init(config: Config) {
104 96
105 while FLASH.acr().read().latency() != ws {} 97 while FLASH.acr().read().latency() != ws {}
106 98
107 // Enables the LSI if configured
108 BackupDomain::configure_ls(config.rtc_mux, config.lsi, config.lse.map(|_| Default::default()));
109
110 match config.mux { 99 match config.mux {
111 ClockSrc::HSI16 => { 100 ClockSrc::HSI16 => {
112 // Enable HSI16 101 // Enable HSI16
@@ -129,12 +118,8 @@ pub(crate) unsafe fn init(config: Config) {
129 w.set_msirange(range); 118 w.set_msirange(range);
130 w.set_msion(true); 119 w.set_msion(true);
131 120
132 if config.rtc_mux == RtcClockSource::LSE { 121 // If LSE is enabled, enable calibration of MSI
133 // If LSE is enabled, enable calibration of MSI 122 w.set_msipllen(config.ls.lse.is_some());
134 w.set_msipllen(true);
135 } else {
136 w.set_msipllen(false);
137 }
138 }); 123 });
139 while !RCC.cr().read().msirdy() {} 124 while !RCC.cr().read().msirdy() {}
140 } 125 }
@@ -156,6 +141,8 @@ pub(crate) unsafe fn init(config: Config) {
156 141
157 // TODO: switch voltage range 142 // TODO: switch voltage range
158 143
144 let rtc = config.ls.init();
145
159 set_freqs(Clocks { 146 set_freqs(Clocks {
160 sys: sys_clk, 147 sys: sys_clk,
161 ahb1: ahb_freq, 148 ahb1: ahb_freq,
@@ -166,6 +153,7 @@ pub(crate) unsafe fn init(config: Config) {
166 apb3: shd_ahb_freq, 153 apb3: shd_ahb_freq,
167 apb1_tim: apb1_tim_freq, 154 apb1_tim: apb1_tim_freq,
168 apb2_tim: apb2_tim_freq, 155 apb2_tim: apb2_tim_freq,
156 rtc,
169 }); 157 });
170} 158}
171 159
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 28dde2eb1..cf34d2191 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -10,7 +10,6 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
10use embassy_sync::blocking_mutex::Mutex; 10use embassy_sync::blocking_mutex::Mutex;
11 11
12pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; 12pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError};
13pub use crate::rcc::RtcClockSource;
14use crate::time::Hertz; 13use crate::time::Hertz;
15 14
16/// refer to AN4759 to compare features of RTC2 and RTC3 15/// refer to AN4759 to compare features of RTC2 and RTC3
@@ -184,7 +183,7 @@ impl Default for RtcCalibrationCyclePeriod {
184 183
185impl Rtc { 184impl Rtc {
186 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { 185 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
187 #[cfg(any(rcc_wle, rcc_wl5, rcc_g4, rcc_g0, rtc_v2l4, rtc_v2wb))] 186 #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))]
188 <RTC as crate::rcc::sealed::RccPeripheral>::enable(); 187 <RTC as crate::rcc::sealed::RccPeripheral>::enable();
189 188
190 let mut this = Self { 189 let mut this = Self {
@@ -204,19 +203,8 @@ impl Rtc {
204 } 203 }
205 204
206 fn frequency() -> Hertz { 205 fn frequency() -> Hertz {
207 #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab))]
208 let freqs = unsafe { crate::rcc::get_freqs() }; 206 let freqs = unsafe { crate::rcc::get_freqs() };
209 207 freqs.rtc.unwrap()
210 // Load the clock frequency from the rcc mod, if supported
211 #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab))]
212 match freqs.rtc {
213 Some(hertz) => hertz,
214 None => freqs.rtc_hse.unwrap(),
215 }
216
217 // Assume the default value, if not supported
218 #[cfg(not(any(rcc_wb, rcc_f4, rcc_f410, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab)))]
219 Hertz(32_768)
220 } 208 }
221 209
222 /// Acquire a [`RtcTimeProvider`] instance. 210 /// Acquire a [`RtcTimeProvider`] instance.
diff --git a/examples/stm32f4/src/bin/rtc.rs b/examples/stm32f4/src/bin/rtc.rs
index e33746008..e95ad5779 100644
--- a/examples/stm32f4/src/bin/rtc.rs
+++ b/examples/stm32f4/src/bin/rtc.rs
@@ -5,16 +5,14 @@
5use chrono::{NaiveDate, NaiveDateTime}; 5use chrono::{NaiveDate, NaiveDateTime};
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; 8use embassy_stm32::rtc::{Rtc, RtcConfig};
9use embassy_stm32::Config; 9use embassy_stm32::Config;
10use embassy_time::{Duration, Timer}; 10use embassy_time::{Duration, Timer};
11use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
12 12
13#[embassy_executor::main] 13#[embassy_executor::main]
14async fn main(_spawner: Spawner) { 14async fn main(_spawner: Spawner) {
15 let mut config = Config::default(); 15 let config = Config::default();
16 config.rcc.lsi = true;
17 config.rcc.rtc = Option::Some(RtcClockSource::LSI);
18 let p = embassy_stm32::init(config); 16 let p = embassy_stm32::init(config);
19 17
20 info!("Hello World!"); 18 info!("Hello World!");
diff --git a/examples/stm32h7/src/bin/rtc.rs b/examples/stm32h7/src/bin/rtc.rs
index eeb94073b..f2a19af81 100644
--- a/examples/stm32h7/src/bin/rtc.rs
+++ b/examples/stm32h7/src/bin/rtc.rs
@@ -5,20 +5,18 @@
5use chrono::{NaiveDate, NaiveDateTime}; 5use chrono::{NaiveDate, NaiveDateTime};
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::rcc::Lse; 8use embassy_stm32::rcc::LsConfig;
9use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; 9use embassy_stm32::rtc::{Rtc, RtcConfig};
10use embassy_stm32::Config; 10use embassy_stm32::Config;
11use embassy_time::{Duration, Timer}; 11use embassy_time::{Duration, Timer};
12use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
13 13
14#[embassy_executor::main] 14#[embassy_executor::main]
15async fn main(_spawner: Spawner) { 15async fn main(_spawner: Spawner) {
16 let p = { 16 let mut config = Config::default();
17 let mut config = Config::default(); 17 config.rcc.ls = LsConfig::default_lse();
18 config.rcc.lse = Some(Lse::Oscillator); 18
19 config.rcc.rtc_mux = Some(RtcClockSource::LSE); 19 let p = embassy_stm32::init(config);
20 embassy_stm32::init(config)
21 };
22 info!("Hello World!"); 20 info!("Hello World!");
23 21
24 let now = NaiveDate::from_ymd_opt(2020, 5, 15) 22 let now = NaiveDate::from_ymd_opt(2020, 5, 15)
diff --git a/examples/stm32l4/src/bin/rtc.rs b/examples/stm32l4/src/bin/rtc.rs
index 7e2b8c783..33efc76b3 100644
--- a/examples/stm32l4/src/bin/rtc.rs
+++ b/examples/stm32l4/src/bin/rtc.rs
@@ -5,7 +5,7 @@
5use chrono::{NaiveDate, NaiveDateTime}; 5use chrono::{NaiveDate, NaiveDateTime};
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::rcc::{self, ClockSrc, PLLSource, PllMul, PllPreDiv, PllRDiv}; 8use embassy_stm32::rcc::{ClockSrc, LsConfig, PLLSource, PllMul, PllPreDiv, PllRDiv};
9use embassy_stm32::rtc::{Rtc, RtcConfig}; 9use embassy_stm32::rtc::{Rtc, RtcConfig};
10use embassy_stm32::time::Hertz; 10use embassy_stm32::time::Hertz;
11use embassy_stm32::Config; 11use embassy_stm32::Config;
@@ -23,8 +23,7 @@ async fn main(_spawner: Spawner) {
23 PllMul::MUL20, 23 PllMul::MUL20,
24 None, 24 None,
25 ); 25 );
26 config.rcc.lse = Some(Hertz(32_768)); 26 config.rcc.ls = LsConfig::default_lse();
27 config.rcc.rtc_mux = rcc::RtcClockSource::LSE;
28 embassy_stm32::init(config) 27 embassy_stm32::init(config)
29 }; 28 };
30 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 8db89be24..7193d1f1f 100644
--- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
+++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
@@ -32,7 +32,6 @@ use embedded_io::Write as bWrite;
32use embedded_io_async::Write; 32use embedded_io_async::Write;
33use hal::gpio::{Input, Level, Output, Speed}; 33use hal::gpio::{Input, Level, Output, Speed};
34use hal::i2c::{self, I2c}; 34use hal::i2c::{self, I2c};
35use hal::rcc::{self};
36use hal::rng::{self, Rng}; 35use hal::rng::{self, Rng};
37use hal::{bind_interrupts, exti, pac, peripherals}; 36use hal::{bind_interrupts, exti, pac, peripherals};
38use heapless::Vec; 37use heapless::Vec;
@@ -86,7 +85,6 @@ async fn main(spawner: Spawner) {
86 None, 85 None,
87 ); 86 );
88 config.rcc.hsi48 = true; // needed for rng 87 config.rcc.hsi48 = true; // needed for rng
89 config.rcc.rtc_mux = rcc::RtcClockSource::LSI;
90 88
91 let dp = embassy_stm32::init(config); 89 let dp = embassy_stm32::init(config);
92 90
diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs
index 6546a4bfa..8c789afbc 100644
--- a/examples/stm32wl/src/bin/lora_lorawan.rs
+++ b/examples/stm32wl/src/bin/lora_lorawan.rs
@@ -34,7 +34,6 @@ bind_interrupts!(struct Irqs{
34async fn main(_spawner: Spawner) { 34async fn main(_spawner: Spawner) {
35 let mut config = embassy_stm32::Config::default(); 35 let mut config = embassy_stm32::Config::default();
36 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; 36 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE;
37 config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI;
38 let p = embassy_stm32::init(config); 37 let p = embassy_stm32::init(config);
39 38
40 pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01)); 39 pac::RCC.ccipr().modify(|w| w.set_rngsel(0b01));
diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs
index d5b819700..7c7e8a4e6 100644
--- a/examples/stm32wl/src/bin/random.rs
+++ b/examples/stm32wl/src/bin/random.rs
@@ -16,7 +16,6 @@ bind_interrupts!(struct Irqs{
16async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
17 let mut config = embassy_stm32::Config::default(); 17 let mut config = embassy_stm32::Config::default();
18 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE; 18 config.rcc.mux = embassy_stm32::rcc::ClockSrc::HSE;
19 config.rcc.rtc_mux = embassy_stm32::rcc::RtcClockSource::LSI;
20 19
21 let p = embassy_stm32::init(config); 20 let p = embassy_stm32::init(config);
22 pac::RCC.ccipr().modify(|w| { 21 pac::RCC.ccipr().modify(|w| {
diff --git a/examples/stm32wl/src/bin/rtc.rs b/examples/stm32wl/src/bin/rtc.rs
index b26ddc2f5..a6bb28013 100644
--- a/examples/stm32wl/src/bin/rtc.rs
+++ b/examples/stm32wl/src/bin/rtc.rs
@@ -5,9 +5,8 @@
5use chrono::{NaiveDate, NaiveDateTime}; 5use chrono::{NaiveDate, NaiveDateTime};
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::rcc::ClockSrc; 8use embassy_stm32::rcc::{ClockSrc, LsConfig};
9use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; 9use embassy_stm32::rtc::{Rtc, RtcConfig};
10use embassy_stm32::time::Hertz;
11use embassy_stm32::Config; 10use embassy_stm32::Config;
12use embassy_time::{Duration, Timer}; 11use embassy_time::{Duration, Timer};
13use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
@@ -17,8 +16,7 @@ async fn main(_spawner: Spawner) {
17 let p = { 16 let p = {
18 let mut config = Config::default(); 17 let mut config = Config::default();
19 config.rcc.mux = ClockSrc::HSE; 18 config.rcc.mux = ClockSrc::HSE;
20 config.rcc.lse = Some(Hertz(32_768)); 19 config.rcc.ls = LsConfig::default_lse();
21 config.rcc.rtc_mux = RtcClockSource::LSE;
22 embassy_stm32::init(config) 20 embassy_stm32::init(config)
23 }; 21 };
24 info!("Hello World!"); 22 info!("Hello World!");
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index ef835eed8..a1481c7c2 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -10,19 +10,19 @@ stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill
10stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc" 10stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc"
11stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo 11stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo
12stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo 12stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo
13stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo 13stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "not-gpdma"] # Nucleo
14stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin"] # Nucleo 14stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac-adc-pin"] # Nucleo
15stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo 15stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" ] # Nucleo
16stm32h563zi = ["embassy-stm32/stm32h563zi", "eth"] # Nucleo 16stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth"] # Nucleo
17stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board 17stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono"] # IoT board
18stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma"] # Nucleo 18stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma"] # Nucleo
19stm32l152re = ["embassy-stm32/stm32l152re", "not-gpdma"] # Nucleo 19stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] # Nucleo
20stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "not-gpdma"] # Nucleo 20stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma"] # Nucleo
21stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "not-gpdma"] # Nucleo 21stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma"] # Nucleo
22stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma"] # Nucleo 22stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma"] # Nucleo
23stm32f767zi = ["embassy-stm32/stm32f767zi", "not-gpdma", "eth"] # Nucleo 23stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth"] # Nucleo
24stm32f207zg = ["embassy-stm32/stm32f207zg", "not-gpdma", "eth"] # Nucleo 24stm32f207zg = ["embassy-stm32/stm32f207zg", "chrono", "not-gpdma", "eth"] # Nucleo
25stm32f303ze = ["embassy-stm32/stm32f303ze", "not-gpdma"] # Nucleo 25stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] # Nucleo
26stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma"] # Nucleo 26stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma"] # Nucleo
27 27
28eth = [] 28eth = []
diff --git a/tests/stm32/src/bin/rtc.rs b/tests/stm32/src/bin/rtc.rs
index 1f0d630c9..46fdbfaeb 100644
--- a/tests/stm32/src/bin/rtc.rs
+++ b/tests/stm32/src/bin/rtc.rs
@@ -10,26 +10,14 @@ use chrono::{NaiveDate, NaiveDateTime};
10use common::*; 10use common::*;
11use defmt::assert; 11use defmt::assert;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_stm32::rcc::RtcClockSource; 13use embassy_stm32::rcc::LsConfig;
14use embassy_stm32::rtc::{Rtc, RtcConfig}; 14use embassy_stm32::rtc::{Rtc, RtcConfig};
15use embassy_time::{Duration, Timer}; 15use embassy_time::{Duration, Timer};
16 16
17#[embassy_executor::main] 17#[embassy_executor::main]
18async fn main(_spawner: Spawner) { 18async fn main(_spawner: Spawner) {
19 let mut config = config(); 19 let mut config = config();
20 20 config.rcc.ls = LsConfig::default_lse();
21 #[cfg(feature = "stm32h755zi")]
22 {
23 use embassy_stm32::rcc::Lse;
24 config.rcc.lse = Some(Lse::Oscillator);
25 config.rcc.rtc_mux = Some(RtcClockSource::LSE);
26 }
27 #[cfg(not(feature = "stm32h755zi"))]
28 {
29 use embassy_stm32::time::Hertz;
30 config.rcc.lse = Some(Hertz(32_768));
31 config.rcc.rtc = Some(RtcClockSource::LSE);
32 }
33 21
34 let p = embassy_stm32::init(config); 22 let p = embassy_stm32::init(config);
35 info!("Hello World!"); 23 info!("Hello World!");
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs
index 55c4aa900..929869bc9 100644
--- a/tests/stm32/src/bin/stop.rs
+++ b/tests/stm32/src/bin/stop.rs
@@ -11,9 +11,8 @@ use common::*;
11use cortex_m_rt::entry; 11use cortex_m_rt::entry;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_stm32::low_power::{stop_with_rtc, Executor}; 13use embassy_stm32::low_power::{stop_with_rtc, Executor};
14use embassy_stm32::rcc::RtcClockSource; 14use embassy_stm32::rcc::LsConfig;
15use embassy_stm32::rtc::{Rtc, RtcConfig}; 15use embassy_stm32::rtc::{Rtc, RtcConfig};
16use embassy_stm32::time::Hertz;
17use embassy_stm32::Config; 16use embassy_stm32::Config;
18use embassy_time::{Duration, Timer}; 17use embassy_time::{Duration, Timer};
19use static_cell::make_static; 18use static_cell::make_static;
@@ -49,9 +48,7 @@ async fn async_main(spawner: Spawner) {
49 let _ = config(); 48 let _ = config();
50 49
51 let mut config = Config::default(); 50 let mut config = Config::default();
52 51 config.rcc.ls = LsConfig::default_lse();
53 config.rcc.lse = Some(Hertz(32_768));
54 config.rcc.rtc = Some(RtcClockSource::LSE);
55 52
56 let p = embassy_stm32::init(config); 53 let p = embassy_stm32::init(config);
57 info!("Hello World!"); 54 info!("Hello World!");