Analog/GPIO pins not recognizing digital interrupts

I’m using a SC20260D and I’m trying to use pin PA5 as a GPIO digital interrupt for a temperature sensor. If I poll the pin manually, I can see the value change from high to low when the alert hits. However, when I configure the pin to interrupt on change (as in the GPIO input tutorial), the interrupt never happens.

I’ve noticed this issue on all pins that are simultaneously used as ADC pins. So, I would like to know if there is a different way to configure these ADC pins as digital interrupts, or if there is a mistake in the pinout documentation.

Many thanks!

1 Like

What kind of temperature sensor are you using? I would not expect an interrupt to work on a ADC input.

Atmel AT30TS75A

According to the documentation, the pin is listed as PA5/ADC12.19/DAC2 and can operate as either GPIO or ADC.

Are you using a pull-up?

Nope! just a straight connection.

It’s weird because when I read normally using “gpioPinName.Read()”, the value is always correct. It’s just the interrupt for some reason…

Here is an example of my code:

//Initialize the interrupt pin
GpioPin _tempInterruptPin = GpioController.GetDefault().OpenPin(SC20260.GpioPin.PA5);
_tempInterruptPin.SetDriveMode(GpioPinDriveMode.InputPullUp);
_tempInterruptPin.ValueChangedEdge = GpioPinEdge.FallingEdge | GpioPinEdge.RisingEdge;
_tempInterruptPin.ValueChanged += TemperatureAlert;

///Invoked if the temp goes outside the specified range
public void TemperatureAlert(GpioPin sender, GpioPinValueChangedEventArgs e)
{
. . . . if (_tempInterruptPin.Read() == GpioPinValue.Low)
. . . . {
. . . . . . . . //alert has been triggered
. . . . }
}

Instead of reading the pin have you tried this in your Event to see what Change Event occurred?

if (e.Edge == GpioPinEdge.FallingEdge) {
        // Pin went low
    } else {
        // Pin went high
    }

No pull-up no work. Read the data sheet.

2 Likes

Why not? If the input is actively driven by something else pull ups should not be necessary.

@Skeller - the interrupt “TemperatureAlert” is never called, so it never even checks the pin value

@Mike - Is that specific to the ADC pins or for all GPIO pins? I get the normal GPIO pins without ADC to work just fine - no pull up required.

Have you tried it with only 1 ValueChangedEdge option? There is something in the back of my mind that I tried Rising and Falling edge and had an issue, but maybe I am mistaken. It would at least simplify it some for testing purposes.

Neither. It is specific to the pin on the chip you are using.

Do you understand the text below from the datasheet?

Alert: The ALERT pin is an open-drain output pin used to indicate when the temperature goes beyond the user-programmed temperature limits.

Activate a pull-up on the input pin and see if it helps.

It is not being “actively” driven. The driving pin is open-drain.

1 Like

I think we might be getting side tracked… unless I’m not understanding this correctly (which is very possible).

Again, if I poll the gpio pin using a while loop, and simply read it’s value using _tempInterruptPin.Read(), I can see the value change from high to low and vice versa. The pin is working and GHI board can successfully read it. The only issue is the intended interrupt function is not being invoked.

I appreciate all the responses! Let me know if I am still off track, thanks!
P.S. @skeller I will try doing one edge and report back

Not invoked at all or not correct?

If not at all, just pull the pin high or low so we can see.

If not correct then default debounce is 20ms and your device triggered less than 20ms. Try to change this smaller or zero if it help.

I don’t think this is part of your problem, but the above code has a sort of race condition.

I have not seen any discussion on how interrupts are handled in TinyClr, but I assume it is the similar to .Net Micro Framework.

When an interrupt occurs, your handler is not called directly. Rather, an interrupt block is created and placed on an internal queue. The associated interrupt handler is then scheduled to run on the event thread.

What this means is there is a delay between the time that the interrupt condition occurs and your handler is dispatched.

In the code snippet you showed, you are reading the current state of the input pin. But, the current state of the pin may not reflect its state when the interrupt fired.

The preferred method is to use the pin state in the GpioPinValueChangedEventArgs object passed to the interrupt. This object contains information about the pin at the time of the interrupt.

Yes, reading the state here is not correct if the state changed quickly.

I think “GpioPinValueChangedEventArgs e” has a field that tell the state caused interrupt. Or simple, just remove checking state to see if interrupt is fired.