sthmal/rtc.c: Add calibration() method to get/set RTC fine-tuning value.

pull/1247/merge
blmorris 2015-05-07 13:18:52 -04:00 zatwierdzone przez Damien George
rodzic a7c02c4538
commit 5df81de7af
5 zmienionych plików z 83 dodań i 0 usunięć

Wyświetl plik

@ -57,3 +57,19 @@ Methods
start up.
- Bit 0x10000 is set if a power-on reset occurred.
- Bit 0x20000 is set if an external reset occurred
.. method:: rtc.calibration(cal)
Get or set RTC calibration.
With no arguments, ``calibration()`` returns the current calibration
value, which is an integer in the range [-511 : 512]. With one
argument it sets the RTC calibration.
The RTC Smooth Calibration mechanism addjusts the RTC clock rate by
adding or subtracting the given number of ticks from the 32768 Hz
clock over a 32 second period (corresponding to 2^20 clock ticks.)
Each tick added will speed up the clock by 1 part in 2^20, or 0.954
ppm; likewise the RTC clock it slowed by negative values. The
usable calibration range is:
(-511 * 0.954) ~= -487.5 ppm up to (512 * 0.954) ~= 488.5 ppm

Wyświetl plik

@ -122,6 +122,7 @@ Q(RTC)
Q(info)
Q(datetime)
Q(wakeup)
Q(calibration)
// for Pin class
Q(Pin)

Wyświetl plik

@ -496,10 +496,46 @@ mp_obj_t pyb_rtc_wakeup(mp_uint_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_wakeup_obj, 2, 4, pyb_rtc_wakeup);
// calibration(None)
// calibration(cal)
// When an integer argument is provided, check that it falls in the range [-511 to 512]
// and set the calibration value; otherwise return calibration value
mp_obj_t pyb_rtc_calibration(mp_uint_t n_args, const mp_obj_t *args) {
mp_int_t cal;
if (n_args == 2) {
cal = mp_obj_get_int(args[1]);
mp_uint_t cal_p, cal_m;
if (cal < -511 || cal > 512) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"calibration value out of range"));
}
if (cal > 0) {
cal_p = RTC_SMOOTHCALIB_PLUSPULSES_SET;
cal_m = 512 - cal;
} else {
cal_p = RTC_SMOOTHCALIB_PLUSPULSES_RESET;
cal_m = -cal;
}
HAL_RTCEx_SetSmoothCalib(&RTCHandle, RTC_SMOOTHCALIB_PERIOD_32SEC, cal_p, cal_m);
return mp_const_none;
} else {
// printf("CALR = 0x%x\n", (mp_uint_t) RTCHandle.Instance->CALR); // DEBUG
// Test if CALP bit is set in CALR:
if (RTCHandle.Instance->CALR & 0x8000) {
cal = 512 - (RTCHandle.Instance->CALR & 0x1ff);
} else {
cal = -(RTCHandle.Instance->CALR & 0x1ff);
}
return mp_obj_new_int(cal);
}
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_calibration_obj, 1, 2, pyb_rtc_calibration);
STATIC const mp_map_elem_t pyb_rtc_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&pyb_rtc_info_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_datetime), (mp_obj_t)&pyb_rtc_datetime_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_wakeup), (mp_obj_t)&pyb_rtc_wakeup_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_calibration), (mp_obj_t)&pyb_rtc_calibration_obj },
};
STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table);

Wyświetl plik

@ -28,3 +28,24 @@ set_and_print((2016, 12, 31, 7, 23, 59, 0, 0))
set_and_print((2016, 12, 31, 7, 23, 59, 1, 0))
set_and_print((2016, 12, 31, 7, 23, 59, 59, 0))
set_and_print((2099, 12, 31, 7, 23, 59, 59, 0))
# check that calibration works correctly
# save existing calibration value:
cal_tmp = rtc.calibration()
def set_and_print_calib(cal):
rtc.calibration(cal)
print(rtc.calibration())
set_and_print_calib(512)
set_and_print_calib(511)
set_and_print_calib(345)
set_and_print_calib(1)
set_and_print_calib(0)
set_and_print_calib(-1)
set_and_print_calib(-123)
set_and_print_calib(-510)
set_and_print_calib(-511)
# restore existing calibration value
rtc.calibration(cal_tmp)

Wyświetl plik

@ -14,3 +14,12 @@
(2016, 12, 31, 7, 23, 59, 1)
(2016, 12, 31, 7, 23, 59, 59)
(2099, 12, 31, 7, 23, 59, 59)
512
511
345
1
0
-1
-123
-510
-511