![]() |
Forum Index : Microcontroller and PC projects : CMM2 RTC falling behind during reset?
Author | Message | ||||
Sasquatch![]() Guru ![]() Joined: 08/05/2020 Location: United StatesPosts: 377 |
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 KingdomPosts: 10310 |
Please try the attached and let me know if it improves things CMM2V1.5.zip |
||||
Sasquatch![]() Guru ![]() Joined: 08/05/2020 Location: United StatesPosts: 377 |
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 KingdomPosts: 10310 |
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 StatesPosts: 377 |
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 StatesPosts: 377 |
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 KingdomPosts: 10310 |
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 StatesPosts: 377 |
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 StatesPosts: 377 |
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 |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |