AnsweredAssumed Answered

Possible compiler bug.

Question asked by Peter847 on Jan 5, 2012
Latest reply on Jan 10, 2012 by CraigG

Hi,

 

I am having trouble with an ISR for a C++ VDK project, the code of which is shown below. I have found that the code if(*pSIC_ISR & 0x00001800) never resolves to TRUE but if I first save the value of *pSIC_ISR to an intermediate variable and use that instead (as shown) it works fine. The really strange thing is that I have to do this for the UART handler but not for the TWI handler below it. I have tried swapping the order of the code so that the TWI is dealt with first but this makes no difference. I have used the debugger to check that the 0x00001000 flag is being set in the SIC_ISR. Am I missing something obvious or is this a compiler bug? The fact that it works OK when testing the 0x00000200 flag but not the 0x00001000 flag is very strange.

 

Anyone any ideas,

 

Thanks,

 

Peter.

 

 

#ifdef VDK_REENTRANT_ISR
EX_REENTRANT_HANDLER(EVT_IVG11_Entry)
#else
EX_INTERRUPT_HANDLER(EVT_IVG11_Entry)
#endif
{
    // Use this value to hold the interrupt flags so we can read the status multiple times without clearing the interrupt.
    int intPending = 0;
   
    // Use this value to hold the SIC_ISR as using it directly doesn't always seem to work.
    unsigned long sic_isr = *pSIC_ISR;


     /************************************************************************
     *                                                                        *
     *                                UART0/1                                    *   
     *                                                                        *
     ************************************************************************/
    
    // Deal with UART0 Rx/Tx.
    intPending = *pUART0_IIR;            // Save contents of IIR (will clear the interrupt).
          if(sic_isr & 0x00001800)               // OK
     //if(*pSIC_ISR & 0x00001800)           // never works

     {
        g_lpUART0->InterruptHandler(intPending);
     }
   
    /************************************************************************
     *                                                                        *
     *                                TWI                                        *   
     *                                                                        *
     ************************************************************************/


     // Don't need to save contents of TWI_INT_STAT as reading it doesn't clear the interrupt.
    if((*pSIC_ISR & 0x00000200) && (*pTWI_INT_STAT & 0xf0) && (g_lpTWIDriver != NULL))
    {
        g_lpTWIDriver->InterruptHandler(*pTWI_INT_STAT);
    }
}

Outcomes