arduino / ArduinoCore-nRF528x-mbedos

[Archived] Arduino core supporting mbed-enabled boards
86 stars 34 forks source link

attachInterrupt() always pulls pin HIGH #77

Open rmlearney-digicatapult opened 4 years ago

rmlearney-digicatapult commented 4 years ago

Hi,

I'm trying to set an interrupt based on detecting a RISING edge using the BLE33. However, the pin reads HIGH after startup. Same happens with pinMode(buttonPin, INPUT_PULLDOWN) followed by attachInterrupt(). It's the attachInterrupt() that pulls it HIGH.

Am I doing something wrong or misunderstanding what's going on here?

const uint8_t buttonPin = 9;

void setup(){
  pinMode(buttonPin, INPUT_PULLDOWN);
  attachInterrupt(digitalPinToInterrupt(buttonPin), buttonISR, RISING);
}

void loop(){}
rmlearney-digicatapult commented 4 years ago

After further investigation this is more serious than I thought. The following code works perfectly well on AVR devices (tested on Nano Every and Duemilanove), but fails on the BLE33:

const uint8_t buttonPin = 2;
const uint8_t testPin = A3;

volatile boolean newPress = false;

void setup(){
  pinMode(testPin, OUTPUT);
  digitalWrite(testPin, HIGH);

  attachInterrupt(digitalPinToInterrupt(buttonPin), buttonISR, RISING);
}

void loop(){
  if(newPress){
    newPress = false;
  }

void buttonISR(void){
  newPress = true;
}

For both the Nano Every and Duemilanove, testPin is HIGH as expected, and buttonPin is LOW as expected.

On the BLE33, testPin is HIGH but buttonPin is also HIGH.

@facchinm I don't think your PR #31 solves this one :(

rmlearney-digicatapult commented 4 years ago

This is turning out to be a fatal issue for something I'm developing.

Does the solution lie in attachInterruptParam of Interrupts.cpp, or is this something mbed themselves have to fix?

 mbed::InterruptIn* irq = new mbed::InterruptIn(digitalPinToPinName(interruptNum));
chibiconsulting commented 4 years ago

I have also tested this and can confirm that only setting up the Pin mode works correctly as expected on Arduino Nano 33 BLE Sense. Examples: pinMode(interruptPin, INPUT); generates a floating input pin. pinMode(interruptPin, INPUT_PULLUP); generates an input pulled high. pinMode(interruptPin, INPUT_PULLDOWN); generates an input pulled low.

However, for any attach Interrupt command, the interruptPin is then pulled high. I would expect that calling attachInterrupt should not change the already set pinMode. Examples: attachInterrupt(digitalPinToInterrupt(interruptPin), buttonISR, CHANGE); generates an input pulled high. attachInterrupt(digitalPinToInterrupt(interruptPin), buttonISR, FALLING); generates an input pulled high. attachInterrupt(digitalPinToInterrupt(interruptPin), buttonISR, HIGH); generates an input pulled high. attachInterrupt(digitalPinToInterrupt(interruptPin), buttonISR, LOW); generates an input pulled high. attachInterrupt(digitalPinToInterrupt(interruptPin), buttonISR, RISING); generates an input pulled high.

Perhaps more troubling, to me at least, is that asserting an interrupt condition on the hardware pin does not trigger the interrupt call in software; rather, it crashes the Arduino Nano 33 BLE Sense requiring a hard reboot. Specifically this test interrupt only generates a response by pulling the interruptPin LOW, which crashes the Arduino Nano 33 BLE Sense.

Tested using Arduino 1.8.12 with an Arduino Nano 33 BLE Sense with board manager current as of today.

rmlearney-digicatapult commented 4 years ago

So I've been trying to convince myself for the past 3 days that this is a hardware or software fault on my side. I've rebuilt my circuit over again and tried every trick I know.

The button example I gave above was just a basic test for what I'm doing - I'm actually communicating with an interrupt-triggered precision ADC over SPI. My library and code work absolutely fine using the exact same pinouts on a Duemilanove and Nano Every.

Even using a 3.3V -> 5V shifter on SCLK/MISO/MOSI/!CS (the ADC is 5V tolerant) still works perfectly on the AVR systems.

But the exact same code with the exact same pinout and the exact same circuit fails on the Nano BLE 33. This is an extremely serious problem for a flagship new product line from Arduino.

@facchinm and others - can we ask that you address this issue as a matter of urgency? Being unable to use interrupt-triggered reads of an SPI ADC is a very serious flaw in your MBed devices that doesn't exist in your AVR devices.

chibiconsulting commented 4 years ago

@rmlearney-digicatapult This is unlikely to be caused by your or my improper/proper use of the software or hardware. I have just opened a brand new NANO 33 BLE and confirmed the exact same response without attaching any hardware other than a jumper wire to test the pin voltage and interrupt behavior.

The interrupt pin is pulled high even if the pin is not previously defined; so the following code will reproduce this at will; and crash the NANO 33 BLE when the pin is externally pulled LOW.

void setup() {
  attachInterrupt(digitalPinToInterrupt(2), wakeInterrupt, LOW);
  Serial.begin(9600);

}
void loop() {}
void wakeInterrupt(void){
Serial.println("Interrupt received");
}

This happens on any input capable pin and any variety of attachInterrupt as noted previously. Note that this program is just a bare minimum to compile and reproduce the error.

Edited : Sorry, the CRASH only happens with a valid function to call. The pin pulling high happens in any case.

facchinm commented 4 years ago

@chibiconsulting the crash is due to Serial.print being called in an interrupt context, while the pullup bug is going to be solved by a modified version of https://github.com/arduino/ArduinoCore-nRF528x-mbedos/pull/31 that will be merged soon.

rmlearney-digicatapult commented 4 years ago

Thank you @facchinm. I've tried the current version of #31 with no luck, so I'm very glad to hear this.

chibiconsulting commented 4 years ago

@facchinm Thank you, that works much better for me.

amirahmady commented 3 years ago

I have the same issue with NANO 33 SENSE! spending 3 days to figure it with interrupts pin is HIGH