Skip to content

Commit f006127

Browse files
authored
rtc: add calibration functionality
1 parent 89d1e6f commit f006127

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
## [Unreleased]
88
### Added
99
- Added `rcc::Lsco` to use the low-speed oscillator output.
10+
- Added `Rtc::calibrate_lp` to calibrate the RTC.
11+
- Added `Rtc::recalibration_pending`.
1012

1113
## [0.5.1] - 2022-05-14
1214
### Added

hal/src/rtc/mod.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub use alarm::{Alarm, AlarmDay};
66

77
use crate::{pac, rcc::lsi_hz};
88
use chrono::{Datelike, NaiveDate, NaiveDateTime, NaiveTime, Timelike};
9+
use core::cmp::min;
910
use pac::{
1011
rcc::{
1112
bdcr::RTCSEL_A,
@@ -356,6 +357,34 @@ impl Rtc {
356357
}
357358
}
358359

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+
359388
/// Calendar Date
360389
///
361390
/// Returns `None` if the calendar has not been initialized.

0 commit comments

Comments
 (0)