cancel
Showing results for 
Search instead for 
Did you mean: 

RTC calibration (STM32L011G4)

A L
Associate II
Posted on April 11, 2018 at 22:27

Hi there! - After looking around for quite a while, I'm still not exactly sure how to calibrate the RTC on my STM32L011G4 board. - For our project, we are using an external LSE crystal (768 kHz) for the RTC. - Do I need to use the RTC_SmoothCalib method (example for other MCU types), or is there another way to adjust the RTC accuracy? I have an accurate 1s clock source from a GPS module hooked up and counting rising edges with EXTI interrupt... That works nicely. But how could the number of LSE clock ticks happening between the external 1s pulses be counted to adjust the calibration registers? (RTC_CALR)There are only 2 timers, and no 32-bit one on the STM32L.. - Any help / hints would be appreciated. I'm simply overwhelmed by all the cryptic options described in the docs...

#rtc #rtc-calibration #lse #calibration #stm32l011g4 #stm32l0x1

Note: this post was migrated and contained many threaded conversations, some content may be missing.
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on April 12, 2018 at 01:19

It wouldn't work, as the lse is too coarse. Each count is 30ppm and you have to count sub cycle for this approach to be useful.

However you are almost on the right path: consider two clocks, one is slow : 1pps from the GPS, or 1pps from the rtc. And another high speed clock. The high speed clock doesn't need to be terribly accurate - it just need to be stable over the measurement period.

Write a code that counts the high speed clock being gated by the slow clock. 

First run the code using the 1pps from the GPS, write down the counts.

Then run the code using the 1pps from the rtc. Write down the counts .

The difference between the two counts, over the high speed clocks frequency, is the ppm error rate of the rtc.

Best of luck to your project.

View solution in original post

20 REPLIES 20
henry.dick
Senior II
Posted on April 11, 2018 at 23:12

Don't worry about how to implement the calibration. Instead, focus on the logic of your calibration. You have two oscillators, one with a known frequency (1pps from the GPS), and another unknown (the lse).

From that, how do you detect the frequency of the lse?

Posted on April 12, 2018 at 00:07

Thank you for the help! This is exactly what I'm struggling with... Somehow there must be a way to count the LSE clock ticks between the 1 second pulses from GPS module (1 pps). I'm trying to find a way to configure one of the timers (TIM2), so that it measures the number of LSE ticks instead of system clock ticks (with prescaler...). Is there a way to set up the internal MUX to let a timer have the LSE as a clock source?

Also, there's a quite suspicious option in STM32CubeMX I've discovered right before in the RTC panel (Pinout screen), to activate the calibration *output* of 1 Hz. I guess, this is to check the accuracy of the RTC after calibration on an external frequency counter... - But there's also an option called 'Reference clock detection'... hm... I'm still a bit lost there...

Posted on April 12, 2018 at 00:19

Or does it even make sense to use an RTC alarm interrupt to measure the difference between the external 1 pps signal and the seconds counted by the RTC (by the external crystal), e.g. by using the SubSeconds HAL's RTC_TimeTypeDef retrieved by a HAL_RTC_GetTime() call? (Yes, I'm only using HAL functions so far no low-level register access yet). Not sure if this would be accurate enough... Also, the time to wait until the difference would be large/significant enough, would be quite long I think...

Posted on April 12, 2018 at 00:40

Select LSE as the clock source for LPTIM, read LPTIM_CNT in EXTI

Select LSE as the clock source for TIM21/22 and use the 1PPS to perform an Input Capture and interrupt subtract the last CCRx latched reading from the current.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 12, 2018 at 01:19

It wouldn't work, as the lse is too coarse. Each count is 30ppm and you have to count sub cycle for this approach to be useful.

However you are almost on the right path: consider two clocks, one is slow : 1pps from the GPS, or 1pps from the rtc. And another high speed clock. The high speed clock doesn't need to be terribly accurate - it just need to be stable over the measurement period.

Write a code that counts the high speed clock being gated by the slow clock. 

First run the code using the 1pps from the GPS, write down the counts.

Then run the code using the 1pps from the rtc. Write down the counts .

The difference between the two counts, over the high speed clocks frequency, is the ppm error rate of the rtc.

Best of luck to your project.

Posted on April 12, 2018 at 02:08

Wonderful! This is exactly what I was trying to figure out

:)

Thanks a lot Clive One!

This is really basic stuff, I'm aware of that... but I'm learning... Please correct me if I'm wrong with the assumptions below...

If I'm understanding correctly, there are two ways of measuring the LSE clock ticks between each 1 PPS on the STM32L011G4: LPTIM1 (internal clock events) *or* TIM21 (Input Capture):

For everybody trying to replicate this in STMCubeMX and with pure HAL code:

---

For LPTIM1:

STM32CubeMX:

- Go to the Pinout screen, activate LPTIM1, Mode 'Counts internal clock events'.

- Go to the Clock Configuration screen, select LSE in the LPTIM Source Mux.

Use this to start the counter in main():

HAL_LPTIM_TimeOut_Start(&hlptim1, 0xFFFF, 0xFFFF);

//HAL_LPTIM_Counter_Start(&hlptim1, 0xFFFF); // not this, counter will overflow

Then, use this to read out the counter register in the EXTI routine, triggering on the rising edge of the 1 PPS signal; and restart the counter:

static __IO uint32_t rtc_calib_lse_capture = 0;

/* (...) */

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

   if (GPIO_Pin == RTC_CALIB_Pin) {

    rtc_calib_lse_capture = HAL_LPTIM_ReadCounter(&hlptim1);

    HAL_LPTIM_TimeOut_Start(&hlptim1, 0xFFFF, 0xFFFF);

  }

}

Now, the rtc_calib_lse_capture variable should always contain the exact number of LSE clock ticks measured between each 1 PPS. To see how much it deviates over time, it can be accumulated and averaged, I guess, to calibrate the RTC with HAL_RTCEx_SetSmoothCalib() later on...

edit: Yes, rtc_calib_lse_capture actually contains the expected number in my case. It is stable and changes only between 32768 and 32767.

---

For TIM21:

- Go to the Pinout screen, activcate TIM21, Clock Source 'Internal Clock', Channel 1 (or 2)  in 'Input Capture direct mode'.

- Go to the Clock Configuration screen, select LSE in the MCO Source Mux.

...

Code:

/* todo */

Posted on April 12, 2018 at 02:30

Thanks a lot dhenry! This is of great help.

(The longer reply below was written before this answer.)

dhenry wrote:

It wouldn't work, as the lse is too coarse. Each count is 30ppm and you have to count sub cycle for this approach to be useful.

Yes, this actually is an issue.

To use the LSE alone, actually does not lead to useful/accurate results. - Since I don't have a HSE (external crystal for system clock), I will try to use the internal MSI (2 MHz in my case) to do what you've described above, tomorrow. More results will follow... It's actually an interesting problem.

(edit: to keep in mind: the STM32L011G4 does not come with a 32-bit timer... so it will probably more complicated to solve this than usual...)

Posted on April 12, 2018 at 02:52

Not against a low clock source. However, if you have a high speed external clock, for example 10Mhz output from the GPS, you are in business - the basic concept applies.

Posted on April 12, 2018 at 02:54

It should work - the phase noise aggravated over a long period of time should be almost nil.