Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHANGE option for attachInterrupt() is not implemented #463

Open
EmbeddedMan opened this issue Mar 9, 2021 · 7 comments
Open

CHANGE option for attachInterrupt() is not implemented #463

EmbeddedMan opened this issue Mar 9, 2021 · 7 comments

Comments

@EmbeddedMan
Copy link
Member

chipKIT currently has no ability to trigger interrupts on CHANGE, only on RISING or FALLING (since that's all that the hardware supports). It might be possible to add support for CHANGE through software.

@JacobChrist
Copy link
Member

I could be mistaken but it appears that every GPIO pin of the PIC32MX has individually selectable change notice interrupt capability. My only lack of clarity is if this is truly implemented on every GPIO pin of every processor but I suspect that it is. To use it though requires some pooling the interrupt flags in the interrupt to see which pin triggered it.

@majenkotech
Copy link
Member

majenkotech commented Mar 9, 2021

Older MX chips ('795 and the like) have change notification on some pins, but not all. The newer ones have it on all pins. But CN is awkward to use as there is one ISR per port, not per pin, which adds overhead in working out what pin actually caused the interrupt. And on the older chips there's no direct relationship between CN number and pin number, so that has to be looked up in a table. Not always desirable when you want interrupts to respond quickly.

@JacobChrist
Copy link
Member

JacobChrist commented Apr 5, 2021

So I was able to turn an edge triggered interrupt into a change interrupt by adding the following function to WInterrupts.c

int  getInterruptMode(uint8_t interruptNum)
{
	return intmode[interruptNum];
}

Adding a prototype to wiring.h

int  getInterruptMode(uint8_t interruptNum);

The using the interrupt like this:

void isr0() 
{ 
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // toggle pin 1
  Serial.print("ISR0 ");
  if(getInterruptMode(digitalPinToInterrupt(24)) == FALLING)
  {
    Serial.print("FALLING EDGE");
    attachInterrupt(digitalPinToInterrupt(24), isr0, RISING);
  }
  else
  {
    Serial.print("RISING EDGE");
    attachInterrupt(digitalPinToInterrupt(24), isr0, FALLING);
  }
  Serial.println();
}

void setup() 
{ 
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(PIN_INT0, INPUT);         // Interrupt pin must be an input
  digitalWrite(1, LOW);
  
  Serial.begin(115200);  // Open the Serial Port
  while(!Serial);
  delay(100);  // Give the serial terminal chance to open
  // Fubraino Mini 2.0 Interrupt Pins: 0, 3, 4, 6, 24
  attachInterrupt(digitalPinToInterrupt(24), isr0, FALLING);
}

void loop() 
{
  delay(1000);
}

EDIT: Example code snip tested on a Fubarino Mini 2.0

@EmbeddedMan
Copy link
Member Author

This would be a nice addition to the core Jacob. Would you be willing to prepare a PR?

@EmbeddedMan
Copy link
Member Author

If not, then maybe just edit the Fubarino Wiki with this example so that others can easily follow in your footsteps?

@JacobChrist
Copy link
Member

So my issue has always been setting up a clean ways to commit changes to the core from Windows. Tonight I got the IDE setup on one of my Linux servers and I'm going to take a crack at it. Ultimately it would be nice to implement the CHANGE mode in the core and hide the details from the users.

@majenkotech
Copy link
Member

Theoretically you can also emulate CHANGE mode interrupts on ICx pins...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants