Internally pulled up interrupt issue and work around

When trying to configure a interrupt pin as internally pulled up theres some flawed logic.
After attachInterrupt is called, pin goes low even though its configured as INPUT_PULLUP.
A HIGH digitalWrite on pins that are INPUT or INPUT_PULLUP are void.

A workaround to the problem seems to be to pinMode the interrupt pin as OUTPUT, attachInterrupt, then digitalWrite HIGH in that order and everything seems to function as its supposed to.

I’m local compiling “latest” branch, and this is on the P1 module. I have not tested this on the Photon or Core.

Im guessing this is a bug thats been created while migrating to the new HAL, I would hunt it down but I really don’t have time.

This would confirm an issue I've just posted. Would setting the pin as a high output then grounding it via something like a button not cause a short?

JumpMaster,

This is true. Because of the issue, it looks like the internal pull-up resistors are not being enabled. Basically because our circuit boards are already done and assembled, we are relying on the fact the component that pulls the interrupt low current limits to under 25mA (the max sink according to table 12 in the STM32F205 datasheet). If your on a breadboard our in a position were you can pull it low through a resister to keep under that max, I wouldn’t recommend dead-heading the pin. I should have been a bit more clear on my original post.

Hi

Are you using the below pinMode=>attachInterrupt way?

  • pin mode INPUT_PULLUP => should use FALLING interrupt mode
  • pin mode INPUT_PULLDOWN => should use RISING interrupt mode

The below is a sample code which works on photon:

#include "application.h"

SYSTEM_MODE(MANUAL);

pin_t myLed = D7;
pin_t myInterruptPin = D3;

void toggleLed(void)
{
    digitalWrite(myLed, 1^digitalRead(D7));
}

void setup()
{
    pinMode(myLed, OUTPUT);

    pinMode(myInterruptPin, INPUT_PULLUP);
    attachInterrupt(myInterruptPin, toggleLed, FALLING);

    //Note: According to current implementation
    //pin mode INPUT_PULLUP => should use FALLING interrupt mode
    //pin mode INPUT_PULLDOWN => should use RISING interrupt mode
}

void loop()
{

}

Also please note on Photon: Following are the shared External Interrupt (EXTI) lines so only one can work at a time:

  • Mode Button, D0, A5 (D0, A5 doesn’t work at present)
  • D1, A4
  • D2, A0, A3
  • D3, DAC
  • D4, A1
1 Like

@JumpMaster & @ProfileElectronics: I’m not able to test your preservations at the moment, but I take your words for it and so I’ve opened an issue on GitHub for this
https://github.com/spark/firmware/issues/585

If you find something like this, creating an issue might lead to better results than just discussing it here.

@ScruffR Thanks for opening the issue. Ill keep that in mind if I run into any other issues.

@satishgn My code is as follows

#include "application.h"

SYSTEM_MODE(MANUAL);

pin_t myLed = P1S4;
pin_t myInterruptPin = A4;

void toggleLed(void)
{
    digitalWrite(myLed, 1^digitalRead(D7));
}

void setup()
{
    pinMode(myLed, OUTPUT);
   
    pinMode(myInterruptPin, OUTPUT);
    attachInterrupt(myInterruptPin, toggleLed, FALLING);
    digitalWrite(myInterruptPin, HIGH);
}

void loop()
{

}

When I pull A4 low it toggles the LED like its supposed too. If I change code to

pinMode(myInterruptPin, INPUT_PULLUP);
attachInterrupt(myInterruptPin, toggleLed, FALLING);

myInterruptPin seems to go low after the attachInterrupt function returns… Not sure why…

I also want to point out that i’m testing only on a P1 module and compiling with "PLATFORM=P1"
Things may me different on the photon.

Thanks for the note about EXT1 on the photon, I wasn’t aware of this. Is this the same deal on the P1 module? If it is, it should be much more clear on the P1 Datasheet

Also, I think the following code from your snippit

//Note: According to current implementation
//pin mode INPUT_PULLUP => should use FALLING interrupt mode
//pin mode INPUT_PULLDOWN => should use RISING interrupt mode

is a bit misleading for anyone else reading this. The interrupt mode is quit independent of the pin mode. It really doesn’t matter who’s doing the pulling-up or pulling-down, or in my working example, if it even thinks its a input at all. The interrupt should fire On the way up, down, or change if thats whats configured in the register.

Well after a clean make and re-flash of the boot-loader, the problem seems to have gone away on my end. I always love a good voodooo mystery bug that happens for no apparent reason. My apologies for blaming the firmware at first sighting, unfortunately i only have one board assembled so far and i wasn’t in a position to test on another device at that moment.

Just to confirm, the code in @satishgn post now works properly.

and hopefully @ScruffR can take down the issue on Github.

Thanks for all the help though!

2 Likes