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.

MSP430f5342 USCI I2C Transmit hold off after Receive

Hi,

I'm fairly new to programming the MSP430 micro and I working on re factoring some old code for my current project.

I'm having an issue with the USCI_B0_ISR interrupt which i am using for acting on USCI_I2C_UCRXIFG & USCI_I2C_UCTXIFG interrupts read from UCB0IV.  My problem is that following several received bytes, the USCI_I2C_UCTXIFG is immediately set and if I don't write any bytes to the OFS_UCBxTXBUF the interrupt doesn't fire again.

What I need to do is hold off writing any bytes to OFS_UCBxTXBUF until i have processed the RX command in the background main loop.

Could someone give me some guidance on how I would achieve this?

#pragma vector=USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
  
  switch (__even_in_range(UCB0IV, 12)) 
  {
    case USCI_I2C_UCRXIFG:
      //receive data
      i2c_receive(USCI_B_I2C_slaveDataGet(USCI_B0_BASE));
    break;

    case USCI_I2C_UCTXIFG:
    //Transmit data
    USCI_B_I2C_slaveDataPut(USCI_B0_BASE, *TXDataPtr++);
    break;
  }
}

  • It's a little hard to know the best solution for your case because we don't know your software protocol, but here is some potential advice. One option would be to implement some sort of variable to tell you how many TX or RX have been serviced so far. For example you could increment the variable every time the RXIFG causes the ISR to be entered, and decrement it when you handle these RX bytes back in the main loop as a way to keep track of if you have data that still needs to be processed. You could also, instead of having the ISR actually write some data when TXIFG is set, you could simply log this flag in a software variable, and then service it/do the sending in your main routine so that the ISR is not blocking.

    Other options include disabling the TX interrupt when you know you don't want to send any more data, but you'll need to re-enable it based on something as well. Hard to say because I don't know your system or protocol, but hopefully this gives you some ideas.

    Regards,
    Katie
  • Are you master or slave?
    In master mode, a TX interrupt only happens when you explicitly started a master transmitter operation. I2C transfers are uni-directional. You either receive or you transmit. You will never do both without doing a (re)start first.
    Probably your (not disclosed) main code starts a receive operation and then imemdiately starts a transmit operation (which implicitly waits until the receive is done, but no longer).
    If you want an additional delay, you need to explicitly wait for the receive to be done (e.g. by checking UCBUSY), then add the delay you want and then start the transmit.

    However, the ISR you posted (and therefore the whole design of your application flow) seems suspicious.
    In your USCIB0 RX handler you call i2c_receive(). I don't know what it does, but if you got an UCRXIFG interrupt, you KNOW that UCB0RXBUF contains the just received byte. Just assign it to where you want it written.
    Same for TX: if you get an UCTXIFG interrupt, then you know that UCB0TXBUF is empty and you can directly write the next byte to it.
    Calling a function that probably does things you don't want to be done inside an ISR (remember, ISRs are no parallel execution threads, they are fast-in, fast-out event handlers).
    Most likely, the calls to I2C_receive (and to the other functions) do not belong in interrupt context at all. At best you're wasting time with function calls. Worst case, you're causing deadlocks, stack overflows or unexplainable behavior.

    Besides this, I don't see that you have any 'all data send' check in your TX, so it is probably sending forever, incrementing TXDataPtr through your whole memory. (Well, unless you're actually using an eUSCI with automatic count, but I guess the library functions would then read "eUSCI..."). Same for RX. I wonder how it will ever end receiving.

**Attention** This is a public forum