@@ -50,10 +50,29 @@ pub enum RtcClockSource {
50
50
/// 11: HSE oscillator clock divided by 32 used as RTC clock
51
51
HSE = 0b11 ,
52
52
}
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
+
53
70
#[ derive( Copy , Clone , Debug , PartialEq ) ]
54
71
pub struct RtcConfig {
55
72
/// RTC clock source
56
73
clock_config : RtcClockSource ,
74
+ /// Wakeup clock source
75
+ wakeup_clock_config : RtcWakeupClockSource ,
57
76
/// Asynchronous prescaler factor
58
77
/// This is the asynchronous division factor:
59
78
/// ck_apre frequency = RTCCLK frequency/(PREDIV_A+1)
@@ -72,6 +91,7 @@ impl Default for RtcConfig {
72
91
fn default ( ) -> Self {
73
92
RtcConfig {
74
93
clock_config : RtcClockSource :: LSI ,
94
+ wakeup_clock_config : RtcWakeupClockSource :: CkSpre ,
75
95
async_prescaler : 127 ,
76
96
sync_prescaler : 255 ,
77
97
}
@@ -96,6 +116,12 @@ impl RtcConfig {
96
116
self . sync_prescaler = prescaler;
97
117
self
98
118
}
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
+ }
99
125
}
100
126
101
127
impl Rtc {
@@ -466,8 +492,10 @@ impl timer::CountDown for WakeupTimer<'_> {
466
492
467
493
/// Starts the wakeup timer
468
494
///
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
470
497
/// 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.
471
499
///
472
500
/// # Panics
473
501
///
@@ -478,7 +506,24 @@ impl timer::CountDown for WakeupTimer<'_> {
478
506
T : Into < Self :: Time > ,
479
507
{
480
508
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
+ } ;
482
527
483
528
let delay = delay - 1 ;
484
529
@@ -494,16 +539,10 @@ impl timer::CountDown for WakeupTimer<'_> {
494
539
unsafe { w. wut ( ) . bits ( delay as u16 ) } ) ;
495
540
496
541
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) ;
505
545
}
506
-
507
546
// Enable wakeup timer
508
547
w. wute ( ) . set_bit ( )
509
548
} ) ;
0 commit comments