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.

Best Way to Determine I2C Peripheral Transaction Is Complete

Other Parts Discussed in Thread: MSP430F5438A

I am using the I2C peripheral in the MSP430F5438A for communication to a 24FC512 EEPROM.  The bus only has this device on it and it is running at ~250kHz.  The driver for this is interrupt driven for transmission and reception but with some polling to make things simpler to manage.  At the moment we are polling the UCTXSTP bit in UCBXCTL1 register to determine if the I2C transaction is complete. 

Every once and a while we timeout waiting for the stop bit to go low signaling the end of the stop bit transmission.  Using the debugger when this happens we can see that there are no errors obvious errors in the I2C registers and using a scope the bus shows both lines high.

So my question is, is the the UCBBUSY bit in UCBXSTAT a better choice to determine if the bus has completed it's transaction or is there something I am missing?

Darren

  • UCTXSTP gets cleared once the stop is sent. You might miss it. Normally, UCBBUSY is a good idea. Or you simply set a global flag inside your ISR when you're done. (doN't forget to make it volatile).

  • Jens-Michael Gross said:
    UCTXSTP gets cleared once the stop is sent. You might miss it.

    Jens-Michael,

    I am not sure how I might miss the stop bit.  I am setting it in the interrupt and the write function is waiting on it to be being cleared.  At the moment I am stuck waiting for it to clear.

    Any thoughts?

    Darren

  • Darren Beckwith said:
    I am not sure how I might miss the stop bit.  I am setting it in the interrupt and the write function is waiting on it to be being cleared.


    I don't know your code, so it's difficult to say what's possibly wrong with it. I have to work on the scarce information you passed, as there is no known "I'm stuck waiting for the stop bit to be cleaed" error.
    My comment about using the UCTXSTP bit to determine when a transaction ends was therefore rather generic: it isn't a good idea, no matter how and when your code does it. Unless you have a direct busy-waiting chain that sets UCTXSTP and hten waits for it to clear again.
    To wait for the it to be cleared, you first have to wait for it to be set. You can miss it when during the ISR that set sit anotehr interrupt happens, whose execution takes longer than the emission of the stop condition. Depending on I2C clock speed and MCLK speed, this can easily happen. I some cases, it may even happen while you're still inside the ISR that set the bit. Then you'll never see it set (indicating that the transfer is about to be ended) and you'll never see it be cleared afterwards (obviously).

    However, you said that the bit won't reset and both lines are clear. There's only one thing that comes in mind for that: the clock source that feeds the USCI is only active upon the USCIs request and deactivates before the USCI state machine updates its status. But this would be a strange racing condition (and a unusual setup anyways, especially since your main thread is active. Or you enter LPM and fail to exit it, so it only seems you're stuck in teh waiting loop while you're actually still in LPM.
    Again, I don't know your code. But then, it should always fail and not only sometimes.
    The device errata sheet doesn't list any known erratum regarding the UCTXSTP bit.
    However, I fear that when UCTXSTP won't clear, UCBUSY won't be set too.

    Ah, another possible reason comes in mind. Also a racing condition. Does it happen in transmit or receive mode?
    In receive mode, UCTXSTP must be set before the ACK cycle for the currently received byte is done, or else another byte will be received before the stop. If the receiving ISR isn't prepared for this excess byte, this may cause an endless interrupt loop when this byte finally comes - and it comes before the stop condition is sent and UCTXSTP clears. This effectively puts the main code into eternal sleep. UCTXSTP will clear, but main won't be able to progress as it never gets an MCLK cycle again. So if your ISR is delayed by more than one I2C clock cycle before it sets UCTXSTP, and doesn't handle the excess byte (read it from RXBUF or clear the IFG bit or read the IV register in this case)...

**Attention** This is a public forum