K64 reading RTC->TPR register

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

K64 reading RTC->TPR register

Jump to solution
889 Views
nicolasguigo
Contributor II

Using a K64FN1M0M12, we tried to log some events with a millisecond resolution. To do so, we use the TPR register from RTC peripheral.

millisec = base->TPR;
millisec = (millisec * 1000) / 32768;

We have a problem with some consecutive reads: the value read from the register can have a lower value than the previous read. To highlight the problem, we implemented a single task which only reads the TPR register every millisecond and prints the value on a console. After about 30 minutes, we have 3 occurrences of the issue. Each read gives the TPR value incremented by 32 or 33. Here are 2 occurrences of the problem with the values of RTC->TPR :

MillisecondTPR read valueIs value correct?TPR expected value
47915711YES-
47615616 (0x3D00)NO15755 (0x3D80)
48115776YES-

 

MillisecondTPR read valueIs value correctTPR expected value
57718911YES-
56218432 (0x4800)NO18944 (0x4A00)
57918976YES-

 

As you can notice, there is a one bit difference between the read value and the expected value. Is there something we do wrong? Is this a known issue? Is there a way to prevent this from happening other than reading the register multiple times?

Tags (4)
0 Kudos
1 Solution
885 Views
bobpaddock
Senior Contributor III

The general solution for reading multiple bytes across different clock domains is:

uint16_t t1,t2;

do{

 t1 = RTC->TPR

 t2 = RTC->TPR

}while( t1 != t2 );

t1 is now valid at this point.
 

View solution in original post

4 Replies
846 Views
myke_predko
Senior Contributor III

@nicolasguigo 

I've run in the same problem and rather than use the RTC, I ended up using a PIT requesting an interrupt every 1ms (actually every 100us in my application) which avoids the issue.

myke

0 Kudos
838 Views
bobpaddock
Senior Contributor III

 

http://www.ganssle.com/tem/tem355.html#article6 explains the general problem with multiple byte reads involving interrupts.  Then throw in that RTC is in a different clock domain...

It is important to note the distinction between simultaneous (the hardware ticking) and concurrent (the software reading the hardware with interrupts).

0 Kudos
886 Views
bobpaddock
Senior Contributor III

The general solution for reading multiple bytes across different clock domains is:

uint16_t t1,t2;

do{

 t1 = RTC->TPR

 t2 = RTC->TPR

}while( t1 != t2 );

t1 is now valid at this point.
 

854 Views
nicolasguigo
Contributor II

Thank you for your reply. It solved the problem we had.

0 Kudos