Hey Paul,
> Can this be accomplished by using the ICER# and ISER# registers
> within the NVIC inside the ARM core, rather than the registers in
> Atmel's peripheral?
Well, AFAICS this only clears the interrupt flag for the entire port,
while we need to clear the interrupt flag just for the pin that is being
attachInterrupt'd. I think that there is a status reg (PIO_ISR) that
keeps a bit for the interrupt status for each pin in a port. This is
AND'd with the pin interrupt enable mask (PIO_IMR). All these pins are
then or'ed together and offered to the NVIC as a single interrupt.
What is not entirely clear to me is wether these ISR flags get set even
when the interrupt for a given pin is disabled in IMR. If I read the
diagram in section 32.5 (Functional description) of the SAM3X/A
datasheet right, the mask is applied to the value of the status
register, which suggests the bits in the status register are set even
when interrupts (for the given pin) are disabled in the mask register,
but I can't find any details about this in the datasheet.
If the status bits do _not_ get set while the pin is masked out in the
IMR register, then the problem I described does not exist, but also code
that relies on saving remembering interrupts while the IRQ is disabled
will not work either. Anyone with a due that can check wether the ISR
bits get set for pins that don't have any handlers registered?
A related observation I noticed in the code is that detachInterrupt on
sam currently disables the pin in the IMR, but leaves the callback
registered in the callbacksPioX arrays. Combined with the fact that the
actual interrupt routine does not look at IMR, just at ISR and the
callbacks arrays, I suspect that this might cause interrupts to be
triggered after they are detached, as a sid effect of another interrupt
being triggered on the same port.
To verify this, I created a small sketch:
https://gist.github.com/matthijskooijman/478727b188d41130ea73
This was compiletested only, I don't have a due. To test this, trigger
interrups on pin 25 and 26 by shorting it to ground. If my suspicion is
correct, touching pin 25 shouldn't show anything, but touching pin 26
afterwards will show both INT25 and INT26, even though 26 is already
detached.
If this is indeed the case, the proper and easy fix is to just reset the
callback to NULL in detachInterrupt.
Gr.
Matthijs