aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/rtc
diff options
context:
space:
mode:
authoreZio Pan <[email protected]>2024-04-27 21:37:58 +0800
committereZio Pan <[email protected]>2024-04-28 00:33:02 +0800
commitd9e59e8e42ea009e365bb893b91d81fe47fe927d (patch)
treec6aa9f34ef6cecc3e9bad121aea4f04d7258bdb8 /embassy-stm32/src/rtc
parent34074e6eb0741e084653b3ef71163393741f558b (diff)
low power for h5
Diffstat (limited to 'embassy-stm32/src/rtc')
-rw-r--r--embassy-stm32/src/rtc/datetime.rs4
-rw-r--r--embassy-stm32/src/rtc/mod.rs49
-rw-r--r--embassy-stm32/src/rtc/v3.rs36
3 files changed, 37 insertions, 52 deletions
diff --git a/embassy-stm32/src/rtc/datetime.rs b/embassy-stm32/src/rtc/datetime.rs
index bab8cf4a3..77d89293d 100644
--- a/embassy-stm32/src/rtc/datetime.rs
+++ b/embassy-stm32/src/rtc/datetime.rs
@@ -148,9 +148,9 @@ impl DateTime {
148 ) -> Result<Self, Error> { 148 ) -> Result<Self, Error> {
149 if year > 4095 { 149 if year > 4095 {
150 Err(Error::InvalidYear) 150 Err(Error::InvalidYear)
151 } else if month < 1 || month > 12 { 151 } else if !(1..=12).contains(&month) {
152 Err(Error::InvalidMonth) 152 Err(Error::InvalidMonth)
153 } else if day < 1 || day > 31 { 153 } else if !(1..=31).contains(&day) {
154 Err(Error::InvalidDay) 154 Err(Error::InvalidDay)
155 } else if hour > 23 { 155 } else if hour > 23 {
156 Err(Error::InvalidHour) 156 Err(Error::InvalidHour)
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index 00abe9356..b12a0db66 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -42,7 +42,7 @@ pub(crate) enum WakeupPrescaler {
42 Div16 = 16, 42 Div16 = 16,
43} 43}
44 44
45#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4, stm32l5, stm32g0))] 45#[cfg(any(stm32f4, stm32l0, stm32g4, stm32l5, stm32wb, stm32h5, stm32g0))]
46impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel { 46impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel {
47 fn from(val: WakeupPrescaler) -> Self { 47 fn from(val: WakeupPrescaler) -> Self {
48 use crate::pac::rtc::vals::Wucksel; 48 use crate::pac::rtc::vals::Wucksel;
@@ -56,7 +56,7 @@ impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel {
56 } 56 }
57} 57}
58 58
59#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4, stm32l5, stm32g0))] 59#[cfg(any(stm32f4, stm32l0, stm32g4, stm32l5, stm32wb, stm32h5, stm32g0))]
60impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler { 60impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler {
61 fn from(val: crate::pac::rtc::vals::Wucksel) -> Self { 61 fn from(val: crate::pac::rtc::vals::Wucksel) -> Self {
62 use crate::pac::rtc::vals::Wucksel; 62 use crate::pac::rtc::vals::Wucksel;
@@ -81,8 +81,7 @@ impl WakeupPrescaler {
81 WakeupPrescaler::Div16, 81 WakeupPrescaler::Div16,
82 ] 82 ]
83 .iter() 83 .iter()
84 .skip_while(|psc| **psc as u32 <= val) 84 .find(|psc| **psc as u32 > val)
85 .next()
86 .unwrap_or(&WakeupPrescaler::Div16) 85 .unwrap_or(&WakeupPrescaler::Div16)
87 } 86 }
88} 87}
@@ -159,7 +158,7 @@ impl RtcTimeProvider {
159 } 158 }
160 } 159 }
161 160
162 return Err(RtcError::ReadFailure); 161 Err(RtcError::ReadFailure)
163 } 162 }
164} 163}
165 164
@@ -190,7 +189,7 @@ impl Default for RtcConfig {
190} 189}
191 190
192/// Calibration cycle period. 191/// Calibration cycle period.
193#[derive(Copy, Clone, Debug, PartialEq)] 192#[derive(Default, Copy, Clone, Debug, PartialEq)]
194#[repr(u8)] 193#[repr(u8)]
195pub enum RtcCalibrationCyclePeriod { 194pub enum RtcCalibrationCyclePeriod {
196 /// 8-second calibration period 195 /// 8-second calibration period
@@ -198,15 +197,10 @@ pub enum RtcCalibrationCyclePeriod {
198 /// 16-second calibration period 197 /// 16-second calibration period
199 Seconds16, 198 Seconds16,
200 /// 32-second calibration period 199 /// 32-second calibration period
200 #[default]
201 Seconds32, 201 Seconds32,
202} 202}
203 203
204impl Default for RtcCalibrationCyclePeriod {
205 fn default() -> Self {
206 RtcCalibrationCyclePeriod::Seconds32
207 }
208}
209
210impl Rtc { 204impl Rtc {
211 /// Create a new RTC instance. 205 /// Create a new RTC instance.
212 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { 206 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
@@ -254,13 +248,13 @@ impl Rtc {
254 /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range. 248 /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range.
255 pub fn set_datetime(&mut self, t: DateTime) -> Result<(), RtcError> { 249 pub fn set_datetime(&mut self, t: DateTime) -> Result<(), RtcError> {
256 self.write(true, |rtc| { 250 self.write(true, |rtc| {
257 let (ht, hu) = byte_to_bcd2(t.hour() as u8); 251 let (ht, hu) = byte_to_bcd2(t.hour());
258 let (mnt, mnu) = byte_to_bcd2(t.minute() as u8); 252 let (mnt, mnu) = byte_to_bcd2(t.minute());
259 let (st, su) = byte_to_bcd2(t.second() as u8); 253 let (st, su) = byte_to_bcd2(t.second());
260 254
261 let (dt, du) = byte_to_bcd2(t.day() as u8); 255 let (dt, du) = byte_to_bcd2(t.day());
262 let (mt, mu) = byte_to_bcd2(t.month() as u8); 256 let (mt, mu) = byte_to_bcd2(t.month());
263 let yr = t.year() as u16; 257 let yr = t.year();
264 let yr_offset = (yr - 2000_u16) as u8; 258 let yr_offset = (yr - 2000_u16) as u8;
265 let (yt, yu) = byte_to_bcd2(yr_offset); 259 let (yt, yu) = byte_to_bcd2(yr_offset);
266 260
@@ -338,7 +332,7 @@ impl Rtc {
338 } 332 }
339 333
340 #[cfg(feature = "low-power")] 334 #[cfg(feature = "low-power")]
341 /// start the wakeup alarm and wtih a duration that is as close to but less than 335 /// start the wakeup alarm and with a duration that is as close to but less than
342 /// the requested duration, and record the instant the wakeup alarm was started 336 /// the requested duration, and record the instant the wakeup alarm was started
343 pub(crate) fn start_wakeup_alarm( 337 pub(crate) fn start_wakeup_alarm(
344 &self, 338 &self,
@@ -422,20 +416,15 @@ impl Rtc {
422 #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))] 416 #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))]
423 regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR)); 417 regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR));
424 418
425 #[cfg(all(stm32g0))] 419 // Check RM for EXTI and/or NVIC section, "Event event input mapping" or "EXTI interrupt/event mapping" or something similar,
426 crate::pac::EXTI 420 // there is a table for every "Event input" / "EXTI Line".
427 .rpr(0) 421 // If you find the EXTI line related to "RTC wakeup" marks as "Configurable" (not "Direct"),
428 .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); 422 // then write 1 to related field of Pending Register, to clean it's pending state.
429 #[cfg(all(not(stm32g0), not(stm32l5)))] 423 #[cfg(any(exti_v1, stm32h7, stm32wb))]
430 crate::pac::EXTI 424 crate::pac::EXTI
431 .pr(0) 425 .pr(0)
432 .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true)); 426 .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
433 427
434 #[cfg(stm32l5)]
435 crate::pac::EXTI
436 .fpr(0)
437 .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
438
439 <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend(); 428 <RTC as crate::rtc::SealedInstance>::WakeupInterrupt::unpend();
440 }); 429 });
441 } 430 }
@@ -465,7 +454,7 @@ pub(crate) fn byte_to_bcd2(byte: u8) -> (u8, u8) {
465 value -= 10; 454 value -= 10;
466 } 455 }
467 456
468 (bcd_high, ((bcd_high << 4) | value) as u8) 457 (bcd_high, ((bcd_high << 4) | value))
469} 458}
470 459
471pub(crate) fn bcd2_to_byte(bcd: (u8, u8)) -> u8 { 460pub(crate) fn bcd2_to_byte(bcd: (u8, u8)) -> u8 {
diff --git a/embassy-stm32/src/rtc/v3.rs b/embassy-stm32/src/rtc/v3.rs
index 8a78d16e1..e51e09e7c 100644
--- a/embassy-stm32/src/rtc/v3.rs
+++ b/embassy-stm32/src/rtc/v3.rs
@@ -50,7 +50,7 @@ impl super::Rtc {
50 clock_drift = Self::RTC_CALR_MAX_PPM; 50 clock_drift = Self::RTC_CALR_MAX_PPM;
51 } 51 }
52 52
53 clock_drift = clock_drift / Self::RTC_CALR_RESOLUTION_PPM; 53 clock_drift /= Self::RTC_CALR_RESOLUTION_PPM;
54 54
55 self.write(false, |rtc| { 55 self.write(false, |rtc| {
56 rtc.calr().write(|w| { 56 rtc.calr().write(|w| {
@@ -129,29 +129,25 @@ impl super::Rtc {
129impl SealedInstance for crate::peripherals::RTC { 129impl SealedInstance for crate::peripherals::RTC {
130 const BACKUP_REGISTER_COUNT: usize = 32; 130 const BACKUP_REGISTER_COUNT: usize = 32;
131 131
132 #[cfg(all(feature = "low-power", stm32g4))] 132 #[cfg(feature = "low-power")]
133 const EXTI_WAKEUP_LINE: usize = 20; 133 cfg_if::cfg_if!(
134 134 if #[cfg(stm32g4)] {
135 #[cfg(all(feature = "low-power", stm32g0))] 135 const EXTI_WAKEUP_LINE: usize = 20;
136 const EXTI_WAKEUP_LINE: usize = 19; 136 type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP;
137 137 } else if #[cfg(stm32g0)] {
138 #[cfg(all(feature = "low-power", stm32g0))] 138 const EXTI_WAKEUP_LINE: usize = 19;
139 type WakeupInterrupt = crate::interrupt::typelevel::RTC_TAMP; 139 type WakeupInterrupt = crate::interrupt::typelevel::RTC_TAMP;
140 140 } else if #[cfg(any(stm32l5, stm32h5))] {
141 #[cfg(all(feature = "low-power", stm32g4))] 141 const EXTI_WAKEUP_LINE: usize = 17;
142 type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP; 142 type WakeupInterrupt = crate::interrupt::typelevel::RTC;
143 143 }
144 #[cfg(all(feature = "low-power", stm32l5))] 144 );
145 const EXTI_WAKEUP_LINE: usize = 17;
146
147 #[cfg(all(feature = "low-power", stm32l5))]
148 type WakeupInterrupt = crate::interrupt::typelevel::RTC;
149 145
150 fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> { 146 fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> {
151 #[allow(clippy::if_same_then_else)] 147 #[allow(clippy::if_same_then_else)]
152 if register < Self::BACKUP_REGISTER_COUNT { 148 if register < Self::BACKUP_REGISTER_COUNT {
153 //Some(rtc.bkpr()[register].read().bits()) 149 //Some(rtc.bkpr()[register].read().bits())
154 None // RTC3 backup registers come from the TAMP peripe=heral, not RTC. Not() even in the L412 PAC 150 None // RTC3 backup registers come from the TAMP peripheral, not RTC. Not() even in the L412 PAC
155 } else { 151 } else {
156 None 152 None
157 } 153 }
@@ -159,7 +155,7 @@ impl SealedInstance for crate::peripherals::RTC {
159 155
160 fn write_backup_register(_rtc: &Rtc, register: usize, _value: u32) { 156 fn write_backup_register(_rtc: &Rtc, register: usize, _value: u32) {
161 if register < Self::BACKUP_REGISTER_COUNT { 157 if register < Self::BACKUP_REGISTER_COUNT {
162 // RTC3 backup registers come from the TAMP peripe=heral, not RTC. Not() even in the L412 PAC 158 // RTC3 backup registers come from the TAMP peripheral, not RTC. Not() even in the L412 PAC
163 //self.rtc.bkpr()[register].write(|w| w.bits(value)) 159 //self.rtc.bkpr()[register].write(|w| w.bits(value))
164 } 160 }
165 } 161 }