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.

Beware of IRQ_clear() call in CSL - steps on interrupts C5515

  Had bizzare behavior which looked like interrupt sources 'freezing' sometimes or at a minimum dropping events. WATCH out for the IRQ_Clear( ) in the CSL! I did not gring out the macro used in the function but it appears to clear all pending interrupt flags in the IFRx reg. NOT just the 1 flag you request it too. My guess is that it reads the IFRx reg then OR's in the bit corresponding to the EVENT_ID you passed it. SInce that reg clears a bit when the user writes a '1' to it, it destroys all pending interrupts. 

  The CSL example(s), specifically a timer 0 interrupt example, has a call to IRQ_clear(TINT_EVENT) in the ISR. It appears that none of the ISR's need to do this. It seems that the fact the interrupt controller vectored to the ISR causes the flag to clear in IFRx. Someone please correct me if i'm wrong but it sure looks true. So the timer example calls IRC_clear() which perisodically destroys my pending SAR interrupt. Also vica versa. My SAR int. was more frequent and it continually destroyed pending timer ints. ANyway BEWARE. I don't beleive anybody needs IRQ_clear() within the ISR. BUT  ALSO BEWARE that all of the CSL example xx_init() calls tend to not only call IRQ_clear() but more importantly do the following: (1) clear ALL interrupts, (2) disable all interrupts. So one must modify these functions when using the init functions while running real code and have interrupts enabled.My modified IRQ_clear() is below. I beleive it works....

 

CSL_Status IRQ_clear (
Uint16          EventId
)
{
    Uint16 bit;
    Bool old_intm;

    /* Wrong Event Id */
    if (SINT31_EVENT < EventId)
    {
        return CSL_ESYS_INVPARAMS;
    }

    old_intm = IRQ_globalDisable();

    if(EventId > RCV2_EVENT)
    {
        /* IFR1 Register */
        bit = 0x0001 << (EventId - (RCV2_EVENT+1));
        CSL_CPU_REGS->IFR1 = bit;
    }
    else
    {
        /* IFR0 Register */
        bit = 0x0001 << EventId;
        CSL_CPU_REGS->IFR0 = bit;
    }

    IRQ_globalRestore(old_intm);
    return CSL_SOK;
}