Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 11:13 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : CMM2 RTC falling behind during reset?

Author Message
Sasquatch

Guru

Joined: 08/05/2020
Location: United States
Posts: 377
Posted: 06:03pm 23 Aug 2020
Copy link to clipboard 
Print this post

Confessions of a time-nut   :

So, I have been comparing the CMM2 RTC to the PPS signal from a GPS receiver, I am noticing that the RTC "loses" some time during CPU restart.  The time lost is somewhat random but on the order of 100-1000 mSec per reset.  It doesn't seem to matter if the reset is from power-on, hardware reset or CPU RESTART command.

I haven't looked at the source-code yet to see if there is some initialization code that could be causing this, or it may be a "hardware feature" that a CPU reset somehow interrupts the RTC function?

Is this a known problem?  Or should I dig into it more to see if I can figure out what is happening?

For now just be aware that a power-on or reset will cause a slight offset in the RTC.

I have been using TassyJim's excellent program from this thread to trim my RTC:

https://www.thebackshed.com/forum/ViewTopic.php?TID=12228&PID=148185#148185

And here is the code I use to compare/sync the RTC to the GPS.  You will need a gps receiver with a "one Pulse Per Second" output to use either program:

' Expects GPS NMEA messages on COM1:
' PPS signal on Pin 38
' Press "Q" to quit or any other key to sync time


Setup:
 Mode 1,8
 Option Milliseconds ON
 Update = 0
 UTCOffset = -6
 PPSPin = 38

Start:
 CLS

 Open"com1:9600" as GPS, UTCOffset

 Pause 1000
 
 SetPin PPSPin,INTH,PPS

 Do
   K$ = Inkey$
   If K$ <> "" THEN Update = 1  'If key pressed update time
 Loop While (K$ <> "Q") And (K$ <> "q")

 SetPin PPSPin,OFF
 
 End


SUB PPS()
 'The PPS pulse is at the start of the new second BEFORE -
 '  the time is transmited in the NMEA messages -
 '  we need to add one second to the last time parsed by the -
 '  GPS functions
 Julian = Epoch(GPS(Date)+" "+GPS(Time))
 GPSTime$ = DateTime$(Julian + 1)  

 If Update Then
   Date$ = Left$(GPSTime$,10)
   Time$ = Right$(GPSTime$,8)  
   Update = 0
 EndIF

 Print "GPS = "; GpsTime$ , GPS(Satellites), "RTC = " Time$

End SUB

Edited 2020-08-24 04:04 by Sasquatch
-Carl
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 09:26pm 23 Aug 2020
Copy link to clipboard 
Print this post

Please try the attached and let me know if it improves things


CMM2V1.5.zip
 
Sasquatch

Guru

Joined: 08/05/2020
Location: United States
Posts: 377
Posted: 10:08pm 23 Aug 2020
Copy link to clipboard 
Print this post

Well, it's definitely different!  Now instead of losing time it's gaining with each reset.  It's highly variable though, after a few tests I am seeing a range of +100mSec to +800mSec.
-Carl
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 08:15am 24 Aug 2020
Copy link to clipboard 
Print this post

  Quote  Well, it's definitely different!  Now instead of losing time it's gaining with each reset.  It's highly variable though, after a few tests I am seeing a range of +100mSec to +800mSec.


It appears the subsecond register is being reset during power-up or resets. I think the best I can do is to set it to mid point. That way the time should be +/- 500msec randomly on each reset but average out over many to close to zero
 
Sasquatch

Guru

Joined: 08/05/2020
Location: United States
Posts: 377
Posted: 02:06pm 24 Aug 2020
Copy link to clipboard 
Print this post

  matherp said  
  Quote  Well, it's definitely different!  Now instead of losing time it's gaining with each reset.  It's highly variable though, after a few tests I am seeing a range of +100mSec to +800mSec.


It appears the subsecond register is being reset during power-up or resets. I think the best I can do is to set it to mid point. That way the time should be +/- 500msec randomly on each reset but average out over many to close to zero


This would help to prevent multiple seconds of error from accumulating over several resets.  As it is now, it just takes a few resets to offset the clock by several seconds.
-Carl
 
Sasquatch

Guru

Joined: 08/05/2020
Location: United States
Posts: 377
Posted: 05:42pm 24 Aug 2020
Copy link to clipboard 
Print this post

Ok, more info and an idea.  I have been digging through the data sheet and I have found some relevant information.  It appears that in order for the RTC pre-scalers to be updated, (including the Sub Second Register) the RTC hardware is placed into "initialization mode" this suspends the RTC operation and then restarts the prescalers and counters when the initialization mode is switched off.  This is all taken care of by the code supplied by ST for managing the RTC.

In the source code for CMM2 MMBasic it appears that main() is calling MX_RTC_INIT() twice.  Inside the MX_RTC_INIT() function, HAL_RTC_Init() is called to setup the RTC hardware before checking if the current date looks valid.  I think this is what is causing the RTC to be placed into "initialization mode" and the timing is suspended while the update takes place.

I would propose re-arranging the code in the MX_RTC_INIT() function such that HAL_RTC_Init() is only called after the check for a valid looking date and only if it looks like the RTC hardware has not already been initialized.

I would try this myself to test it, but I don't currently have the IDE setup and the source code that I have is way out of date.


For the curious, see the following sections in the ST RM0433 manual linked here:

https://www.st.com/resource/en/reference_manual/dm00314099-stm32h742-stm32h743753-and-stm32h750-value-line-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

46.6.4 RTC initialization and status register (RTC_ISR) Bit 7

46.6.5 RTC prescaler register (RTC_PRER)
Edited 2020-08-25 03:45 by Sasquatch
-Carl
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 06:31pm 24 Aug 2020
Copy link to clipboard 
Print this post

Doesn't work like that. If you don't call init you can't read the clock and calling it twice is benign as it caters for that in ST's code. The problem is that subseconds doesn't seem to have a valid value after init. It always reads 4095. My partial solution in b20 seems as good as I can get. Try the following over an extended period on b20

option autorun on
print time$
a=rnd()*6000
pause a
cpu restart
 
Sasquatch

Guru

Joined: 08/05/2020
Location: United States
Posts: 377
Posted: 06:50pm 24 Aug 2020
Copy link to clipboard 
Print this post

  matherp said  Doesn't work like that. If you don't call init you can't read the clock and calling it twice is benign as it caters for that in ST's code. The problem is that subseconds doesn't seem to have a valid value after init. It always reads 4095. My partial solution in b20 seems as good as I can get. Try the following over an extended period on b20

option autorun on
print time$
a=rnd()*6000
pause a
cpu restart



That makes sense!  There are some security bits that prevent RTC registers from being overwritten with garbage on reset.  

See section 46.3.8 RTC initialization and configuration.

I was hoping this would be handled by the read/write functions, but maybe not?  

I will dig a little deeper to see if I can find the functions to enable read/write of the registers without disturbing the Sub Second Register (SSR) which is actually one of the RTC pre-scalers.  We just need to find the function() to enable access to the RTC registers without placing the RTC hardware into "initialization mode" which suspends/clears the timing in the SSR pre-scaler.  



I'll keep digging, why would they make an RTC that must be cleared before it can be read under normal operation?  I think we are getting close!
-Carl
 
Sasquatch

Guru

Joined: 08/05/2020
Location: United States
Posts: 377
Posted: 03:13pm 26 Aug 2020
Copy link to clipboard 
Print this post

Ok,

V5.05.05b20 does exactly as you say.  The RTC timing offsets on reset are within about +/- 1 second with little or no accumulation over multiple reset cycles.


I finally got some time to install the IDE and do some testing.  I have tested this code through many CPU RESTART, Hardware Reset and Power On/Off cycles as well as multiple "backup domain reset" (battery removal) cycles.  It seems solid. The RTC timing offset for CPU RESTART and Hardware reset is near zero.  Cycling the power seems to still introduce a small offset of about -2mSec.  This may be a hardware limitation, but I haven't completely given up on finding a solution.

Here is the tested version of the MX_RTC_Init() function.  You should be able to copy/paste this into main.c assuming there have been no other changes to the MX_RTC_Init function since 5.05.04 release source code.  If you do implement this code, don't forget to back out the other fix from b20.


Edit: Sorry I managed to get the wrong version of the file uploaded here is the correct file:


MX_RTC_Init.zip
Edited 2020-08-27 01:45 by Sasquatch
-Carl
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025