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.

MSP430FG4618: Timing Issues with USCI running I2C at low processor clock rates

Part Number: MSP430FG4618

This relates to an earlier query (some months back) related to I2C transactions failing when the processor clock rate was slowed. As there was an easy workaround (don't run the clock so slow!), I had put it into the curio basket, but it has bugged me, and have finally had a bit of spare time to play with it and try and understand what is happening.

As a brief precis, I've been running a USCI based I2C at 100K, in master receiver mode, reading 3 bytes of data (2 bytes plus a PEC) from a sensor. This worked fine at higher clock rates (above 4MHz), but under this attempted to read an additional spurious byte. What follows is my understanding of what is happening.

The documentation states that the STP must be requested while the final byte is being read. In code terms, this means that the STP needs to be requested immediately the RXBUF for the penultimate byte is serviced. I had assumed that I had the time taken to read the final byte to play with - at 100K this should have given me around 80uS. This should have easily been adequate, particularly as nothing was happening between servicing the RXBUF for the penultimate byte, and requesting the STP. But I was still seeing the failures, even with some trivial test logic with the RXBUF read immediately followed by the STP. A play with a logic analyser, together with yet another read of the documentation has finally shed some light on this.

I had ignored that the USCI buffers the incoming bytes, and will continue to clock and read data while waiting for the previous RXBUF to be serviced. If the RXBUF is not serviced in time (which is what was occurring at the reduced clock rates), the USCI will eventually halt the I2C clock when it has buffered all but the last bit of the next byte. Once the RXBUF is read, it will immediately clock this last bit. What this means is that rather than the time taken to read a whole byte to get the STP in place (~80us), if the next byte is already fully buffered, the available window is only the time needed to read the final bit (around 8us). At low MSP clock rates (like 1MHz), there is simply not enough time to request the STP before the USCI completes reception of the current byte, and starts reading another, spurious byte.

Does this sound valid?  I can't see any means of protecting from this, other than being very cautious with combinations of low MSP clock rates, and high I2C data rates.

Regards - Andrew

  • Hi, Andrew, 

    I think your analysis is correct. 

    In the I2C Master Receiver Mode section of user's guide slau056, there is description "If a master wants to receive a single byte only, the UCTXSTP bit must be set while the byte is being received.". It is also demonstrated in the code examples msp430xG46x_uscib0_i2c_10.c. 

    If the MCLK is too slow, the UCTXSTP is set after the last byte is received into RXBUF, the stop and NACK will not generated normally. 

    ISR of msp430xG46x_uscib0_i2c_10.c: 

    __interrupt void USCIAB0TX_ISR(void)
    {
        RXByteCtr--; // Decrement RX byte counter
        if (RXByteCtr)
       {
            *PRxData++ = UCB0RXBUF; // Move RX data to address PRxData
            if (RXByteCtr == 1) // Only one byte left?
                UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
        }
        else
        {
            *PRxData = UCB0RXBUF; // Move final RX data to PRxData
            __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
        }
    }

    Thanks,

    Lixin

  • Thanks for that!

    For posterity, I have just done a few tests to get a feel for the combined limits of MSP clock speed and I2C clock, before this starts to appear. The logic simply put a in delay before the penultimate real byte was read to ensure the USCI had fully buffered the final byte (verified on a data analyser by sighting the clock stretch), then executed the read of the RXBUF, immediately followed by the STP request. The results were somewhat surprising! The 4618 I was running on limited the clock to 8MHz, and the I2C slave was an SMBUS compliant device which limited the I2C clock to 100KHz.

    At 8MHz clock, everything was fine up to 100K,and the transaction completed without the USCI reading any spurious data. At a 4MHz clock, anything above 60K I2C failed to stop the USCI in time. At 2MHz the maximum I2C was 30K. At 1MHz, I was starting to run into other issues with timing on the I2C slave, and couldn't drop the I2C clock enough to get a clean transaction without the slave giving up talking to me.

    But, does this really matter? While it is definitely more elegant to stop the transaction cleanly, the slave has already provided all the information we require, so in reality we can simply ignore any spurious data. If the data was going the other way, and we depended on the correct termination to commit the transaction to the slave, it could be a problem. However in this scenario, the USCI cannot write ahead of data we provide, so we should always have the full byte window to terminate the transaction correctly (I think!).

    I'll go ahead and close this. I'm confident I understand what's happening, and can easily work around it.

    Regards

    Andrew

**Attention** This is a public forum