Browse Source

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

pull/1247/merge
blmorris 10 years ago
committed by Damien George
parent
commit
5df81de7af
  1. 16
      docs/library/pyb.RTC.rst
  2. 1
      stmhal/qstrdefsport.h
  3. 36
      stmhal/rtc.c
  4. 21
      tests/pyb/rtc.py
  5. 9
      tests/pyb/rtc.py.exp

16
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

1
stmhal/qstrdefsport.h

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

36
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);

21
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)

9
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

Loading…
Cancel
Save