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.

TI RTOS 2.161.14 for Tiva C GPIO initalization issue

Other Parts Discussed in Thread: TPS22904, DLPC150, SN74ALVC08, CC2564, ADS1255, TMP006, HDC1000

Hi,

I have a Tiva C project working on 2.10.1.38 TI RTOS version. I just migrated it to TI RTOS 2.16.1.14; following the migration guides. Pasted below is the GPIO init part from my board file...

It appears that configuring GPIO pins as input with interrupt type FALLING_EDGE or BOTH_EDGES is not working correctly. Adding the following lines (from my old version of board file) after GPIO_init() fixes the problem. This tell me that there is an issue in GPIO_init() function in initializing interrupt type correctly or there is something wrong in the way I have specified the parameters in gpioPinConfigs[]. 


MAP_GPIOIntTypeSet( GPIO_PORTQ_BASE, GPIO_PIN_3 | GPIO_PIN_4, GPIO_BOTH_EDGES | GPIO_DISCRETE_INT );
MAP_GPIOIntTypeSet( GPIO_PORTP_BASE, GPIO_PIN_2 | GPIO_PIN_1 | GPIO_PIN_6 | GPIO_PIN_7, GPIO_FALLING_EDGE | GPIO_DISCRETE_INT );

Could you please look into and advise if the error is on my part? 

Thanks,

Sreeram

/*
* =============================== GPIO ===============================
*/
/* Place into subsections to allow the TI linker to remove items properly */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(GPIOTiva_config, ".const:GPIOTiva_config")
#endif

#include <ti/drivers/GPIO.h>

/* GPIO configuration structure */
GPIO_PinConfig gpioPinConfigs[] = {

{GPIOTiva_PB_2 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW}, /* Schematic Name - P1P8V_EN; Connection - TPS22904 */
{GPIOTiva_PD_2 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW}, /* TIVA_EXP_I2C_SCL; Lamp Power */
{GPIOTiva_PD_3 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW}, /* TIVA_EXP_I2C_SDA; DLPC150 TRIG_INr */
{GPIOTiva_PD_5 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW}, /* BAT_VSENSE_EN; DMC2990 */
{GPIOTiva_PD_7 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_HIGH}, /* TIVA_TRIG_SEL; J5 Connector */
{GPIOTiva_PE_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_HIGH}, /* TIVA_DATAEN_MASK; SN74ALVC08 */
{GPIOTiva_PE_1 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_HIGH}, /* TIVA_VSYNC_MASK; SN74ALVC08 */
{GPIOTiva_PE_2 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW}, /* TIVA_TRIG_IN_0 */
{GPIOTiva_PE_3 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW}, /* TIVA_TRIG_IN_1 */
{GPIOTiva_PH_5 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW}, /* BT_nSHUTD; CC2564 */
{GPIOTiva_PH_6 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW}, /* SYNCZ; ADS1255 */
{GPIOTiva_PJ_7 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW}, /* PROJ ON */
{GPIOTiva_PQ_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW}, /* BC_EN2 */
{GPIOTiva_PQ_1 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_HIGH}, /* BC_EN1 */
{GPIOTiva_PQ_2 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW}, /* BC_CSZ */

{GPIOTiva_PP_0 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_RISING }, /* DLPC_XLAT0_TIVA DLPC150 GPIO_4 (FRAME) */
{GPIOTiva_PP_1 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_FALLING }, /* DLPC_XLAT1_TIVA DLPC150 GPIO_16 (PATTERN) */
{GPIOTiva_PP_2 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_FALLING }, /* DRDY; ADS1255 */
{GPIOTiva_PP_6 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_FALLING }, /* TDRDYZ; TMP006 */
{GPIOTiva_PP_7 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_FALLING }, /* HUM_DRDYz; HDC1000 */
{GPIOTiva_PQ_4 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_BOTH_EDGES }, /* mSD_CARD_DET */
{GPIOTiva_PQ_5 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_FALLING }, /* BC_INT */
{GPIOTiva_PQ_6 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_FALLING }, /* PAD_RSTz */
{GPIOTiva_PQ_7 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_RISING }, /* DLPC_HOST_IRQ */


{GPIOTiva_PQ_3 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_BOTH_EDGES }, /* NIRscanNano_BUTTON_Scan */
};

GPIO_CallbackFxn NIRscanNano_gpioCallbackFxns[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};

const GPIOTiva_Config GPIOTiva_config = {
.pinConfigs = (GPIO_PinConfig *) gpioPinConfigs,
.callbacks = (GPIO_CallbackFxn *) NIRscanNano_gpioCallbackFxns,
.numberOfPinConfigs = sizeof(gpioPinConfigs) / sizeof(GPIO_PinConfig),
.numberOfCallbacks = sizeof(NIRscanNano_gpioCallbackFxns) / sizeof(GPIO_CallbackFxn),
.intPriority = (~0)
};

/*
* ======== NIRscanNano_initGPIO ========
*/
void NIRscanNano_initGPIO(void)
{
// Enable Hybernation Peripheral
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);

/* Once GPIO_init is called, GPIO_config cannot be changed */
GPIO_init();

#ifdef SCAN_BUTTON_TIVA_BOARD
MAP_GPIOIntEnable( GPIO_PORTQ_BASE, GPIO_PIN_3);
#endif

#ifdef SCAN_BUTTON_EXP_CONN
MAP_GPIOIntEnable( GPIO_PORTK_BASE, GPIO_PIN_3);
#endif
}

  • Your gpioPinConfigs[] looks ok. Can you step through the code and determine what changes when you call the functions that make the program work?

    If the state of the GPIO pins are different when you call your functions then you need to determine what the difference is and see if you are missing something in your gpioPinConfigs[].
  • Hi,
    Thanks for the response.

    After GPIO_init(), the register 0x40066408 (which is GPIO_PORTQ_BASE + GPIO_O_IBE) is 0. It should have been 0x18 because GPIOTiva_PQ_3 and GPIOTiva_PQ_4 are specified as GPIO_CFG_IN_INT_BOTH_EDGES in gpioPinConfigs[].
    After I explicitly call MAP_GPIOIntTypeSet( GPIO_PORTQ_BASE, GPIO_PIN_3 | GPIO_PIN_4, GPIO_BOTH_EDGES | GPIO_DISCRETE_INT ), 0x40066408 gets correctly set to 0x18.

    Here's what I suspect is the problem -
    In C:\ti\tirtos_tivac_2_16_01_14\products\tidrivers_tivac_2_16_01_13\packages\ti\drivers\GPIO.h; Interrupt types are defined as below
    #define GPIO_CFG_IN_INT_NONE (((uint32_t) 0) << GPIO_CFG_INT_LSB) /*! No Interrupt */
    #define GPIO_CFG_IN_INT_FALLING (((uint32_t) 1) << GPIO_CFG_INT_LSB) /*! Interrupt on falling edge */
    #define GPIO_CFG_IN_INT_RISING (((uint32_t) 2) << GPIO_CFG_INT_LSB) /*! Interrupt on rising edge */
    #define GPIO_CFG_IN_INT_BOTH_EDGES (((uint32_t) 3) << GPIO_CFG_INT_LSB) /*! Interrupt on both edges */
    #define GPIO_CFG_IN_INT_LOW (((uint32_t) 4) << GPIO_CFG_INT_LSB) /*! Interrupt on low level */
    #define GPIO_CFG_IN_INT_HIGH (((uint32_t) 5) << GPIO_CFG_INT_LSB) /*! Interrupt on high level */

    Above is what we use to populate gpioPinConfigs[].
    But GPIO_init() in turn calls GPIOIntTypeSet() with the above extracted value as parameter; which is defined in C:\ti\tirtos_tivac_2_16_01_14\products\TivaWare_C_Series-2.1.1.71b\driverlib\gpio.c.
    But in that file, it refers to a different header file - C:\ti\tirtos_tivac_2_16_01_14\products\TivaWare_C_Series-2.1.1.71b\driverlib\gpio.h and refers to a different set of #defines as below..
    #define GPIO_FALLING_EDGE 0x00000000 // Interrupt on falling edge
    #define GPIO_RISING_EDGE 0x00000004 // Interrupt on rising edge
    #define GPIO_BOTH_EDGES 0x00000001 // Interrupt on both edges
    #define GPIO_LOW_LEVEL 0x00000002 // Interrupt on low level
    #define GPIO_HIGH_LEVEL 0x00000006 // Interrupt on high level
    #define GPIO_DISCRETE_INT 0x00010000 // Interrupt for individual pins

    I think the above discrepancy in the two header files is causing this bug. Can you please look into it?

    Thanks,
    Sreeram
  • Sreeram,

    I configured GPIOTiva_PP_4 as BOTH_EDGES and it works fine.

    I then took your code above and configured the following in my gpioPinConfgs[]:

    GPIOTiva_PQ_3 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_BOTH_EDGES,
    GPIOTiva_PQ_4 | GPIO_CFG_INPUT | GPIO_CFG_IN_INT_BOTH_EDGES

    After the GPIO_init() function executed, I see 0x18 in 0x40066408 as you were expecting.
    My conclusion is, I think there is something else that you are doing that is clobbering the GPIO_init().

    Judah
  • Hi,

    Upon further debug, I see that inside the function GPIO_setConfig() in GPIOTiva.c, the call to Hwi_create() is failing and returning handle as NULL whenever pin is configured as GPIO_CFG_IN_INT_BOTH_EDGES. In error block eb, msg = E_againD when it fails. Because it fails and returns there, GPIOIntTypeSet() is not getting executed for those pins.
    I removed the clutter in gpioPinConfigs[] and kept only a couple of pins, and still the above behavior happens.
    Do you have any suggestions on what might be causing Hwi_create() to fail? Thanks.


    regards,

    Sreeram
  • Sreeram,

    Is the error block message really E_againD? I don't find that string anywhere.
    I'm thinking its probably returning Hwi_E_alreadyDefined?

    If that is the case, that means that you're trying to create a Hwi that has already been created.
    Could you step through your code and see what's going on.
    Especially pay attention to the function "getGpioIntIndex" as it looks like there is something special done for Ports P & Q.

    Judah
  • Hi Judah,

    It appears that HWI_create is failing for me because I have added the Hwi in my .cfg file also. So I guess during RTOS init, it creates the Hwi for this particular interrupt number. When GPIO_init() tries to create the same Hwi again it fails. Once I removed the Hwi from .cfg, GPIO_init() initialized that pin correctly. 

    So the question is what is the right way to do this? Am I not supposed to add the Hwi in my .cfg file? Or is it a bug in GPIO_init()/GPIO_SetConfig() that it should have set the intrerrupt type for the pin correctly even if Hwi_create failed?

    Regards,

    Sreeram

  • You should not be adding Hwi for this in you .cfg file.

    Judah
  • There was a suggested answer and since there has been no active on this thread for more than a week, the suggested answer was marked as verify. Please feel free to select the "Reject Answer" button and reply with more details.