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.

OMAP L138 GPIO Bank interrupt

Other Parts Discussed in Thread: TL16C752C, OMAPL138, AM1808

The project I am working on uses a GPIO interrupt (Bank 6) for the OMAP L138.

We have noticed this problem. When an interrupt is generated (triggered on the rising edge) on the GPIO Bank 6 pin, the interrupt service routine is called properly in most instances. However, the GPIO Bank 6 ISR software is responsible for clearing the GPIO Bank 6 signal that generates the interrupt. Therefore, it is possible that another interrupt might be generated while the GPIO Bank 6 ISR is still executing. Note: The rising edge trigger of this GPIO signal is generated by an external hardware peripheral (TL16C752C). When the rising edge is generated while the ISR servicing the previous rising edge is still in progress, the ISR is never invoked again because the ISR is responsible for clearing the signal. The time between the falling edge and the rising edge in this failure scenario is approximately 2 microseconds.

I have tried disabling the Bank 6 interrupt at the beginning of the ISR and re-enabling at the end of the ISR, but to no avail. This disable/enable of interrupts includes both the OMAP as well as the external peripheral (TL16C752C).

The project uses Micrium’s OS (MicroC – OS ) for the OMAP, I also noticed, via the IAR debugger, that the ISR is 5 calls deep on the call stack. This might be part or all of the problem. There isn’t any way that I know of in preventing the TL16C752C from creating another rising edge interrupt while the current interrupt is being serviced. Also, I stopped the debugger and discovered that the Bank 6 IRQ signal is active, but it seems the AINTC is not invoking the ISR.

Any help or suggestions would be appreciated. I realize I was brief with the above description and will post additional details and/or code snippets if requested.

  • Hi David,

     

    You may want to check where in the ISR the interrupt flag is cleared.  One possibility is that If there was another interrupt already in the queue while the ISR was execution and interrupt flag is cleared at the end of the ISR execution then the  pending interrupt flag will be cleared and the device won't see the later interrupt.  In such case clearing the flag at the beginning of the ISR should fix the problem

  • Hi Muhammad,

     

    Thanks for your quick reply.

     

    Here is the Interrupt Service Routine.

     

    static void TL16C752_ISR(void)
    {

        INT32U irqStat = GPIO_BANK67->IRQ_STAT;
     
         /* Check for debug interrupt */
         if (irqStat & 0x08)
         {
                GPIO_BANK67->IRQ_STAT = 0x08;
                TL16C752_ServiceInterrupt();
          }

          CSP_IntClr(CSP_INT_CTRL_NBR_MAIN, CSP_INT_SRC_NBR_GPIO_06);


    }

     

    I also tried to move the CSP_IntClr() just prior to the "if" statement but to no luck. Also, I tried reversing the order of the statements within the if block, but again, no luck.

  • What does CSP_IntClr() do?  If GPIOBNK6 interrupt is tied to one of the 12 maskable interrupts then you do not have to do anything further.  In fact, that might actually be causing your problem!  If you are using the Interrupt Combiner then you would need to clear out the event.  Can you clarify?

  • The CSP_IntClr() function does the following:

    CSP_INT_REG_SICR = src_nbr & DEF_BIT_FIELD(7u, 0u);         /* Clear interrupt status */

    In effect, it modifies the System Interrupt Clear Register with the interrupt source (GPIO6).

     

  • David,

    You're doing the interrupt acknowledgment in the wrong order.  Please see:

    http://processors.wiki.ti.com/index.php/Configuring_GPIO_Interrupts#GPIO_ISR

    You should first write SICR and THEN acknowledge INTSTAT.

    Brad

  • Hi Brad,

    Thanks for your response. I tried the ISR code below and it still did not solve my problem. When operating the serial port at full duplex (asynchronous TX & RX), the interrupt service routine eventually stops being called, but through the use of a debug variable, I can determine that GPIO_BANK67->IRQ_STAT has a value of 0x08 which means either:

    1) the GPIO is not raising the interrupt

    2) the AINTC is not recognizing it or

    3) the software is either not setting the ISR up properly or not servicing it properly

     

    void GPIO67_Interrupt_Service(void)

    {

        // Clear the bank 6 interrupt in the AINTC (call modifies AINTC SICR register)
        CSP_IntClr(CSP_INT_CTRL_NBR_MAIN, CSP_INT_SRC_NBR_GPIO_06);
       
       
        while (1)
        {

            INT32U irqStat = GPIO_BANK67->IRQ_STAT;
           
            if (irqStat == 0)
            {
                break;
            }
           
            if (irqStat & 0x08)
            {
                // Clear the bank 6 pin 3 interrupt in the GPIO (pin 3 still high at this point)
                GPIO_BANK67->IRQ_STAT = 0x08;

                // The next call pulls the interrupt line low
                // (pin 3 should be low after exit but might transition high any time after the call; can't control when pin 3 goes back high
                // due to the asynchronous nature of full duplex serial interface)

               TL16C752_ServiceInterrupt(DEBUG_PORT);
            }

        }

    }

    From the link you pointed me to, could you explain the difference between a direct interrupt versus a banked interrupt (Again using the OMAP - L138 ARM interrupt).

    Thanks in advance.

  • David Smail said:
    From the link you pointed me to, could you explain the difference between a direct interrupt versus a banked interrupt (Again using the OMAP - L138 ARM interrupt).

    The OMAPL138 has only bank interrupts so that isn't applicable.  So for example, on the OMAPL138 the Bank 6 interrupt is connected to interrupt #48 of the AINTC.  Some devices actually have connections for specific PINS rather than the whole bank.  The advantage of this is that you wouldn't need to look at the IRQSTAT register in the corresponding ISR because only a single pin could be responsible for that specific interrupt.

  • David Smail said:

    void GPIO67_Interrupt_Service(void)

    {

        // Clear the bank 6 interrupt in the AINTC (call modifies AINTC SICR register)
        CSP_IntClr(CSP_INT_CTRL_NBR_MAIN, CSP_INT_SRC_NBR_GPIO_06);
       
       
        while (1)
        {

            INT32U irqStat = GPIO_BANK67->IRQ_STAT;

     

    You mentioned you're using Micrium OS (sorry, I have no experience with Micrium).  Also, I see that you are not using the interrupt keyword.  From these 2 things I conclude that at the OS level there must be some kind of rudimentary interrupt dispatcher.  That being the case, I would assume that the OS itself would write to SICR to clear out the pending interrupt.  Do you know if that's the case?  If so, does the bit get cleared before your code runs or after.

    One other thing that came to mind is the DSP.  Is there code running on the DSP and could there be some kind of contention over this Bank 6 interrupt?

  • Hi..

    I have AM1808 as my processor. 

    I want to have information about "CSP_INT_CTRL_NBR_MAIN". Can it be used in programming for MPU's in AM1808 ??

    http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/t/158135.aspx  . In the given link , it has been used.

    Is it a function, pointer, ...??I am not able to figure out.

    I am new to this and have recently started doing this. Pardon my ignorance.