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 slave sometimes holds scl low until bus is restarted

Part Number: MSP430FR5738

Hi,

We are having an issue where sometimes the msp stops replying correctly on the i2c until it gets reset. 

The msp acts as slave.

When it starts to misbehave, the msp acknowledges the address, the data received, but stops acknowledging afterwards. SCL gets stuck low when it should ack.  SCL stays low for 32ms, and then bus is restarted in the handling of USCI_I2C_UCCLTOIFG

However the msp keeps misbehaving after the bus reset, with the same pattern. It works ok only if I reset the msp completely. 

Here is how I reset the bus.

    case USCI_I2C_UCCLTOIFG:
    //Timeout of the bus, reset i2c
        ucBusyDetectionCounter += 1;
        P1SEL1 &= ~(BIT6);      // Generate NACK by releasing SDA,
        P1SEL1 &= ~(BIT7);      //  then SCL, via disconnecting from the I2C

        UCB0CTLW0 |= UCSWRST;   // Reset

        UCB0CTLW0 |= UCMODE_3 | UCSYNC;          // I2C mode, sync mode
        UCB0I2COA0 = SLAVE_ADDR | UCOAEN;        // Own Address and enable

        UCB0CTLW0 &= ~UCSWRST;
        P1SEL1 |=  (BIT6|BIT7); // Re-connect pins to I2C
        UCB0IE |= UCRXIE + UCSTPIE + UCCLTOIE;   // Enable RX and TX interrupt
        break;

I suppose I have two issues: 

1: Some internal issue which prevents it to reach next state

2: An incomplete bus restart which fails to correct it.

From the doc:

The clock is stretched by the eUSCI_B under the following conditions:

1: The internal shift register is expecting data, but the TXIFG is still pending

2: The internal shift register is full, but the RXIFG is still pending

3: The arbitration lost interrupt is pending  => Unlikely, it is handled in the same routine than USCI_I2C_UCCLTOIFG which works fine

4: UCSWACK in UCBxCTLW1 is selected and UCBxI2COA0 did cause a match => Not possible, UCSWACK  is not activated

I'm currently digging into the first two causes for clock stretching.

My questions:

- Have you seen such issue? Any pointer which could help me understand the root cause of the issue?

- Do you see any issue with the bus reset code?

Notes:

I'm quite sure the i2c master is not the issue, the problem stops when the msp is reset, and the communication with other i2c slaves is ok. 

Thanks,

Cédric

  • One hazard I do know about is that UCSTPIFG has a higher priority (in UCB0IV) than the RX/TXIFGs, which sets up a race. If you use UCSTPIFG and do the usual sort of Stop-things (notably disabling IE-s) you may leave an RX/TXIFG condition stuck in the I2C unit. 

    I don't know offhand why a SWRST sequence wouldn't clear that, though.

  • Thanks for the tip! 

    After some more debug, I found why the bus reset failed to resolve the issue. It missed a reset of the state machine: 

    "SlaveMode = RX_REG_ADDRESS_MODE;"

    I'm still not sure why the bus sometimes has issues, but now when it occurs the bus is quickly reset and functions well.

**Attention** This is a public forum