Handling GPIO interrupts using Zephyr gpio.h while using DK_Buttons_and_LEDs driver make unwanted behavior for the rising edge trigger just when "GPIO_INT_EDGE_BOTH" flag is used.

Hello,

While I was handling GPIO interrupts using Zephyr GPIO Driver in an sample that already uses the DK Buttons and LEDs driver, I get that the interrupt callback is called twice at the rising edge when the interrupt was configured using "GPIO_INT_EDGE_BOTH", this flag only is what cause the issue.

When I disabled the DK Buttons and LEDs driver the issue disappeared!

Here are my code:

/*
 * Copyright (c) 2016 Open-RnD Sp. z o.o.
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/printk.h>
#include <inttypes.h>

#include <dk_buttons_and_leds.h>

#define SLEEP_TIME_MS	1

/*
 * Get button configuration from the devicetree sw0 alias. This is mandatory.
 */
#define SW0_NODE	DT_ALIAS(sw1)
#if !DT_NODE_HAS_STATUS(SW0_NODE, okay)
#error "Unsupported board: sw0 devicetree alias is not defined"
#endif
static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios,
							      {0});
static struct gpio_callback button_cb_data;

/*
 * The led0 devicetree alias is optional. If present, we'll use it
 * to turn on the LED whenever the button is pressed.
 */
static struct gpio_dt_spec led = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios,
						     {0});

void button_pressed(const struct device *dev, struct gpio_callback *cb,
		    uint32_t pins)
{
	(gpio_pin_get_dt(&button)) ? printk("Button pressed \n") : printk("Button released \n");
}




void ButtonEventHandler(uint32_t buttonState, uint32_t hasChanged)
{
	printk("ButtonEventHandler was called \n");

}





int main(void)
{
	int ret;

	/* Initialize buttons */
	ret = dk_buttons_init(ButtonEventHandler);
	if (ret) {
		printk("Error: ButtonEventHandler \n");
		return 0;
	}


	if (!gpio_is_ready_dt(&button)) {
		printk("Error: button device %s is not ready\n",
		       button.port->name);
		return 0;
	}

	ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
	if (ret != 0) {
		printk("Error %d: failed to configure %s pin %d\n",
		       ret, button.port->name, button.pin);
		return 0;
	}

	ret = gpio_pin_interrupt_configure_dt(&button,
					      GPIO_INT_EDGE_BOTH);
	if (ret != 0) {
		printk("Error %d: failed to configure interrupt on %s pin %d\n",
			ret, button.port->name, button.pin);
		return 0;
	}

	gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
	gpio_add_callback(button.port, &button_cb_data);
	printk("Set up button at %s pin %d\n", button.port->name, button.pin);

	if (led.port && !device_is_ready(led.port)) {
		printk("Error %d: LED device %s is not ready; ignoring it\n",
		       ret, led.port->name);
		led.port = NULL;
	}
	if (led.port) {
		ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT);
		if (ret != 0) {
			printk("Error %d: failed to configure LED device %s pin %d\n",
			       ret, led.port->name, led.pin);
			led.port = NULL;
		} else {
			printk("Set up LED at %s pin %d\n", led.port->name, led.pin);
		}
	}

	printk("Press the button\n");
	if (led.port) {
		while (1) {
			/* If we have an LED, match its state to the button's. */
			int val = gpio_pin_get_dt(&button);

			if (val >= 0) {
				gpio_pin_set_dt(&led, val);
			}
			k_msleep(SLEEP_TIME_MS);
		}
	}
	return 0;
}


Response for just one press:

*** Booting Zephyr OS build v3.3.99-ncs1 ***
Set up button at gpio@842500 pin 24
Set up LED at gpio@842500 pin 28
Press the button
Button pressed 
Button pressed 
ButtonEventHandler was called 
Button released 
ButtonEventHandler was called 

Why is this happening?

How can I prevent it?

Best regards,

Basem

Parents
  • Hi Basem,

    Why are you using the DK button and LED library when you are configuring the pin yourself?

    you can achieve what you want to do by just configuring the pin as you are doing and not using the DK button lib, or just by using the DK button lib. Below I am just using the DK button library and removed pin interrupt config from the main. I can see clock cycles when the button is pressed and released:

    (showing short, short and long button press).

  • Why are you using the DK button and LED library when you are configuring the pin yourself?

    Hi Naeem,

    Thank you for your response, and actually I'm using Matter: Template sample to create my matter light bulb device, and this sample uses the DK button and LED library, where I used zephyr GPIO.h, I just didn't modify what the sample uses.

    The behavior I got is strange and I can't understand its reason.

    I can't use the DK button and LED library because I think it can't provide more than 4 LEDs and 4 buttons, and I need to control 10 buttons and around 10 LEDs.

    Regards,

    Basem

Reply
  • Why are you using the DK button and LED library when you are configuring the pin yourself?

    Hi Naeem,

    Thank you for your response, and actually I'm using Matter: Template sample to create my matter light bulb device, and this sample uses the DK button and LED library, where I used zephyr GPIO.h, I just didn't modify what the sample uses.

    The behavior I got is strange and I can't understand its reason.

    I can't use the DK button and LED library because I think it can't provide more than 4 LEDs and 4 buttons, and I need to control 10 buttons and around 10 LEDs.

    Regards,

    Basem

Children
Related