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.

MSP430FR2433: I2C clock Low Timeout Interrupt

Part Number: MSP430FR2433
Other Parts Discussed in Thread: MSP430FR2476

Hi, 

I'm implementing MSP430 as an I2C slave device with multiple read / write registers. For some reason, I2C clock is held low and master cannot communicate with slave anymore. 

To handle this, I've enabled I2C clock low timeout interrupt. Interrupt is being triggered, as can be seen on LED being toggled. 

Now I want to reset I2C module inside Interrupt handler. Referring to 

24.3.7.3 Clock Low Timeout
The UCCLTOIFG interrupt allows the software to react if the clock is low longer than a defined time. It is
possible to detect the situation, when a clock is stretched by a master or slave for a too long time. The
user can then, for example, reset the eUSCI_B module by using the UCSWRST bit.
The clock low time-out feature is enabled using the UCCLTO bits. It is possible to select one of three
predefined times for the clock low time-out. If the clock has been low longer than the time defined with the
UCCLTO bits and the eUSCI_B was actively receiving or transmitting, the UCCLTOIFG is set and an
interrupt request is generated if UCCLTOIE and GIE are set as well. The UCCLTOIFG is set only once,
even if the clock is stretched a multiple of the time defined in UCCLTO.

 

I'm adding following lines inside interrupt handler 

UCB0CTLW0 = UCSWRST; 

UCB0CTLW0 &= ~UCSWRST; 

It does not reset the I2C module.

What could be done inside interrupt handler to restart I2C module? 

 

  • Are you fairly certain it's your slave that's holding SCL low? (What happens if you reset (RST button) the slave?)

  • Yes, If I reset slave, again communication starts. On the other hand, if I reset master, same error persists. 

    Thanks. 

  • Hi,

    Is there anything else on the I2C bus that might be causing the MSP I2C slave to get stuck in a weird state? I did a search for similar phenomena and this E2E post ( https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/301670 ) seems to also have a I2C line held low issue that was being caused by another device on the I2C bus affecting the MSP430.

    Are you able to recreate the issue consistently or is it sporadic?

    Best regards,

    Matt

  • It turns out there's a little more to the "reset" sequence. The SWRST by itself does release the bus, but doesn't leave the slave operational.

    My platform is an MSP430FR2476 Launchpad with firmware that acts as both Master (UCB0) and Slave (UCB1), connected by patch wires. The FR2476 is a fairly close cousin to the FR2433, but has 2x EUSCI_B devices. I added a CLTO and a hook in the Slave to trigger a bus hang (by ignoring an RXIFG).

    1) UCSWRST clears the IE register, so you'll need to put the IE bits back. [Ref User Guide (SLAU445I) Sec 24.3.1]

    2) In my platform, releasing the bus using SWRST seemed to cause trouble for the Master. Observed behavior was that it began sending Start conditions as fast as it could. (I don't know if this is an I2C rule or an MSP430 I2C quirk.) I suspect it had to do with SDA and SCL being released simultaneously, since I was able to avoid this by releasing them separately, in a particular order.

    Here's the sequence I ended up with:

            r = UCB1IE;             // Save current IE bits
            P4SEL0 &= ~(BIT3);      // Release SCL by disconnecting from the I2C
            P4SEL0 &= ~(BIT4);      //  then SDA
            UCB1CTLW0 |= UCSWRST;   // Reset
            UCB1CTLW0 &= ~UCSWRST;
            P4SEL0 |=  (BIT3|BIT4); // Re-connect pins to I2C
            UCB1IE = r;             // Put IE back
    

    [Edit: In retrospect what that sequence does is generate an ACK. It seems that a NACK (opposite order) would be better, but the Master doesn't seem to accept that.]

  • In retrospect: That bus-release sequence succeeded by generating an ACK. A NACK, to immediately end the transaction, is probably preferable. That order failed because my Master was incorrect (I forgot to enable UCNACKIE on a Read). Here's the updated sequence:

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

  • Hi, 

    Thank you very much for your efforts. This sequence does solve the problem. 

**Attention** This is a public forum