Page 1 of 2

MOD54415 RTC Month Error

Posted: Wed Nov 12, 2014 12:35 am
by gavinm
This is such an obvious problem that it must have been fixed - but I can't find any posts about it in the forums. I'm using V2.6.7 of the Netburner tools.

I'm using the RTC in the processor of the MOD 54415. I have a battery connected to Vstandby to keep the RTC (and 2kRAM) powered when the main supply is off.
Software wise I'm using the system function MCF541X_RTCSetSystemFromRTCTime() to set the system time on power up and MCF541X_RTCSetTime(dateTime) to set the RTC date/time when the user uses a clock setting page in the web server interface.
In normal use with the power on, my software gets date / time information from the system time. The RTC is only accessed on power on to set the system time.
The problem that I notice is that if the unit is powered off over a month end, the next time it is switched on the date can be 1 day out (either ahead or behind). This is fairly obviously the RTC thinking the month transition that just occurred was a 30 day month when it was a 31 day month (which would cause the date to advance to the 1st of the next month when it should be the 31st of the previous month ie be one day ahead), or a 31 day month when it was a 30 day month (which would cause the date to not advance to the 1st of the next month until a day late ie be one day behind).

Looking at the RTC system code in C:\nburn\MOD5441X\system the problem seems pretty obvious just by looking at the comments and a quick read of the Freescale Ref Manual for the 54415.
The system code uses a dateTime structure of type tm. In the comments the month element of this is described as having values of 0 to 11

Code: Select all

 *    int tm_mon;     // Month of the year [January(0)-December(11)]
However, the Freescale manual specifies that the month byte should have values of 1 to 12 (Chap 37 section 37.4.1)
But in the code the system time 0 to 11 value seems to be directly applied to the RTC month byte

Code: Select all

WORD ym=(WORD)year|(WORD)bts.tm_mon;
...
sim2.rtc.yearmon = ym;
and read directly back

Code: Select all

ym =sim2.rtc.yearmon;
bts.tm_mon=(ym&0xff);          // Month of the year [January(0)-December(11)]
This would explain what I observe. On one of my systems the power was turned off before the end of October and yesterday (11th Nov) when I turned it on it reported the 12th Nov. The RTC would have been set with a month value 1 less than it should have been (9 for Oct using the 0 to 11 system, which using it's actual 1 to 12 system it interprets as September). So with the power off the RTC would change to the 1st of the next month on the 30th Oct (which it thinks is the 30th Sep) ie a day early. The opposite happened at the end of Sep (which the RTC would think was Aug) so with the power off it changed month a day late!

To correct this surely when setting the RTC 1 needs to be added to the month and when reading 1 needs to be subtracted?

But I can't believe no one else has found this and reported it?

If I fix this by editing the code in "C:\nburn\MOD5441X\system\mcf5441x_rtc.cpp" do I then need to use the NBEclipse menu "Rebuild Modified System Files"?

Thanks

Re: MOD54415 RTC Month Error

Posted: Wed Nov 12, 2014 12:52 am
by roland.ames
Or copy the "C:\nburn\MOD5441X\system\mcf5441x_rtc.cpp" file into your project directory and then treat it as if it is your own code, edit it and experiment with different code without having to rebuild the system libraries each time.

I don't think many people have used the MOD54415 RTC routines

Re: MOD54415 RTC Month Error

Posted: Wed Nov 12, 2014 6:50 am
by greengene
And that's the way it is...
This isn't new for the 54415 (well, the RTC being internal is). I've had to do
(or not) that +/-1 for years depending on the RTC chip I was using. The library
for the clock functions is generic so I just adapt my app's service functions to
the part being used - here internal. I don't change the library, I either write a
wrapper or make a replacement. I don't like to have/maintain separate libraries
for individual products. Now if those libs were c++ I could just inherit/override...

Re: MOD54415 RTC Month Error

Posted: Wed Nov 12, 2014 9:59 am
by dciliske
This issue has been fixed and it's exactly as you explained. It will be in the next release here in a few days. The issue was first reported October 3.

Re: MOD54415 RTC Month Error

Posted: Thu Nov 13, 2014 2:31 am
by gavinm
Thanks for the replies.
Roland - very good idea - saves messing with system files - thanks.

greengene - I understand what you are saying about compatibility with different external RTC ICs. BUT these are library routines specifically provided for the RTC built into the processor module of the 54415. So I would expect them to match the capability of the specific hardware they are intended for...

Dan - thanks for the update on the fix - I find it hard to believe that I couldn't find any other reports of this on the forums. The 54415 isn't that new and the built in RTC is a useful feature. Though it's not that accurate. I need to look into using the compensation register ... and I've said elsewhere in a separate post that it's quite high current at 17micro amps. Absolutely no good to just use a super capacitor! A 3v battery is needed. I'm using a 3v re-chargeable pcb mounted coin cell.

Thanks all anyway.

Re: MOD54415 RTC Month Error

Posted: Thu Nov 13, 2014 3:32 am
by gavinm
Actually I think I've noticed other errors in the MOD54415 RTC routines at C:\nburn\MOD5441X\system\mcf5441x_rtc.cpp

In library function MCF541X_RTCGetTime ...

Code: Select all

do
{
  WORD sr1=sim2.rtc.sr;
  ym =sim2.rtc.yearmon;
  dy =sim2.rtc.days;
  hm =sim2.rtc.hourmin;
  s  =sim2.rtc.seconds;
  WORD sr2=sim2.rtc.sr;
  if((sr1& 1) || (sr2&1))
  {
	OSTimeDly(1);
  }
  else break;

} while(nTries<5);
So nTries is counting attempts to correctly read the date time registers by monitoring the least significant bit in the Status register which indicates if the RTC is on a second boundary and thus the counters may be inconsistent..... BUT where is nTries ever incremented?
Shouldn't it be ...

Code: Select all

while(nTries++ <5);
In practice, with a 50ms delay between read attempts, this should never need more than 2 attempts, BUT if there was a hardware error with the RTC keeping the INVALID bit in the status register high, this code would never return.

There is the same problem in function MCF541X_RTCSetTime

Also, I guess the code at the end of function MCF541X_RTCGetTime is wrong for a couple of reasons (I've not tested this - it's just wrong by observation. I've included the declaration of the days in a month variable d_inmob at the top of the file for completeness) ...

Code: Select all

static const int d_inmob[13]=
{
0, //0
0, //jan
31, //feb
59, //mar
90, //april
120, //may
151, //jun
181, //jul
212, //aug
243, //sep
273, //oct
304, //now
334  //dec
};
...
...

bts.tm_yday=d_inmob[bts.tm_mon]+(bts.tm_mday-1);

//Fix up leap year
if((bts.tm_mon>2)&& ((year % 4 == 0 && year % 100 != 0 || year % 400 == 0)))
{
bts.tm_yday++;
}
As we've already established from the comments in this code the month field in a type tm structure has valid values of 0 to 11 for Jan to Dec. So d_inmob[bts.tm_mon] will only return the correct value for January! Feb will return zero, Mar 31 instead of 59 etc. Fix it by converting d_inmob to a 12 element array by getting rid of the extra zero at the beginning (or use bts.tm_mon +1 as the index).

Also the Leap year Fix condition of (bts.tm_mon>2) is surely wrong. This will only correct the days in the year from April onwards not March onwards. (bts.tm_mon>1) or (bts.tm_mon>=2) might work better ;).
(As an aside you don't really need the 400 year condition as the date range of the 54415 RTC is only up to 2239 and the next 400 year boundary is in 2400, which won't trouble any of us!!).

Finally, I wonder why your calculation of the day in the year ranges from 0 to 364 (365 for a leap year), rather than 1 to 365/366? Is this a unix standard definition for this field in the tm structure? In practice the use of this field that I can see is in calculating the Ordinal date for date stamping applications? (see ISO 8601). This ranges from 1 to 365/366.
So if it's not a unix standard in the tm structure I'd delete the -1 in the (bts.tm_mday-1). But of course that might break other folks' code that might be using it ... but they're likely to have already modified the code to fix the February issue anyway.

Are all these fixes already in the update you mentioned?

Re: MOD54415 RTC Month Error

Posted: Thu Nov 13, 2014 6:30 pm
by roland.ames
great work Gavin.

I am developing on a MOD54415 and intend to add rtc support in the near future but haven't yet. I had done some initial tests to verify register access on a prototype board just to test the h/w design, but that's as far as I have got.

It looks like you are saving me a lot of work that I would have had to do in the next few months :D hopefully all the rtc library functions will be debugged before I get to use them.
the next 400 year boundary is in 2400, which won't trouble any of us!!
Hmm, that's what they said about Y2K

and I don't think Ray Kurzweil would agree, after all, the singularity is near !

Re: MOD54415 RTC Month Error

Posted: Thu Nov 13, 2014 7:21 pm
by gavinm
Even Ray wasn't predicting that time would accelerate - just technological advancement (or complexity).

The next 400 year leap year boundary will still be 355 years away at his point of singularity in 2045, so I'm happy to say it won't trouble me!!

(..and I got all of that from 30 seconds on Google ... interesting ideas ...)

On the RTC front - it looks good and effectively comes at just the cost of the battery and a resistor (there is a diode and small resistor on the MOD54415).
As I said before not very accurate - but I'm interested in seeing how good the compensation register might make it. I've studied the Freescale manual and I think I've got it sorted in my mind. You can set correction time interval of between 1 and 255 seconds and then once per this time interval a correction value (-128 to +127) that will be used to adjust the 32768 divider that gives the 1 Hz clock. The trouble is you'd have to monitor the RTC over a significant length of time and compare against an accurate clock to judge how much to compensate by. Then hope that all the crystals in a batch of modules are similar enough to apply the same correction! But interesting.

The other part of the RTC functional block is the 2k bytes of battery backed up (with a write protection mechanism) RAM. Useful for a bit of none volatile storage of often changing values that you wouldn't want to keep writing to flash ... like product or test counters for example. Again - it all comes effectively "free" with the 54415.

Good luck with your project.

Re: MOD54415 RTC Month Error

Posted: Thu Nov 13, 2014 8:00 pm
by roland.ames
from https://en.wikipedia.org/wiki/The_Singularity_Is_Near
Kurzweil says revolutions in genetics, nanotechnology and robotics will usher in the beginning of the Singularity.[21] Kurzweil feels with sufficient genetic technology it should be possible to maintain the body indefinitely, reversing aging while curing cancer, heart disease and other illnesses.[22]
Only problem is by 2045 i'll be over 80 so that's a lot of reversing :!:


My intended use for the NVRAM is to store the timezone environment variable. http://forum.embeddedethernet.com/viewt ... rt=0#p8840

Re accuracy, I guess as long as the device is connected to a NTP server you do not need to worry too much, but my application cannot rely on always being connected so the accuracy / compensation information may be more relevant to me than most.
I was thinking that if the 25MHz xtal that supplies the clock for the processor is assumed to be perfect, then the processor could calculate how to compensate for the inaccuracy of the 32khz RTC xtal. But that is a big if.

Re: MOD54415 RTC Month Error

Posted: Thu Nov 13, 2014 9:55 pm
by greengene
I feel rolling my own for this device is the way I'll go too. Thanks for pointing
out the issues. I hadn't gotten this far to the ToD from lack of need at this point.
At least Moto kept on using the Gregorian calendar. ;)

I didn't see the "gone to battery" indicator and time freeze that I'm used to on
other off-chip RTCs - need more reading I suppose. That's a feature I like/need
to use.

The compensation issue is one that I've looked into before due to the extremes
of operating environment some devices I've worked on that also couldn't count
on external time reference. In the end the system specs had their accuracy
requirements widened; not my choice, but their nickel.

As an aside, the standard replacement of the off-chip RTCs I'm now using has a
trickle charge circuit built into it for the clock's battery. (Don't open that door
about how do you know the battery's chemistry.)