Clearing the interrupt flag on an Arduino Due, OMG

Hi,

i attach a FALLING interrupt to two I/O Pins on my Arduino Due in the setup() function. When they get attached they fire one time.

I suppose that at the time of attachement, they already have a interrupt flag set. The interrupt can be caused for example when powering up the Arduino or something else?

So how do i clear the interrupt flag of a specific I/O pin in the Arduino Due (SAM3X processor). I already looked into the NVIC description of the SAM3X datasheet, but the examples didnt work for me, i guess i did something wrong.

Please help!

I think that's just the semantics of the SAM - if the pin is low then enabling interrupt on FALLING will reliably trigger an interrupt. Its completely different hardware from the ATmega, remember.

The usual way to handle stuff like this is to gate the ISR with a boolean so you can arrange for interrupts to be ignored until you are ready for them. Having said that there's probably a register you can write to change the default behaviour, there are a plethora of control registers in the SAM architecture.

32.7.14 PIO Controller Interrupt Enable Register
Name: PIO_IER
• P0-P31: Input Change Interrupt Enable
0: No effect.
1: Enables the Input Change Interrupt on the I/O line.

Notice that each port has this register, the Due has 4 ports, A,B,C,D

32.7.17 PIO Controller Interrupt Status Register
Name: PIO_ISR
• P0-P31: Input Change Interrupt Status
0: No Input Change has been detected on the I/O line since PIO_ISR was last read or since reset.
1: At least one Input Change has been detected on the I/O line since PIO_ISR was last read or since reset.

From experience, I believe you have to check (no set, simply call) this register inside your interrupt handler to reset the flag to 0 which will re-enable your interrupt. (or at least thats how it works with Timer Interrupts)

And from looking at the WInterrupts.c file, this is true

void PIOA_Handler(void) {
	uint32_t isr = PIOA->PIO_ISR; //<==HERE IT IS!!!
	uint32_t i;
	for (i=0; i<32; i++, isr>>=1) {
		if ((isr & 0x1) == 0)
			continue;
		if (callbacksPioA[i])
			callbacksPioA[i]();
	}
}
//the other port handlers...
//callbacksPioA[i](); is an array of all the callback functions you attached...

I feel like you can re-engineer this, mainly because it is slow…looking through all the pins to see if you have an interrupt attached to it…

Oh you want to disable it?! Oh, well go to those pages in the datasheet (657 or somewhere right around there) and look for the disable register, you will have to clear that register to get your interrupts working again!

MarkT: I think that's just the semantics of the SAM - if the pin is low then enabling interrupt on FALLING will reliably trigger an interrupt. Its completely different hardware from the ATmega, remember.

The usual way to handle stuff like this is to gate the ISR with a boolean so you can arrange for interrupts to be ignored until you are ready for them. Having said that there's probably a register you can write to change the default behaviour, there are a plethora of control registers in the SAM architecture.

Shure, gating it in the ISR would be ok, is that what you mean:

volatile boolean isr_gate = false;

....

setup(){
isr_gate = true;
}

void myISR(){
if (isr_gate){...}
}

I would love to save the extra code though. I have multiple I/O interrupts and want a way that they dont fire when they are attached. Why would they register a FALLING state when i attach an interrupt? The interrupt I/O pin has a pull-up resistor, so its at HIGH when its attached.

Ps991: Oh you want to disable it?! Oh, well go to those pages in the datasheet (657 or somewhere right around there) and look for the disable register, you will have to clear that register to get your interrupts working again!

I tried to use several registers, but in the Arduino sketch it doesnt recognize the register name. It kinda sucks that all the good tutorials on interrupts are on AVR processors :(

put REG_ before the register, for some cases that works

Hey,

i am digging deeper into it, but at what Port (PIOA, PIOB etc...) is pins 2 and 4 ?

I was looking around in the SAM3X datasheet but didnt find it....

My general idea was to do something like this:

PIOA->PIO_AIMDR = 0x00000000;
attachInterrupt(2, myISR, FALLING);

The little yellow rectangles with like letter.# thats the port and pin

Great diagram, thanks!

I tried several registers but still:

attachInterrupt(PIN_SWITCH_MOTOR, calibrateMotorSide, FALLING);
      attachInterrupt(PIN_SWITCH_END, calibrateEndSide, FALLING);

always fires once when attached, even if the buttons werent pressed... Its driving me TOTALLY nuts

What i also noticed, and thats really blowing my mind:

When the interrupts are attached to Pins 2 and 3 , they fire once when the button is pressed...pretty much what you'd want from a clean interrrupt. But when they are attached to Pins 6 and 7, they fire like 5 times when the button is pressed and also when its released.

Why is that? What is going on???

Ever heard of something called bouncing, basically as you press the button the connection between the button makes and breaks it's connection a few times before settling, same with release. I have never tried this but the sam3x has a built in denounce filter, good luck with that part.

I agree, debouncing has to be taken care of. Right now i am using this circuit proposed by dlloyd, and it does a good job. I also looked briefly at the SAM3X datasheet and spotted the built in debounce / filter functions. I didn’t have the time to implement them yet, but it definitely seems worth to be investigated!

A ready to use function to set debounce filters on the SAM and futher explanations can be found here:

http://forum.arduino.cc/index.php?topic=156474.0

Note that the debounce filters do not work for "FALLING" and "RISING" interrupts, but only for "CHANGE" interrupts as far as I know..