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.

CCS/TM4C123GH6PM: Doubt in using NVIC table entry for GPIO interrupt

Part Number: TM4C123GH6PM

Tool/software: Code Composer Studio

Hi,

I am using launch pad TIVA C series microcontroller with CCS in windows.

I am trying to use the GPIO interrupt function to toggle the LED. My objective is to light up the red LED on PF1 when the switch SW1 on PF4 is pressed.

I got the sample code from this link on e2e forum. 

I modified the code a little and it is working when using the interrupt register function to register the ISR.

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>

#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/debug.h"


// Line 118 in NVIC vector table
void interruptHandler_portF_Balaji(void){
    GPIOIntClear(GPIO_PORTF_BASE,GPIO_PIN_4);
    uint8_t currentValueF4 = GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4);
    if (currentValueF4==GPIO_PIN_4){
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);
    }
    else{
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
    }
}


int main(void)
{
    SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)){}

    // PF4 as input
    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4); // PF4 as input
    GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);

    // Configure interrupt
    GPIOIntDisable(GPIO_PORTF_BASE, GPIO_PIN_4);
    GPIOIntClear(GPIO_PORTF_BASE, GPIO_PIN_4);
    GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_BOTH_EDGES);
    GPIOIntRegister(GPIO_PORTF_BASE,interruptHandler_portF_Balaji);// Without this interrupt does not work even if it is nvic table.
    GPIOIntEnable(GPIO_PORTF_BASE, GPIO_PIN_4);

    // Red off
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3|GPIO_PIN_1| GPIO_PIN_2); // LED outputs
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3| GPIO_PIN_2|GPIO_PIN_1,0);

    while(1){
        // Main infinite loop
    }
}

However I am unable to use the NVIC table approach to register the ISR routine. I have put the pointer to the ISR named interruptHandler_portF_Balaji() in the NVIC table in the startup.c file. When I run the code below and press SW1, the red led does not light up. When I pause the code, i could see it is stuck  in the infinite loop in the main function and not in any fault isr infinite loop. My suspicion is that the code below which am using in the NVIC table approach is not enabling some interrupt that is mandatory. If someone could point out my mistake in the below code, that would be very helpful.

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>

#include "inc/tm4c123gh6pm.h"
#include "inc/hw_types.h"
#include "driverlib/interrupt.h"


#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/debug.h"


// Line 118 in NVIC vector table
void interruptHandler_portF_Balaji(void){
    GPIOIntClear(GPIO_PORTF_BASE,GPIO_PIN_4);
    uint8_t currentValueF4 = GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4);
    if (currentValueF4==GPIO_PIN_4){
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);
    }
    else{
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
    }
}


int main(void)
{
    SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)){}

    // PF4 as input
    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4); // PF4 as input
    GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);

    // Configure interrupt
    GPIOIntDisable(GPIO_PORTF_BASE, GPIO_PIN_4);
    GPIOIntClear(GPIO_PORTF_BASE, GPIO_PIN_4);
    //GPIOIntRegister(GPIO_PORTF_BASE,interruptHandler_portF_Balaji);// Without this interrupt does not work even if it is nvic table.
    GPIOIntEnable(GPIO_PORTF_BASE, GPIO_PIN_4);
    GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_BOTH_EDGES);
    IntMasterEnable();

    // Red off
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3|GPIO_PIN_1| GPIO_PIN_2); // LED outputs
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3| GPIO_PIN_2|GPIO_PIN_1,0);

    while(1){
        // Main infinite loop
    }
}

  • Hello Balaji,

    If you are not using GPIOIntRegister, then you need to enable to the interrupt for the GPIO in the NVIC by using the IntEnable API. GPIOIntRegister does this for you, so when not using it, you need to take this step.

    So you have 3 total enables:

    1) GPIOIntEnable for enabling the interrupt in the GPIO peripheral registers

    2) IntEnable for enabling the interrupt in the NVIC

    3) IntMasterEnable for enabling interrupts at the processor level as a whole (i.e. not a specific interrupt, but allowing interrupts to occur overall)

    Add this to your code and it will work:

    IntEnable(INT_GPIOF);

  • Hi Ralph,

    This solved the issue. I could find relevant info in the first 2 pages of chapter 17 (Interrupts) on the data sheet of the MCU. It was given clearly to enable the interrupts in NVIC, overall MCU and the peripheral registers separately. Thank you .