2025-11-25 5:57 AM - edited 2025-11-25 6:10 AM
Hello,
I am working with an STM32L072 and trying to generate a 1Hz interrupt with as little time drift as possible. For this, I am using the RTC wakeup interrupt at 1Hz, with the LSE (32.768 kHz quartz, 10 ppm) as the clock source.
On several products, I observe a periodic time drift of about 4ms. The period and sign of the drift vary from one product to another, but the pattern is repeated consistently. The attached graph shows that the drift is periodic for each product, but with different periods.
To measure the interrupt timing, I set a flag in the interrupt handler that triggers a USB message to the computer. This explains the noise in the reception time, but not the 4ms discontinuities or their periodicity. The MCU remains in run mode during these tests. And there is no reset of the board.
The 4ms drift corresponds to approximately 0.0039978s, which is equal to 131 LSE ticks (131/32768). This seems significant and unexpected.
Initially, I suspected an issue with my RTC configuration, so I switched to a 1Hz low-power timer (LPTIM) also clocked by the LSE, but observed the same behavior. During testing, the temperature is constant and all products are powered simultaneously via USB, so I assume the power supply is stable.
I am looking for an explanation for this periodic discontinuity and a way to eliminate or reduce it in my 1Hz timer implementation.
void MX_RTC_Init(void)
{
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
/** Enable the WakeUp
*/
if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)
{
Error_Handler();
}
}Thank you in advance,
Best Regards,
Augustin
2025-11-25 7:29 AM
How are you calculating the y value of the points in your plot? Please be precise. Code helps. I'm a little confused why it has so much jitter, even without the 4ms discontinuities.
2025-11-25 7:55 AM
To caluclate time drift, in the RTC interrupt, I raise a flag that then triggers a USB HID report to the PC. The PC then calculates the reception time and the drift relative to the fixed time. This explains the jitter observed around zero in the time drift measurements that depends on ST application and PC processing latency.
To ensure that the issue is not coming from the USB application, I also tested a blank project that simply toggles an LED on the RTC interrupt across all four products. Visually, I observed a timing shift in the LED blinking that is of the same order of magnitude as the one i presented in the post
What concerns me are the discontinuities, which I believe are caused by a fixed shift in the RTC interrupt timing. This shift is constant and offsets all subsequent interrupts.
2025-11-25 8:16 AM
> The 4ms drift corresponds to approximately 0.0039978s, which is equal to 131 LSE ticks
I too don't quite understand what are you comparing to what, but maybe 128 LSE ticks, i.e. one tick of the asynchronous prescaler output, that would be 1/256=0.00390625 s. The largest deviation you show is around 50ppm, which is not unthinkable a deviation of an individual product from any reference you are using (even if you've said the crystal is nominally 10ppm). So maybe you try to use the subseconds from the RTC to find out that deviation, and as those granularity is said 1/256 seconds, that would explain the roughly 4ms jumps.
JW
2025-11-25 9:22 AM - edited 2025-11-25 9:24 AM
> To caluclate time drift, in the RTC interrupt, I raise a flag that then triggers a USB HID report to the PC. The PC then calculates the reception time and the drift relative to the fixed time.
Okay, so you're getting reports on the PC that are about 1s apart, but you see this changing by 4 ms. Let me guess, is the HID update rate set to 250 Hz somewhere? That would explain the granularity of the shift being in increments of 4 ms. Packets are not sent immediately whenever a report is made, but rather on a fixed schedule. Just the way USB works here.
I believe you're just seeing clock drift that is being quantized by the USB reply rate schedule.
Consider removing the PC from the equation here--you should see a regular interval with very little jitter. Logic analyzer and pin toggle would work. Clocks will drift, no way around that.
2025-11-26 4:21 AM
One more vote for "measurement setup".
I'd start with SysTick (1ms) for comparison with highest interrupt priority, RTC interrupt prio 2nd highest.
Take a snapshot of SysTick in each RTC interrupt, then compare.
To make it more precise, you could use a 20 µs timer (50k ticks / sec - the L07x only has 16 bit timers) and let that run to max (no interrupts!) and take snapshots.