Pushpa Gangashanaiah
Pushpa Gangashanaiah

Reputation: 31

GPIO: Getting ISR on both edges though edge is set to ''rising"

Specific GPIO pin is connected to switch, upon pressing the switch the ISR needs to triggered. So I have the user space application to read the ISR, but I am getting the ISR on both the edges.

Receiving the interrupt when switch is pressed and also when released. How to configure to receive the ISR only on rising edge

 #include <stdio.h>
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <poll.h>

 int main(int argc, char *argv[]) {
    int fd;
    char value;
    struct pollfd poll_gpio;

    poll_gpio.events = POLLPRI;

    // export GPIO
    fd = open ("/sys/class/gpio/export", O_WRONLY);
    write (fd, "44", 4);
    close (fd);

    // configure as input
    fd = open ("/sys/class/gpio/gpio44/direction", O_WRONLY);
    write (fd, "in", 3);
    close (fd);

    // configure interrupt
    fd = open ("/sys/class/gpio/gpio44/edge", O_WRONLY);
    write (fd, "rising", 7); // configure as rising edge
    close (fd);

    // open value file
    fd = open("/sys/class/gpio/gpio44/value", O_RDONLY );
    poll_gpio.fd = fd;

    poll (&poll_gpio, 1, -1); // discard first IRQ
    read (fd, &value, 1);

    // wait for interrupt
    while (1) {
         poll (&poll_gpio, 1, -1);
         if ((poll_gpio.revents & POLLPRI) == POLLPRI) {
             lseek(fd, 0, SEEK_SET);
             read (fd, &value, 1);
             usleep  (50);
             printf("Interrupt GPIO val: %c\n", value);
         }
    }

    close(fd); //close value file
    return EXIT_SUCCESS;
 }

Upvotes: 1

Views: 1417

Answers (1)

Pushpa Gangashanaiah
Pushpa Gangashanaiah

Reputation: 31

I used gpio test driver also to test the ISR, but even in driver code I am getting ISR on both edges when the switch is pressed Here is the gpio test driver code

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/gpio.h>

#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/timer.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("");
MODULE_DESCRIPTION("A Button driver for the GPIO Switch");
MODULE_VERSION("0.1");

#define GPIO_NUM    44
#define GPIO_KEY_NAME   "GPIO_INT_KEY"
static int irq;

/* interrupt handler*/
static irqreturn_t gpio_int_key_isr(int irq, void *dev_id)
{
    
    printk(KERN_INFO "GPIO:Interrupt received. key: %s\n", GPIO_KEY_NAME);
    return IRQ_HANDLED;
}

static int __init gpio_test_probe(struct platform_device *pdev)
{
    int ret_val;
    struct device *dev = &pdev->dev;

    printk(KERN_INFO "GPIO Platform_probe enter\n");

    gpio_request(GPIO_NUM, "sysfs");
    gpio_direction_input(GPIO_NUM);
    gpio_set_debounce(GPIO_NUM, 200);
    gpio_export(GPIO_NUM, false);

    irq = gpio_to_irq(GPIO_NUM);
    if (irq < 0)
    {
        pr_err("IRQ is not available\n");
        return -EINVAL;//1;
    }
    printk(KERN_INFO "IRQ using gpio_to_irq: %d\n", irq);

    /*Register the interrupt handler*/
    ret_val = devm_request_irq(dev, irq, gpio_int_key_isr, IRQF_TRIGGER_RISING,  GPIO_KEY_NAME, pdev->dev.of_node);
    if(ret_val)
    {
        pr_err("Failed to request GPIO interrupt %d, error %d\n",irq, ret_val);
        return ret_val;
    }

    return 0;
}

static int __exit gpio_test_remove(struct platform_device *pdev)
{
    pr_info("%s function is called. \n",__func__);
    return 0;
}

/*Declare list of devices supported by the driver*/
static const struct of_device_id my_of_ids[] = {
        { .compatible = "gpio-intr-key"},
        {},
};

MODULE_DEVICE_TABLE(of, my_of_ids);

/*Define platform driver structure*/
static struct platform_driver my_platform_driver = {
        .probe = gpio_test_probe,
        .remove = gpio_test_remove,
        .driver = {
                .name = "gpioIntrKey",
                .of_match_table = of_match_ptr(my_of_ids),
                .owner = THIS_MODULE,
        }
};

module_platform_driver(my_platform_driver);

Below is the dts entry

gpio_test {
            compatible = "gpio-intr-key";
            gpio = <&gpio2a 44>;
            interrupt-controller;
            interrupt-parent = <&gpio2a>;
            interrupts = <44 IRQ_TYPE_EDGE_RISING>;
            status = "okay";
    };

Upvotes: 2

Related Questions