How to get equal number of clock cycles before ISR on an AVR

avrclockinterruptstiming

While writing a time critical piece of code for an Attiny13, I figured I could use the rising edge of an input as a trigger to read in some self clocking data. However, the number of clock cycles needed to go into the interrupt routine differs depending on the instruction being executed at the moment.

  • How can I ensure the time from rising edge interrupt until start of the interrupt routine is always the same number of clock cycles?

Except for the interrupt routine there's no code running at the moment, so maybe there's a way to loop with a single instruction in the main code?

Best Answer

One option would be to have two triggers, the first causes the code to jump into a loop waiting for the signal to go low and then back high. As soon as the signal has gone back high, then start clocking the data.

Something like:

while(PINREG & (1<<PORTBIT)); //wait for low
while(!(PINREG & (1<<PORTBIT))); //wait for next high
//Clock in your data here...

In that code, the two while loops should simplify to branch when bit in register is set (or clear), which means that every 2 clock cycles it would check the trigger bit, and once the second edge was found, it would start with a predictable latency.

The latency would however be +/-1 cycle depending on where the rising edge occurred with relation to the clock, but this would be the case in all scenarios as the signals go through a clock synchronised in the I/O chain.

If your data symbol rate I less than ~F_CPU/4, then minor variation in latency of the above shouldn't be an issue. Any faster than that and you probably wouldn't be able to process in anyway - no time to actually do anything with the data as you clock it in.