I am using the real time clock(RTC) on the K65 processor and by the end of the day the clock is off by 2 minutes. That is off by a very lot for what an accurate real time clock should be. I have heard of them being of by 4 minutes but it takes 31 days for the to happen not 24 hours. Is there a way to make the real time clock (RTC) accurate.
This is how I am configuring the Real time clock. Should I do anything different to make the real time clock accurate.
rtc_init();
initRtcOsc();//enable oscillator
RTC_HAL_EnableCounter(g_rtcBase[RTC_IDX], true);//enable (seconds) time counter
static void rtc_init()
{
rtc_datetime_t rtc_date;
//Enable clock gate to RTC module (so access to periph won't cause hardfault)
CLOCK_SYS_EnableRtcClock(0U);
RTC_HAL_Init(g_rtcBase[RTC_IDX]);
//get current year so we know if we need to contact NTP for actual time
RTC_HAL_GetDatetime(g_rtcBase[RTC_IDX],&rtc_date);
OPT_printf("%s: INFO current RTC datetime: %04hu/%02u/%02u, %02u:%02u:%02u\n",
__FUNCTION__,rtc_date.year,rtc_date.month,rtc_date.day,
rtc_date.hour,rtc_date.minute,rtc_date.second);
//note that we ignore milliseconds here (could retain current msec)
//if current RTC year is less than the year we wrote this, our RTC
//isn't set, we must be on a board that is just now being initialized
//we are trying to minimize the need to get time from ntp as it may not be
//available on a deployed device (meaning this happens at factory only)
if (rtc_date.year < 2017)
{
TIME_STRUCT ts;
//get time from network (SNTP sets the os time if it is successful)
uint32_t error_code = SNTP_oneshot(0x81060f1c/*129.6.15.28 time-a-g.nist.gov*/,15000ul);//see http://tf.nist.gov/tf-cgi/servers.cgi
if (error_code == RTCS_OK)
{
time_already_set = true;
_time_get(&ts);//SNTP sets the OS to time received
DATE_STRUCT sntp_date = {0};
_time_to_date(&ts,&sntp_date);
//set RTC seconds
RTC_HAL_SetDatetimeInsecs(g_rtcBase[RTC_IDX], ts.SECONDS);
RTC_HAL_ConvertSecsToDatetime(&ts.SECONDS, &rtc_date);
OPT_printf("%s: INFO NTP time stored in OS & RTC: %04u/%02u/%02u, %02u:%02u:%02u\n",
__FUNCTION__,rtc_date.year,rtc_date.month,rtc_date.day,
rtc_date.hour,rtc_date.minute,rtc_date.second);
}
else
{
OPT_printf("%s: FAIL SNTP_oneshot returned error 0x%04lx so RTC not set\n",__FUNCTION__,error_code);
//this means our RTC is not set. next bootup it will try again
//to do: do we need to do something to notify?
}
}
else
{
//rtc appears to be set so use that time to tell OS what time it is
//so all use of OS time results in using time from (battery backed) RTC
DATE_STRUCT date = {0};
TIME_STRUCT ts = {0};
date.HOUR = rtc_date.hour;
date.MINUTE = rtc_date.minute;
date.SECOND = rtc_date.second;
date.MONTH = rtc_date.month;
date.DAY = rtc_date.day;
date.YEAR = rtc_date.year;
_time_from_date(&date, &ts);
_time_set(&ts);
OPT_printf("%s: INFO RTC datetime sent to OS: %04u/%02u/%02u, %02u:%02u:%02u\n",
__FUNCTION__,rtc_date.year,rtc_date.month,rtc_date.day,
rtc_date.hour,rtc_date.minute,rtc_date.second);
}
rtc_initialized = true;
}
static void initRtcOsc(void)
{
rtc_osc_user_config_t rtcOscConfig =
{
.freq = 32768U,
.enableCapacitor2p = false,
.enableCapacitor4p = false,
.enableCapacitor8p = false,
.enableCapacitor16p = false,
.enableOsc = true,
};
CLOCK_SYS_RtcOscInit(0U, &rtcOscConfig);
}