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 gets stuck

Part Number: MSP430FR2155
Other Parts Discussed in Thread: MSP430FR5949

Tool/software:

The implementation of an I2C communication between 2 MC often works and then gets stuck. The bit rate is about 260000 bit/s. Each I2C pin of each microcontroller is provided with a 4.7K pull up resistor.

The MSP430FR5949 (master) sends data to an MSP430FR2155 (slave), followed by a restart and a read command. The master then wants to read 6 bytes. The slave places the first byte on the bus. The master reads it, gives an ACK and wants to read the next byte. Now comes the problem. The slave holds the SDA line low after a few bits. When this happens varies. Sometimes everything works fine. After resetting the slave, it works again a few times until the error occurs. The UCSCLLOW bit in the UCB0 of the slave is ‘0’ in the event of an error.

In some cases, the SCL line is held low instead of the SDA line in the jammed state.

Can anyone tell me whether this is a hardware problem? Can it be handled by software? How can the problem be ruled out from the outset?

Many thanks for your support.

  • Having the slave halt in mid-byte is rather unusual. In the cases I've diagnosed it (almost) always happened because the master (for whatever reason) stopped sending clocks. 

    It sounds like you have a scope trace of such an event; seeing that would be very informative.

  • Thanks for your answer.
    Yes, I have a logic analyser trace as a picture (.png). But how can I put it in this site? "image/video"file" not works with local file system (win10).

  • I succeeded in doing that (with a .png) just now [Win11]. Clicking on the word "UPLOAD" below the "URL" box gets you a "File Open" dialog.

  • Sorry, I ignored this word.

    This is the trace with SDA is low.

    This is a trace with is low. It is possible that this is a different problem. There are two parts. They have a large time gap, but belong together.

    Is it readeble?

    Thanks for your support.

  • In the first trace (SDA low): It appears that the master has stopped sending clocks. After the ACK at the end of the third Rx byte, it doesn't bring SCL low to allow the slave to take over, nor does it try to issue a Stop. 

    In the second/third traces (SCL low): That very long mid-byte clock-stretch is unusual. It's legal for either side to stretch the clock mid-byte, but I don't think I've seen that done before. 

    It occurs to me that either of these could happen if you were to turn off the input clock to the USCI. Are you using LPM? Are you doing anything with the SMCLKREQEN bit?

  • For the first trace: Re-reading User Guide (SLAU367P) Sec 32.3.5.2.2 with a more jaundiced eye, it says "If UCBxRXBUF is not read, the master holds the bus during reception of the last data bit and until the UCBxRXBUF is read." I always took that to mean "stretches the clock", but maybe I didn't look closely and it actually means that it holds the clock high to prevent the slave from presenting its next bit.

    Wordsmithing aside: Is there any chance your firmware can "forget" to read RXBUF?

  • I did not write that in the first case (SDA=low) the following bytes should be transferred from the slave: 0x13, 0x22, 0x45,... These bytes are constant for the test. It looks as if the slave stops sending in the 2nd byte. The SMCLKREQEN bit is 1 and is not changed in the firmware. The individual addresses of the two controllers are entered in UCB0I2COA1. There are interrupt routines for these interrupts:
    USCI_I2C_UCALIFG
    USCI_I2C_UCNACKIFG
    USCI_I2C_UCSTTIFG
    USCI_I2C_UCCLTOIFG
    USCI_I2C_UCSTPIFG
    USCI_I2C_UCRXIFG1
    USCI_I2C_UCTXIFG1
    USCI_I2C_UCRXIFG0
    USCI_I2C_UCTXIFG0
    When the bytes are received in master mode, the routine for USCI_I2C_UCRXIFG0 is executed and UCB0RXBUF is read. The processors run at 16 MHz (master) or 24 MHz (slave). Unfortunately, it is not easy to find out whether the processing of the interrupts is blocked at the crucial moment. Do you have any idea how to test this?

  • The fault is almost certainly with your code. Master, slave, or both. So without seeing that code the best anyone can do is guess.

  • I'm not sure disabling interrupts is the problem. There is flow control (see UG quote above), so progress will be made once interrupts are enabled again. But if the master lost track (lost the RXIFG?) and never read RXBUF again, you might see a symptom like this.

    What do you do in response to UCCLTOIFG? More generally: Are there any cases where you might apply UCSWRST during a transaction?

    As a general point: Logic analyzers often gloss over small anomalies on the wire, notably noise. The cases I've seen the most SDA-stuck-low conditions had very noisy buses (the master sees too many glitches and gives up). If you have a scope, this might be the time to use it.

  • Thanks for the thoughts. I will investigate this with an oscilloscope. I have seen that in the code an attempt was made to save something with UCSWRST and a re-initialisation. I will revise the code. Unfortunately it is very long to show it here. I have one more question. The logic analyser shows a NACK at the end of the read, then SCL and SDA go low and then high at the same time. Is this a correct end of a read operation of the master?

  • Is this a correct end of a read operation of the master?

    It would help if you understood how I2C works instead of depending on the logic analyzer.

    The data line was pulled low for an ACK when the clock went low as expected. But that clock cycle was cut short for some reason. Confusing the analyzer. The clock low time should have been the same as the previous cycles. Perhaps the master was reset. That would explain the lack of a stop condition.

**Attention** This is a public forum