"For Example, we are using 2 channels (Channel 0 and Channel 1) in a chain mode to make it a 64-Bit value. When we read the timer value thrice i.e., Timer1: 0x1B9FFFFFFF7, Timer2: 0x1B900000001, Timer3: 0x1BA0000000B, it is observed that when the Timer2 value is read, the higher 32-Bit timer value is not updated and when the timer value is read for the third time, the higher 32-Bit timer value is updated with the actual rollover count value."
A properly designed Micro will have facilities to latch the multi-byte values, so that they are stable during reads. Channing things together there is no such latch across the whole span. This is actually expected behavior that few expect. It depends on the sampling rate how often the 'bad reads' will happen. Sampling rate depends on system clock speeds, counter frequencies, how often the software reads, where interrupts fall etc. which makes it look 'random' when it isn't. As well as being rare. A two day sample run is not long enough. It could take months or years for things to fall 'just right'. It comes down to Murphy's Law. It will happen at the worst possible time.
This is the style of code I use for such situations:
/*
* Return system_tick count while accounting for possible timer
* interrupt happening while reading the counter:
*/
uint32_t system_ticks_get( void )
{
uint32_t t1_u32 = system_ticks_u32; /* Read twice to make sure that */
uint32_t t2_u32 = system_ticks_u32; /* an interrupt did not occur during the read */
while( t1_u32 != t2_u32 ) /* If the readings do not match, */
{
t1_u32 = system_ticks_u32; /* try again */
t2_u32 = system_ticks_u32;
}
return( t1_u32 ); /* Return the stable time */
}
I originally had code in there to count that there was a split read.
There never was, so I removed it to speed up the read function.
Even if I've never seen the issue, I know that it can happen, so I protect against it.
More details here:
http://www.ganssle.com/articles/asynchf.htm