From 5df81de7afbf4e9f24413ba957f4a7cce89fa1e0 Mon Sep 17 00:00:00 2001 From: blmorris Date: Thu, 7 May 2015 13:18:52 -0400 Subject: [PATCH] sthmal/rtc.c: Add calibration() method to get/set RTC fine-tuning value. --- docs/library/pyb.RTC.rst | 16 ++++++++++++++++ stmhal/qstrdefsport.h | 1 + stmhal/rtc.c | 36 ++++++++++++++++++++++++++++++++++++ tests/pyb/rtc.py | 21 +++++++++++++++++++++ tests/pyb/rtc.py.exp | 9 +++++++++ 5 files changed, 83 insertions(+) diff --git a/docs/library/pyb.RTC.rst b/docs/library/pyb.RTC.rst index eeefa100c..cd4b28eab 100644 --- a/docs/library/pyb.RTC.rst +++ b/docs/library/pyb.RTC.rst @@ -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 diff --git a/stmhal/qstrdefsport.h b/stmhal/qstrdefsport.h index e2fd0bbaf..a8b52f346 100644 --- a/stmhal/qstrdefsport.h +++ b/stmhal/qstrdefsport.h @@ -122,6 +122,7 @@ Q(RTC) Q(info) Q(datetime) Q(wakeup) +Q(calibration) // for Pin class Q(Pin) diff --git a/stmhal/rtc.c b/stmhal/rtc.c index b4fa69e86..8b21c6ee5 100644 --- a/stmhal/rtc.c +++ b/stmhal/rtc.c @@ -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); diff --git a/tests/pyb/rtc.py b/tests/pyb/rtc.py index f2c96f160..001553ac3 100644 --- a/tests/pyb/rtc.py +++ b/tests/pyb/rtc.py @@ -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) diff --git a/tests/pyb/rtc.py.exp b/tests/pyb/rtc.py.exp index 43ea70d95..d8d5e0f0a 100644 --- a/tests/pyb/rtc.py.exp +++ b/tests/pyb/rtc.py.exp @@ -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