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.

C6678 GPIO Interrupt problem

Other Parts Discussed in Thread: SYSBIOS

Hi all,

I am trying to get GPIO_0 interrupt working on my EVM6678L board.

I am using the DSP_GPIO_00 pin on the EVM 80-pin test header  (pin 50) to interrupt Core 0 GPIO 0...NOTHING happenning when I toggle the pin?

 

I started with MCSDK "ledplay" example that uses task to play the leds...Here is my code:

PS: I also tried different GPIO and "HWI" under "Target Specific Support"/"C66" but nothing worked...

I used XGCONF to configure the HWI "static" as follows:

--------------------------------------------------------------------------------------------------

var ti_sysbios_hal_Hwi = xdc.useModule('ti.sysbios.hal.Hwi');

var instti_sysbios_hal_Hwi0Params0 = new ti_sysbios_hal_Hwi.Params();

instti_sysbios_hal_Hwi0Params0.enableInt = true;

instti_sysbios_hal_Hwi0Params0.eventId = 90;

instti_sysbios_hal_Hwi0Params0.priority = 5;

Program.global.HWI_GPIOn = ti_sysbios_hal_Hwi.create(5, "&hwiGPIOnFunc", instti_sysbios_hal_Hwi0Params0);

--------------------------------------------------------------------------------------------------------------------------------------------------------

 

and this is my C code :

--------------------------------------------------------

Void hwiGPIOnFunc(

UArg arg)

{

platform_infop_info;

uint32_t

led_no = 0;

// this runs when interrupt #5 goes off

platform_write("Murad entered HWI\n");

/*

while(1) {

platform_led(led_no, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);

platform_delay(30000);

platform_led(led_no, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);

led_no = (++led_no) % p_info.led[PLATFORM_USER_LED_CLASS].count;

}

*/

}

-------------------------------------------------------------------

What am I missing?

 

Thanks in advance

  • HI Murad ,

    I have faced issues when i had I/O calls inside the ISR function. I suggest that u remove the platform_write call in the hwiGPIOFunc . You can post a semaphore that another thread can wait on an have the platfrom_write there.

    -Anil

     

  • Thanks Anil for the reply,

    I took the "platform_write" and used the LED as indicator to entering the HWI but no luck...do you mind verify my HWI initialization and the pin I am using on the EVM...Thanks in advance...

  • Murad,

    Could you please check the GPIOn registers before running your project to see if the GPIOn pin has been set as interrupt source (BINTEN) and the combination of RIS_TRIG and FAL_TRIG is correct as well (SET/CLR_RIS_TRIG and SET/CLR_RIS_TRIG)?

    The section 1.3 in the GPIO user' s guide talks about the interrupt generation requirement for GPIO pins. It may be good to check the pin has been enabled for interrupt first. Thanks.

    Sincerely,

    Steven

  • Hi Steven,

    CCS shows some of the reg like GIE, enabled interrupts, etc, but don't see BITEN, RIS_TRIG or FAL_TRIG...I am not sure if I need to call any CSL functions to setup the HWI because when I read the examples of chapter 7 of "SYS/BIOS SPRUEX3J", it seems that their is no calls to other functions...I tried the follwoing but still no HW interrupt on the GPIO

     

    int

    main()

    {

    /* Start the BIOS 6 Scheduler - it will kick off our main thread ledPlayTask() */

    platform_write("Start BIOS 6\n");

    gpioInit();

    gpioSetDirection(GPIO_0, GPIO_IN);

    gpioSetRisingEdgeInterrupt(GPIO_0);

    gpioSetFallingEdgeInterrupt(GPIO_0);

    gpioEnableGlobalInterrupt();

    //gpioSetOutput(GPIO_0);

    BIOS_start();

    }

  • Murad,

    You do NOT need to call CSL for HWI setup. But you HAVE to setup the GPIO interrupt manually first.

    The following example should be working in your 6678 EVM. It sets GPIO_0 as output pin and toggles the output value to trigger the GPIO interrupt. If you want to set it as input and trigger it externally, you can modify part of the code accordingly.

    Basically, you have to configure the GPIO registers to enable the GPIO interrupt in the main() routine. You can still use your HWI setup in the .cfg file, while add one idle function to indicate the GPIO interrupt occurred.

    example.cfg file:

    ............

    var ti_sysbios_hal_Hwi = xdc.useModule('ti.sysbios.hal.Hwi');

    var instti_sysbios_hal_Hwi0Params0 = new ti_sysbios_hal_Hwi.Params();

    instti_sysbios_hal_Hwi0Params0.enableInt = true;

    instti_sysbios_hal_Hwi0Params0.eventId = 90;

    instti_sysbios_hal_Hwi0Params0.priority = 5;

    Program.global.HWI_GPIOn = ti_sysbios_hal_Hwi.create(5, "&hwiGPIOnFunc", instti_sysbios_hal_Hwi0Params0);

    var Idle = xdc.useModule('ti.sysbios.knl.Idle');
    Idle.addFunc('&myIdleFunc');

    ............

    example.C file:

    #include <xdc/std.h>

    #include <xdc/runtime/System.h>
    #include <ti/sysbios/BIOS.h>

    #define GPIO_CFG_BASE            (0x02320000)
    #define GPIO_REG_BINTEN            (0x8)
    #define GPIO_REG_DIR            (0x10)
    #define GPIO_REG_OUT_DATA        (0x14)
    #define GPIO_REG_SET_DATA        (0x18)
    #define GPIO_REG_CLR_DATA        (0x1C)
    #define GPIO_REG_IN_DATA        (0x20)
    #define GPIO_REG_SET_RIS_TRIG    (0x24)
    #define GPIO_REG_CLR_RIS_TRIG    (0x28)
    #define GPIO_REG_SET_FAL_TRIG    (0x2C)
    #define GPIO_REG_CLR_FAL_TRIG    (0x30)

    unsigned int GPIO_INT_DONE = 0;


    Void hwiGPIOnFunc(UArg arg)
    {
        GPIO_INT_DONE = 1;
    }

    Void myIdleFunc()
    {
        //using software to toggle GPIO_0 output to trigger the interrupt
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_OUT_DATA) &= 0xFFFFFFFE;    //GPIO_0=0
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_OUT_DATA) |= 0x1;            //GPIO_0=1
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_OUT_DATA) &= 0xFFFFFFFE;    //GPIO_0=0

        while (GPIO_INT_DONE != 1){}

        System_printf("GPIO_0 interrupt occurred!\n");
        System_exit(0);

    }

    Void main()
    {

        //set GPIO_0 pin as an input
        //*(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_DIR) |= 0x1;
        //set GPIO_0 pin as an output
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_DIR) &= 0xFFFFFFFE;

        //set rising edge to trigger GPIO_0 interrupt
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_SET_RIS_TRIG) |= 0x1;

        //clear falling edge of GPIO_0
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_SET_FAL_TRIG) &= 0xFFFFFFFE;

        //enable GPIO interrupts
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_BINTEN) |= 0x1;

        //Start BIOS
        BIOS_start();
    }

    Sincerely,

    Steven

  • Murad,

    Can you update the status, regarding the GPIO setup as posted by Steven.

    One more thing :

    Can you use the HWI module instead ? 

    var Hwi = xdc.useModule('ti.sysbios.family.c64p.Hwi')

  • Hi Steve,

    Thanks for the code...I am assuming that this is all the code I need...but I am getting the following error...I started empty RTSC project and added .c and .cfg files and copied what you sent me to it...I also added a link to the library and include search path as for the led_play project in the MCSDK user's guide:

    2766.GPIO.docx

  • Murad,

    The C code is pretty much all you need. But the .CFG code is only part of the whole piece, which only configures the HWI and add idle function. There are some other parts needed for the whole project.

    I think you can create one example SYS/BIOS project (e.g. Hello Example under the SYS/BIOS Generic Examples) and copy the .CFG code to the end of the example .CFG file. Then add the .C file to the project as well for compilation.

    Or you can try the attached hello.cfg code, which is the whole file from my example project. But I suggest you can try to create your own SYS/BIOS project. Thanks.

    Sincerely,

    Steven

    2158.hello.zip

  • Dear Steve, Varada,

    Thank you so much for your help...The code is working now...

    before I close the post, couple questions if you don't mind:

    1- how do I know when to use

    xdc.useModule('ti.sysbios.hal.Hwi');

     vs.

    xdc.useModule('ti.sysbios.family.c64p.Hwi')

     

    specially when the name is c64 while my DSP is c6678...

    2- in the CCS Buil->RTSC->Products and Respositories: do I need to include "SYS/BIOS" even when I include "MCSDK"?...my understanding of the MCSDK is that it includes all the packages including the "SYS/BIOS", "CSL", etc

     

    3- can I use the CSL to replace configure the "GPIO"? and if so, how do I know which .h, libraries, packages...to include?...I used it in another project but I had to add many files and links to work with no errors...

  • Murad,
    Glad to know the status update.

    1.
    xdc.useModule('ti.sysbios.hal.Hwi');
    vs.
    xdc.useModule('ti.sysbios.family.c64p.Hwi')

    Please use c64p, irrespective of the name. Becasue the INTC is similar.


    2. MCSDK and SYS/BIOS are different components. BiosMCSDK is also the name of the package which containts all different components. 
    MCSDK component by itself some demos and boot related utilities. 
    So if you are using SYSBIOS features like HWI, you need to have these 'RTSC products and repositories'. 
    'CSL" is provided in component named 'MCSDK PDK TMS66.." 


    3.  CSL is provided under directory 'pdk_C667x_1_1_0_0'. 
    The name of the component in the 'RTSC products and repositories' is 'MCSDK PDK TMS667x'. Please try this and let us know, if it builds and works fine.

    Hope this helps.
    Regards,
    Varada
  • Thank you guys for your help and I am sorry that a simple project like this taking all this work...

    Unfortunately, the GPIO interrupt is not working as I thought, the cause of the interrupt was due to the enabling it as startup:

    instti_sysbios_hal_Hwi0Params0.enableInt = true;

     

    if I change it to false, no interrupts occur and the app freeze at the

    while (GPIO_INT_DONE != 1){}

     

    Regards,

     

    Murad

  • Murad,

    The "enabledInt" parameter is used to automatically enable or disable an interrupt upon Hwi object creation. "Enable the interrupt" is different from "trigger the interrupt". The interrupt has to be enabled first. Then you can trigger this interrupt by toggling the GPIO pin and the CPU will take the corresponding actions.

    If you make it as "false" in the .cfg file, the interrupt will be disabled by default. You have to add "#include <ti/sysbios/hal/Hwi.h>" and call "Hwi_enableInterrupt(5)" before "BIOS_start()" in the C code to enable the interrupt #5 before you trigger it. Because the DISABLED interrupt will not be provided to the CPU, even it has been triggered.The example will keep looking for the flag=1 in while loop, since the CPU will not enter into the ISR to change the flag.

    Please refer to the example in 7.2.5 of the SYS/BIOS user's guide.

    Sincerely,

    Steven

  • Thanks Steve,

    I totally forgot what I read in that chapter :-(...

    I am trying to have multiple interrupts (may use a timer to trigger the GPIO_0), but before doing anything, I noticed that if I comment "System_exit(0);" form the "myIdleFunc()", I never get "GPIO_0 interrupt occurred!" to be printed...is it that the interrupts hasn't occured or something else?


  • Murad -

    Can you confirm that you are getting GPIO interrupt ?

    Maybe you can put a breakpoint in ISR.

    Or better still can you use System_printf() and System_flush() functions ?

    Pls let us know.

  • Dear Steve and Varada,

    Thank you very much for all your help...the code is working now with no problems...System_flush() took care of the last question I had...

     

    Best Regards,

     

    Murad

  • Hi muard,I face the same same problem with you,could you tell me how did you fixed it.
  • Please find attached .c and .cfg files...

    #include <xdc/std.h>
    
    #include <xdc/runtime/System.h>
    #include <ti/sysbios/BIOS.h>
    
    #define GPIO_CFG_BASE            (0x02320000)
    #define GPIO_REG_BINTEN            (0x8)
    #define GPIO_REG_DIR            (0x10)
    #define GPIO_REG_OUT_DATA        (0x14)
    #define GPIO_REG_SET_DATA        (0x18)
    #define GPIO_REG_CLR_DATA        (0x1C)
    #define GPIO_REG_IN_DATA        (0x20)
    #define GPIO_REG_SET_RIS_TRIG    (0x24)
    #define GPIO_REG_CLR_RIS_TRIG    (0x28)
    #define GPIO_REG_SET_FAL_TRIG    (0x2C)
    #define GPIO_REG_CLR_FAL_TRIG    (0x30)
    
    unsigned int GPIO_INT_DONE = 0;
    
    
    Void hwiGPIOnFunc(UArg arg)
    {
        GPIO_INT_DONE = 1;
    }
    
    Void myIdleFunc()
    {
        //using software to toggle GPIO_0 output to trigger the interrupt
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_OUT_DATA) &= 0xFFFFFFFE;    //GPIO_0=0
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_OUT_DATA) |= 0x1;            //GPIO_0=1
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_OUT_DATA) &= 0xFFFFFFFE;    //GPIO_0=0
    
        while (GPIO_INT_DONE != 1){}
    
        GPIO_INT_DONE = 0;
        System_printf("GPIO_0 interrupt occurred!\n");
        System_flush();
        //System_exit(0);
    
    }
    
    Void main()
    { 
    
        //set GPIO_0 pin as an input
        //*(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_DIR) |= 0x1;
        //set GPIO_0 pin as an output
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_DIR) &= 0xFFFFFFFE;
    
        //set rising edge to trigger GPIO_0 interrupt
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_SET_RIS_TRIG) |= 0x1;
    
        //clear falling edge of GPIO_0
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_SET_FAL_TRIG) &= 0xFFFFFFFE;
    
        //enable GPIO interrupts
        *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_BINTEN) |= 0x1;
    
        //Start BIOS
        BIOS_start();
    }
    
    hello.cfg