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