INT0 takes 6usec to respond ... can it go faster?

Greetings.

I am using an Arduino MEGA (1280) for a video project.

On pin 2 (INT0) I have vSync, a negative going signal which lasts for > 160usec and repeats every 20 msec.

On pin 20 (PIND0) I have hSync, a negative going signal which lasts for just 5.375 usec and repeats every 64 usec.

hSync is alternately high and low when vSync asserts, corresponding to even and odd fields in the video stream.

When vSync asserts, I check hSync using the fastest method I have available:-

void INT0ServiceFALL() {
  //check Hsync when Vsync drops.  
  //If Hsync = LOW, then ODD FIELD (f1)
  //If Hsync = HIGH, then EVEN FIELD (f2)
  //note this has not worked due to delay in servicing this interrupt :-(
  //Hsync is low for just 5.25usec
  portDinput = PIND;
  
  vSyncTimeStamp = micros();
  
  portDinput = portDinput & B00000001;
  
  vSyncDetected = true;
}

where portDinput is a volatile byte defined as global (i.e. in the header before void setup()

Most of the time (say 199 / 200 times) I grab hSync successfully by this method. The interrupt service routine runs in under 5 usec from trigger and all is well. The 200th time, the ISR takes 6.25usec from trigger to run, and falsely reads hSync as high rather than low.

Is there any way to speed up the interrupt handling execution?

I use INT0 as it would appear to be fairly high in priority. I have micros() called in the code which I kind of need, but disabling it does not reduce the incidence of slow INT0 handling.

INT0 is invoked in the usual way:-

attachInterrupt(0, INT0ServiceFALL, FALLING);  //Vsync

If there is no way to reduce the overhead in calling an interrupt handler, then I will probably go with an averaging algorithm which predicts what hSync ought to be, on the basis of several successful tries, and over-rides it if the fetch is bad. However this complicates what ought to be an elegant solution.

If any knowledgeable person has any thoughts on the subject, please feel free to let me know.

Regards, Tony Barry

You may be barking up the wrong tree. It's important to remember that the timer 0 overflow interrupt is also firing at a regular rate. If that ISR is running, yours will be delayed until it finishes. Even though your Sketch will very likely go haywire I suggest stopping timer 0 to see if your ISR becomes more responsive.

Thank you Coding Badly for your thoughts. I gather timer0 is used under the hood by the Arduino environment for such things as millis() and micros() ...

Hmmm. Might have to work out some other way.

Regards, Tony Barry

Thank you Coding Badly for your thoughts.

You are welcome.

I gather timer0 is used under the hood by the Arduino environment for such things as millis() and micros() ...

Yes.

Hmmm. Might have to work out some other way.

I didn't mean to scare you off of using interrupts!

Interrupt service routines have a fairly high overhead that can be eliminated if you're willing to introduce a bit of inline assembly. I suspect you'll be able to get what you want. The first step is to identify the problem.

Unfortunately I am not able to kill Timer0 with impunity. I need my Timer0 working! I also can not kill it from within my interrupt service routine, as by then the thing I want to catch is over.

However the inline assembly might be interesting, if I can get out of the overhead associated with setting up an interrupt service routine. Can you point to where this is described?

Regards, Tony Barry

However the inline assembly might be interesting, if I can get out of the overhead associated with setting up an interrupt service routine. Can you point to where this is described?

I suggest you start by taking a look at the assembly generated for your Sketch. This will give you an idea of what the C compiler outputs for a given expression.

You'll be using a program named "avr-objdump.exe"... http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207951658/2#2

...on "*.elf" files that will be located in your %TEMP% directory... http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1241117308