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 ISR nesting problem



I am working with C5515.
I have a GPIO ISR that services several gpio.
I am experiencing a problem where after some time, the GPIO ISR is not called any more, although the IOINTFLG1 register indicates there are pending interrupts.
From the DSP system user guide I have read that :
"If two (or more) GPIO pins happen to interrupt simultaneously, the IOINTFLG1/IOINTFLG2 register indicates the two (or more)
interrupt flags. In this case, the ISR can choose to service both/all GPIO interrupts or only one-at-a-time. If
the ISR services only one of them, then it should clear only one of the IOINTFLG1/IOINTFLG2 flags and
upon exiting the ISR, the CPU is immediately interrupted again to service the others."
From what I see, this does not happen. The CPU is not interrupted again is there is an interrupt during the ISR.
Has anyone encoutnered a similar problem ?
Thanks.
  • I have had a similar problem with the DMA, where reading the status register clears all flags. Thus, if I try to read the status register twice, my code was missing additional flags.

    My workaround was to read the (DMA) interrupt status register once at the beginning of my interrupt subroutine and cache the value in a local variable. Then, I tested multiple flags as many times as I needed by masking the local copy.

    Part of the reason my workaround is successful is that I handle all potential interrupt flags within a single interrupt call, so I am not depending upon an additional interrupt being generated if I only process one flag.  Of course, the DMA peripheral in my C5506 is probably not designed to handle sequential interrupts, so this could be a very different situation.

    In your case, it seems that there are two registers. I would guess that you should not even read the 'other' register unless you're prepared to service any interrupts associated with that particular register.

    On a related note, do you have the 'interrupt' keyword in front of your subroutine to mark it as a special function instead of a standard C function? There are a few different ways that the compiler allows you to mark a function, but you should make sure that at least one is present. I use both the #pragma and the keyword.

    That's all I can think of now that might be of help,

    Brian

  • Thanks,

    I am using the BIOS HWI dispatcher, so I dont use the interrupt keyword.

    I do save the register on entry .

    The problem is that the ISR stops working. When I pause the run in the debugger I see that there are pending GPIO ISRS. Only when I clear the pending ISRS from the debugger, the 

    ISR resumes to work.

    My code is:

    extern "C" void HWI_GpioISR()
    {
        volatile Uint16 keepIOINTFLG1 = CSL_GPIO_REGS->IOINTFLG1;
        volatile Uint16 keepIOINTFLG2 = CSL_GPIO_REGS->IOINTFLG2;
    
    
    
     // Process ISRS 
    
    
        // Clear ALL interrupt flags
        CSL_GPIO_REGS->IOINTFLG1 = keepIOINTFLG1;
        CSL_GPIO_REGS->IOINTFLG2 = keepIOINTFLG2;
    }
    
  • Can anyone from TI comment ?

    We are clearly seeing in the scope that the problem occurs when two GPIO lines are triggered simultanuously.

    I forgot to mention that we are working with DSP BIOS and use the HWI dispatcher.

  • I had the same problem. It was solved by not using macroses CSL_FINSR and CSL_FEXTR from CSL.

    Just do the next:

    Uint16 io_int = CSL_GPIO_REGS->IOINTFLG1;

    CSL_GPIO_REGS->IOINTFLG1 = io_int;

    and decode io_int after it.