The first falling edge after a reset on PIN PD7 (PE3, PB7, ...) does not cause an interrupt

The first falling edge after a reset on PIN PD7 (PE3, PB7, …) does not cause an interrupt. Why?
Tested on SM20260D Dev and custom board with SCM20260N. FW 2.2.0.61

var gpio = GpioController.GetDefault();

var button = gpio.OpenPin(SC20260.GpioPin.PD7);
button.SetDriveMode(GpioPinDriveMode.InputPullUp);
button.ValueChangedEdge = GpioPinEdge.FallingEdge | GpioPinEdge.RisingEdge;
button.ValueChanged += Button_ValueChanged;
button.DebounceTimeout = TimeSpan.FromMilliseconds(50);

Thread.Sleep(Timeout.Infinite);

void Button_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e)
{
    if (e.Edge == GpioPinEdge.FallingEdge)
    {
        Debug.WriteLine("Pin went low");
    }
    else
    {
        Debug.WriteLine("Pin went high");
    }
}

I’ve also noticed this issue on many gpio pins! For example button won’t trigger interrupt event until the second time it is pressed.

1 Like

Could it be this?

SITCore Interrupt limitation

Digital input events rely on internal GPIO interrupts to work. On SITCore, these interrupts are only available on 16 pins at any given time, the pin number must be unique, over all of the available ports. For example: PA1 and PB1 cannot both be used as interrupts at the same time. However, PA1 and PB2, or even PA1 and PA2, can be used simultaneously.

Consider other internal system functions that need interrupts, such as WiFi. Those also reserve one of the 16 available interrupts.

PD7 and PB7 use the same interrupt.

@Mike, how many interrupts do you think I used in the example to verify the issue?

I’ve noticed this too.

In our case we are using it to wake the app up when a user presses a button, if it doesn’t wake the first time they will just press again so no big issue, but annoying.

On the other hand the “random” failure to wake on RTC depending on actual time, which seems to be due to an internal math error, is currently a real show-stopper for us :slightly_frowning_face:

@C_Born, @willcooper12 , it can be partially bypassed as follows

button.ValueChangedEdge = button.Read() == GpioPinValue.High ? GpioPinEdge.FallingEdge : GpioPinEdge.FallingEdge | GpioPinEdge.RisingEdge;

and redefine the edges in the interrupt handler

button.ValueChangedEdge = GpioPinEdge.FallingEdge | GpioPinEdge.RisingEdge;

The whole solution:

var gpio = GpioController.GetDefault();

var button = gpio.OpenPin(SC20260.GpioPin.PD7);
button.SetDriveMode(GpioPinDriveMode.InputPullUp);
button.ValueChangedEdge = button.Read() == GpioPinValue.High ? GpioPinEdge.FallingEdge : GpioPinEdge.FallingEdge | GpioPinEdge.RisingEdge;
button.ValueChanged += Button_ValueChanged;
button.DebounceTimeout = TimeSpan.FromMilliseconds(50);

Thread.Sleep(Timeout.Infinite);

void Button_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e)
{
    if (e.Edge == GpioPinEdge.FallingEdge)
    {
        Debug.WriteLine("Pin went low");
    }
    else
    {
        Debug.WriteLine("Pin went high");
    }

    button.ValueChangedEdge = GpioPinEdge.FallingEdge | GpioPinEdge.RisingEdge;
}

I am also waiting for the RTC issue to be resolved, I am delivering 200pcs of devices to a customer in January 24.

1 Like

We are working on RTC issue.