3

I found this part from the example code for UART for MSP430FR57xx from TI. I don't understand what __even_in_range(UCA0IV,0x08) does mean?

#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
    switch(__even_in_range(UCA0IV,0x08))
    {
    case 0:break;                             // Vector 0 - no interrupt
    case 2:                                   // Vector 2 - RXIFG
        while (!(UCA0IFG&UCTXIFG));           // USCI_A0 TX buffer ready?
        UCA0TXBUF = UCA0RXBUF;                // TX -> RXed character
        break;
    case 4:break;                             // Vector 4 - TXIFG
    default: break;
    }
}
CL.
  • 173,858
  • 17
  • 217
  • 259

2 Answers2

5

The interrupt vector register never has a value that is odd, or larger than eight. So if you tell the compiler about this, it is possible to generate slightly more efficient code by leaving out the checks for those values, and by implementing the cases with a simple jump table.

CL.
  • 173,858
  • 17
  • 217
  • 259
0

According to the MSP430 Optimizing C/C++ Compiler User's Guide, __even_in_range is a compiler intrinsic:

The __even_in_range intrinsic provides a hint to the compiler when generating switch statements for interrupt vector routines. The intrinsic is usually used as follows:

switch (__even_in_range( x , NUM ))
{
...
}

The __even_in_range intrinsic returns the value x to control the switch statement, but also tells the compiler that x must be an even value in the range of 0 to NUM, inclusive.

Compiler intrinsics are compiler-specific* tools that allow you to do things not possible within the bounds of strictly conforming C or C++ code. Sometimes intrinsics allow you to do something that would otherwise require assembly language. In this case, the even_in_range intrinsic is merely a tool to inform the compiler of characteristics of the argument to the switch statement. By guaranteeing to the compiler that the value used as the argument to the switch statement is both even and between 0 and some other small integral value, the compiler is able to emit more efficient assembly code to implement the switch statement than it would if it did not know the characteristics of that argument.

So, the following two lines are functionally equivalent:
switch(UCA0IV)
switch(__even_in_range(UCA0IV,0x08))
...but the 2nd line results in more efficient assembly code.

*compiler-specific: This means not all compilers support it. In fact, your compiler may be the only one that does.

phonetagger
  • 7,701
  • 3
  • 31
  • 55