imx6q GPIO interrupt

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

imx6q GPIO interrupt

Jump to solution
2,548 Views
salvatoreuras
Contributor I

Hello everyone.

We are trying to use a GPIO to generate an interrupt - in an OS-less program based on the platform SDK code, so bare metal and no linux below.

The following code should produce on our board a printf in response to a button press, and we have successfully tested the event and its handling in polling mode before.

Unfortunately, our interrupt routine never gets called.

Anybody can see what's wrong in our sample code below?

Thanks in advance,

Gabriele Hofmann & Salvatore Uras


void myIO_interrupt_handler(void)

{

      printf("myIO interrupt\n");

      myIO_irq_served = TRUE;

}




int myIO_irq_test(void)

{

      uint32_t *gpio7_base;


      gpio7_base = (uint32_t *)0x20b4000;

      printf("Start myIO IRQ test:\n");

      gpio7_iomux_config();

      gpio_set_direction(GPIO_PORT7, 4, GPIO_GDIR_INPUT);

      *(gpio7_base + 0xc) = (uint32_t)0x300; // GPIO7 ICR1 falling edge for IO4

      *(gpio7_base + 0x14) = (uint32_t)0x10; // GPIO7 IMR enabling mask for IO4


      /* register the IRQ sub-routine */

     register_interrupt_routine(IMX_INT_GPIO7_INT15_0, myIO_interrupt_handler);


     /* enable the IRQ */

      enable_interrupt(IMX_INT_GPIO7_INT15_0, CPU_0, 0);


      while (myIO_irq_served == FALSE);


      return TEST_PASSED;

}

Labels (3)
0 Kudos
1 Solution
1,214 Views
salvatoreuras
Contributor I

Thanks both for your helpful answers.

We discovered that our code (as confirmed by your answers) was conceptually correct, but in order to make it work we had to take special care in respecting the following points:

1) all writes to memory mapped hardware registers are better implemented using preprocessor macros that evaluate to a constant, i.e.:

     #define GPIO7_ISR ((uint32_t *)0x-----)

     *(variable pointing to GPIO7_ISR) = any value; // BETTER NOT

     *(GPIO7_ISR) = any value; // BETTER

2) alway better reboot the board before reloading newly compiled software via GDB: if not, everything seems to work, but the interrupt vector table gets lost ;-)

Thanks again,

Gabriele Hofmann & Salvatore Uras.

View solution in original post

0 Kudos
4 Replies
1,215 Views
salvatoreuras
Contributor I

Thanks both for your helpful answers.

We discovered that our code (as confirmed by your answers) was conceptually correct, but in order to make it work we had to take special care in respecting the following points:

1) all writes to memory mapped hardware registers are better implemented using preprocessor macros that evaluate to a constant, i.e.:

     #define GPIO7_ISR ((uint32_t *)0x-----)

     *(variable pointing to GPIO7_ISR) = any value; // BETTER NOT

     *(GPIO7_ISR) = any value; // BETTER

2) alway better reboot the board before reloading newly compiled software via GDB: if not, everything seems to work, but the interrupt vector table gets lost ;-)

Thanks again,

Gabriele Hofmann & Salvatore Uras.

0 Kudos
1,214 Views
tongchunyang
Contributor III

Hi

0 Kudos
1,214 Views
qiang_li-mpu_se
NXP Employee
NXP Employee

For default, the platform SDK code doesn't support interrupt, when interrupt happens, it will goto dead loop.

To support interrupt, you need modify the file "src\init\vectors.S", add the interrupt serveice function:

The original code is as followed, it means when interrupt happens, it will just do dead loop:

IRQ_Handler:

        B       IRQ_Handler

You can change it to:

IRQ_Handler:

        bl       Do_Irq

You can inplement the Do_Irq() fucntion in your C code to handle your interrupts.

1,214 Views
AnsonHuang
NXP Employee
NXP Employee

Hi, Salvatore

     My suggestion to debug such issue is as below:

1. Check whether GPIO interrupt is enabled in GPIOx_IMR and GPIOx_ICR;

2. When you press button, you expect an interrupt pending, read GPIOx_ISR to see whether the interrupt you want is pending here;

3. If the interrupt is pending already, but the interrupt's service routine is not called, then you should check whether you have the irq enabled in GIC, and whether ARM's irq is also enabled, first you should have vector table ready at either 0xffff0018 or 0x00000018, you can use a JTAG to add break point here.