0

I have an Atmega328p that I want to program to precisley caputre the time of an input event.

However now a question came up to me if my code would work in all situations. This question, I think, is more related to the general handling of interrupts on the Atmega platform.

So my code looks like this (in summary):

volatile uint16_t overflow = 0;

ISR(TIMER1_CAPT_vect) {
    uint16_t captureCount = ICR1;
    uint32_t t = ((uint32_t) overflow << 16) | captureCount;
}

ISR(TIMER1_OVF_vect) {
    overflow++;
}

This should capture when an input event occures within the interrupt ISR(TIMER1_CAPT_vect), furthermore the overflow of timer1 is counted with the other interrupt. As far as I understand it correctly ICR1 stores the time of timer1 exactly when the input event occures and then some short time later fires the interrupt to notify the code that this event occures where I then calculated the real time by using the current overflow counter.

I know from this answer that the code inside the interrupt is not interrupted by another interrupt (e.g. the overflow interrupt), so the addition of overflow and captureCount to form t is "atomic"/"thread safe". But what I am wondering now is what would happen if the ICR1 is set by the current timer1 value and right after that an overflow occured, before my code is notified by the ISR(TIMER1_CAPT_vect). With this it could be that, maybe, the overflow interrupt is run before the event-capture interrupt. This would then result in the possibility that the overflow counter is increased by 1 but the ICR1 stills holds the time corresponding to the old overflow range, giving a wrong t.

So in general this problem would only occure if the overflow interrupt is fired before the event-capture interrupt is fired, although the true capture event (when ICR1 is set to current timer1) happend before the overflow.

This leads me to the overall general question: Are interrupts handled in the same order as the actual true event occure on Atmega?

And especially regarding my two interrupts of timer1?

1 Answers1

0

The ATmega328P datasheet makes it sounds like the interrupts with the lower addresses have a higher priority. So if multiple interrupts are trying to run at the same time, I expect the AVR to pick the one with the lowest address and run it.

From section 6.7, Reset and Interrupt Handling:

The complete list of vectors is shown in Section 11. "Interrupts" on page 49. The list also determines the priority levels of the different interrupts. The lower the address the higher is the priority level. RESET has the highest priority, and next is INT0 – the external interrupt request 0.

It would require a lot of extra machinery if the AVR were to behave as you suggested, and remember the order that each interrupt happened in.

If we go to section 11 of the datasheet as mentioned in the quote above, we see that the Timer 1 capture interrupt has a higher priority than the Timer 1 overflow interrupt (since it has a lower address).

David Grayson
  • 71,301
  • 23
  • 136
  • 171