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.

GPIO interrupt on the CC3200(TI RTOS)

Other Parts Discussed in Thread: CC3200, SYSBIOS, CC3200SDK

How to initialize a GPIO interrupt on the CC3200.I want to use the pins other than the ones defined in Board.h file.What is the procedure to be followed?

Which documentation is to be used to understand the interrupt API's.I am using the CC3200 EVAL Board.Say I want to setup the interrupt for P08.

Thanks

Regards

John

  • Hi John,

        First thing, I'll recommend looking at the CC3200 Datasheet (look at Table 3-1) to understand the pin-multiplexing. P08 is the package pin number and has it's GPIO pin alias (GPIO17) that is used to configure the pins. In CC3200_LAUNCHXL.h , you'll need to add a new enum type to CC3200_LAUNCHXL_GPIOName for your new pin. In the corresponding CC3200_LAUNCHXL.c file you'll add a new entry for GPIOCC3220_GPIO_17 (P08) to the gpioConfigs array. Since you want P08 to be an interrupt input pin, look at the lines for CC3200_LAUNCHXL_SW2 as examples. Now you can provide your interrupt function as a GPIO callback using the gpioCallbackFunctions array (note the order should match the order of pins in your gpioPinConfig array).

       In Board.h, you can add a define (e.g #define Board_Pin08   CC3200_LAUNCHXL_P08)  for your new pin using the enum type you added in CC3200_LAUNCHXL.h. The Board.h name is what you use in your application.

       I'll recommend reading section 5.5 of the TI-RTOS User Guide to understand better the GPIO driver.

    Let me know if this helps.

    Moses

  • Hi Moses,

    Thanks for the reply.Actually I have seen the GPIO interrupt example and did the required changes in the project and it works fine.But I want to use HWI API from BIOS.

    Any help regarding the code given below.

    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>

    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/hal/Hwi.h>

    /* TI-RTOS Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/ports/HwiP.h>

    /* Example/Board Header files */
    #include "Board.h"

    /* variable to be read by GUI Composer */
    int count = 0;

    /*
    * ======== gpioButtonFxn0 ========
    * Callback function for the GPIO interrupt on Board_BUTTON0.
    */
    void gpioButtonFxn0(void)
    {
    /* Clear the GPIO interrupt and toggle an LED */
    GPIO_toggle(Board_LED0);

    if (count++ == 100) {
    count = 0;
    }
    }

    /*
    * ======== gpioButtonFxn1 ========
    * Callback function for the GPIO interrupt on Board_BUTTON1.
    * This may not be used for all boards.
    */
    void gpioButtonFxn1(void)
    {
    /* Clear the GPIO interrupt and toggle an LED */
    GPIO_toggle(Board_LED1);

    if (count++ == 100) {
    count = 0;
    }
    }

    void myIsr (void)
    {
    GPIO_toggle(Board_LED1);
    }
    /*
    * ======== main ========
    */
    int main(void)
    {
    /* Call board init functions */
    Board_initGeneral();
    Board_initGPIO();
    Board_initUART();

    HwiP_Params hwiParams;
    HwiP_Handle myHwi;
    //Error_Block eb;

    /* Turn on user LED */
    //GPIO_write(Board_LED0, Board_LED_ON);

    System_printf("Starting the GPIO Interrupt example\nSystem provider is set"
    " to SysMin. Halt the target to view any SysMin contents in"
    " ROV.\n");
    /* SysMin will only print to the console when you call flush or exit */
    System_flush();

    /* install Button callback */
    //GPIO_setCallback(Board_BUTTON0, gpioButtonFxn0);

    /* Enable interrupts */
    //GPIO_enableInt(Board_BUTTON0);

    /*
    * If more than one input pin is available for your device, interrupts
    * will be enabled on Board_BUTTON1.
    */
    /* install Button callback */
    //GPIO_setCallback(Board_BUTTON1, gpioButtonFxn1);
    //GPIO_enableInt(Board_BUTTON1);

    /* initialize error block and hwiParams to default values */
    //Error_init(&eb);

    Hwi_enable();
    HwiP_enableInterrupt(17);

    HwiP_Params_init(&hwiParams);
    hwiParams.arg = 10;
    //hwiParams.enableInt = FALSE;
    myHwi = HwiP_create(17, (Hwi_FuncPtr)myIsr, &hwiParams);
    if (myHwi == NULL) {
    System_abort("Hwi create failed");
    }
    else
    {
    System_printf("Hwi Object Created\n");
    System_flush();
    }

    /* Start BIOS */
    BIOS_start();

    return (0);
    }

    Also the number 17 is for the port GPIOA. But does it read the entire port or a particular pin?

    Thanks

    Regards

    John

  • Hi John,

       I'm guessing you took a look at the TI-RTOS GPIO driver to come up with using the "HwiP" API's.  HwiP is an abstraction/indirection layer that the drivers use that enable them to work on top of TI-RTOS or FreeRTOS. Since you're running TI-RTOS the HwiP APIs are redirected to Hwi calls. If you intend to use Hwi then you should use Hwi_xxx calls directly. Only the drivers need to be using HwiP.

       Another thing is you shouldn't be calling Hwi_enable in main. Once BIOS starts, Hwis are globally enabled. Also Hwi_create enables the Hwi for interrupt 17 so no need to call Hwi_enableInterrupt(17).

       That said, just enabling the global interrupts and registering your ISR function isn't enough (what the Hwi calls perform). Interrupts need to enabled at the GPIO peripheral as well. Thats what the TI-RTOS GPIO_enableInt API does (you can take a look at its implementation). Since you choose to not use the TI-RTOS GPIO driver you'll need to use either the CC3200 SDK GPIO driver or turn on the right bits in one of the GPIO registers. Interrupts at the GPIO end are enabled on a per pin basis and not the entire port.

    I'll recommend you take a look at the API reference for the Hwi module as well to help your understanding.

    Regards,

    Moses

  • Moses,

    As you have told I have used the Hwi_xxx calls only and also used the GPIO_enableInt API also. Please check this code and tell me what is the problem.I am getting the following error "Write error: Invalid File ID (121) in CIO message!" on the Hwi_create line.Or if this is the correct method of initialization.

    /*
    * ======== empty.c ========
    */
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>

    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/hal/Hwi.h>

    /* TI-RTOS Header files */
    #include <ti/drivers/GPIO.h>

    /* Example/Board Header files */
    #include "Board.h"

    #define TASKSTACKSIZE 512

    Task_Struct task0Struct;
    Char task0Stack[TASKSTACKSIZE];

    /*
    * ======== heartBeatFxn ========
    * Toggle the Board_LED0. The Task_sleep is determined by arg0 which
    * is configured for the heartBeat Task instance.
    */
    Void heartBeatFxn(UArg arg0, UArg arg1)
    {
    while (1) {
    Task_sleep((UInt)arg0);
    GPIO_toggle(Board_LED2);
    }
    }

    Void hwiFunc (UArg arg0)
    {
    GPIO_toggle(Board_LED1);
    }
    /*
    * ======== main ========
    */
    int main(void)
    {
    Task_Params taskParams;
    Hwi_Params hwiParams;
    Hwi_Handle hwi0;


    /* Call board init functions */
    Board_initGeneral();
    Board_initGPIO();

    /* Construct heartBeat Task thread */
    Task_Params_init(&taskParams);
    taskParams.arg0 = 1000;
    taskParams.stackSize = TASKSTACKSIZE;
    taskParams.stack = &task0Stack;
    Task_construct(&task0Struct, (Task_FuncPtr)heartBeatFxn, &taskParams, NULL);

    Hwi_Params_init(&hwiParams);
    hwiParams.arg = 500;
    hwiParams.enableInt = TRUE;
    hwi0 = Hwi_create (17,(Hwi_FuncPtr) hwiFunc, &hwiParams,NULL);
    if (hwi0 == NULL)
    {
    System_abort("Hwi create failed");
    }
    else
    {
    System_printf("Hardware Interrupt Object Created\n");
    }

    GPIO_enableInt(Board_BUTTON0);


    /* Turn on user LED */
    //GPIO_write(Board_LED0, Board_LED_ON);

    System_printf("Starting the example\nSystem provider is set to SysMin. "
    "Halt the target to view any SysMin contents in ROV.\n");
    /* SysMin will only print to the console when you call flush or exit */
    System_flush();

    /* Start BIOS */
    BIOS_start();

    return (0);
    }
  • Hi Moses,

    Side by side I was trying this example (code below).

    /*
    * ======== gpiointerrupt.c ========
    */

    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>

    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>

    /* TI-RTOS Header files */
    #include <ti/drivers/GPIO.h>

    /* Example/Board Header files */
    #include "Board.h"

    /* variable to be read by GUI Composer */
    int count = 0;

    /*
    * ======== gpioButtonFxn0 ========
    * Callback function for the GPIO interrupt on Board_BUTTON0.
    */
    void gpioButtonFxn0(void)
    {
    /* Clear the GPIO interrupt and toggle an LED */
    GPIO_toggle(Board_LED0);

    if (count++ == 100) {
    count = 0;
    }
    }

    /*
    * ======== gpioButtonFxn1 ========
    * Callback function for the GPIO interrupt on Board_BUTTON1.
    * This may not be used for all boards.
    */
    void gpioButtonFxn1(void)
    {
    /* Clear the GPIO interrupt and toggle an LED */
    GPIO_toggle(Board_LED2);

    if (count++ == 100) {
    count = 0;
    }
    }

    void gpioButtonFxn2(void)
    {
    /* Clear the GPIO interrupt and toggle an LED */
    GPIO_toggle(Board_LED1);

    if (count++ == 100) {
    count = 0;
    }
    }

    /*
    * ======== main ========
    */
    int main(void)
    {
    /* Call board init functions */
    Board_initGeneral();
    Board_initGPIO();
    Board_initUART();

    /* Turn on user LED */
    //GPIO_write(Board_LED0, Board_LED_ON);

    System_printf("Starting the GPIO Interrupt example\nSystem provider is set"
    " to SysMin. Halt the target to view any SysMin contents in"
    " ROV.\n");
    /* SysMin will only print to the console when you call flush or exit */
    System_flush();

    /* install Button callback */
    GPIO_setCallback(Board_BUTTON0, gpioButtonFxn0);

    /* Enable interrupts */
    GPIO_enableInt(Board_BUTTON0);


    GPIO_setCallback(P55, gpioButtonFxn1);
    GPIO_enableInt(P55);

    GPIO_setCallback(P21, gpioButtonFxn2);
    GPIO_enableInt(P21);

    /* Start BIOS */
    BIOS_start();

    return (0);
    }

    I have initialized the all the Board LED's and done the required changes in the pin mux config,as well as in the CC3200LP.c and .h files.
    Also I have initialized two pins namely the P15 and P55 as input pins and done the above changes.On pressing the Board Button 0 as expected the LED0 toggles.But now when I switch P55 again instead of LED 1 ,LED 0 toggles. And on switching P21 nothing happens at all.What is wrong?
  • Hi John,

           The issues you're having is because of mixing the use of the TI-RTOS GPIO driver (GPIO_xxx APIs) with the Hwi you're manually trying to create. If I breakdown in summary the steps to use an interrupt on a GPIO it'll include: configuring the pins (pin direction, pullups, interrupt trigger, etc) , creating an interrupt and registering an ISR, enabling the GPIO interrupt. The first 2 steps are done by the TI-RTOS GPIO driver when you call Board_initGPIO. Hwis for the input pins in the GPIO_pinConfig array (in CC3220_LAUNCHXL.c) are created automatically. So Board_initGPIO in your code has already created a Hwi for that pin if you added it to gpioPinConfig array and this conflicts with you trying to manually create a Hwi in main.

         If you don't want to use the TI-RTOS  GPIO driver you'll need to do without Board_initGPIO as well. The CC3200SDK driverlib (which the TI-RTOS GPIO driver internally uses) has APIs to configure the pins, then you create your Hwi and register your ISR function and to begin receiving interrupts you enable it with the CC3200SDK GPIOIntEnable API. May I ask what you're trying to achieve here? The TI-RTOS GPIO driver does all these things for you and is easy to use.

    Let me know if this helps,

    Moses

  • Hi Moses,

    Thanks for the reply.Actually the reason I want to choose the Hwi_xxx API's is because it gives me better control over the parameters of the hardware interrupt.I have used the interrupt API's given by the TI RTOS GPIO driver but I do not see anyways of changing the interrupt priority(I want to make one interrupt higher priority than the other).Or is there a way to get finer control over the interrupts using the TI-RTOS GPIO driver?(This is dynamic creation of the interrupt).

    Also I would like to know from where the interrupt number on CC3200 has to be found(for the static creation of hwi).As in the video tutorial for HWI it is mentioned as PIE Vector Table for the CC2000 series. Where is the interrupt number mentioned for the CC3200?I have found this post (  )for the CC3200 and it mentions the interrupt sources based on the ports and not pins?Am I missing something here?

    Thanks
    Regards
    John

  • Hi John,

      If it's the priority you're trying to control then there is the Hwi_setPriority API that you can use to set the priority of an interrupt by just specifying the interrupt number. You'll have to use the family specific Hwi module to access this API, so use "#include <ti/sysbios/family/m3/Hwi.h>" instead of "#include <ti/sysbios/hal/Hwi.h>". Now you can go back to using the TI-RTOS GPIO driver which automatically creates and manages the Hwi for you and you can call Hwi_setPriority from your application just to adjust the priority. I'd recommend taking a look at the Hwi API reference here.

      To find the interrupt number take a look at Table 2-6 and 2-7 in the Technical Reference Manual for the device. Another place is in the hw_ints.h file in <TI-RTOS_INSTALL_DIR>/products/CC3200_driverlib_1.1.0/inc. Also sorry for misleading you about the port vs pin registering of interrupts. For GPIO interrupts are registered on a per port basis and there's a register in the GPIO peripheral where you can read what particular pin triggered it.

    Let me know if this helps.

    Moses

  • Hi Moses,

    Thanks for the reply.I have implemented as you have said and everything seems to work fine.

    Regards

    John