K64 reading RTC->TPR register

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

K64 reading RTC->TPR register

跳至解决方案
1,013 次查看
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?

标记 (4)
0 项奖励
1 解答
1,009 次查看
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.
 

在原帖中查看解决方案

4 回复数
970 次查看
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 项奖励
962 次查看
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 项奖励
1,010 次查看
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.
 

978 次查看
nicolasguigo
Contributor II

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

0 项奖励