@@ -6,6 +6,7 @@ pub use alarm::{Alarm, AlarmDay};
6
6
7
7
use crate :: { pac, rcc:: lsi_hz} ;
8
8
use chrono:: { Datelike , NaiveDate , NaiveDateTime , NaiveTime , Timelike } ;
9
+ use core:: cmp:: min;
9
10
use pac:: {
10
11
rcc:: {
11
12
bdcr:: RTCSEL_A ,
@@ -356,6 +357,34 @@ impl Rtc {
356
357
}
357
358
}
358
359
360
+ /// Calibrate the RTC using the low-power mode.
361
+ ///
362
+ /// This does not poll for completion, use [`recalibration_pending`] if you
363
+ /// need to wait for completion.
364
+ ///
365
+ /// The calibration argument is in units of 0.9537 ppm.
366
+ /// The calibration range is -487.1 ppm to +488.5 ppm (-511 to 512), values
367
+ /// outside of this range will saturate.
368
+ ///
369
+ /// [`recalibration_pending`]: Self::recalibration_pending
370
+ pub fn calibrate_lp ( & mut self , calibration : i16 ) {
371
+ while self . recalibration_pending ( ) { }
372
+ let ( calp, calm) : ( bool , u16 ) = if let Ok ( calibration_pos) = u16:: try_from ( calibration) {
373
+ ( true , 512_u16 . saturating_sub ( calibration_pos) )
374
+ } else {
375
+ ( false , min ( calibration. abs_diff ( 0 ) , 511 ) )
376
+ } ;
377
+ self . rtc
378
+ . calr
379
+ . write ( |w| w. calp ( ) . bit ( calp) . lpcal ( ) . set_bit ( ) . calm ( ) . bits ( calm) )
380
+ }
381
+
382
+ /// Returns `true` if recalibration is pending.
383
+ #[ inline]
384
+ pub fn recalibration_pending ( & self ) -> bool {
385
+ self . rtc . icsr . read ( ) . recalpf ( ) . is_pending ( )
386
+ }
387
+
359
388
/// Calendar Date
360
389
///
361
390
/// Returns `None` if the calendar has not been initialized.
0 commit comments