Hi all,
I have made a small improvement to WInterrupts.c which allows a faster interrupt dispatching associated to generic I/O pins. That is, the callbacks we set with function attachInterrupt().
Basically I have modified the code of the interrupt handler functions PIOA_Handler(), PIOB_Handler(), PIOC_Handler() and PIOD_handler() in the original WInterrupts.c. The improvement consists mainly in taking advantage of ATSAM3XE assembler instruction CLZ. With this instruction it is possible to calculate the number of leading zeros in a 32 bit value in just one machine instruction. CLZ is available in C/C++ using CMSIS function __CLZ().
Using this small improvement I have been able to get to a bit rate of 115200 with my software serial library for the DUE, soft_uart (using the example provided with soft_uart and two stop bits). Take into account that soft_uart uses the interrupt for pin level changes on the RX pin associated to the software serial object when used. Without the improvement soft_uart could only get to 57600 (same example also with two stop bits).
Herein I include attached the file WInterrupts.c with the PIO handlers modified (the previous versions of the handlers are also on the file, but commented). To illustrate the change here you have the code for handler PIOA_Handler() (the previous one appears commented), the other ones are alike:
//void PIOA_Handler(void) {
// uint32_t isr = PIOA->PIO_ISR;
// uint32_t i;
// for (i=0; i<32; i++, isr>>=1) {
// if ((isr & 0x1) == 0)
// continue;
// if (callbacksPioA[i])
// callbacksPioA[i]();
// }
//}
void PIOA_Handler(void) {
register uint32_t isr = PIOA->PIO_ISR;
register uint8_t leading_zeros;
while((leading_zeros=__CLZ(isr))<32)
{
register uint8_t pin=32-leading_zeros-1;
if(callbacksPioA[pin]) callbacksPioA[pin]();
isr=isr&(~(1<<pin));
}
}
If you want to check this version of WInterrupts.c just overwrite the original with this new one.
Sincerely, I consider this change can benefit any code using interrupts associated to any Arduino DUE I/O pin with function attachInterrupt(). Once tested enough by more people, maybe it might be convenient to apply the change to the official Arduino DUE standard library. Anybody knows to whom I have to address to propose the change?.
WInterrupts.c (5.42 KB)