This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Multiple interrupts in one port?

Other Parts Discussed in Thread: TM4C123GH6PM

Hello,

I was searching information about enable interrupts for  few GPIO pin's in one port (say like port A ), but what I found just "cb1 mobile" comment , like:

"Should your requirement exceed this method's frequency limitation - simple solution would see your input signal routed to 2 different GPIO inputs (on different ports) with each pin triggering on opposite edges.  Entry into the respective interrupt handler (again - different ports) confirms the signal's edge...  The GPIOIEV Register enables selection of the specific edge.  It may be possible to employ 2 GPIO from the same Port (setting GPIOIEV uniquely (i.e. opposite) for each of the 2 pins) although we've not yet attempted this "single port" method..."

http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/257198/901017.aspx#901017


So, how I could make run this code?

#include <stdint.h>
#include <stdbool.h>
#include "inc/tm4c123gh6pm.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"

#define RED_LED   GPIO_PIN_1
#define BLUE_LED  GPIO_PIN_2
#define GREEN_LED GPIO_PIN_3

int main(void)
{
SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED);

GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7);
GPIOIntTypeSet(GPIO_PORTA_BASE, GPIO_PIN_6, GPIO_RISING_EDGE);
GPIOIntTypeSet(GPIO_PORTA_BASE, GPIO_PIN_7, GPIO_FALLING_EDGE);

GPIOIntEnable(GPIO_PORTA_BASE, GPIO_INT_PIN_6);
GPIOIntEnable(GPIO_PORTA_BASE, GPIO_INT_PIN_7);

IntEnable(INT_GPIOA); ??

IntMasterEnable();

while(1)
{
}

}

void IntGPIOb (void)
{
    GPIOIntClear(GPIO_PORTA_BASE, GPIO_PIN_6);

    //
    GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED, RED_LED);

    SysCtlDelay(2000000);

    GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED, 0x00);

}

void IntGPIOa (void)
{
    GPIOIntClear(GPIO_PORTA_BASE, GPIO_PIN_7);

    //
    GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED, BLUE_LED);

    SysCtlDelay(2000000);

    GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED, 0x00);

}

And what I should write to startup.c file at line:

    IntGPIOa,    ??                           // GPIO Port A
    IntDefaultHandler,                               // GPIO Port B
    IntDefaultHandler,                               // GPIO Port C

  • Hello Gylis,

    The startup.c is correct. In the main.c you have to write the interrupt clearing in the same ISR Function. To determine which GPIO caused the interrupt, use the function GPIOPinIntStatus to read the MIS register and then follow it up with if-else condition for each of the GPIOPinIntClear

    Regards

    Amit

  • While this, "read the MIS register" may appear to work under some conditions - is it robust/foolproof?

    Consider the implications of the triggering port interrupt being one of many MCU interrupts - and designated of lower priority.  Should that port interrupt be held off it may happen that multiple pins w/in that same port trigger interrupts - and the subsequent "read of MIS register" is unlikely to reveal any sequence of interrupt arrival.  (thus confounding the original poster's attempt - to employ a single gpio port - to precisely determine the width of a narrow pulse!) 

    ARM MCUs are generally rich in Timers & GPIO Ports (but for the newer, [usually M0] sub 40 pin devices).  Employ of separate GPIO Ports - each dedicated to a different gpio edge - continues to enjoy advantages when precision and/or measurement robustness is a requirement.