@@ -8,6 +8,7 @@ use crate::time::{Hertz, Hz};
88
99use core:: convert:: Infallible ;
1010use core:: marker:: PhantomData ;
11+ use fugit:: RateExtU32 ;
1112
1213// The LSE runs at at 32 768 hertz unless an external clock is provided
1314const LSE_HERTZ : Hertz = Hz ( 32_768 ) ;
@@ -43,6 +44,7 @@ pub enum RestoredOrNewRtc<CS> {
4344*/
4445pub struct Rtc < CS = RtcClkLse > {
4546 regs : RTC ,
47+ frequency : Hertz ,
4648 _clock_source : PhantomData < CS > ,
4749}
4850
@@ -63,22 +65,12 @@ impl Rtc<RtcClkLse> {
6365 [`restore_or_new`](Rtc::<RtcClkLse>::restore_or_new) instead.
6466 */
6567 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) ;
7069
7170 Self :: enable_rtc ( bkp, rcc) ;
7271
7372 // 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 ( ) ) ;
8274
8375 result
8476 }
@@ -105,10 +97,15 @@ impl Rtc<RtcClkLse> {
10597 if !Self :: is_enabled ( ) {
10698 RestoredOrNewRtc :: New ( Rtc :: new ( regs, bkp, rcc) )
10799 } 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 ,
112109 }
113110 }
114111
@@ -149,22 +146,12 @@ impl Rtc<RtcClkLsi> {
149146 [`restore_or_new_lsi`](Rtc::<RtcClkLsi>::restore_or_new_lsi) instead.
150147 */
151148 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) ;
156150
157151 Self :: enable_rtc ( bkp) ;
158152
159153 // 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 ( ) ) ;
168155
169156 result
170157 }
@@ -175,10 +162,15 @@ impl Rtc<RtcClkLsi> {
175162 if !Rtc :: < RtcClkLsi > :: is_enabled ( ) {
176163 RestoredOrNewRtc :: New ( Rtc :: new_lsi ( regs, bkp) )
177164 } 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 ,
182174 }
183175 }
184176
@@ -224,22 +216,12 @@ impl Rtc<RtcClkHseDiv128> {
224216 [`restore_or_new_hse`](Rtc::<RtcClkHseDiv128>::restore_or_new_hse) instead.
225217 */
226218 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) ;
231220
232221 Self :: enable_rtc ( bkp) ;
233222
234223 // 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 ( ) ) ;
243225
244226 result
245227 }
@@ -254,10 +236,15 @@ impl Rtc<RtcClkHseDiv128> {
254236 if !Self :: is_enabled ( ) {
255237 RestoredOrNewRtc :: New ( Rtc :: new_hse ( regs, bkp, hse) )
256238 } 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 ,
261248 }
262249 }
263250
@@ -290,9 +277,10 @@ impl<CS> Rtc<CS> {
290277 pub fn select_frequency ( & mut self , frequency : Hertz ) {
291278 // The manual says that the zero value for the prescaler is not recommended, thus the
292279 // minimum division factor is 2 (prescaler + 1)
293- assert ! ( frequency <= LSE_HERTZ / 2 ) ;
280+ assert ! ( frequency <= self . frequency / 2 ) ;
294281
295- let prescaler = LSE_HERTZ / frequency - 1 ;
282+ let prescaler = self . frequency / frequency - 1 ;
283+ assert ! ( prescaler < 1 << 20 ) ;
296284 self . perform_write ( |s| {
297285 s. regs . prlh ( ) . write ( |w| unsafe { w. bits ( prescaler >> 16 ) } ) ;
298286 s. regs
0 commit comments