Unexpected Behavior with GPIO_INT_EDGE_BOTH Interrupt on Button Release in nRF Connect SDK

I'm encountering an issue with the use of the GPIO interrupt type GPIO_INT_EDGE_BOTH on a GPIO connected to a button. When pressed, the button pulls the GPIO to GND, and when released, it sets it to VDD. Searching online, I found that others have faced the same issue, but I couldn't find a clear explanation or a well-thought-out solution.

The problem is that when the button is pressed, the callback function is called as expected, providing the correct GPIO value. However, when the button is released, the callback function is called twice: first, it reports the previous GPIO value, and only afterward does it provide the correct value. I simplified my code to isolate the issue (nRF Connect SDK 2.6.1):

static const struct gpio_dt_spec signalTouch = GPIO_DT_SPEC_GET(DT_NODELABEL(touch_mcu), gpios);
static struct gpio_callback signalTouchCbData;

gpio_pin_configure_dt(&signalTouch, GPIO_INPUT) < 0);

if (gpio_pin_interrupt_configure_dt(&signalTouch, GPIO_INT_EDGE_BOTH) != 0) {
    return;
}

gpio_init_callback(&signalTouchCbData, Signal_Touch_Changed_Callback, BIT(signalTouch.pin));
gpio_add_callback(signalTouch.port, &signalTouchCbData);

static void Signal_Touch_Changed_Callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {
    int touchState;

    touchState = gpio_pin_get_dt(&signalTouch);
    LOG_WRN("touchState: %d at %lld", touchState, k_uptime_get());
}

The code produces the following output:

00> [00:00:10.980,895] <wrn> app: touchState: 1 at 10980  <--- button pressed
00> [00:00:12.531,433] <wrn> app: touchState: 1 at 12531  <--- button released
00> [00:00:12.531,585] <wrn> app: touchState: 0 at 12531
00> [00:00:18.167,999] <wrn> app: touchState: 1 at 18167  <--- button pressed
00> [00:00:20.063,323] <wrn> app: touchState: 1 at 20063  <--- button released
00> [00:00:20.063,476] <wrn> app: touchState: 0 at 20063

What is causing this issue?

Related