@@ -8,6 +8,7 @@ use crate::time::{Hertz, Hz};
8
8
9
9
use core:: convert:: Infallible ;
10
10
use core:: marker:: PhantomData ;
11
+ use fugit:: RateExtU32 ;
11
12
12
13
// The LSE runs at at 32 768 hertz unless an external clock is provided
13
14
const LSE_HERTZ : Hertz = Hz ( 32_768 ) ;
@@ -44,6 +45,7 @@ pub enum RestoredOrNewRtc<CS> {
44
45
45
46
pub struct Rtc < CS = RtcClkLse > {
46
47
regs : RTC ,
48
+ frequency : Hertz ,
47
49
_clock_source : PhantomData < CS > ,
48
50
}
49
51
@@ -64,20 +66,12 @@ impl Rtc<RtcClkLse> {
64
66
[`restore_or_new`](Rtc::<RtcClkLse>::restore_or_new) instead.
65
67
*/
66
68
pub fn new ( regs : RTC , bkp : & mut BackupDomain ) -> Self {
67
- let mut result = Rtc {
68
- regs,
69
- _clock_source : PhantomData ,
70
- } ;
69
+ let mut result = Self :: init ( regs) ;
71
70
72
71
Self :: enable_rtc ( bkp) ;
73
72
74
73
// Set the prescaler to make it count up once every second.
75
- let prl = LSE_HERTZ . raw ( ) - 1 ;
76
- assert ! ( prl < 1 << 20 ) ;
77
- result. perform_write ( |s| {
78
- s. regs . prlh . write ( |w| unsafe { w. bits ( prl >> 16 ) } ) ;
79
- s. regs . prll . write ( |w| unsafe { w. bits ( prl as u16 as u32 ) } ) ;
80
- } ) ;
74
+ result. select_frequency ( 1u32 . Hz ( ) ) ;
81
75
82
76
result
83
77
}
@@ -100,10 +94,15 @@ impl Rtc<RtcClkLse> {
100
94
if !Self :: is_enabled ( ) {
101
95
RestoredOrNewRtc :: New ( Rtc :: new ( regs, bkp) )
102
96
} else {
103
- RestoredOrNewRtc :: Restored ( Rtc {
104
- regs,
105
- _clock_source : PhantomData ,
106
- } )
97
+ RestoredOrNewRtc :: Restored ( Self :: init ( regs) )
98
+ }
99
+ }
100
+
101
+ fn init ( regs : RTC ) -> Self {
102
+ Self {
103
+ regs,
104
+ frequency : LSE_HERTZ ,
105
+ _clock_source : PhantomData ,
107
106
}
108
107
}
109
108
@@ -150,20 +149,12 @@ impl Rtc<RtcClkLsi> {
150
149
[`restore_or_new_lsi`](Rtc::<RtcClkLsi>::restore_or_new_lsi) instead.
151
150
*/
152
151
pub fn new_lsi ( regs : RTC , bkp : & mut BackupDomain ) -> Self {
153
- let mut result = Rtc {
154
- regs,
155
- _clock_source : PhantomData ,
156
- } ;
152
+ let mut result = Self :: init ( regs) ;
157
153
158
154
Self :: enable_rtc ( bkp) ;
159
155
160
156
// Set the prescaler to make it count up once every second.
161
- let prl = LSI_HERTZ . raw ( ) - 1 ;
162
- assert ! ( prl < 1 << 20 ) ;
163
- result. perform_write ( |s| {
164
- s. regs . prlh . write ( |w| unsafe { w. bits ( prl >> 16 ) } ) ;
165
- s. regs . prll . write ( |w| unsafe { w. bits ( prl as u16 as u32 ) } ) ;
166
- } ) ;
157
+ result. select_frequency ( 1u32 . Hz ( ) ) ;
167
158
168
159
result
169
160
}
@@ -174,10 +165,15 @@ impl Rtc<RtcClkLsi> {
174
165
if !Rtc :: < RtcClkLsi > :: is_enabled ( ) {
175
166
RestoredOrNewRtc :: New ( Rtc :: new_lsi ( regs, bkp) )
176
167
} else {
177
- RestoredOrNewRtc :: Restored ( Rtc {
178
- regs,
179
- _clock_source : PhantomData ,
180
- } )
168
+ RestoredOrNewRtc :: Restored ( Self :: init ( regs) )
169
+ }
170
+ }
171
+
172
+ fn init ( regs : RTC ) -> Self {
173
+ Self {
174
+ regs,
175
+ frequency : LSI_HERTZ ,
176
+ _clock_source : PhantomData ,
181
177
}
182
178
}
183
179
@@ -228,20 +224,12 @@ impl Rtc<RtcClkHseDiv128> {
228
224
[`restore_or_new_hse`](Rtc::<RtcClkHseDiv128>::restore_or_new_hse) instead.
229
225
*/
230
226
pub fn new_hse ( regs : RTC , bkp : & mut BackupDomain , hse : Hertz ) -> Self {
231
- let mut result = Rtc {
232
- regs,
233
- _clock_source : PhantomData ,
234
- } ;
227
+ let mut result = Self :: init ( regs, hse) ;
235
228
236
229
Self :: enable_rtc ( bkp) ;
237
230
238
231
// Set the prescaler to make it count up once every second.
239
- let prl = hse. raw ( ) / 128 - 1 ;
240
- assert ! ( prl < 1 << 20 ) ;
241
- result. perform_write ( |s| {
242
- s. regs . prlh . write ( |w| unsafe { w. bits ( prl >> 16 ) } ) ;
243
- s. regs . prll . write ( |w| unsafe { w. bits ( prl as u16 as u32 ) } ) ;
244
- } ) ;
232
+ result. select_frequency ( 1u32 . Hz ( ) ) ;
245
233
246
234
result
247
235
}
@@ -256,10 +244,15 @@ impl Rtc<RtcClkHseDiv128> {
256
244
if !Self :: is_enabled ( ) {
257
245
RestoredOrNewRtc :: New ( Rtc :: new_hse ( regs, bkp, hse) )
258
246
} else {
259
- RestoredOrNewRtc :: Restored ( Rtc {
260
- regs,
261
- _clock_source : PhantomData ,
262
- } )
247
+ RestoredOrNewRtc :: Restored ( Self :: init ( regs, hse) )
248
+ }
249
+ }
250
+
251
+ fn init ( regs : RTC , hse : Hertz ) -> Self {
252
+ Self {
253
+ regs,
254
+ frequency : hse / 128 ,
255
+ _clock_source : PhantomData ,
263
256
}
264
257
}
265
258
@@ -294,9 +287,10 @@ impl<CS> Rtc<CS> {
294
287
pub fn select_frequency ( & mut self , frequency : Hertz ) {
295
288
// The manual says that the zero value for the prescaler is not recommended, thus the
296
289
// minimum division factor is 2 (prescaler + 1)
297
- assert ! ( frequency <= LSE_HERTZ / 2 ) ;
290
+ assert ! ( frequency <= self . frequency / 2 ) ;
298
291
299
- let prescaler = LSE_HERTZ / frequency - 1 ;
292
+ let prescaler = self . frequency / frequency - 1 ;
293
+ assert ! ( prescaler < 1 << 20 ) ;
300
294
self . perform_write ( |s| {
301
295
s. regs . prlh . write ( |w| unsafe { w. bits ( prescaler >> 16 ) } ) ;
302
296
s. regs
0 commit comments