Configured GPIO interrupt but ISR is not hitting

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Configured GPIO interrupt but ISR is not hitting

Jump to solution
10,704 Views
phaniteja
Contributor II

Hello,

I am using IMX6.ULL board, I have followed the thread 381277 to configure a GPIO pin and to trigger isr when interrupt happened

DTS changes:

 &iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
pinctrl_hog_1: hoggrp-1 {
fsl,pins = <
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059  /* ADDED THIS LINE */

driver:

#define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr))

#define GPIO_PIN IMX_GPIO_NR(1, 19)
#define INPUT_PIN_DESC "gpio_pin_test"
#define GPIO_DEVICE_DESC "my_device"

gpio_request(gpio_pin, INPUT_PIN_DESC);
gpio_direction_output(gpio_pin, 0);
gpio_export(gpio_pin, false);

gpio_to_irq(gpio_pin);

request_irq(irq_input_pin, (irq_handler_t ) r_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, INPUT_PIN_DESC, GPIO_DEVICE_DESC);


static irqreturn_t r_irq_handler(int irq, void *dev_id) {

unsigned long flags;

local_irq_save(flags);

/* TODO: Need to blink a LED here */
printk(KERN_NOTICE "Interrupt [%d] for device %s was triggered !.\n", irq, (char *)dev_id);

local_irq_restore(flags);

return IRQ_HANDLED;
}

 

After loading driver I am able to see the registered interrupt(cat /sys/proc/interrupts) and I am able to change the value of the gpio(echo 1 > /sys/class/gpio/gpio19/value)

Here are my issues:

1. My ISR is not hitting when I set or clear the GPIO values

2. GPIO19 folder is not showing the direction interface.

Could you anybody suggest what I am missing.

Thanks,

Phani Movva

Labels (2)
0 Kudos
1 Solution
7,311 Views
shivanipatel
Senior Contributor II

Hi Phani,

You are changing the direction of GPIO pin as an output using sysfs. Interrupt can not be generate on output line of GPIO. You need to configure GPIO as an input line and trigger any key or change level of that line externally to generate a interrupt on that GPIO. Basically Interrupt generate when something happen on input line to let us know about the event.

You can find a good explanation of GPIO in this link.

Here I have configured GPIO1_IO21 pin as an interrupt.

I have done the following changes in imx6ul-14x14-evk.dts file.

Changes in imx6ul-14x14-evk.dts file

 gpio-test {
        compatible = "gpio-intr-key";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_gpio_keys>;
        gpio = <&gpio1 21 GPIO_ACTIVE_LOW>;
        interrupts = <21 0>;
        interrupt-parent = <&gpio1>;
    };

pinctrl_gpio_keys: gpio_keysgrp {
            fsl,pins = <
                MX6UL_PAD_UART2_RX_DATA__GPIO1_IO21    0x1b0b0
            >;
        };

With these changes, you need to give HIGH/LOW input externally on that pin then ISR is triggered on that pin.

I have also attached the driver.

Regards,

Shivani

View solution in original post

4 Replies
7,312 Views
shivanipatel
Senior Contributor II

Hi Phani,

You are changing the direction of GPIO pin as an output using sysfs. Interrupt can not be generate on output line of GPIO. You need to configure GPIO as an input line and trigger any key or change level of that line externally to generate a interrupt on that GPIO. Basically Interrupt generate when something happen on input line to let us know about the event.

You can find a good explanation of GPIO in this link.

Here I have configured GPIO1_IO21 pin as an interrupt.

I have done the following changes in imx6ul-14x14-evk.dts file.

Changes in imx6ul-14x14-evk.dts file

 gpio-test {
        compatible = "gpio-intr-key";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_gpio_keys>;
        gpio = <&gpio1 21 GPIO_ACTIVE_LOW>;
        interrupts = <21 0>;
        interrupt-parent = <&gpio1>;
    };

pinctrl_gpio_keys: gpio_keysgrp {
            fsl,pins = <
                MX6UL_PAD_UART2_RX_DATA__GPIO1_IO21    0x1b0b0
            >;
        };

With these changes, you need to give HIGH/LOW input externally on that pin then ISR is triggered on that pin.

I have also attached the driver.

Regards,

Shivani

7,311 Views
rans
Senior Contributor I

Hello Shivan,

Is the "interrupts" node really needed in the above example for dts ?

I think that if the gpio is configured as input and the driver request irq from gpio, than it should be sufficient , Right ?

Thank you,

ran

0 Kudos
7,311 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Phani,

please be aware that interrupts are handled in kernel space.

In the following thread you can find the source code of a kernel module that handles an interrupt Issue with configuring GPIO as an interrupt - i.MX6Q 

Please also refer to generic linux documentation on found on web, like Linux Device Drivers, 2nd Edition: Chapter 9: Interrupt Handling 4.6. Interrupt Handling - Understanding the Linux Kernel, 3rd Edition [Book] and sect.3.2 Interrupts (Operation) i.MX_Linux_Reference_Manual.pdf

The following may also be helpful How do I configure the INT0-INT7 interrupt request of GPIO1 source? 


Regards,
Carlos
NXP Technical Support
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
7,311 Views
phaniteja
Contributor II

Hello Carlos Musich,

Thanks for the response. 

I am still facing some issues with GPIO interrupt. I am attaching the driver that I am using to register GPIO interrupt and dts changes as below

File: "imx6ull-14x14-evk.dts"
&gpiotest {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio>;
status = "okay";
};

pinctrl_gpio: gpiogrp {
fsl,pins = <
MX6UL_PAD_UART5_RX_DATA__GPIO1_IO31 0xb0
>;
};

File: "imx6ull.dtsi"
gpiotest: gpio@020b0000 {
compatible = "fsl,imx-gpiotest";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_key>;
gpios = <&gpio1 31 1>;
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&gpio1>;
};

With the above changes and driver, following  are my observations:

1. The pin I selected is having always 3.3v and I am able to get interrupt for 5 times as soon as I load module and later if I do following steps:

$ echo out > direction

$ echo 1 > value

$ echo in > direction

Here I am getting interrupt when I am following above three steps.

Question:

1.Is my pin(GPIO1_IO31) pad settings are correct ?

2. As the voltage on pin is always high, Why it is generating interrupt only when I change the direction ? Is this the correct way of testing for this particular pin?

2. If I select any other pin like GPIO1_IO15 (MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15) with pad value 0xb0, its not at all hitting the ISR. This pin default value is 0v and to generate interrupt I am shorting this pin with 3.3v. But its not generating any interrupt.

Question:

1.Is my pin(GPIO1_IO15 ) pad settings are correct ?

2.As the pin direction is configured as input, I am expecting a interrupt when ever I am giving voltage signal to the pin. Am I doing any wrong here in the hardware connection ?

Could you please suggest the proper pin and simple procedure to test the interrupt?

0 Kudos