DUE Double HW Interrupt (Arduino 1.5.5- r2)

I've been using the HW Interrupts on the DUE for my extensive project and I've notices what seems to me to be a compiler issue.

When a HW ISR executes it seems to do so 2 times no matter what. I am unsure why and I would very much like to look at the base code for attachInterrupt(); and noInterrupts(); the problem is either in the idea that it takes a few clock cycles to turn off interrupts in noInterrupts(); or the compiler is inherently flawed.

Let me give you an example.

void gapISR(){              
        case rightDir:
        case leftDir:
            //doing nothing

with out getting into to much detail on what my project is and what I am doing let me explain the above mentioned ISR. signal goes low, based on a variable "currentDirection" another variable "column" is increased or decreased.

First I saw that the program was double calling the function unsure how this was possible seeing as I turn off interrupts and detach the HW ISR from the pin prior to doing anything else.

Does anyone else know why this might be happening? As I said I think it is a compiler issue.

You disable interrupts and do a detachInterrupt(gapSensor), does that mean at some point you re-enable the interrupt and attachInterrupt(gapSensor)?

There was a thread the other day about interrupts firing as soon as they are enabled (or something like that), maybe that's causing a second pass.


That isn't possible with my code, it is quite in depth to fully explain it but let me try.

I use two sensors and 2 functions for said sensors. They are set to fire while going along a wall with small gaps in it. When the front sensor fires it turns it self off and then turns on the back sensor and ISR. When the back sensor fires it turns it self off and then turns on the front sensor and ISR, and then increments the gap count (IE: column). (the above set of code is for the back sensor ISR but is simplified for you here)

The sensors are a set distance apart and the gaps are a set distance apart. (The gaps are further apart than the sensors.)

I suppose if you are handling/clearing the interrupts then they should not fire just because they were disables then enabled. Does the Arduino interrupt handler clear the hardware, I would assume so but don't know. If it does how does it handle many interrupts from the same port, eg in theory you could attach 32 interrupts to a single hardware port, if it clears the flags it then has to make sure it calls all 32 handlers. If it doesn't clear the flag(s) that's up to the user (pretty unlikely).

I've never looked at the code (will do soon though), just floating ideas.

What about the external hardware, do you get a clean edge from your sensors?


They can be bouncy but considering my use (attaching and detaching as I am) I feel that a bouncy signal shouldn't be an issue. Is there a guide some where that shows me how to extract the arduino main headers and perhaps the compiler code? (assuming the compiler isn't written in assembly) I'd like to take a look at it myself. I'm assuming this is just a simple glitch (as if any glitch is simple) that will probably be fixed prior to moving the DUE compiler to official release.

I can't see that it's a bug in the compiler, but if you reckon you can decipher the GCC source code knock yourself out :)

I can see that there would be a bug in the Arduino libraries, especially for the Due. I'm downloading 1.5.5 (not r2) now to see what they have done. I did look at 1.5.0 and the code did not make sense, doesn't seem to be finished in the attachInterrupt() func.


You're probably right, blaming the compiler is probably a bit overboard. I found the library files.


I think that is the path location for them. (correct me if I'm wrong)

I looked at WInterrupts.c and WInterrupts.h and I see how detach and attach work so I'm fairly convinced the issue doesn't exist there. (from what I understand, few comments and ambiguous variable names make it quite difficult to understand)

Still looking for interrupts(); and noInterrupts();

On a side note the compiler doesn't recognize cli(); and sei(); I'm unsure why that is but perhaps that is related.



CLI and SEI are AVR-specific assembly instructions, IIRC cli(); and sei() are just macros for them so they won't be defined on a SAM.

in wiring_constants.h you will find

define interrupts() __enable_irq()

define noInterrupts() __disable_irq()

so this is the SAM equivelant to CLI/SEI although in the case of an ARM I think you will find that __enable_irq() and __disable_irq() are not native instructions but actually small functions. Certainly I've written my own versions on an LPC.

These do not allow for nesting interrupts which can be a gotcha, but I don't think (m)any people nest interrupts in the Arduino world. But another thing is that in many environments you shouldn't just enable interrupts without knowing that they were enabled before you disabled them, these Arduino macros do not test for that.

All very interesting I'm sure but I suspect nothing to do with your problem.


Well now I'm stumped! I figured that there was more to interrupts(); and noInterrupts(); than just calling the SAM defined functions.

I suppose for now I will just compensate for the interrupt double call in my code. Someone I know was having the same issue and was unsure if it always called twice or if it sometimes called 3 times. I will try and do some extensive testing tonight or tomorrow to find out the answer to this question.