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.

Clearing GPIO interrupt for HWI

Hello,

I try to use a GPIO as interrupt trigger on the CortexA8 of a TI814x chip. It seems as if I found the correct location to set it up and the correct interrupt id for  GPIO1[7].

My sys/bios version is 6_32_03_43.

(Is it correct that I have to set up my GPIO "manually" or is there a way to do it through sys/bios?)

The function I configure in the cfg-file is really called, but I do not succeed in clearing the interrupt, so that I would get another later GPIO trigger. Currently the HWI function gets called as soon as I enable the interrupt for the GPIO (IRQSTATUS_SET_0). Is there another location where I have to clear the interrupt?

Thanks and best regards,
René

 

 

  • Rene,

    Yes, you will need to setup the GPIO “manually”, SYS/BIOS doesn’t have a mechanism to do this.

    I’m not familiar with that GPIO module but searched the documentation a bit.  Unfortunately I couldn’t find any ‘theory of operation’ information on processing those GPIO interrupts.  But, from looking at the register definitions, I’m thinking that you may need to write to the GPIO_EOI register to signal the “end of interrupt” processing for the corresponding output line.  Are you doing this?  Also, you may need to write to the appropriate GPIO_IRQSTATUS_CLR_x register too?

    Usually when a specific interrupt status bit needs to be cleared by the ISR (to prevent an immediate re-interrupt, or to allow future interrupts to be signaled), SYS/BIOS won’t handle this, but it is up to the user’s ISR to do this.

    If this doesn’t help, I think it would be best to move this thread to a device-specific forum, where a device expert can provide quicker help…

    Scott 

  • Hi Scott,

    Thanks for the input. To be honest I overread the GPIO_EOI.

    But anyway, even if I write to the EOI register, the interrupt gets called over and over again (as soon as I set the irqstatus register again).

    If I clear the bit in the IRQSTATUS register (and do not set it again), the interrupt gets never called again!

    Is there a specific scope I have to consider? E.g. "do not set these registers in the hwi function" or similar?

     

    I'm not sure whether it is device-specific, maybe it's a general problem in my call sequence...

     

    Thanks and best regards,
    Rene

  • Is the GPIO pin configured for level or edge triggering?

    If its configured for level sensitivity, the interrupt will remain active until the level changes.

    Alan

  • The GPIO pin is configured to trigger on rising edge.

    Regards,

    Rene

  • Hello,

    After changing from set-and-clear-protocol to direct setting, I get the expected behaviour! How can this be explained?

    This is what I used before in my hwi-function:

    gpioRegs1->EOI = 0xFFFFFFFF;

    gpioRegs1->IRQSTATUS_CLR_1 = (1 << 7);

    Result: the IRQ gets cleared forever unless I write

    gpioRegs1->IRQSTATUS_SET_1 = (1 << 7);

    afterwards! But then the hwi gets called over and over again although the line was not pulled!

     

    Now I use the following:

    gpioRegs1->EOI = 0xFFFFFFFF;

    gpioRegs1->IRQSTATUS_1 = (1 << 7);

    And now I get the desired result (hwi gets called on rising edge!

     

    How can this be explained? Is it an error in the set-and-clear protocol of this controller or is it a wrong usage on my side?

    Thanks and best regards,
    Rene

     

     

  • Is there maybe a problem with the structure definition for the GPIO registers?

    Alan

  • I read the GPIO register descriptions in the DM8148 TRM a little and I don't believe you should be writing to the IRQSTATUS_SET and IRQSTATUS_CLR registers within the ISR.

    The bits in these registers DO NOT reflect the current STATUS of their corresponding interrupts as the register name would suggest!

    These bits define whether an interrupt is ENABLED or DISABLED for a particular GPIO pin.

    Consequently, I think you should only write to them when you want to enable or disable the interrupt for a particular GPIO pin.

    Writing a 1 to the corresponding bit in the IRQSTATUS_n register DOES clear the interrupt status which is what you want to do.

    Alan

     

  • Hi Alan,

    You are correct. But then the DM814X TRM (Oct 14 2011) should be updated. "9.2.4.2 Set and Clear Instructions" recommend the usage for clearing the interrupts, futhermore the names of the registers are absolutely misleading!

    Thanks,

    René

  • Hi, My name is Ryan.

    I have a question about triggering gpio 15.

    I got a reference code from this forum and It works, definitely with gpio 0 the code i attached below.

    But, I just want to trigger the gpio 15. it doesn't work now.

    How to change this code for triggering gpio 15?

    For example, do I have to change the event id or vectid so on... ? where do I have to check such as which data sheets?

    Please check it out for me.

    Thanks a lot.

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

    #include "ti/csl/csl_chip.h"
    #include "ti/csl/csl_chipAux.h"
    #include "ti/csl/src/intc/csl_intc.h"
    #include "ti/csl/csl_gpio.h"
    #include "ti/csl/csl_gpioAux.h"

    #include <stdio.h>

    CSL_IntcContext intcContext;
    CSL_IntcEventHandlerRecord EventHandler[30];
    CSL_IntcObj intcObj;
    CSL_IntcHandle hTest;
    CSL_IntcGlobalEnableState state;
    CSL_IntcEventHandlerRecord EventRecord;
    CSL_IntcParam vectId;

    CSL_GpioHandle hGpio;


    volatile int a = 0;

    interrupt void intIsr()
    {
    a = 1;

    return ;
    }

    void main(void)
    {
    //GpioInit(); //GPIO Initialization
    int pinNum;
    int bankNum;

    /************************************************
    *************** INTC Configuration *************
    ************************************************/

    printf ("Debug: GEM-INTC Configuration...\n");

    /* INTC module initialization */
    intcContext.eventhandlerRecord = EventHandler;
    intcContext.numEvtEntries = 10;
    if (CSL_intcInit(&intcContext) != CSL_SOK)
    {
    printf("Error: GEM-INTC initialization failed\n");
    return;
    }

    /* Enable NMIs */
    if (CSL_intcGlobalNmiEnable() != CSL_SOK)
    {
    printf("Error: GEM-INTC global NMI enable failed\n");
    return;
    }

    /* Enable global interrupts */
    if (CSL_intcGlobalEnable(&state) != CSL_SOK)
    {
    printf ("Error: GEM-INTC global enable failed\n");
    return;
    }

    /* Open the INTC Module for Vector ID: 4 and Event ID: 90 (GPIO_n in C6678)*/
    vectId = CSL_INTC_VECTID_4;   // <=== do I have to change this for testing gpio 15 instead of gpio 0?
    hTest = CSL_intcOpen (&intcObj, 90, &vectId , NULL); //  <=== do I have to change this event id(90) for testing gpio 15 instead of gpio 0?
    if (hTest == NULL)
    {
    printf("Error: GEM-INTC Open failed\n");
    return;
    }

    /* Register an call-back handler which is invoked when the event occurs. */
    EventRecord.handler = &intIsr;
    EventRecord.arg = 0;
    if (CSL_intcPlugEventHandler(hTest,&EventRecord) != CSL_SOK)
    {
    printf("Error: GEM-INTC Plug event handler failed\n");
    return;
    }

    /* Enabling the events. */
    if (CSL_intcHwControl(hTest,CSL_INTC_CMD_EVTENABLE, NULL) != CSL_SOK)
    {
    printf("Error: GEM-INTC CSL_INTC_CMD_EVTENABLE command failed\n");
    return;
    }

    printf ("Debug: GEM-INTC Configuration Completed\n");

    // 1. Init Flag
    a = 0;
    printf("a = %d\n",a);

    // 2. Trigger GPIO_0 in Core0
    pinNum = 0;
    bankNum = 0;

    // Open the CSL GPIO Module 0
    hGpio = CSL_GPIO_open (0);

    // Set GPIO pin number 0 as an output pin
    CSL_GPIO_setPinDirOutput (hGpio, pinNum);

    // Set interrupt detection on GPIO pin 0 to rising edge
    CSL_GPIO_setRisingEdgeDetect (hGpio, pinNum);

    // Enable GPIO per bank interrupt for bank zero
    CSL_GPIO_bankInterruptEnable (hGpio, bankNum);

    // Toggle GPIO_0 pin to trigger GPIO interrupt
    CSL_GPIO_clearOutputData (hGpio, pinNum); //GPIO_0=0
    CSL_GPIO_setOutputData (hGpio, pinNum); //GPIO_0=1


    // 3. Wait for entering into ISR
    while(a!=1){}


    printf("a = %d\n",a);
    printf("GPIO interrupt occurs\n");

    return 0;