@@ -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 ) ;
@@ -43,6 +44,7 @@ pub enum RestoredOrNewRtc<CS> {
43
44
*/
44
45
pub struct Rtc < CS = RtcClkLse > {
45
46
regs : RTC ,
47
+ frequency : Hertz ,
46
48
_clock_source : PhantomData < CS > ,
47
49
}
48
50
@@ -63,22 +65,12 @@ impl Rtc<RtcClkLse> {
63
65
[`restore_or_new`](Rtc::<RtcClkLse>::restore_or_new) instead.
64
66
*/
65
67
pub fn new ( regs : RTC , bkp : & mut BackupDomain , rcc : & mut RCC ) -> Self {
66
- let mut result = Rtc {
67
- regs,
68
- _clock_source : PhantomData ,
69
- } ;
68
+ let mut result = Self :: init ( regs) ;
70
69
71
70
Self :: enable_rtc ( bkp, rcc) ;
72
71
73
72
// Set the prescaler to make it count up once every second.
74
- let prl = LSE_HERTZ . raw ( ) - 1 ;
75
- assert ! ( prl < 1 << 20 ) ;
76
- result. perform_write ( |s| {
77
- s. regs . prlh ( ) . write ( |w| unsafe { w. bits ( prl >> 16 ) } ) ;
78
- s. regs
79
- . prll ( )
80
- . write ( |w| unsafe { w. bits ( prl as u16 as u32 ) } ) ;
81
- } ) ;
73
+ result. select_frequency ( 1u32 . Hz ( ) ) ;
82
74
83
75
result
84
76
}
@@ -105,10 +97,15 @@ impl Rtc<RtcClkLse> {
105
97
if !Self :: is_enabled ( ) {
106
98
RestoredOrNewRtc :: New ( Rtc :: new ( regs, bkp, rcc) )
107
99
} else {
108
- RestoredOrNewRtc :: Restored ( Rtc {
109
- regs,
110
- _clock_source : PhantomData ,
111
- } )
100
+ RestoredOrNewRtc :: Restored ( Self :: init ( regs) )
101
+ }
102
+ }
103
+
104
+ fn init ( regs : RTC ) -> Self {
105
+ Self {
106
+ regs,
107
+ frequency : LSE_HERTZ ,
108
+ _clock_source : PhantomData ,
112
109
}
113
110
}
114
111
@@ -149,22 +146,12 @@ impl Rtc<RtcClkLsi> {
149
146
[`restore_or_new_lsi`](Rtc::<RtcClkLsi>::restore_or_new_lsi) instead.
150
147
*/
151
148
pub fn new_lsi ( regs : RTC , bkp : & mut BackupDomain ) -> Self {
152
- let mut result = Rtc {
153
- regs,
154
- _clock_source : PhantomData ,
155
- } ;
149
+ let mut result = Self :: init ( regs) ;
156
150
157
151
Self :: enable_rtc ( bkp) ;
158
152
159
153
// Set the prescaler to make it count up once every second.
160
- let prl = LSI_HERTZ . raw ( ) - 1 ;
161
- assert ! ( prl < 1 << 20 ) ;
162
- result. perform_write ( |s| {
163
- s. regs . prlh ( ) . write ( |w| unsafe { w. bits ( prl >> 16 ) } ) ;
164
- s. regs
165
- . prll ( )
166
- . write ( |w| unsafe { w. bits ( prl as u16 as u32 ) } ) ;
167
- } ) ;
154
+ result. select_frequency ( 1u32 . Hz ( ) ) ;
168
155
169
156
result
170
157
}
@@ -175,10 +162,15 @@ impl Rtc<RtcClkLsi> {
175
162
if !Rtc :: < RtcClkLsi > :: is_enabled ( ) {
176
163
RestoredOrNewRtc :: New ( Rtc :: new_lsi ( regs, bkp) )
177
164
} else {
178
- RestoredOrNewRtc :: Restored ( Rtc {
179
- regs,
180
- _clock_source : PhantomData ,
181
- } )
165
+ RestoredOrNewRtc :: Restored ( Self :: init ( regs) )
166
+ }
167
+ }
168
+
169
+ fn init ( regs : RTC ) -> Self {
170
+ Self {
171
+ regs,
172
+ frequency : LSI_HERTZ ,
173
+ _clock_source : PhantomData ,
182
174
}
183
175
}
184
176
@@ -224,22 +216,12 @@ impl Rtc<RtcClkHseDiv128> {
224
216
[`restore_or_new_hse`](Rtc::<RtcClkHseDiv128>::restore_or_new_hse) instead.
225
217
*/
226
218
pub fn new_hse ( regs : RTC , bkp : & mut BackupDomain , hse : Hertz ) -> Self {
227
- let mut result = Rtc {
228
- regs,
229
- _clock_source : PhantomData ,
230
- } ;
219
+ let mut result = Self :: init ( regs, hse) ;
231
220
232
221
Self :: enable_rtc ( bkp) ;
233
222
234
223
// Set the prescaler to make it count up once every second.
235
- let prl = hse. raw ( ) / 128 - 1 ;
236
- assert ! ( prl < 1 << 20 ) ;
237
- result. perform_write ( |s| {
238
- s. regs . prlh ( ) . write ( |w| unsafe { w. bits ( prl >> 16 ) } ) ;
239
- s. regs
240
- . prll ( )
241
- . write ( |w| unsafe { w. bits ( prl as u16 as u32 ) } ) ;
242
- } ) ;
224
+ result. select_frequency ( 1u32 . Hz ( ) ) ;
243
225
244
226
result
245
227
}
@@ -254,10 +236,15 @@ impl Rtc<RtcClkHseDiv128> {
254
236
if !Self :: is_enabled ( ) {
255
237
RestoredOrNewRtc :: New ( Rtc :: new_hse ( regs, bkp, hse) )
256
238
} else {
257
- RestoredOrNewRtc :: Restored ( Rtc {
258
- regs,
259
- _clock_source : PhantomData ,
260
- } )
239
+ RestoredOrNewRtc :: Restored ( Self :: init ( regs, hse) )
240
+ }
241
+ }
242
+
243
+ fn init ( regs : RTC , hse : Hertz ) -> Self {
244
+ Self {
245
+ regs,
246
+ frequency : hse / 128 ,
247
+ _clock_source : PhantomData ,
261
248
}
262
249
}
263
250
@@ -290,9 +277,10 @@ impl<CS> Rtc<CS> {
290
277
pub fn select_frequency ( & mut self , frequency : Hertz ) {
291
278
// The manual says that the zero value for the prescaler is not recommended, thus the
292
279
// minimum division factor is 2 (prescaler + 1)
293
- assert ! ( frequency <= LSE_HERTZ / 2 ) ;
280
+ assert ! ( frequency <= self . frequency / 2 ) ;
294
281
295
- let prescaler = LSE_HERTZ / frequency - 1 ;
282
+ let prescaler = self . frequency / frequency - 1 ;
283
+ assert ! ( prescaler < 1 << 20 ) ;
296
284
self . perform_write ( |s| {
297
285
s. regs . prlh ( ) . write ( |w| unsafe { w. bits ( prescaler >> 16 ) } ) ;
298
286
s. regs
0 commit comments