Hi
The SAM7X has independent interrupt for each port (A and B). Therefore you can improve efficiency by spreading your port edge interrupts over these two ports.
The following is the general handler from the uTasker project which allows each pin to dispatch its own interrupt handler sub-routine:
// Port A interrupt
//
static __interrupt void PortA_Interrupt(void)
{
unsigned long ulInputChanges = PIO_ISR_A;
unsigned long ulBit = 0x40000000;
int iInterrupt = 30;
ulInputChanges &= PIO_IMR_A; // only treat enabled inputs
while (ulInputChanges != 0) { // for each input change that has been detected
if (ulInputChanges & ulBit) { // an enabled input has changed
if ((gpio_config_a[iInterrupt] & 0x1) // any edge accepted
|| ((gpio_config_a[iInterrupt] & HIGH_LEVEL_SENSITIVE) && (PIO_PDSR_A & ulInputChanges)) // positive edge accepted
|| ((gpio_config_a[iInterrupt] == NEGATIVE_EDGE_TRIGGERED) && (~PIO_PDSR_A & ulInputChanges))) { // negative edge accepted
iInterruptLevel = 1;
(gpio_handlers_a[iInterrupt])(); // call the application handler
iInterruptLevel = 0;
}
ulInputChanges &= ~ulBit;
}
iInterrupt--;
ulBit >>= 1;
}
}
Of course there needs to be a loop or similar to check each individual interrupt pin source but this shows that the higher port interrupts are more efficient since they are handled first and the loop exits as soon as all waiting interrupts have been treated.
The bit checking order could also be changed from PA00..PA30 to give PA00 priority (and higher efficiency).
In your case, if you use both Ports A and B and position the interrupt at the same end (eg. PA00, PA01 or PA30, PA29) the worst case would be once around the loop and so still quite efficient.
Don't forget that the SAM7X has, in addition, interrupt inputs (IRQ0, IRQ1, FIG) which generate their own dedicated interrupt (edges and levels). By using these as well as dedicated interrupts from port A and port B you can again improve efficiency.
Note that the ATMEL AVR32 (which is very similar to the SAM7X in terms of peripherals) has one interrupt for each 8 bits of a port. Therefore Port A has an interrupt for each change in PA00..PA07, then one of PA08..PA15, etc. This allows more efficient dispatchers since the worst case is then 8 checks rather than up to 31 to handle PA00..P30.
Regards
Mark
http://www.uTasker.com