Interrupts with GPIO1 INT0-7

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

Interrupts with GPIO1 INT0-7

Jump to solution
10,352 Views
benanderson
Contributor II

I am then stuck with needing a gpio that I can use as an interrupt that can also have its cpu affinity changed.  From the freescale imx6 documentation it list several gpio interrupts within the 255 limit.   See this previous post for info on why I want a interrupt below 255: https://community.freescale.com/thread/301130.

*** In the below I am referencing Rev. 0, 11/2012 of the  i.MX 6Dual/6Quad Applications Processor Reference Manual.

I can not find any indication in either the interrupt or the GPIO chapter how the GPIO1 is configured to deliver these interrupts.

Here is a table for the reference manual that shows the IRQ number and source.  However it lists the source as just GPIO1.  I am not sure what GPIO in GPIO1 maps to which INT0-7.  For example does GPIO1_1 map to INT1?   It is also possible I just don't understand how the gpio's work with the interrupts in general.  There seems very little information about this subject in the documentation.

---------------------------------------------

Table 3-1.

.

.

90 GPIO1 INT7 interrupt request.

91 GPIO1 INT6 interrupt request.

92 GPIO1 INT5 interrupt request.

93 GPIO1 INT4 interrupt request.

94 GPIO1 INT3 interrupt request.

95 GPIO1 INT2 interrupt request.

96 GPIO1 INT1 interrupt request.

97 GPIO1 INT0 interrupt request.

.

.

---------------------------------------------

I also see that in mx6.h I have the following.  Which matches up with documentation.

#define MXC_INT_GPIO1_INT7_NUM90
#define MXC_INT_GPIO1_INT6_NUM91
#define MXC_INT_GPIO1_INT5_NUM92
#define MXC_INT_GPIO1_INT4_NUM93
#define MXC_INT_GPIO1_INT3_NUM94
#define MXC_INT_GPIO1_INT2_NUM95
#define MXC_INT_GPIO1_INT1_NUM96
#define MXC_INT_GPIO1_INT0_NUM97
#define MXC_INT_GPIO1_INT15_0_NUM98
#define MXC_INT_GPIO1_INT31_16_NUM99
#define MXC_INT_GPIO2_INT15_0_NUM100
#define MXC_INT_GPIO2_INT31_16_NUM101
#define MXC_INT_GPIO3_INT15_0_NUM102
#define MXC_INT_GPIO3_INT31_16_NUM103
#define MXC_INT_GPIO4_INT15_0_NUM104
#define MXC_INT_GPIO4_INT31_16_NUM105
#define MXC_INT_GPIO5_INT15_0_NUM106
#define MXC_INT_GPIO5_INT31_16_NUM107
#define MXC_INT_GPIO6_INT15_0_NUM108
#define MXC_INT_GPIO6_INT31_16_NUM109
#define MXC_INT_GPIO7_INT15_0_NUM110
#define MXC_INT_GPIO7_INT31_16_NUM111

The manual also has this tidbit about how the GPIO's and Interrupts work.  However I not sure I gain any more insight.

---------------------------------------------

28.2 General Overview

.

.

Each GPIO input has a dedicated edge-detect circuit which can be configured through

software to detect rising edges, falling edges, logic low-levels or logic high-levels on the

input signals. The outputs of the edge detect circuits are optionally masked by setting the

corresponding bit in the interrupt mask register (GPIO_IMR). These qualified outputs are

OR'ed together to generate two one-bit interrupt lines:

• Combined interrupt indication for GPIOx signals 0 - 15

• Combined interrupt indication for GPIOx signals 16 - 31

In addition, GPIO1 provides visibility to each of its 8 low order interrupt sources (i.e.

GPIO1 interrupt n, for n = 0 – 7). However, individual interrupt indications from other

GPIOx are not available.

---------------------------------------------

The last paragraph is the most helpful (in bold) but it doesn't seem to say anything different then table 3-1 except that it kinda seems to indicate a 0-0, 1-1 mapping but not sure.

I have a driver with a "normal" interrupt working already.  The problem is that these interrupts are registered outside of the irq 255 limit for moving to different cores.

I have a driver registering irq 92 (GPIO1 INT5) but the system does not ever raise this interrupt when I trigger GPIO1_5.  I also tried registering both irq 92 and the "normal" GPIO1_5 interrupt (irq number 292) with the same result.

Is there somewhere I can get more information or does someone have examples on how to use these gpio irqs?

thanks,

Ben Anderson

i.mx6 Linux CPU IRQ affinity

Labels (1)
Tags (3)
1 Solution
3,504 Views
RodBorras
NXP Employee
NXP Employee

Ben,

Kevin Anderle has asked me to take a look at this question. We are very sorry for the delay!

This is my understanding of how the MX6Q GPIO interrupts work:

a) GPIO1 (32 pins) through GPIO7 (32 pins) can be configured to generate interrupts when the pins are set to inputs

b) GPIO2 through GPIO7 do not have an "ARM interrupt" for each pin, but rather for the OR'ed results of 16 pins

     ==> e.g. GPIO2 will cause an "ARM IRQ 100" if there is a valid interrupt    on any pin within 0-15

     ==> e.g. GPIO2 will cause an "ARM IRQ 101" if there is a valid interrupt    on any pin within 16-31

     ==> So even though GPIO2 can monitor 32 pins for activity, the ARM Core will only see 1 of 2 IRQs happen (#100 or #101)

c) GPIO1 has the same functionality as described in b), but also some further granularity: its bottom 8 pins (0-7) will cause 8 specific "ARM interrupts"

     ==> GPIO1_0 will cause an "ARM IRQ 97", and so on for pins 1,2,3,4,5,6; GPIO1_7 will cause an "ARM IRQ 90"

     ==> for GPIO1_8 through GPIO1_31, these can only be seen through "ARM IRQ98" for pins 0-15, or "ARM IRQ99" for pins 16-31

d) In addition, all the 8 registers for the specific GPIOx need to be configured correctly:

   - GPIOx_IMR: the appropriate bits need to be set to 1 to enable those interrupts

   - GPIOx_ISR: the interrupt routine must write a 1 to the appropriate bit to clear the interrupt flag

   - GPIOx_ICR1 and GPIOx_ICR2: these allow you to select between level (low or high) or edge (rising or falling) for the given interrupt pin

   - GPIOx_EDGE_SEL: this allows you to override GPIOx_ICR1 and GPIOx_ICR2 for historical reasons

   - GPIOx_GDIR: the appropriate pin must be set to an input (bit=0) to allow for interrupts

   - GPIOx_DR and GPIO_PSR: not relevant here

e) Finally, you need to use the IOMUX Controller to set the specific pins to be in GPIO mode

Now, based on what you say (you do not see GPIO1_5 create IRQ 92), I have a few questions:

     1) Can you see if GPIO1_5 generates interrupt IRQ 98 (pins 0-7)? If that works, I would try IRQ 95 (in case the list was input backwards)

     2) If 1) does not work, I would check to see that all the configurations in d) here above are correct

Please let us know how it goes, or if you have further questions.

Thanks,

Rod.


View solution in original post

6 Replies
3,504 Views
michael_richmon
Contributor I

Sorry for the thread jack.

Where can the interrupt and register values be found for a given gpio?

I'm trying to update the linux dtsi file for the imx6 SabreLite board to enable gpio9 (which is exposed on jumper 7 of the SabreLite board).

Thanks,
Michael Richmond

0 Kudos
3,505 Views
RodBorras
NXP Employee
NXP Employee

Ben,

Kevin Anderle has asked me to take a look at this question. We are very sorry for the delay!

This is my understanding of how the MX6Q GPIO interrupts work:

a) GPIO1 (32 pins) through GPIO7 (32 pins) can be configured to generate interrupts when the pins are set to inputs

b) GPIO2 through GPIO7 do not have an "ARM interrupt" for each pin, but rather for the OR'ed results of 16 pins

     ==> e.g. GPIO2 will cause an "ARM IRQ 100" if there is a valid interrupt    on any pin within 0-15

     ==> e.g. GPIO2 will cause an "ARM IRQ 101" if there is a valid interrupt    on any pin within 16-31

     ==> So even though GPIO2 can monitor 32 pins for activity, the ARM Core will only see 1 of 2 IRQs happen (#100 or #101)

c) GPIO1 has the same functionality as described in b), but also some further granularity: its bottom 8 pins (0-7) will cause 8 specific "ARM interrupts"

     ==> GPIO1_0 will cause an "ARM IRQ 97", and so on for pins 1,2,3,4,5,6; GPIO1_7 will cause an "ARM IRQ 90"

     ==> for GPIO1_8 through GPIO1_31, these can only be seen through "ARM IRQ98" for pins 0-15, or "ARM IRQ99" for pins 16-31

d) In addition, all the 8 registers for the specific GPIOx need to be configured correctly:

   - GPIOx_IMR: the appropriate bits need to be set to 1 to enable those interrupts

   - GPIOx_ISR: the interrupt routine must write a 1 to the appropriate bit to clear the interrupt flag

   - GPIOx_ICR1 and GPIOx_ICR2: these allow you to select between level (low or high) or edge (rising or falling) for the given interrupt pin

   - GPIOx_EDGE_SEL: this allows you to override GPIOx_ICR1 and GPIOx_ICR2 for historical reasons

   - GPIOx_GDIR: the appropriate pin must be set to an input (bit=0) to allow for interrupts

   - GPIOx_DR and GPIO_PSR: not relevant here

e) Finally, you need to use the IOMUX Controller to set the specific pins to be in GPIO mode

Now, based on what you say (you do not see GPIO1_5 create IRQ 92), I have a few questions:

     1) Can you see if GPIO1_5 generates interrupt IRQ 98 (pins 0-7)? If that works, I would try IRQ 95 (in case the list was input backwards)

     2) If 1) does not work, I would check to see that all the configurations in d) here above are correct

Please let us know how it goes, or if you have further questions.

Thanks,

Rod.


3,504 Views
Jean_Marc
Contributor II

Hello,

I read your repply about "Interrupts with GPIO1 INT0-7", I am having a problem with GPIO1_5, I am using it as interrupt, IRQ 92. It work fine if I set the following registers inside the driver (dm9000) :

0x209C00C = 0x0400;  // Active High

0x209C014 = 0x20 // INT5 on

My problem is I did not find how to do that from the device tree.

From the bellow device tree line

"interrupts = <0 60 4>; "

driver dm900 can get irq 92 (60) but not active high level-sensitive (4)

and I canot find how to setup GPIO1 as intterupt for dm9000

Any help is welcome, I am a beginner with device tree

Regards

Jean-marc

0 Kudos
3,504 Views
benanderson
Contributor II

Thanks for reply!

It is working now!

I went over everything above and determined that the interrupt was not being enabled.  I had thought I had checked it several times before but I think it was a combinations of errors on my part that caused the interrupt not to work.  I had assumed from the start that requesting irq92 would not in itself enable the interrupt in the GPIO module.  So I had also requested another interrupt from the GPIO interrupt controller knowing that it does enable the interrupt because I had gotten it to work in that mode before.  However I requested the wrong GPIO interrupt and somehow when I had check the IMR it looked fine.  I am guessing I double checked the wrong IMR.  I also found that my hardware to test the interrupt was not as dependable as well.

Results:

So I have determined that indeed gpio1_5 maps to interrupt 92 which is the gpio1 INT5.  I am assuming the other gpio pin 0-7 map directly as well.  I am also assuming that only gpio1_5 causes an interrupt 92.  I didn't test the combined interrupts as that is not what is needed and I have the single pin interrupt working.

For completeness I am posting the salient code I used to get it to work.

---------------------------------------------------------------------------------------------------

///*** Assume that the board file does the correct muxing for gpio1_5

// Request gpio1_5 and set as input

gpio_request(IMX_GPIO_NR(1, 5), "itest");

gpio_direction_input(IMX_GPIO_NR(1, 5));

//Request irq92

request_irq(MXC_INT_GPIO1_INT5_NUM, itest_irq_handler,0 ,"itest", &itest_device);

//write directly to gpio1 imr reg

//Test only! normally don't do this way as it clears all the other irqs that may have been enabled)

__raw_writel(0x20,MX6_IO_ADDRESS(GPIO1_BASE_ADDR+0x14))

---------------------------------------------------------------------------------------------------

From userspace after loading driver I can see that it has requested irq.  I can also trigger the interrupt and see the count go up on the cpu.

>cat /proc/interrupts

          CPU0       CPU1       CPU2       CPU3

92:     107826          2          0          0       GIC  itest

I can also switch the affinity to cpu1 and the count goes up on that cpu.

Thanks,

Ben

3,504 Views
9crkzhou
Contributor III

is there any APIs to use?like set_irq_type?

0 Kudos
3,502 Views
AlbertT
Contributor V

Hello Ben !

I am very interesting in your work since I have to do approximately the same thing. But I don't know anything in GPIO so I am requesting some help. My board is an imx6q sabrelite.

  1. You said "Assume that the board file does the correct muxing for gpio1_5". How can I do it ?
  2. How can I physically find the GPIO1_5 ?
  3. In what file should I include the code you pasted here ?

Thanks a lot!

0 Kudos