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.

c6654 set up an interrupt on a GPIO through CIC0

Other Parts Discussed in Thread: SYSBIOS

Hi,

I've just started to use the c6654 for my application, and I have a little problem setting up an interrupt on one of the GPIO handled by the CIC0 system.
As it didn't work the first time using a true input signal of my board, I've setup a test where I trigger the interrupt by setting/clearing the GPIO (configured as output) in my code. It works fine with a GPIO that is directly connected to the core0 (e.g. GPIO12), but doesn't work (myIsr is never called) using a GPIO connected to CIC0 (GPIO 22 in this example).

My code use sysbios and its CpIntc module, and I just copied the sample code in the module documentation :

// in main.c

...
// set interrupt on all GPIOs, so I don't have to bother
// the dir of GPIOs is set to output elsewhere
// GPIO_CLR_RIS_TRIG = 0xFFFFFFFF;
// GPIO_CLR_FAL_TRIG = 0xFFFFFFFF;
GPIO_SET_RIS_TRIG = 0xFFFFFFFF;
GPIO_SET_FAL_TRIG = 0xFFFFFFFF;
GPIO_BITEN = 1 ;

// CIC0 sys event 6 = GPINT22 on c6654, according to datasheet
CpIntc_mapSysIntToHostInt(0, 6, 1);
CpIntc_dispatchPlug(6, &myIsr, 6, TRUE);

// the eventId returned is correct, hostInt 1 = event 23, according to datasheet
int eventId = CpIntc_getEventId(1);
System_printf("event Id = %d\n", eventId);
System_flush();

Error_Block eb;
Error_init(&eb);
Hwi_Params params;
Hwi_Params_init(&params);
params.eventId = eventId;
params.arg = 0;
params.enableInt = 1;
Hwi_create(5, &CpIntc_dispatch, &params, &eb);

// I also tried using directly myIsr

//Hwi_create(5, &myIsr, &params, &eb);

BIOS_start();     /* enable interrupts and start SYS/BIOS */

...

GPIO_SET_DATA = 1 << 22;
GPIO_CLR_DATA = 1 << 22;

if I use GPIO12 with the same code, using event86(according to datasheet) for the HWI, it works fine...

When I look at the CIC/GPIO registers with JTAG, they seem to be configured correctly, from what I understand after reading CIC documentation.

thansk in advance

  • Could you try to add the CIC host enable as follows and see if it could fix the issue please?

    CpIntc_mapSysIntToHostInt(0, 6, 1);
    CpIntc_dispatchPlug(6, &myIsr, 6, TRUE);

    // Enable host interrupt #1
     CpIntc_enableHostInt(0, 1); // enable host interrupt 1



    The following page has some details for the interrupt mechanism for KeyStone devices as well. Hope it helps.

    http://processors.wiki.ti.com/index.php/Configuring_Interrupts_on_Keystone_Devices

  • thx for your answer. unfortunately it's still not working. I tried to add :

        CpIntc_enableHostInt(0, 1);
        CpIntc_enableSysInt(0, 6);

    I did a dump of the INTC0 registers during my test (after configuration and bios start) :

    INTC0    
        revision_reg    0x4E82A900    Memory Mapped    
        control_reg    0x00000000    Memory Mapped    
        host_control_reg    0x00000000    Memory Mapped    
        global_enable_hint_reg    0x00000001    Memory Mapped    
        glb_nest_level_reg    0x00000000    Memory Mapped    
        status_set_index_reg    0x00000000    Memory Mapped    
        status_clr_index_reg    0x00000000    Memory Mapped    
        enable_set_index_reg    0x00000000    Memory Mapped    
        enable_clr_index_reg    0x00000000    Memory Mapped    
        hint_enable_set_index_reg    0x00000000    Memory Mapped    
        hint_enable_clr_index_reg    0x00000000    Memory Mapped    
        vector_null_reg    0x00000000    Memory Mapped    
        glb_pri_intr_reg    0x00000000    Memory Mapped    
        glb_vector_addr_reg    0x00000000    Memory Mapped    
        global_secure_enable_reg    0x00000000    Memory Mapped    
        secure_pri_intr_reg    0x00000000    Memory Mapped    
        raw_status_reg    0x00000000    (1 of 32, stride 4) [Memory Mapped]    
        ena_status_reg    0x00000000    (1 of 32, stride 4) [Memory Mapped]    
        enable_reg    0x00000040    (1 of 32, stride 4) [Memory Mapped]    
        enable_clr_reg    0x00000040    (1 of 32, stride 4) [Memory Mapped]    
        ch_map    0x00000000    (1 of 256, stride 4) [Memory Mapped]    
        hint_map    0x03020100    (1 of 64, stride 4) [Memory Mapped]    
        pri_hint_reg    0x00000000    (1 of 256, stride 4) [Memory Mapped]    
        polarity_reg    0x00000000    (1 of 32, stride 4) [Memory Mapped]    
        type_reg    0x00000000    (1 of 32, stride 4) [Memory Mapped]    
        dbg_select_reg    0x00000000    (1 of 64, stride 4) [Memory Mapped]    
        secure_enable_reg    0x00000000    (1 of 32, stride 4) [Memory Mapped]    
        secure_enable_clr_reg    0x00000000    (1 of 32, stride 4) [Memory Mapped]    
        nest_level_reg    0x00000000    (1 of 256, stride 4) [Memory Mapped]    
        enable_hint_reg    0x00000002    (1 of 8, stride 4) [Memory Mapped]    
        vector_address_reg    Error: unable to read    (1 of 1024, stride 4) [Memory Mapped]    

    Of course using event6 we don't see the sys/host mapping in this dump (which show only first 4 event) so I did another one with event 2 :

    INTC0    
        revision_reg    0x4E82A900    Memory Mapped    
        control_reg    0x00000000    Memory Mapped    
        host_control_reg    0x00000000    Memory Mapped    
        global_enable_hint_reg    0x00000001    Memory Mapped    
        glb_nest_level_reg    0x00000000    Memory Mapped    
        status_set_index_reg    0x00000000    Memory Mapped    
        status_clr_index_reg    0x00000000    Memory Mapped    
        enable_set_index_reg    0x00000000    Memory Mapped    
        enable_clr_index_reg    0x00000000    Memory Mapped    
        hint_enable_set_index_reg    0x00000000    Memory Mapped    
        hint_enable_clr_index_reg    0x00000000    Memory Mapped    
        vector_null_reg    0x00000000    Memory Mapped    
        glb_pri_intr_reg    0x00000000    Memory Mapped    
        glb_vector_addr_reg    0x00000000    Memory Mapped    
        global_secure_enable_reg    0x00000000    Memory Mapped    
        secure_pri_intr_reg    0x00000000    Memory Mapped    
        raw_status_reg    0x00000000    (1 of 32, stride 4) [Memory Mapped]    
        ena_status_reg    0x00000000    (1 of 32, stride 4) [Memory Mapped]    
        enable_reg    0x00000044    (1 of 32, stride 4) [Memory Mapped]    
        enable_clr_reg    0x00000044    (1 of 32, stride 4) [Memory Mapped]    
        ch_map    0x00010000    (1 of 256, stride 4) [Memory Mapped]    
        hint_map    0x03020100    (1 of 64, stride 4) [Memory Mapped]    
        pri_hint_reg    0x00000000    (1 of 256, stride 4) [Memory Mapped]    
        polarity_reg    0x00000000    (1 of 32, stride 4) [Memory Mapped]    
        type_reg    0x00000000    (1 of 32, stride 4) [Memory Mapped]    
        dbg_select_reg    0x00000000    (1 of 64, stride 4) [Memory Mapped]    
        secure_enable_reg    0x00000000    (1 of 32, stride 4) [Memory Mapped]    
        secure_enable_clr_reg    0x00000000    (1 of 32, stride 4) [Memory Mapped]    
        nest_level_reg    0x00000000    (1 of 256, stride 4) [Memory Mapped]    
        enable_hint_reg    0x00000002    (1 of 8, stride 4) [Memory Mapped]    
        vector_address_reg    Error: unable to read    (1 of 1024, stride 4) [Memory Mapped]    

    from what I understand of CIC0 config registers I don't see what's missing ? the code seem to do the right thing.

  • The following "params.arg" may have the value of host interrupt number

    /* Host interrupt value*/ params.arg = 1;  

    So could you use "1" instead of "0" in your test code since you map the system interrupt to host interrupt 1 please?
  • yes, I already modified this after reading the wiki, but forgot to mention it.

    here is the full test code up to date :

    int flag = 0;

    void myIsr(UArg arg)
    {
        flag = 1;
    }

    void task(void)
    {
        while(1)
        {

    // I'm using breakpoints here
            GPIO_SET_DATA = 1 << 22;
            GPIO_CLR_DATA = 1 << 22;
        }
    }

    Void main()
    {
        System_printf("enter main()\n");
        System_flush();

        GPIO_SET_RIS_TRIG = 0xFFFFFFFF;
        GPIO_SET_FAL_TRIG = 0xFFFFFFFF;
        GPIO_BITEN = 1 ;

        CpIntc_mapSysIntToHostInt(0, 6, 1);
        CpIntc_dispatchPlug(6, &myIsr, 6, 1);
        CpIntc_enableHostInt(0, 1);
        CpIntc_enableSysInt(0, 6);

        int eventId = CpIntc_getEventId(1);

        Error_Block eb;
        Error_init(&eb);
        Hwi_Params params;
        Hwi_Params_init(&params);
        params.eventId = eventId;
        params.arg = 1;
        params.enableInt = 1;
        Hwi_create(5, &CpIntc_dispatch, &params, &eb);
    //    Hwi_create(5, &myIsr, &params, &eb);

        BIOS_start();
    }

    regards,

    Emmanuel

  • ok, so I tried using the CSL instead of sysbios to configure the CIC0, but apparently I'm to stupid to find the library I'm supposed to link to the project :

    Undefined synbol : CSL_CPINTC_open

    I installed MCSDK and have csl libraries for c6657evm (not c6654 but I guess it's not important). Tried to link some of those, but to no avail, so if anyone could help me find a lib with this symbol and make this test compile ?

    (bonus question : why is the CSL not included automagically by the RTSC tool, while the sysbios libraries are ?)

    anyway, here is the code using the CSL

    int flag = 0;

    void myIsr(UArg arg)
    {
        flag = 1;
    }

    void task(void)
    {
        while(1)
        {
            GPIO_SET_DATA = 1 << 22;
            Task_sleep(1);
            GPIO_CLR_DATA = 1 << 22;
            Task_sleep(1);
        }
    }

    Void main()
    {
        System_printf("enter main()\n");
        System_flush();

        GPIO_CLR_RIS_TRIG = 0xFFFFFFFF;
        GPIO_CLR_FAL_TRIG = 0xFFFFFFFF;
        GPIO_SET_RIS_TRIG = 0xFFFFFFFF;
        GPIO_SET_FAL_TRIG = 0xFFFFFFFF;
        GPIO_BITEN = 1 ;
    #if 0
        // CIC0 sys event 6 = GPIO22 on c6654
        CpIntc_mapSysIntToHostInt(0, 6, 1);
        CpIntc_dispatchPlug(6, &myIsr, 6, TRUE);
        // Enable host interrupt #1
        CpIntc_enableHostInt(0, 1);
        CpIntc_enableSysInt(0, 6);

        int eventId = CpIntc_getEventId(1);
        System_printf("event Id = %d\n", eventId);
        System_flush();
    #else

        CSL_CPINTC_Handle hnd;
        hnd = CSL_CPINTC_open(0);
        if (! hnd) {
            return;
        }
        CSL_CPINTC_disableAllHostInterrupt(hnd);
        CSL_CPINTC_setNestingMode (hnd, CPINTC_NO_NESTING);
        CSL_CPINTC_clearSysInterrupt (hnd, CSL_INTC0_GPINT22);
        CSL_CPINTC_enableSysInterrupt (hnd, CSL_INTC0_GPINT22);
        CSL_CPINTC_mapSystemIntrToChannel (hnd, CSL_INTC0_GPINT22, 0);
        CSL_CPINTC_enableHostInterrupt (hnd, 0);
        CSL_CPINTC_enableAllHostInterrupt(hnd);
    #endif
        Error_Block eb;
        Error_init(&eb);
        Hwi_Params params;
        Hwi_Params_init(&params);
        params.eventId = 22;
    //    params.eventId = 86;
        params.arg = 1;
        params.enableInt = 1;
    //    Hwi_create(5, &CpIntc_dispatch, &params, &eb);
        Hwi_create(5, &myIsr, &params, &eb);

        BIOS_start();     /* enable interrupts and start SYS/BIOS */
    }

    this is becoming more urgent to make this work for our project so if anyone could help us, it would be much appreciated

    (I mean, come on, this is an interrupt on a gpio, should be trivial to debug right ?)

    maybe someone with the same dsp could setup a (working) test project and send us the code ?

    thanks in advance,

    Emmanuel

  • Emmanuel,

    The CSL library is located at "C:\ti\pdk_C6657_x_x_x\packages\ti\csl\lib" as "ti.csl.ae66" and "ti.csl.intc.ae66" for little endian and "ti.csl.ae66e" and "ti.csl.intc.ae66e" for big endian.

    One thing to note is previously you are mapping GPIO event to CIC host interrupt 1 and here you are mapping to host interrupt 0.

    Not sure if you want to try "params.arg = 0;".

    Sorry that I do not have device at my hand this week to debug the code for you. I may try something next week. But it will good if someone else could step in to help as well.

  • thanks, I had found ti.csl.ae66 but had somehow missed (despite its explicit name) ti.csl.intc.ae66... now it links okay... but still doesn't work :(

    I'd greatly appreciate if you could try it with a c6654 (not 57) on your side next week, and send me the working project, if it's still unresolved by then.

    I'm starting to wonder whether there is some mistake in our custom  made init code that would prevent the CIC0 from working correctly. it can't be on the GPIO side of things since everything works fine with GPIOs < 15...

    thanks again for your time,

    Emmanuel

  • Emmanuel,

    C6654 and C6657 are the same so the interrupt do work in the exact same way on both devices.

    It seem that there is a GEL file provided in the wiki page mentioned above. It might help to debug the GPIO interrupt side too.
    For example in the GEL setup the I2C and UART events seem to go to CICx so you could compare your setup with what is done in the GEL file for I2C and UART.

    Also can you try with a "real" input signal (like connect a wire between GPIO output to the GPIO input you want to use as interrupt)?
    Please try this for both the working case and the none working one.

    Anthony

  • Emmanuel,

    Please note several things In order to use GPIO[31-16] in C6654/5/7 devices. 

    1. GPIO[31-16] are pin muxed with other peripherals. You need to program PIN_CONTROL_0 register to enable GPIO functionality. And you need to program KICK registers to unlock boot configuration registers as well. You can add following code to your project for this:

    #define KICK0 (*(unsigned int*)(0x02620038))
    #define KICK1 (*(unsigned int*)(0x0262003C))
    #define KICK0_KEYVAL 0x83e70b13
    #define KICK1_KEYVAL 0x95a4f1e0
    #define PIN_CONTROL_0 (*(unsigned int*)(0x02620580))

    ......

    //unlock boot cfg registers and configure GPIO pin16-31 mux
    KICK0 = KICK0_KEYVAL;
    KICK1 = KICK1_KEYVAL;
    //Configuring the chip_pin_control0 register
    PIN_CONTROL_0 = 0xFFFF0000;

    2. GPIO user guide needs to be updated for BINTEN register that bit 0 is for Bank 0 (GPIO pins 15:0) and bit 1 is for Bank 1 (GPIO pins 31-16).

    So you need to set bit 1 to 1 in BINTEN to enable the interrupt of GPIO pins 31-16.

     GPIO_BITEN = 0x2 ;

    There are other things related to C665x EVM only. It seems like some GPIO pins are connected to other circuits which prevent the user changing the GPIO pin level to trigger the interrupt, such as pin 22 is connected to UART.

    But with the above 2 updates, you should be able to trigger interrupt on pin 18. You can make the following changes to trigger GPIO 18 event and observe "flag=1":

    CSL_CPINTC_clearSysInterrupt (hnd, CSL_INTC0_GPINT18);
    CSL_CPINTC_enableSysInterrupt (hnd, CSL_INTC0_GPINT18);
    CSL_CPINTC_mapSystemIntrToChannel (hnd, CSL_INTC0_GPINT18, 0);

    and 

    GPIO_SET_DATA = 1 << 18;
    Task_sleep(1);
    GPIO_CLR_DATA = 1 << 18;
    Task_sleep(1);

    If you have customized board without limitation on GPIO pins, you should be able to trigger the event on any GPIO pins with the notes above.

    Hope they could help.

  • Hi all,

    I played a little with the gel file but it's for c667x and the CIC0 event are not the same, and it's missing the GPIOs event anyway. From reading the script, I didn't see anything missing from my mental model of the CIC0 configuration. And then...

    >> 2. GPIO user guide needs to be updated for BINTEN register that bit 0 is for Bank 0 (GPIO pins 15:0) and bit 1 is for Bank 1 (GPIO pins 31-16).

    >> So you need to set bit 1 to 1 in BINTEN to enable the interrupt of GPIO pins 31-16.

    >> GPIO_BITEN = 0x2 ;

    this helps a lot.

    should have guessed, I already found out that the GPIO doc describe only the first 16 ios in the registers, and that the bits for the io > 16 are following in each configuration register. just didn't think there could be another biten for the other half of the ios, just beside the described biten >_>

    so now I can make my sample project work with the GPIO22, either by configuring it to output and toggling the data_out in the code, or as input by applying a true signal on the pin, and with csl or sysbios, with or without dispatcher...

    no luck with GPIO17/18 though, which is the opposite of what you were saying steven ? so maybe it's just that I can't trigger the interrupt on these pins because in reality they are inputs, driven by another component on my board...

    now I'll try to go back to my main project and make it work there in the true configuration, using GPIO17/18 as input. I'll keep you informed whether all is well or still not working.

    Thanks for the biten info and for all the help.

    best regards,

    Emmanuel

    For reference, here is the final test code :

    int flag = 0;
    int test_gpio = 22;
    int hostInterrupt = 0;
    CSL_CPINTC_Handle hnd;

    #define CSL 1
    #define DISPATCH 1

    void myIsr(UArg sysInterrupt)
    {
    #if !CSL
    #if !DISPATCH
        CpIntc_disableHostInt(0, hostInterrupt);
        CpIntc_clearSysInt(0, sysInterrupt);
    #endif
    #else
        CSL_CPINTC_disableHostInterrupt(hnd, hostInterrupt);
        CSL_CPINTC_clearSysInterrupt(hnd, sysInterrupt);
    #endif
        flag = 1;

    #if !CSL
    #if !DISPATCH
        CpIntc_enableHostInt(0, hostInterrupt);
    #endif
    #else
        CSL_CPINTC_enableHostInterrupt(hnd, hostInterrupt);
    #endif
    }

    void task(void)
    {
        while(1)
        {
            GPIO_SET_DATA = 1 << test_gpio;
            Task_sleep(1);
            GPIO_CLR_DATA = 1 << test_gpio;
            Task_sleep(1);
        }
    }

    Void main()
    {
        System_printf("enter main()\n");
        System_flush();

        GPIO_CLR_RIS_TRIG = 0xFFFFFFFF;
        GPIO_CLR_FAL_TRIG = 0xFFFFFFFF;
        GPIO_SET_RIS_TRIG = 0xFFFFFFFF;
        GPIO_SET_FAL_TRIG = 0xFFFFFFFF;
        GPIO_BITEN = 0xFFFFFFFF;

        int sysInterrupt = test_gpio - 16;
    #if !CSL
        CpIntc_disableAllHostInts(0);
        CpIntc_clearSysInt(0, sysInterrupt);
        CpIntc_enableSysInt(0, sysInterrupt);
        CpIntc_mapSysIntToHostInt(0, sysInterrupt, hostInterrupt);
        CpIntc_enableHostInt(0, hostInterrupt);
        CpIntc_dispatchPlug(sysInterrupt, &myIsr, sysInterrupt, TRUE);
        CpIntc_enableAllHostInts(0);

        int eventId = CpIntc_getEventId(hostInterrupt);
        System_printf("event Id = %d\n", eventId);
        System_flush();
    #else
        hnd = CSL_CPINTC_open(0);
        if (! hnd) {
            return;
        }
        CSL_CPINTC_disableAllHostInterrupt(hnd);
        CSL_CPINTC_setNestingMode (hnd, CPINTC_NO_NESTING);
        CSL_CPINTC_clearSysInterrupt (hnd, sysInterrupt);
        CSL_CPINTC_enableSysInterrupt (hnd, sysInterrupt);
        CSL_CPINTC_mapSystemIntrToChannel (hnd, sysInterrupt, hostInterrupt);
        CSL_CPINTC_enableHostInterrupt (hnd, hostInterrupt);
        CSL_CPINTC_enableAllHostInterrupt(hnd);

        int eventId = hostInterrupt + 22;
    #endif
        Error_Block eb;
        Error_init(&eb);
        Hwi_Params params;
        Hwi_Params_init(&params);
        params.eventId = eventId;
    //    params.eventId = 86;
        params.enableInt = 1;
    #if !CSL
    #if !DISPATCH
        params.arg = sysInterrupt;
        Hwi_create(5, &myIsr, &params, &eb);
    #else
        params.arg = hostInterrupt;
        Hwi_create(5, &CpIntc_dispatch, &params, &eb);
    #endif
    #else
        params.arg = sysInterrupt;
        Hwi_create(5, &myIsr, &params, &eb);
    #endif

        BIOS_start();     /* enable interrupts and start SYS/BIOS */
    }

  • alright it finally works with GPIO17 and 18 used as true inputs with external signals from the ASIC.

    thanks again,

    Emmanuel

  • I change the code acording your answer, but there are some other problems that cause it doesn't work.
    I set up an interrupt on GPIO16 through CIC0. The systhem interrupt(CIC0 input) number is 0 and the host interrupt(CIC0 output) number is 1. Event id=23. I use the INT4. GPIO16 is setted the input IO. However, it can't run into the interupt dealing fuction when the gpio16 is high.

    My code use sysbios module. Can I use csl on this situation.

    static void SetInterrupt()
    {
    // CSL_GpioHandle hGpio;
    Error_Block eb;
    Hwi_Params hwiParams;
    Hwi_Handle hwi0;
    int sysInterrupt=0;
    System_printf("enter main()\n");
    System_flush();

    // Open the CSL GPIO Module 0
    hGpio = CSL_GPIO_open (0);
    KICK0 = 0x83e70b13;
    KICK1 = 0x95a4f1e0;
    PIN_CONTROL_0 = 0xFFFF0000;
    CSL_GPIO_setPinDirInput ( hGpio, 16) ; //set pin as input
    CSL_GPIO_setRisingEdgeDetect (hGpio, 16); // Set interrupt detection on GPIO pin 1 to rising edge
    CSL_GPIO_bankInterruptEnable (hGpio, 1);
    // Enable GPIO per bank interrupt for bank zero
    //chip-level INTC0 is for corepac0~1
    hnd = CSL_CPINTC_open(0);
    if (! hnd) {
    return;
    }
    //disable all host interrupt
    CSL_CPINTC_disableAllHostInterrupt(hnd);
    //configure no nesting support in the cpintc module
    CSL_CPINTC_setNestingMode (hnd, CPINTC_NO_NESTING);
    CSL_CPINTC_clearSysInterrupt (hnd, 0);
    //enable system interrupt 0
    CSL_CPINTC_enableSysInterrupt (hnd, 0);
    //map system interrupt 0(gpio16 gpint) to host interrupt 1
    CSL_CPINTC_mapSystemIntrToChannel (hnd, 0, 1);
    //enable host interrupt 1
    CSL_CPINTC_enableHostInterrupt (hnd, 1);
    //enable all host interrupts
    CSL_CPINTC_enableAllHostInterrupt(hnd);

    Error_init(&eb);
    Hwi_Params_init(&hwiParams);
    hwiParams.eventId = 23;
    // params.eventId = 86;
    // hwiParams.enableInt = 1;

    // params.arg = sysInterrupt;
    hwiParams.enableInt = 1;
    hwiParams.arg = 1;
    hwiParams.priority =1;
    hwi0=Hwi_create(4, (ti_sysbios_hal_Hwi_FuncPtr) &hwiFunc, &hwiParams, &eb);
    // hwiParams.enableInt = 1;
    if(hwi0==NULL)
    {
    System_abort("Hwi create failed");
    }
    }

    void hwiFunc(UArg sysInterrupt)
    {

    // CSL_CPINTC_disableHostInterrupt(hnd, 1);
    // CSL_CPINTC_clearSysInterrupt(hnd, sysInterrupt);
    flag = 1;
    // CSL_CPINTC_enableHostInterrupt(hnd, 1);
    }