Go Down

Topic: Serial.print messing with Timer Interrupts (Read 2 times) previous topic - next topic

Nick Gammon

Interesting! Here, you mean?

Code: [Select]

void MsTimer2::_overflow() {
count += 1;

if (count >= msecs && !overflowing) {
overflowing = 1;
count = 0;
(*func)();
overflowing = 0;
}
}


So it relies on not missing those "overflow" ticks? I see what you mean.

Udo Klein

#21
Nov 09, 2012, 08:46 pm Last Edit: Nov 09, 2012, 08:49 pm by Udo Klein Reason: 1
No. It relies on skipping 6 cycles by setting TCNT2 to 6. However this implies that TCNT2 would be 0 which is not necessarily the case. It never misses any of the 1ms ticks. It is only sometimes some cycles to late. As I said: this is very subtle and it took me ~4 weeks to figure this one out.

To be more precise: the bug is:

Code: [Select]

TCNT2 = MsTimer2::tcnt2;


Actually the underlying issue is to use "normal" mode instead of CTC mode.
Check out my experiments http://blog.blinkenlight.net

Nick Gammon

As calculated here?

Code: [Select]

tcnt2 = 256 - (int)((float)F_CPU * 0.001 / prescaler);


Hmm. I see. Well I don't like fiddling with counters anyway, I believe they "belong" to the timer, especially if it is running.

Nick Gammon


As I said: this is very subtle and it took me ~4 weeks to figure this one out.
...
Actually the underlying issue is to use "normal" mode instead of CTC mode.


Well done, BTW.

It didn't occur to me to look in the library, nor did it occur to me that the library-writer would use a method like that which relied on things happening "just right".

Udo Klein

#24
Nov 09, 2012, 09:12 pm Last Edit: Nov 09, 2012, 09:20 pm by Udo Klein Reason: 1
This is another issue. Compare

Code: [Select]

tcnt2 = 256 - (int)((float)F_CPU * 0.001 / prescaler);


to

Code: [Select]

TCNT2 = MsTimer2::tcnt2;

C is case sensitive. The first line sets tcnt2 in the  MsTimer2 namespace. The second line changes the timer register. So he does not rely on things happening just right. He just created a race condition. This happens even to the best ;) The tricky part is to find and eliminate them.

Thanks for the compliments. I am proud of this analysis as well. Now the way is paved to the most resilent DIY DCF77 clock ever. The whole story will take probably 4 months of blogging :)
Check out my experiments http://blog.blinkenlight.net

Go Up