Skip to content

Commit 5df81de

Browse files
blmorrisdpgeorge
authored andcommitted
sthmal/rtc.c: Add calibration() method to get/set RTC fine-tuning value.
1 parent a7c02c4 commit 5df81de

5 files changed

Lines changed: 83 additions & 0 deletions

File tree

docs/library/pyb.RTC.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,19 @@ Methods
5757
start up.
5858
- Bit 0x10000 is set if a power-on reset occurred.
5959
- Bit 0x20000 is set if an external reset occurred
60+
61+
.. method:: rtc.calibration(cal)
62+
63+
Get or set RTC calibration.
64+
65+
With no arguments, ``calibration()`` returns the current calibration
66+
value, which is an integer in the range [-511 : 512]. With one
67+
argument it sets the RTC calibration.
68+
69+
The RTC Smooth Calibration mechanism addjusts the RTC clock rate by
70+
adding or subtracting the given number of ticks from the 32768 Hz
71+
clock over a 32 second period (corresponding to 2^20 clock ticks.)
72+
Each tick added will speed up the clock by 1 part in 2^20, or 0.954
73+
ppm; likewise the RTC clock it slowed by negative values. The
74+
usable calibration range is:
75+
(-511 * 0.954) ~= -487.5 ppm up to (512 * 0.954) ~= 488.5 ppm

stmhal/qstrdefsport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ Q(RTC)
122122
Q(info)
123123
Q(datetime)
124124
Q(wakeup)
125+
Q(calibration)
125126

126127
// for Pin class
127128
Q(Pin)

stmhal/rtc.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,10 +496,46 @@ mp_obj_t pyb_rtc_wakeup(mp_uint_t n_args, const mp_obj_t *args) {
496496
}
497497
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_wakeup_obj, 2, 4, pyb_rtc_wakeup);
498498

499+
// calibration(None)
500+
// calibration(cal)
501+
// When an integer argument is provided, check that it falls in the range [-511 to 512]
502+
// and set the calibration value; otherwise return calibration value
503+
mp_obj_t pyb_rtc_calibration(mp_uint_t n_args, const mp_obj_t *args) {
504+
mp_int_t cal;
505+
if (n_args == 2) {
506+
cal = mp_obj_get_int(args[1]);
507+
mp_uint_t cal_p, cal_m;
508+
if (cal < -511 || cal > 512) {
509+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
510+
"calibration value out of range"));
511+
}
512+
if (cal > 0) {
513+
cal_p = RTC_SMOOTHCALIB_PLUSPULSES_SET;
514+
cal_m = 512 - cal;
515+
} else {
516+
cal_p = RTC_SMOOTHCALIB_PLUSPULSES_RESET;
517+
cal_m = -cal;
518+
}
519+
HAL_RTCEx_SetSmoothCalib(&RTCHandle, RTC_SMOOTHCALIB_PERIOD_32SEC, cal_p, cal_m);
520+
return mp_const_none;
521+
} else {
522+
// printf("CALR = 0x%x\n", (mp_uint_t) RTCHandle.Instance->CALR); // DEBUG
523+
// Test if CALP bit is set in CALR:
524+
if (RTCHandle.Instance->CALR & 0x8000) {
525+
cal = 512 - (RTCHandle.Instance->CALR & 0x1ff);
526+
} else {
527+
cal = -(RTCHandle.Instance->CALR & 0x1ff);
528+
}
529+
return mp_obj_new_int(cal);
530+
}
531+
}
532+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_calibration_obj, 1, 2, pyb_rtc_calibration);
533+
499534
STATIC const mp_map_elem_t pyb_rtc_locals_dict_table[] = {
500535
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&pyb_rtc_info_obj },
501536
{ MP_OBJ_NEW_QSTR(MP_QSTR_datetime), (mp_obj_t)&pyb_rtc_datetime_obj },
502537
{ MP_OBJ_NEW_QSTR(MP_QSTR_wakeup), (mp_obj_t)&pyb_rtc_wakeup_obj },
538+
{ MP_OBJ_NEW_QSTR(MP_QSTR_calibration), (mp_obj_t)&pyb_rtc_calibration_obj },
503539
};
504540
STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table);
505541

tests/pyb/rtc.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,24 @@ def set_and_print(datetime):
2828
set_and_print((2016, 12, 31, 7, 23, 59, 1, 0))
2929
set_and_print((2016, 12, 31, 7, 23, 59, 59, 0))
3030
set_and_print((2099, 12, 31, 7, 23, 59, 59, 0))
31+
32+
# check that calibration works correctly
33+
# save existing calibration value:
34+
cal_tmp = rtc.calibration()
35+
36+
def set_and_print_calib(cal):
37+
rtc.calibration(cal)
38+
print(rtc.calibration())
39+
40+
set_and_print_calib(512)
41+
set_and_print_calib(511)
42+
set_and_print_calib(345)
43+
set_and_print_calib(1)
44+
set_and_print_calib(0)
45+
set_and_print_calib(-1)
46+
set_and_print_calib(-123)
47+
set_and_print_calib(-510)
48+
set_and_print_calib(-511)
49+
50+
# restore existing calibration value
51+
rtc.calibration(cal_tmp)

tests/pyb/rtc.py.exp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,12 @@
1414
(2016, 12, 31, 7, 23, 59, 1)
1515
(2016, 12, 31, 7, 23, 59, 59)
1616
(2099, 12, 31, 7, 23, 59, 59)
17+
512
18+
511
19+
345
20+
1
21+
0
22+
-1
23+
-123
24+
-510
25+
-511

0 commit comments

Comments
 (0)