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.

Problems when using Interrupts to configure a Button on TiRTOS

Hello Guys,

  I am programming a TM4C in Tiva-C using TI-RTOS 2.10.01 and I used the example project called gpiointerrupt, that configures the interrupts for the buttons on Tiva board . That´s OK and the example works fine.

  But, my program is a little bit complicated andI have a task that starts more 2 tasks for controlling a socket connection with my server and the serial port. I am also configuring diferent ports on my project - PORT_M, PIN_2, PIN_3, PIN_4, PIN_5  and PIN_6 as my control buttons (PIN_2 is for future use).

  I am doing all configurations according the example and, of course, 

  Please find below some extracts of my code.

// Enabling interrupts and callbacks in main.c
GPIO_setupCallbacks(&buttonCallbacks);
GPIO_enableInt(BUTTON_PM6, GPIO_INT_RISING);

// Board.h
#define buttonCallbacks        		EK_TM4C1294XL_gpioPortMCallbacks

// EK_TM4C1294XL.h
typedef enum EK_TM4C1294XL_GPIOName {
    BUTTON_PM6 = 0,
    BUTTON_PM3,
    BUTTON_PM5,
    BUTTON_PM4,
    BUTTON_PM2,

    BUTTON_PM_COUNT
} EK_TM4C1294XL_GPIOName;

// EK_TM4C1294XL.c

/* Callback functions for the GPIO interrupt example. */
void button1Callback(void);
void button2Callback(void);
void button3Callback(void);
void button4Callback(void);
void button5Callback(void);

/* GPIO configuration structure */
const GPIO_HWAttrs gpioHWAttrs[BUTTON_PM_COUNT] = {
    {GPIO_PORTM_BASE, GPIO_PIN_6, GPIO_INPUT}, 	/* Botao 1  */
    {GPIO_PORTM_BASE, GPIO_PIN_3, GPIO_INPUT}, 	/* Botao 2 */
    {GPIO_PORTM_BASE, GPIO_PIN_5, GPIO_INPUT},  /* Botao 3 */
    {GPIO_PORTM_BASE, GPIO_PIN_4, GPIO_INPUT},  /* Botao 4 */
    {GPIO_PORTM_BASE, GPIO_PIN_2, GPIO_INPUT}   /* Botao Interno- Nao usado */
};

/* Memory for the GPIO module to construct a Hwi */
Hwi_Struct callbackPortMHwi;

const GPIO_Callbacks EK_TM4C1294XL_gpioPortMCallbacks = {
    GPIO_PORTM_BASE, INT_GPIOM, &callbackPortMHwi,
    {button1Callback, button2Callback, button3Callback, button4Callback, button5Callback, NULL, NULL, NULL}
};

const GPIO_Config GPIO_config[] = {
    {&gpioHWAttrs[0]},
    {&gpioHWAttrs[1]},
    {&gpioHWAttrs[2]},
    {&gpioHWAttrs[3]},
    {&gpioHWAttrs[4]},
    {NULL},
};


// initGPIO()
 GPIOPinTypeGPIOInput(GPIO_PORTM_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6);
 GPIOPadConfigSet(GPIO_PORTM_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6,
    		GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

In the Interrupt function, for example, button1Callback, I am doing:

void button1Callback() {

    GPIO_clearInt(BUTTON_PM6);

}

But when I press the button, I receive the following error on Console:

ti.sysbios.family.arm.m3.Hwi: line 1036: E_hardFault: FORCED
ti.sysbios.family.arm.m3.Hwi: line 1148: E_usageFault: INVSTATE: Invalid EPSR and instruction combination
Exception occurred in ISR thread at PC = 0x00000000.
Core 0: Exception occurred in ThreadType_Hwi.
Hwi name: {unknown-instance-name}, handle: 0x200250a0.
Hwi stack base: 0x200264c8.
Hwi stack size: 0x800.
R0 = 0x00000000  R8  = 0x000223ac
R1 = 0x00000001  R9  = 0x000223a4
R2 = 0x200262d8  R10 = 0x000223a8
R3 = 0x00000000  R11 = 0x00000000
R4 = 0x00000001  R12 = 0x00000000
R5 = 0x00000006  SP(R13) = 0x20026c58
R6 = 0x00021d8c  LR(R14) = 0x0001cafb
R7 = 0x000223b8  PC(R15) = 0x00000000
PSR = 0x60000058
ICSR = 0x00423003
MMFSR = 0x00
BFSR = 0x00
UFSR = 0x0002
HFSR = 0x40000000
DFSR = 0x0000000b
MMAR = 0xe000ed34
BFAR = 0xe000ed38
AFSR = 0x00000000
Terminating execution...

I don't have a lot of experience with programming in TM4C and TiRTOS and I don't know how to implement this. The fact is that I need to have 4 buttons (5 in the future) and I need to know when one of theses buttons are pressed to take some action.

Any advice will be welcome.

Best Regards,

Leandro

  • Hi Leandro,

    It seems like you may be passing in the incorrect parameters to the gpioPinConfigs array. If you look at the GPIO interrupt example you can see that the entries OR'ed together include defines from the GPIOTiva.h and GPIO.h header files. You must use these, so I suggest starting with the GPIO interrupt example's Board.c file and using those structures to base your code off of.

    It looks like the EK_TM4C1294XL.h file is correct, but again the gpioPinConfigs array should have a single entry per pin.

    Eg:

        /* EK_TM4C129EXL_USR_SW2 */
        GPIOTiva_PJ_1 | GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_RISING,

    And use a similar approach for all of your button inputs.

    Best,

    Alexander

  • Hi Alex,

      Tks for your answer. I started from gpiointerrupt program and, as a small test, I changed the program adding more one "button" and configuring the interrupt. I choosed the pin PM_3 and with a Jumper, I can connect the 3.3V in the Pin, acting as a button.

    Well, I had no success.

    The changes I did, below:

    gpiointerrupt.c

    void gpioButtonFxnM(void)
    {
        /* Clear the GPIO interrupt and toggle an LED */
    	if (GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_1) != 0)
    		GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0);
    	else
    		GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, GPIO_PIN_1);
    
        //GPIO_toggle(Board_LED1);
        GPIO_clearInt(Board_BUTTON2);
    
        if (count++ == 100) {
            count = 0;
        }
    }
    
    
    int main(void) {
    ...
    GPIO_setupCallbacks(&Board_gpioCallbacks2);
    GPIO_enableInt(Board_BUTTON2, GPIO_INT_RISING);
    ...
    }
    

    Board.h

    #define Board_BUTTON2               EK_TM4C1294XL_USR_SW3
    #define Board_gpioCallbacks2        EK_TM4C1294XL_gpioPortMCallbacks

    EK_TM4C1294XL.h

    typedef enum EK_TM4C1294XL_GPIOName {
        EK_TM4C1294XL_USR_SW1=0,
        EK_TM4C1294XL_USR_SW2,
    	EK_TM4C1294XL_USR_SW3,
    
        EK_TM4C1294XL_GPIOCOUNT
    } EK_TM4C1294XL_GPIOName;

    EK_TM4C1294XL.c

    #include <ti/drivers/GPIO.h>
    
    /* Callback functions for the GPIO interrupt example. */
    void gpioButtonFxn0(void);
    void gpioButtonFxn1(void);
    void gpioButtonFxnM(void);
    
    /* GPIO configuration structure */
    const GPIO_HWAttrs gpioHWAttrs[EK_TM4C1294XL_GPIOCOUNT] = {
        {GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_INPUT},  /* EK_TM4C1294XL_USR_SW1 */
        {GPIO_PORTJ_BASE, GPIO_PIN_1, GPIO_INPUT},   /* EK_TM4C1294XL_USR_SW2 */
        {GPIO_PORTM_BASE, GPIO_PIN_3, GPIO_INPUT}   /* EK_TM4C1294XL_USR_SW3 */
    };
    
    /* Memory for the GPIO module to construct a Hwi */
    Hwi_Struct callbackPortJHwi, callbackPortMHwi;
    
    const GPIO_Callbacks EK_TM4C1294XL_gpioPortJCallbacks = {
        GPIO_PORTJ_BASE, INT_GPIOJ, &callbackPortJHwi,
        {gpioButtonFxn0, gpioButtonFxn1, NULL, NULL, NULL, NULL, NULL, NULL}
    };
    const GPIO_Callbacks EK_TM4C1294XL_gpioPortMCallbacks = {
        GPIO_PORTM_BASE, INT_GPIOM, &callbackPortMHwi,
        {gpioButtonFxnM, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
    };
    
    const GPIO_Config GPIO_config[] = {
        {&gpioHWAttrs[0]},
        {&gpioHWAttrs[1]},
        {&gpioHWAttrs[2]},
        {NULL},
    };
    
    /*
     *  ======== EK_TM4C1294XL_initGPIO ========
     */
    void EK_TM4C1294XL_initGPIO(void)
    {
        /* Setup the LED GPIO pins used */
        GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        /* Setup the button GPIO pins used */
        GPIOPinTypeGPIOInput(GPIO_PORTJ_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_STRENGTH_2MA,
                         GPIO_PIN_TYPE_STD_WPU);
        GPIOPinTypeGPIOInput(GPIO_PORTM_BASE, GPIO_PIN_3);
        GPIOPadConfigSet(GPIO_PORTM_BASE, GPIO_PIN_3, GPIO_STRENGTH_2MA,
                         GPIO_PIN_TYPE_STD_WPU);
    
    
        /* Once GPIO_init is called, GPIO_config cannot be changed */
        GPIO_init();
    }

    The both functions gpioButtonFxn0 and gpioButtonFxn1 continue to work but the new one, gpioButtonFxnM, unhapply, is not called when I put 3.3 V and remove the contact 1 second later, for example. 

    How can I solve this? Any clue?

    Best Regards

    Leandro

  • Hi Leandro,

    I just noticed that you're using a very old version of TI-RTOS. The GPIO driver has changed significantly since the 2.10 release and I would highly recommend updating to 2.16. In the most recent version it's much simpler to add a new input.

    Best,
    Alexander
  • I will update my version and see if it works.

    Regards
    Leandro
  • Hi Alex,

    I was checking last night the new version 2.16 and the way that GPIO is handled is very different. All code wrote with 2.10 must be changed to fit new version.
    I worry about that because, besides GPIO access, I have a Display (using GPIO), Sockets, UART communication, FLASH, SD, PWM, Semaphores and multitask, I mean, a lot of code depending of RTOS. I am afraid I have no time to change it. For sure I will update to a new version but it is a kind of work that must be done carefully and, of course, I will do in a way I can isolate the specific code from the generic code (in fact, I should have done it, but, you know...)

    In a nutshell, I need to launch the product with version 2.10 and, after stable and running, plan the RTOS migration to 2.16 version.
    I will still investigate why it is not working the new Pins I added.

    Any advance I will let you know

    Thanks and Best regards
    L.

  • I see, one more approach you could try would be to do a quick sanity test to see whether it's the ISR or pin that's not configured correctly.

    I would do a GPIO read with the 3.3v source applied and not applied to see whether your code can detect it.

    If that's working then you can look at the register view to see if the specific GPIO interrupt flag is being asserted. Finally, if that's working there's something wrong with the interrupt setup.

    Best,

    Alexander