LPC1769: interrupt on GPIO pin change

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

LPC1769: interrupt on GPIO pin change

Jump to solution
4,519 Views
danielholala
Senior Contributor II

Hello,

I'm developing on a LPCXpresso LPC1769 (OM13085) board using LPCOpen's chip specific drivers ("lpc_chip_175x_6x").

According to the manual, chapter 9: 

- Port 0 and Port 2 can provide a single interrupt for any combination of port pins.

-  Each port pin can be programmed to generate an interrupt on a rising edge, a falling edge, or both.

I'd like trigger an interrupt on both a rising edge and a falling edge on a GPIO pin signal.

However, when the ISR EINT3_IRQHandler() is called, GPIO interrupt status registers indicate a falling edge interrupt (register IO0IntStatF) and a rising edge interrupt (register IO0IntStatR).

Why is this?

This is my example code:

#include "chip.h"
#include <stdio.h>

/* use semi-hosting for printf() console output */

void EINT3_IRQHandler(void) {
    printf("GPIO IRQ Status:%08x ENF:%08x ENR:%08x\n",
               LPC_GPIOINT->STATUS,
               LPC_GPIOINT->IO0.ENF,
               LPC_GPIOINT->IO0.ENR);
    Chip_GPIOINT_ClearIntStatus(LPC_GPIOINT, GPIOINT_PORT0, 1 << 19);
}

int main(void) {
    SystemCoreClockUpdate();

    printf("Start\n");
    // configure Pin P0.19 for interrupt on input signal change
    Chip_GPIOINT_ClearIntStatus(LPC_GPIOINT, GPIOINT_PORT0, 1 << 19);
    Chip_GPIOINT_SetIntFalling( LPC_GPIOINT, GPIOINT_PORT0, 1 << 19);
    Chip_GPIOINT_SetIntRising(  LPC_GPIOINT, GPIOINT_PORT0, 1 << 19);
    NVIC_ClearPendingIRQ(EINT3_IRQn); // avoid extraneous IRQ on restart
    NVIC_EnableIRQ(EINT3_IRQn);

    volatile static int i = 0 ;
    Chip_GPIO_Init(LPC_GPIO);
    Chip_GPIO_SetPinDIROutput(LPC_GPIO, 0, 17); // Pin P0.17
    Chip_GPIO_SetPinDIROutput(LPC_GPIO, 0, 22); // red led on board
    while(1) {
         Chip_GPIO_SetPinOutHigh(LPC_GPIO, 0, 17);
         Chip_GPIO_SetPinOutHigh(LPC_GPIO, 0, 22);
         for (i = 0; i< 10000000; i++) { }
         Chip_GPIO_SetPinOutLow(LPC_GPIO, 0, 17);
         Chip_GPIO_SetPinOutLow(LPC_GPIO, 0, 22);
         for (i = 0; i< 10000000; i++) { }
    }
    return 0 ;
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I wired GPIO output P0.17 to P0.19.

  • P0.17 is switched with a periode of about 3 seconds
  • The red LED on the eval board is also switched (for visual feedback)
  • P0.19 is configured for interrupt on both rising and falling edge
  • ISR prints interrupt status registers.

This is the output I get:

[MCUXpresso Semihosting Telnet console for 'Test02-newlib LinkServer Debug' started on port 60095 @ 127.0.0.1]

Start
GPIO IRQ Status:00000001 ENF:00080000 ENR:00080000
GPIO IRQ Status:00000001 ENF:00080000 ENR:00080000
GPIO IRQ Status:00000001 ENF:00080000 ENR:00080000

Thanks for your comments.

Labels (1)
Tags (1)
1 Solution
2,996 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Daniel,

If you reference the user manual (UM10360.pdf) chapter 9 table 103. You will see that ENR and ENF represents if  the GPIO Interrupt is enable for Rising and Falling edge respectively.

pastedImage_2.png

So, since you want to trigger the interrupt on both rising edge and a falling edge the values of ENR and ENF will always be 1. The values you need to look to know which interrupt was triggered are STATR and STATF, since these values represent the status for either rising edge and falling edge interrupt. 

I made an example using the same characteristics that you mentioned, so you can see how the registers work. In the next image you can see that the values of ENR and ENF are static in 1 since I activate the interrupt in both edges. But, the value  of STATF changed to 1 because the falling edge interrupt was triggered, STATR reminds low. 

pastedImage_3.png

In the next interrupt you can see that the values of ENR and ENF are still the same. However,  this time the STATF is 0 and STATR is 1 since now you detected a rising edge interrupt.

pastedImage_4.png

So, in your interrupt handler you should check these values. Here is the handler I declared for the example I made.

void GPIO_IRQ_HANDLER(void)
{
     if(LPC_GPIOINT->IO0.STATR != 0){ //Rising edge detected
          Board_LED_Set(0, true);//turns off the red led
          Board_LED_Set(1, false);//turns on the blue led
     }
     else if(LPC_GPIOINT->IO0.STATF != 0){//Falling edge detected
          Board_LED_Set(1, true);//turns off the red led
          Board_LED_Set(0, false);//turns on the blue led
     }
     Chip_GPIOINT_ClearIntStatus(LPC_GPIOINT, GPIO_INTERRUPT_PORT, 1 << GPIO_INTERRUPT_PIN);
}‍‍‍‍‍‍‍‍‍‍‍‍

Calling a printf function inside the handler is not a really good practice. I changed a little bit the example. When I detect a rising edge I turn on the blue led of the evaluation board, and when I detect a falling edge I turn on the red led.

Hope it helps!

Victor.

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

View solution in original post

4 Replies
2,996 Views
athmesh_n
Contributor IV

Hi, I'm Using LPC1754, where I have selected Port 1 for DI, so cant I enable it as interrupt? I saw PORT 0 and PORT 2 are selected as interrupt in datasheet. Is the interrupt option exclusively for PORT0 and PORT2?

0 Kudos
2,996 Views
danielholala
Senior Contributor II

I think so. The manual states:

9.2.2 Interrupt generating digital ports
• Port 0 and Port 2 can provide a single interrupt for any combination of port pins.

0 Kudos
2,997 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Daniel,

If you reference the user manual (UM10360.pdf) chapter 9 table 103. You will see that ENR and ENF represents if  the GPIO Interrupt is enable for Rising and Falling edge respectively.

pastedImage_2.png

So, since you want to trigger the interrupt on both rising edge and a falling edge the values of ENR and ENF will always be 1. The values you need to look to know which interrupt was triggered are STATR and STATF, since these values represent the status for either rising edge and falling edge interrupt. 

I made an example using the same characteristics that you mentioned, so you can see how the registers work. In the next image you can see that the values of ENR and ENF are static in 1 since I activate the interrupt in both edges. But, the value  of STATF changed to 1 because the falling edge interrupt was triggered, STATR reminds low. 

pastedImage_3.png

In the next interrupt you can see that the values of ENR and ENF are still the same. However,  this time the STATF is 0 and STATR is 1 since now you detected a rising edge interrupt.

pastedImage_4.png

So, in your interrupt handler you should check these values. Here is the handler I declared for the example I made.

void GPIO_IRQ_HANDLER(void)
{
     if(LPC_GPIOINT->IO0.STATR != 0){ //Rising edge detected
          Board_LED_Set(0, true);//turns off the red led
          Board_LED_Set(1, false);//turns on the blue led
     }
     else if(LPC_GPIOINT->IO0.STATF != 0){//Falling edge detected
          Board_LED_Set(1, true);//turns off the red led
          Board_LED_Set(0, false);//turns on the blue led
     }
     Chip_GPIOINT_ClearIntStatus(LPC_GPIOINT, GPIO_INTERRUPT_PORT, 1 << GPIO_INTERRUPT_PIN);
}‍‍‍‍‍‍‍‍‍‍‍‍

Calling a printf function inside the handler is not a really good practice. I changed a little bit the example. When I detect a rising edge I turn on the blue led of the evaluation board, and when I detect a falling edge I turn on the red led.

Hope it helps!

Victor.

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

2,996 Views
danielholala
Senior Contributor II

Good catch, Victor. While I wrote in the text that one has to read, e.g., register IO0IntStatF, the code does not do that and instead reads the enable registers. Thanks.