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.

TM4C123GH6PM: GPIO pin interrupt routine issue

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: EK-TM4C123GXL,

I am writing a simple code that works as follows:

press SW1

when SW1 is released a falling edge is detected and the ISR corresponding to the pin PF4 is executed and an LED is turned on.

similarly it happens when SW2 is pressed.

I am not able to configure the interrupt properly.

in the user guide there are APIs for peripheral specific interrupts and NVIC interrupts, how to know which one to use?

Please guide me regarding the same.

I am posting my code for reference.

#include<stdint.h>
#include<stdbool.h>
#include<hw_memmap.h>
#include<gpio.h>
#include<interrupt.h>
#include<sysctl.h>


#define GPIOCR (*(unsigned long *)0x40025524)
#define GPIOLOCK (*(unsigned long *)0x40025520)


void gpio_Interrupt_Init(void);
void SW1isr(void);
void SW2isr(void);

int main(void)
{
    gpio_Interrupt_Init();

    return 0;
}

void gpio_Interrupt_Init()
{
    void (*SW1_int)(void);
    void (*SW2_int)(void);

    SW1_int = &SW1isr;
    SW2_int = &SW2isr;


    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);


     GPIOLOCK       =0x4C4F434B;
     GPIOCR         =0xFF;

     GPIOIntRegisterPin(GPIO_PORTF_BASE,GPIO_PIN_4, SW1_int);
       GPIOIntRegisterPin(GPIO_PORTF_BASE,GPIO_PIN_0, SW2_int);


    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, (GPIO_PIN_0 | GPIO_PIN_4));
      GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, (GPIO_PIN_2 | GPIO_PIN_3));
    GPIOIntTypeSet(GPIO_PORTF_BASE, (GPIO_PIN_0 | GPIO_PIN_4), GPIO_FALLING_EDGE);

   GPIOIntEnable(GPIO_PORTF_BASE, GPIO_PIN_0|GPIO_PIN_4);
  

}

void SW1isr()
{


    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, ~(uint8_t)GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2));
    GPIOIntClear(GPIO_PORTF_BASE, GPIO_INT_PIN_4);
}

void SW2isr()
{

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, ~(uint8_t)GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_3));
    GPIOIntClear(GPIO_PORTF_BASE, GPIO_INT_PIN_0);
}

 

  • I think you are close. There is only one interrupt vector for each GPIO port. In the interrupt routine you need to determine which pin caused the interrupt. Also, you need to call IntMasterEnable(). Here is a working example for the EK-TM4C123GXL launchpad.

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_types.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    
    //*****************************************************************************
    //
    // Define pin to LED color mapping.
    //
    //*****************************************************************************
    #define RED_LED   GPIO_PIN_1
    #define BLUE_LED  GPIO_PIN_2
    #define GREEN_LED GPIO_PIN_3
    
    void GPIOFisr(void);
    
    uint32_t ledColor;
    
    //*****************************************************************************
    //
    // Main 'C' Language entry point.  Toggle an LED using TivaWare.
    //
    //*****************************************************************************
    int
    main(void)
    {
        //
        // Setup the system clock to run at 50 Mhz from PLL with crystal reference
        //
        SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|
                        SYSCTL_OSC_MAIN);
    
        //
        // Enable and wait for the port to be ready for access
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF))
        {
        }
        
        //
        // Configure the GPIO port for the LED operation.
        //
        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED);
    
        // Register the interrupt service routine for the switches
        GPIOIntRegister(GPIO_PORTF_BASE, GPIOFisr);
    
        // Configure GIOF pins 0 and 4 (switch inputs) as interrupts
        // Must unlock GIOF pin 0 first
        HWREG(GPIO_PORTF_BASE + 0x520u) = 0x4C4F434Bu;
        HWREG(GPIO_PORTF_BASE + 0x524u) = 0xFFu;
        GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, (GPIO_PIN_0 | GPIO_PIN_4));
        GPIOPadConfigSet(GPIO_PORTF_BASE, (GPIO_PIN_0 | GPIO_PIN_4), GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
        GPIOIntTypeSet(GPIO_PORTF_BASE, (GPIO_PIN_0 | GPIO_PIN_4), GPIO_FALLING_EDGE);
        IntEnable(INT_GPIOF);
        GPIOIntEnable(GPIO_PORTF_BASE, GPIO_PIN_0|GPIO_PIN_4);
    
        IntMasterEnable();
    
        ledColor = RED_LED;
    
        //
        // Loop Forever
        //
        while(1)
        {
            //
            // Turn on the LED
            //
            GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED, ledColor);
    
            //
            // Delay for a bit
            //
            SysCtlDelay(2000000);
    
            //
            // Turn off the LED
            //
            GPIOPinWrite(GPIO_PORTF_BASE, RED_LED|BLUE_LED|GREEN_LED, 0u);
    
            //
            // Delay for a bit
            //
            SysCtlDelay(2000000);
        }
    }
    
    void GPIOFisr()
    {
        uint32_t intStatus;
    
        intStatus = GPIOIntStatus(GPIO_PORTF_BASE, 1u);
    
        if(intStatus == GPIO_PIN_0)
        {
            ledColor = BLUE_LED;
        }
        else if (intStatus == GPIO_PIN_4)
        {
            ledColor = GREEN_LED;
        }
        GPIOIntClear(GPIO_PORTF_BASE, intStatus);
    }
    
    

  • launchpad.pdfYes, my code worked once I used the API GPIOIntRegister.

    I don't understand, it should have worked with the API for PIN specific ISR too, i.e. GPIOIntRegisterPin.

    Another thing related to the same code:

    wrt the document, i.e. the user guide , that I have uploaded, on page 20, there is a diagram given for sw1 and sw2 , does that diagram suggest that I need to only connect a pull up register for SW1 and not SW2, for having the same functionality for both switches?

  • The TM4C123GH6PM does not have individual interrupts for each GPIO pin. See table 2-9 on page 104 of the datasheet for the list of available interrupt vectors.

    Yes, it is not absolutely necessary to enable the internal pullup on PF0 as on the EK-TM4C123GXL launchpad this signal is tied to a 1M Ohm pullup resistor by virtue of being attached to the WAKE signal. That 1M Ohm resistor is very weak though.