Interrupts on DUE. Odd behaviour of attachinterrupt()

I was having a problem testing interrupts on a DUE.

It seemed to me that the ISR routine, where a flag was being set, was being called when there was no interrupt. The interrupt pin was an alarm wake up from an RTC.

Mr Google found this;

And the code needed to make attachinterrupt() behave was;

volatile boolean Flag;      

void setup()
{
  Serial.begin(250000);
  pinMode(6, INPUT);
  PIOC->PIO_ISR;                    // Clear status register
  NVIC_ClearPendingIRQ(PIOC_IRQn);  // Clear pending ISR
  attachInterrupt(6, message, LOW);
}

void loop()
{

  if ((Flag == true)){
    Serial.println(" pin 6 is low ");
    Flag = false;
  }
}

void message()
{ 
  Flag = true; 
}

These two lines, for the port the pin was on, were needed to prevent the attachinterrupt() from triggering the ISR call;

PIOC->PIO_ISR;                    // Clear status register
NVIC_ClearPendingIRQ(PIOC_IRQn);  // Clear pending ISR

The Arduino rererence for interrupts;

https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Mentions the DUE, but there is no note about the preceding port commands that appear to be needed.

Is there any fix planned, or one that I have missed, when using interrupts on a DUE ?

How would such a fix know what the intended pin configuration should be, because use cases are not always the same?

Well, I tried the fix for a pins on port B as well.

PIOB->PIO_ISR;                    // Clear status register
NVIC_ClearPendingIRQ(PIOB_IRQn);  // Clear pending ISR

If the attachinterrupt() function knows the pin, maybe it could work out the port and apply the two commands ?

attachInterrupt is supposed to just attach an interrupt. Not futz around with I/O pins. It's the programmers responsibility to make sure the pins for an interrupt are configured correctly for the specific hardware that is attached to it.

Which it appears not to, it configures the interrupt in such a way that the ISR is called when there is no interrupt.

Oh, wait, this doesn't configure pins, just the IRQ status. The same thing should apply to interrupt status flags. It's normal that you need to clear them. There may be cases (not saying I can say which) where you don't want to alter those.

Probably, in the case of other interrupts like an input pin interrupt, the hardware itself clears the IRQ flags.

Then the example code provided in the Arduino reference does not match what is actually or normally required.

No example code can be comprehensive. I think you would find that those examples work because they don't behave like this special case. The special case should be documented there. If it isn't, that is a problem...

The actual code lines I was using, that dont work, is;

#define PCF8563INT    11

attachInterrupt(digitalPinToInterrupt(PCF8563INT), wakeUp, LOW);

Seems pretty standard use of the interrupts, rather than special case.

Are there any other Arduino platforms where the attachinterrupt() function also triggers an interrupt ?

attachInterrupt() is not supposed to be a high-level call. It is only supposed to do one thing, attach an interrupt. If the hardware requires more, then it is the programmers responsibility to supply it.

To answer your question directly, I think it is not relevant, in how many cases are extra steps required to make a fully functional interrupt. It just needs to be documented properly.

To require such a basic function to clear flags would both hard code an action that some programs might not want to use, and also create a maintenance nightmare as every implementation of it would have to be continuously vetted and updated.

Keep in mind, it's happening because of a hardware dependency.

The problem is that the requirement is ambiguous. The "attachInterrupt()" will in general should be expected to cause an interrupt if the condition specified has ever occurred. In this case, if the pin was ever LOW. This is apparently not what you want, and we could spend a lot of time arguing about just how ancient an event should be considered, but at least some of the time, this is the correct behavior (what if the pin state had changed just milliseconds before you attached the interrupt?)

The ISR function should be smart enough to actually check the pin state and/or other conditions (time read from the RTC chip?) before it decides that the "alarm" has actually occurred.

It'd be nice if there were a standard "clearInterrupt()" function, or maybe another argument to attachInterrupt, so that you could do this without having to delve into the guts of the chip's GPIO configuration. (but the ISR should STILL check...)

In this case the pin going low has never occured since the processor has come out of reset, so the state of the pin is not ambiguous.

It'd be nice if there were a standard "clearInterrupt()" function, or maybe another argument to attachInterrupt, so that you could do this without having to delve into the guts of the chip's GPIO configuration. (but the ISR should STILL check...)

Thats the point really, and if that were so, then the examples given in the reference would more closely match the reality.

I checked the data sheet. Before being explicitly configured, the pin interrupts will be detected on any input transition, potentially the ones that happen during device startup. And there are a bunch of different register to set, so it might go though intermediate states when other conditions set the int bit. uggh.

Otoh, it looks like reading some of those int statuses might reset the all, which would be a bad thing…. Sigh.

No application programmer should even enable interrupts unless they understand the hardware ramifications. It will never be plug and play, let's not trick people by pretending it can be.

If you start building automatic accomodations into a function like that, it loses its flexibility (neutrality?) and risks side effects.