Skip to content
This repository has been archived by the owner on Apr 16, 2021. It is now read-only.

Only one pin interrupt supported #7

Closed
ohazi opened this issue Sep 1, 2019 · 5 comments
Closed

Only one pin interrupt supported #7

ohazi opened this issue Sep 1, 2019 · 5 comments

Comments

@ohazi
Copy link

ohazi commented Sep 1, 2019

Attaching interrupts for multiple pin change events via attachInterrupt(...) doesn't appear to work on the new nRF52840 based nano boards.

In the simplified test case below, the first call to attachInterrupt appears to work (falling edge of IN3, or pin 6). The other ones don't work. You can change the order of the attachInterrupt calls to get a different pin change interrupt to start working, but I've only ever seen one interrupt working at a time.

I think pins 4, 5, and 6 are actually pins P1_15, P1_13, and P1_14 on the nRF52840 (from variant.cpp), although this could be wrong (the documentation for these new nano boards is pretty lacking). Could this be because all of the inputs are on the same port? This normally isn't a restriction, e.g. when using Nordic's SDK, although I haven't used mbed on a Nordic IC.

In any case, this seems like a bug.

#define IN1 4
#define IN2 5
#define IN3 6

// LEDs
#define OUT1  22
#define OUT2  23
#define OUT3  24

int out1 = 1;
int out2 = 1;
int out3 = 0;

void in1_handler() {
  out1 = (out1 + 1) % 2;
  digitalWrite(OUT1, out1);
}

void in2_handler() {
  out2 = (out2 + 1) % 2;
  digitalWrite(OUT2, out2);
}

void in3_handler() {
  out3 = (out3 + 1) % 2;
  digitalWrite(OUT3, out3);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  while(!Serial) {}
  Serial.println("setup");

  digitalWrite(OUT1, out1);
  digitalWrite(OUT2, out2);
  digitalWrite(OUT3, out3);

  pinMode(OUT1, OUTPUT);
  pinMode(OUT2, OUTPUT);
  pinMode(OUT3, OUTPUT);

  pinMode(IN1, INPUT_PULLUP);
  pinMode(IN2, INPUT_PULLUP);
  pinMode(IN3, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(IN3), in3_handler, FALLING);
  attachInterrupt(digitalPinToInterrupt(IN2), in2_handler, FALLING);
  attachInterrupt(digitalPinToInterrupt(IN1), in1_handler, FALLING);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("delay");
  delay(500);
}
@ohazi
Copy link
Author

ohazi commented Sep 1, 2019

@ohazi
Copy link
Author

ohazi commented Sep 1, 2019

ARMmbed/mbed-os#10949

@DuncanLHS
Copy link

Confirmed here also. Simple sketch reading a rotary encoder that should use 2 interrupts only one works.

@sandeepmistry
Copy link
Contributor

There's a tip by @ohazi on the forum for this: https://forum.arduino.cc/index.php?topic=634250.msg4295322#msg4295322

ohazi added a commit to ohazi/ArduinoCore-nRF528x-mbedos that referenced this issue Sep 5, 2019
ARMmbed/mbed-os@79c7fa1

- Set GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS and
NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS to 8 to allow more pin
interrupt sources. This addresses
arduino#7
- Cherry pick manual edits to cores/arduino/mbed/ after running
mbed-os-to-arduino script.
@ohazi
Copy link
Author

ohazi commented Sep 5, 2019

I have a fix for this here: https://github.com/ohazi/ArduinoCore-nRF528x-mbedos

To get here, I went through the steps in the mbed-os-to-arduino script. After a lot of false starts, I eventually ended up using this branch: https://github.com/ARMmbed/mbed-os/tree/mbed-os-5.14

Before compiling mbed-os, I changed GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS and NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS from 1 to 8 in:

mbed-os/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/config/sdk_config.h

This should increase the number of available pin interrupts from 1 to 8. You can change this to a larger number if you need more, but 8 seemed reasonable.

Note that you need to make this change before you compile mbed-os because it ends up affecting libmbed.a -- you can't just edit the copied header (in cores/arduino/mbed/).

The mbed-os-to-arduino script wipes the /cores/arduino/mbed/ directory and refills it with headers from the mbed-os version that it's building. But there are a few manual edits that have been made to these headers, so you have to cherry-pick those and reapply them after the headers have been copied.

I then found a bug (#9), as well as a workaround.

I can now run the original example (3 pin interrupt sources), and it works as expected.

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

Successfully merging a pull request may close this issue.

3 participants