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.

MSP430FR5738: I2C

Part Number: MSP430FR5738

Hi,

On one of our product, we have an issue where sometimes SCL is stuck low. I2C Master is the cc3235, slave is the msp430fr5738 (there are 2 other i2c slaves but we have confirmed that they are not the ones holding the line).

We see SCL being held low for an infinite time, and released when the msp is reseted.

It's very difficult to debug because it's affecting only about 3% of devices per year. Fortunately when doing another change the error rate was increased to ~5% per week, so still not easy to reproduce on an instrumented device but feasible.

We are not sure of the root cause yet, we suspect it might be caused by USCI37, from the errata https://www.ti.com/lit/er/slaz391ag/slaz391ag.pdf?ts=1699367487148&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FMSP430FR5738


Our questions:

- Can you confirm that we should detect if the msp is holding SCL by checking UCB0STATW & (UCSCLLOW | UCBBUSY) ?

- Is there an easy way to put the msp in this error mode? This would help us confirm that it is the issue we see, and make the master code more robust as well.

- What is the proper way to reset the bus properly on the msp? We are planning to use the code below.

    UCB0CTLW0 |= UCSWRST;                   // Software reset enabled
    UCB0IE &= ~(UCRXIE | UCSTPIE);          // Disable RX and TX interrupt
    UCB0IFG = 0;                            //Clear pending interrupts

    for (int i = 0; i < 200; i++) // Wait 200ms
    {
        __delay_cycles(8000); // Wait 1ms, ~1ms because MCLK = 8MHz
    }

    UCB0CTLW0 &= ~UCSWRST;                   // clear reset register
    UCB0IE |= UCRXIE + UCSTPIE;              // Enable RX and TX interrupt

Some infos about our system :

Clock = 8 Mhz

I2C frequency 100 Khz

I hope it's clear enough.

Thanks,

Cédric

  • I've had some success with this sequence:

        case UCIV__UCCLTOIFG:       // Bus timeout
            r = UCB1IE;             // Save current IE bits
            P4SEL0 &= ~(BIT4);      // Generate NACK by releasing SDA,
            P4SEL0 &= ~(BIT3);      //  then SCL, via disconnecting from the I2C
            UCB1CTLW0 |= UCSWRST;   // Reset
            UCB1CTLW0 &= ~UCSWRST;
            P4SEL0 |=  (BIT3|BIT4); // Re-connect pins to I2C
            UCB1IE = r;             // Put IE back
            break;

    Context: I had an experiment slave which included a "hang the bus, please" request the master could send. The slave did this by ignoring the next UCTXIFG0 (read request) it saw. This code was the response to the eventual UCCLTO timeout. 

    The code I pasted above ran on an FR2355; I think I tried it on a few others (all with EUSCIs).

  • Thank you! 

    We've managed to make the bus hang with scl low by deactivating both TX and RX interrupt at the proper time. And also to reset it using UCCLTO as you did.

**Attention** This is a public forum