Skip to content

Instantly share code, notes, and snippets.

@esynr3z
Last active February 5, 2024 13:50
Show Gist options
  • Save esynr3z/8284f6dc10feab1e00609f26e42b974c to your computer and use it in GitHub Desktop.
Save esynr3z/8284f6dc10feab1e00609f26e42b974c to your computer and use it in GitHub Desktop.
STM32 RTC calibration calculator
#!/usr/bin/env python3
'''
Script to calculate STM32F0x RTC calibration values based on a measured time variation.
All references to STM32 RM0091: 25.4.12 RTC smooth digital calibration
'''
from datetime import datetime
# set rtc ideal freq
rtc_ref_freq = 32768
# set datetime when was last RTC sync
last_sync_dt = datetime(2019, 10, 8, 22, 36, 00)
# set reference datetime when RTC was checked
check_ref_dt = datetime(2019, 11, 13, 20, 41, 18)
# set RTC datetime when it was checked
check_rtc_dt = datetime(2019, 11, 13, 20, 40, 00)
# calculate all things
check_total_s = (check_ref_dt - last_sync_dt).total_seconds()
rtc_err_s = (check_rtc_dt - check_ref_dt).total_seconds()
rtc_err_ppm = 1E6 * rtc_err_s / check_total_s
rtc_real_freq = rtc_ref_freq + rtc_ref_freq * rtc_err_ppm * 1e-6
calp = 1 if rtc_err_ppm < 0 else 0
calm = calp * 512 - ((2**20) * (rtc_ref_freq - rtc_real_freq) + calp * 512 * (rtc_real_freq - rtc_ref_freq)) / (rtc_ref_freq)
rtc_calib_freq = rtc_real_freq * (1 + ((calp * 512 - calm)/((2 ** 20) + calm - calp * 512)))
# print results
print("Last RTC sync before check was %d seconds ago" % check_total_s)
print("RTC is %s for %d seconds" % ('slow' if rtc_err_s < 0 else 'fast', rtc_err_s))
print("RTC frequency error is %d ppm" % rtc_err_ppm)
print("RTC real frequency is %f Hz" % rtc_real_freq)
print("Calculated value for RTC_CALR.CALP = %d" % calp)
print("Calculated value for RTC_CALR.CALM = %d" % calm)
print("RTC calibrated frequency will be %f Hz" % rtc_calib_freq)
@mustafaabdullahk
Copy link

thank you for sharing

Zephyr RTC Calibration

Zephyr rtc interface has got a set/get calibration apis and that apis take PPB(part per billion) value. Zephyr developer can add following line:

rtc_err_ppb = 1E9 * rtc_err_s / check_total_s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment