Skip to content

Commit bc65035

Browse files
committed
Add different WUCKSEL variants to Rtc Config
1 parent 630f957 commit bc65035

File tree

1 file changed

+50
-11
lines changed

1 file changed

+50
-11
lines changed

src/rtc.rs

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,29 @@ pub enum RtcClockSource {
5050
/// 11: HSE oscillator clock divided by 32 used as RTC clock
5151
HSE = 0b11,
5252
}
53+
54+
#[derive(Copy, Clone, Debug, PartialEq)]
55+
#[repr(u8)]
56+
pub enum RtcWakeupClockSource {
57+
/// RTC/16 clock is selected
58+
RtcClkDiv16 = 0b000,
59+
/// RTC/8 clock is selected
60+
RtcClkDiv8 = 0b001,
61+
/// RTC/4 clock is selected
62+
RtcClkDiv4 = 0b010,
63+
/// RTC/2 clock is selected
64+
RtcClkDiv2 = 0b011,
65+
/// ck_spre (usually 1 Hz) clock is selected. Handling of the 2 ** 16 bit is done if values
66+
/// larger than 2 ** 16 are passed to the timer start function.
67+
CkSpre = 0b100,
68+
}
69+
5370
#[derive(Copy, Clone, Debug, PartialEq)]
5471
pub struct RtcConfig {
5572
/// RTC clock source
5673
clock_config: RtcClockSource,
74+
/// Wakeup clock source
75+
wakeup_clock_config: RtcWakeupClockSource,
5776
/// Asynchronous prescaler factor
5877
/// This is the asynchronous division factor:
5978
/// ck_apre frequency = RTCCLK frequency/(PREDIV_A+1)
@@ -72,6 +91,7 @@ impl Default for RtcConfig {
7291
fn default() -> Self {
7392
RtcConfig {
7493
clock_config: RtcClockSource::LSI,
94+
wakeup_clock_config: RtcWakeupClockSource::CkSpre,
7595
async_prescaler: 127,
7696
sync_prescaler: 255,
7797
}
@@ -96,6 +116,12 @@ impl RtcConfig {
96116
self.sync_prescaler = prescaler;
97117
self
98118
}
119+
120+
/// Set the Clock Source for the Wakeup Timer
121+
pub fn wakeup_clock_config(mut self, cfg: RtcWakeupClockSource) -> Self {
122+
self.wakeup_clock_config = cfg;
123+
self
124+
}
99125
}
100126

101127
impl Rtc {
@@ -466,8 +492,10 @@ impl timer::CountDown for WakeupTimer<'_> {
466492

467493
/// Starts the wakeup timer
468494
///
469-
/// The `delay` argument specifies the timer delay in seconds. Up to 17 bits
495+
/// The `delay` argument specifies the timer delay. If the wakeup_clock_config is set to
496+
/// CkSpre, the value is in seconds and up to 17 bits
470497
/// of delay are supported, giving us a range of over 36 hours.
498+
/// Otherwise, the timeunit depends on the RTCCLK and the configured wakeup_clock_config value.
471499
///
472500
/// # Panics
473501
///
@@ -478,7 +506,24 @@ impl timer::CountDown for WakeupTimer<'_> {
478506
T: Into<Self::Time>,
479507
{
480508
let delay = delay.into();
481-
assert!(1 <= delay && delay <= 1 << 17);
509+
assert!(1 <= delay);
510+
511+
if self.rtc.rtc_config.wakeup_clock_config == RtcWakeupClockSource::CkSpre {
512+
assert!(delay <= 1 << 17);
513+
} else {
514+
assert!(delay <= 1 << 16);
515+
}
516+
517+
// Determine the value for the wucksel register
518+
let wucksel = self.rtc.rtc_config.wakeup_clock_config as u8;
519+
let wucksel = wucksel
520+
| if self.rtc.rtc_config.wakeup_clock_config == RtcWakeupClockSource::CkSpre
521+
&& delay & 0x1_00_00 != 0
522+
{
523+
0b010
524+
} else {
525+
0b000
526+
};
482527

483528
let delay = delay - 1;
484529

@@ -494,16 +539,10 @@ impl timer::CountDown for WakeupTimer<'_> {
494539
unsafe { w.wut().bits(delay as u16) });
495540

496541
rtc.cr.modify(|_, w| {
497-
if delay & 0x1_00_00 != 0 {
498-
unsafe {
499-
w.wucksel().bits(0b110);
500-
}
501-
} else {
502-
unsafe {
503-
w.wucksel().bits(0b100);
504-
}
542+
// Write WUCKSEL depending on value determined previously.
543+
unsafe {
544+
w.wucksel().bits(wucksel);
505545
}
506-
507546
// Enable wakeup timer
508547
w.wute().set_bit()
509548
});

0 commit comments

Comments
 (0)