Odd behavior of TIFR bits with PRR bit set

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

I have code for a GPSDO running on an ATTiny4313. It uses timer1 with ICP to time the system clock (which is a VCTCXO) against a GPS PPS source. Interrupts are used both for the input capture, and for overflow. The overflow is used to extend the basic timer counter to 32 bits (the overflow ISR simply increments a UINT16 with the high bits).

 

One thing I discovered was that there was some odd behavior that happened once a month or so. To make a long story short, when the ICP happens right as the timer overflows, the ICP interrupt takes precedence and the increment doesn't happen until after the capture ISR. The result of that is that the extended timer value is 0x10000 too low.

 

I added workaround code to the capture ISR. The code said:

 

uint16_t captured_low_bits = ICR1;
uint16_t saved_hi_bits = timer_hibits; // the volatile high bit value
// If the captured low bits are "high", then it very likely means that the overflow happened
// later, and should be ignored - the overflow ISR will run next and take care of it.
if ((TIFR & TOV1) && (captured_low_bits < 0x8000)) saved_hi_bits++;
uint32_t captured_timer_value = (saved_hibits << 16) | captured_low_bits;

The astute among you will have already spotted the error. The comparison should be to (TIFR & _BV(TOV1)).

 

But the point of this post isn't really about that, it's about the behavior I actually saw, which was unexpected. The workaround code was now manifesting much more often than expected.

 

Early on, I disabled timer 0 by writing 1 to the appropriate bit in PRR. TOV1 is 7, so TIFR & 7 will be any of TOV0, OCF0A and OCF0B. But I never started timer 0, and turned the power off as the third line in main(). So why should that have ever happened? Do the timer 0 bits in TIFR flap when the timer power is off or something?

 

Last Edited: Sun. Jan 24, 2016 - 03:54 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Curious.  Can you post a minimal test program which demonstrates the problem?  FWIW, I tried to elicit the same behaviour from a 328P and could not.   Admittedly the 328P is a different device, with separate flag registers for TIMER0 and TIMER1.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
Can you post a minimal test program which demonstrates the problem?

Indeed.

 

I recall a fairly recent thread where IIRC it was determined that compare matches and similar fire even if the timer is not running.  So I could certainly see a compare match flag being set.  ICP?  Perhaps--pins float.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I haven't gone down that road yet, as at the moment I'm focussing on an unrelated problem with this unit (looking for it pointed out the mistake that led to this question). But when I get a chance, I'll try to configure the hardware the same and just write some code to mirror those three bits of TIFR out to I/O pins and see what they look like.