aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/rcc/f4.rs1
-rw-r--r--embassy-stm32/src/rcc/mod.rs6
-rw-r--r--embassy-stm32/src/rcc/wb.rs1
-rw-r--r--embassy-stm32/src/rtc/mod.rs73
-rw-r--r--embassy-stm32/src/rtc/v2.rs8
-rw-r--r--embassy-stm32/src/rtc/v3.rs8
6 files changed, 45 insertions, 52 deletions
diff --git a/embassy-stm32/src/rcc/f4.rs b/embassy-stm32/src/rcc/f4.rs
index 10d3322aa..c2c78a45e 100644
--- a/embassy-stm32/src/rcc/f4.rs
+++ b/embassy-stm32/src/rcc/f4.rs
@@ -499,6 +499,7 @@ pub(crate) unsafe fn init(config: Config) {
499 pllsai: None, 499 pllsai: None,
500 500
501 rtc: rtc, 501 rtc: rtc,
502 rtc_hse: None,
502 }); 503 });
503} 504}
504 505
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 9f1b3b663..0430e4a74 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -78,8 +78,12 @@ pub struct Clocks {
78 pub adc: Option<Hertz>, 78 pub adc: Option<Hertz>,
79 79
80 #[cfg(any(rcc_wb, rcc_f4, rcc_f410))] 80 #[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
81 /// Set only if the lsi or lse is configured 81 /// Set only if the lsi or lse is configured, indicates stop is supported
82 pub rtc: Option<Hertz>, 82 pub rtc: Option<Hertz>,
83
84 #[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
85 /// Set if the hse is configured, indicates stop is not supported
86 pub rtc_hse: Option<Hertz>,
83} 87}
84 88
85#[cfg(feature = "low-power")] 89#[cfg(feature = "low-power")]
diff --git a/embassy-stm32/src/rcc/wb.rs b/embassy-stm32/src/rcc/wb.rs
index 6a3eab707..6496b41e1 100644
--- a/embassy-stm32/src/rcc/wb.rs
+++ b/embassy-stm32/src/rcc/wb.rs
@@ -271,6 +271,7 @@ pub(crate) fn compute_clocks(config: &Config) -> Clocks {
271 apb1_tim: apb1_tim_clk, 271 apb1_tim: apb1_tim_clk,
272 apb2_tim: apb2_tim_clk, 272 apb2_tim: apb2_tim_clk,
273 rtc: rtc_clk, 273 rtc: rtc_clk,
274 rtc_hse: None,
274 } 275 }
275} 276}
276 277
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 796fd7d96..9db4f69c5 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -12,6 +12,7 @@ use embassy_sync::blocking_mutex::Mutex;
12pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError}; 12pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError};
13use crate::rcc::bd::BackupDomain; 13use crate::rcc::bd::BackupDomain;
14pub use crate::rcc::RtcClockSource; 14pub use crate::rcc::RtcClockSource;
15use crate::time::Hertz;
15 16
16/// refer to AN4759 to compare features of RTC2 and RTC3 17/// refer to AN4759 to compare features of RTC2 and RTC3
17#[cfg_attr(any(rtc_v1), path = "v1.rs")] 18#[cfg_attr(any(rtc_v1), path = "v1.rs")]
@@ -84,47 +85,23 @@ impl core::ops::Sub for RtcInstant {
84 85
85/// RTC Abstraction 86/// RTC Abstraction
86pub struct Rtc { 87pub struct Rtc {
87 rtc_config: RtcConfig,
88 #[cfg(feature = "low-power")] 88 #[cfg(feature = "low-power")]
89 stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<RtcInstant>>>, 89 stop_time: Mutex<CriticalSectionRawMutex, Cell<Option<RtcInstant>>>,
90} 90}
91 91
92#[derive(Copy, Clone, PartialEq)] 92#[derive(Copy, Clone, PartialEq)]
93pub struct RtcConfig { 93pub struct RtcConfig {
94 /// Asynchronous prescaler factor 94 /// The subsecond counter frequency; default is 256
95 /// This is the asynchronous division factor: 95 ///
96 /// ck_apre frequency = RTCCLK frequency/(PREDIV_A+1) 96 /// A high counter frequency may impact stop power consumption
97 /// ck_apre drives the subsecond register 97 pub frequency: Hertz,
98 async_prescaler: u8,
99 /// Synchronous prescaler factor
100 /// This is the synchronous division factor:
101 /// ck_spre frequency = ck_apre frequency/(PREDIV_S+1)
102 /// ck_spre must be 1Hz
103 sync_prescaler: u16,
104} 98}
105 99
106impl Default for RtcConfig { 100impl Default for RtcConfig {
107 /// LSI with prescalers assuming 32.768 kHz. 101 /// LSI with prescalers assuming 32.768 kHz.
108 /// Raw sub-seconds in 1/256. 102 /// Raw sub-seconds in 1/256.
109 fn default() -> Self { 103 fn default() -> Self {
110 RtcConfig { 104 RtcConfig { frequency: Hertz(256) }
111 async_prescaler: 127,
112 sync_prescaler: 255,
113 }
114 }
115}
116
117impl RtcConfig {
118 /// Set the asynchronous prescaler of RTC config
119 pub fn async_prescaler(mut self, prescaler: u8) -> Self {
120 self.async_prescaler = prescaler;
121 self
122 }
123
124 /// Set the synchronous prescaler of RTC config
125 pub fn sync_prescaler(mut self, prescaler: u16) -> Self {
126 self.sync_prescaler = prescaler;
127 self
128 } 105 }
129} 106}
130 107
@@ -147,23 +124,37 @@ impl Default for RtcCalibrationCyclePeriod {
147 124
148impl Rtc { 125impl Rtc {
149 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { 126 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
150 RTC::enable_peripheral_clk(); 127 #[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
128 use crate::rcc::get_freqs;
151 129
152 #[cfg(not(feature = "low-power"))] 130 RTC::enable_peripheral_clk();
153 let mut rtc_struct = Self { rtc_config }; 131 BackupDomain::enable_rtc();
154 132
155 #[cfg(feature = "low-power")] 133 let mut this = Self {
156 let mut rtc_struct = Self { 134 #[cfg(feature = "low-power")]
157 rtc_config,
158 stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), 135 stop_time: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)),
159 }; 136 };
160 137
161 BackupDomain::enable_rtc(); 138 #[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
139 let freqs = unsafe { get_freqs() };
140
141 // Load the clock frequency from the rcc mod, if supported
142 #[cfg(any(rcc_wb, rcc_f4, rcc_f410))]
143 let frequency = match freqs.rtc {
144 Some(hertz) => hertz,
145 None => freqs.rtc_hse.unwrap(),
146 };
162 147
163 rtc_struct.configure(rtc_config); 148 // Assume the default value, if not supported
164 rtc_struct.rtc_config = rtc_config; 149 #[cfg(not(any(rcc_wb, rcc_f4, rcc_f410)))]
150 let frequency = Hertz(32_768);
165 151
166 rtc_struct 152 let async_psc = ((frequency.0 / rtc_config.frequency.0) - 1) as u8;
153 let sync_psc = (rtc_config.frequency.0 - 1) as u16;
154
155 this.configure(async_psc, sync_psc);
156
157 this
167 } 158 }
168 159
169 /// Set the datetime to a new value. 160 /// Set the datetime to a new value.
@@ -228,10 +219,6 @@ impl Rtc {
228 }) 219 })
229 } 220 }
230 221
231 pub fn get_config(&self) -> RtcConfig {
232 self.rtc_config
233 }
234
235 pub const BACKUP_REGISTER_COUNT: usize = RTC::BACKUP_REGISTER_COUNT; 222 pub const BACKUP_REGISTER_COUNT: usize = RTC::BACKUP_REGISTER_COUNT;
236 223
237 /// Read content of the backup register. 224 /// Read content of the backup register.
diff --git a/embassy-stm32/src/rtc/v2.rs b/embassy-stm32/src/rtc/v2.rs
index 49f66e957..482b6e75d 100644
--- a/embassy-stm32/src/rtc/v2.rs
+++ b/embassy-stm32/src/rtc/v2.rs
@@ -1,6 +1,6 @@
1use stm32_metapac::rtc::vals::{Init, Osel, Pol}; 1use stm32_metapac::rtc::vals::{Init, Osel, Pol};
2 2
3use super::{sealed, RtcConfig}; 3use super::sealed;
4use crate::pac::rtc::Rtc; 4use crate::pac::rtc::Rtc;
5use crate::peripherals::RTC; 5use crate::peripherals::RTC;
6use crate::rtc::sealed::Instance; 6use crate::rtc::sealed::Instance;
@@ -154,7 +154,7 @@ impl super::Rtc {
154 154
155 /// Applies the RTC config 155 /// Applies the RTC config
156 /// It this changes the RTC clock source the time will be reset 156 /// It this changes the RTC clock source the time will be reset
157 pub(super) fn configure(&mut self, rtc_config: RtcConfig) { 157 pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) {
158 self.write(true, |rtc| { 158 self.write(true, |rtc| {
159 rtc.cr().modify(|w| { 159 rtc.cr().modify(|w| {
160 #[cfg(rtc_v2f2)] 160 #[cfg(rtc_v2f2)]
@@ -166,8 +166,8 @@ impl super::Rtc {
166 }); 166 });
167 167
168 rtc.prer().modify(|w| { 168 rtc.prer().modify(|w| {
169 w.set_prediv_s(rtc_config.sync_prescaler); 169 w.set_prediv_s(sync_psc);
170 w.set_prediv_a(rtc_config.async_prescaler); 170 w.set_prediv_a(async_psc);
171 }); 171 });
172 }); 172 });
173 } 173 }
diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs
index 12952b15a..a6b2655d8 100644
--- a/embassy-stm32/src/rtc/v3.rs
+++ b/embassy-stm32/src/rtc/v3.rs
@@ -1,6 +1,6 @@
1use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Init, Key, Osel, Pol, TampalrmPu, TampalrmType}; 1use stm32_metapac::rtc::vals::{Calp, Calw16, Calw8, Fmt, Init, Key, Osel, Pol, TampalrmPu, TampalrmType};
2 2
3use super::{sealed, RtcCalibrationCyclePeriod, RtcConfig}; 3use super::{sealed, RtcCalibrationCyclePeriod};
4use crate::pac::rtc::Rtc; 4use crate::pac::rtc::Rtc;
5use crate::peripherals::RTC; 5use crate::peripherals::RTC;
6use crate::rtc::sealed::Instance; 6use crate::rtc::sealed::Instance;
@@ -8,7 +8,7 @@ use crate::rtc::sealed::Instance;
8impl super::Rtc { 8impl super::Rtc {
9 /// Applies the RTC config 9 /// Applies the RTC config
10 /// 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
11 pub(super) fn configure(&mut self, rtc_config: RtcConfig) { 11 pub(super) fn configure(&mut self, async_psc: u8, sync_psc: u16) {
12 self.write(true, |rtc| { 12 self.write(true, |rtc| {
13 rtc.cr().modify(|w| { 13 rtc.cr().modify(|w| {
14 w.set_fmt(Fmt::TWENTYFOURHOUR); 14 w.set_fmt(Fmt::TWENTYFOURHOUR);
@@ -17,8 +17,8 @@ impl super::Rtc {
17 }); 17 });
18 18
19 rtc.prer().modify(|w| { 19 rtc.prer().modify(|w| {
20 w.set_prediv_s(rtc_config.sync_prescaler); 20 w.set_prediv_s(sync_psc);
21 w.set_prediv_a(rtc_config.async_prescaler); 21 w.set_prediv_a(async_psc);
22 }); 22 });
23 23
24 // TODO: configuration for output pins 24 // TODO: configuration for output pins