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.

I2C Interrupt Program Flow Question

Other Parts Discussed in Thread: MSP430FR5969

Hi All,

This is more of a design/program flow question, not an actual bug.

I'm using the eUSCI peripheral of an MSP430FR5969 microcontroller, to interface with multiple I2C sensors. So far, I've been using interrupts to do the communication, which uses an interrupt handler which usually looks something like the one below:

// EUSCI_B I2C Interrupt
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
  {
    case USCI_NONE:          break;         // Vector 0: No interrupts
    case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
    case USCI_I2C_UCNACKIFG: break;         // Vector 4: NACKIFG
    case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
    case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
    case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
    case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
    case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
    case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
    case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
    case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
    case USCI_I2C_UCRXIFG0:  		        // Vector 22: RXIFG0
        // Receiving code goes here
    	break;
    case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
    	// Sending code goes here
    	break;
    default: break;
  }
}

Here's my question: what is the best way to handle multiple sensors with this method? If you just have one sensor, you can just put the receiving code and the sending code in the commented areas above. But, if you have multiple sensors with multiple kinds of commands, the only way I can think of handling all events is by using flags and putting a lot of code in the interrupt handler. I know you are supposed to keep interrupts as short as possible but that seems very difficult with my current method. Is there a better way to do what I am talking about?

If anyone is confused, I would be happy to add pseudo code to explicitly show my thoughts.

Thanks in advance for any help!

- NG 

  • I2C is a connection-based interface. So you should know which sensor you are currently accessing. Either you make this information available through a volatile global variable, or you check the current slave address inside the ISR (and then you need some globally available mapping information to map the slave address to your logical sensor number.
    In any case, if main initiated a transfer with sensor A, the ISR won’t get any data from sensor B :)

    The amount of code inside the ISR handler is not a problem, as long as the execution time is short. So if only one branch is executed at a time (the one for the currently active sensor), it is unimportant how much code for how many other sensors is inside the ISR but skipped.

    But it should be noted that the maximum distance between the switch statement and the target case can’t be larger than 1024 bytes, when using the __even_in_range intrinsic.

    However, the ISR should not handle any device specific information anyway. It should just dumb receive or send a given amount of data, not knowing where the data comes from or goes to. When the transfer is done, main can handle the data based on where it comes from.

  • Jens-Michael,

    That helps a lot, thank you very much!

    - Nipun

**Attention** This is a public forum