Reputation: 31
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
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