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 hang when reading

Other Parts Discussed in Thread: MSP430F6779

the mcu is MSP430F6779.

the i2c module is eusci(similar to usci).

my implementation is based on interrupt so minimal power and cpu resources are used.


the problem after running a while normally the scl hanged, stay low for ever.

i checked the mcu's errata sheet,

I doubt it's caused by this hardware bug

USCI37
eUSCI Module
Function:   Reading RXBUF during an active I2C communication might result in  
                unintended bus stalls.
Description: The falling edge of SCL bus line is used to set an internal RXBUF-
                   written flag register, which is used to detect a potential RXBUF 
                   overflow. If this flag is cleared with a read access from the RXBUF
                   register during a falling edge
of SCL, the clear condition might be missed. This could result in an I2C bus stall at
    the next received byte.
Workaround
(1) Execute two consecutive reads of RXBUF, if tSCL >4 x t IFCLK . or (2) Provoke an I2C bus stall before reading RXBUF. A bus stall can be verified by checking if the   clock line low status indicator bit UCSCLLOW is set for at least three USCI       bit     clock cycles i.e.3xt BitClock

I like to try the workround (1)

reading RXBUF twice,

so it 's like

data[index++] = USCIRXBUF;

dummy = USCIRXBUF

?

can some one shed some light on this?

Thanks

  • The erratum basically means: after a byte has been received, the USCI will immediately continue reading the next. When it reads bit 7 of the next byte, it will check whether the precious byte has been fetched from RXBUF. If so, it continues, if not, it waits until you did read RXBUF.
    However, if you happen read RXBUF exactly the moment when it performs this check, weird things may happen.

    So either you ensure that you have already read RXBUF before this moment, which you cannot ensure unless writing highly inefficient busy-waiting code. Or you always wait with reading RXBUF after this moment (when SCLLOW is set), which can also be done by highly inefficient busy-waiting code or by starting a timer in the RX ISR, and instead of reading  RXIFG there, you read it in the timer ISR. (you know the baudrate, so you know how long it takes to receive the next byte).

    The two consecutive reads only work for a certain ratio of I2c clock rate and MCLK.

**Attention** This is a public forum