K65 Real Time clock (RTC) is off by 2 minutes each day.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

K65 Real Time clock (RTC) is off by 2 minutes each day.

1,537 Views
MattJCole
Contributor V

 

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

 

 

 

 

0 Kudos
8 Replies

1,477 Views
MattJCole
Contributor V

Is it better to use a separate real time clock chip then to use the real time clock provided.  

0 Kudos

1,460 Views
mjbcswitzerland
Specialist V

I would use the internal one unless there is some very special reason for using an external one (like extremely low current consumption).

Also the external ones may need to be tuned....

Regards

Mark

0 Kudos

1,487 Views
MattJCole
Contributor V

How do you find the big offset?

0 Kudos

1,485 Views
mjbcswitzerland
Specialist V

You have found the big offset - 2 minutes in a day. It should be at least < 0.8s a day before it is worth looking at temperature compensation too.

Note that the problem with temperature compensation is that it doesn't work when the RTC is running from a battery backup. It only works when the system is active (the processor is checking the temperature and performing any 'temporary' compensation). If the product is left on the shelf for a month with the RTC running from a battery and the processor is otherwise off and the temperature is either very high or very low there will be additional drift when the product is turned on the next time that has accumulated.

Regards

Mark

 

0 Kudos

1,501 Views
MattJCole
Contributor V

I thought there was a way to calculate what you need to compensate based on temperature? Is that correct or am I wrong? If I am correct do you know how to do that? 

0 Kudos

1,494 Views
mjbcswitzerland
Specialist V

Hi

RTC Crystals are designed to be pretty stable with temperatures between the 20..30°C range. Outside of this range they tend to slow down and the frequency deviation can be expressed by
Delta F / F = 0.04ppm x (Delta T x Delta T)

If you can measure the local temperature to calculate the delta from 25°C you can also compensate for shifts due to temperature. Search the Internet to find a plethora of articles on doing in.

But first you need to solve your big offset before fine tuning to compensate small drifts due to temperature could become relevant.

Regards

Mark

0 Kudos

1,528 Views
MattJCole
Contributor V

Is there a way to read what frequency EXTAL32 is receiving. the reason I am asking I have seen formulas that use the actual RTC clock frequency and the expected RTC clock frequency. 

0 Kudos

1,507 Views
mjbcswitzerland
Specialist V

Hi

32kHz crystal based RTCs are typically accurate to around 5 minutes a year (< 1s/day) but this requires that the crystal used is matched to the circuit. The rtcOscConfig settings you are using are with no loading capacitors selected so if your RTC is running fast you can first load it more to try to correct its frequency.

In addition the RTC contains a variable pre-scaler which allows compensation for errors between 0.12 ppm and 3906 ppm.

Using these two methods it should be possible to 'tune' the circuit and the RTC to achieve acceptable accuracy. In case different batches of crystal/boards require slight adjustments the settings can be taken from parameters (in Flash) that you can adjust for each batch.

I use a spectrum analyser (with high impedance probe close to the circuitry it picks up the 32kHz signal and measures it with high accuracy without loading the circuit and thus potentially introducing measurement errors) in order to optimise the circuit frequency.

Alternatively you can do tests over a few days with different capacitor settings to see which ones give the best performance. Finally you can calculate the remaining error and compensate it with the pre-scaler.

Generally what I do when I receive new batches of HW is I take two of them and immediately program them up and let them run for a couple of days. If they remain accurate to < 0.8s a day they meet the <5 minutes a year (generally expected) accuracy. Should they ever not it would mean a batch of crystals have been used that have a deviation and then a fix could be made.

Regards

Mark

 

P.S. If your K65 is otherwise running fro a high accuracy crystal/oscillator (these are often more accurate that the 32kHz ones) you can use it to measure a period of RTC operation to detect the deviation and then automatically adjust it by setting the pre-scaler compensation.