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 lockup due to void message

This is just an "FYI" for anyone that might bump into this issue.  It is very rare, but I thought it would be a good idea to log the issue on the forum...

Background:  A "void message" is a START condition followed by a STOP condition (without any address or data).  In simpler terms, let's assume the bus is idle and so both SCL and SDA are pulled high.  Nothing is happening...  If a slave happens to pull SDA low (START) and then release it (STOP), that would be considered a "void message".  I've only seen a couple of mis-behaving slaves ever do this... (Neither was a TI device by the way!)  Void messages are illegal in the I2C specification. 

Description: When operating as an I2C master the I2C peripheral automatically returns to a slave state (MST=0) after each master transaction is completed.  This is to allow the peripheral to perform in both the master and slave role.  If the SDA line gets pulled low momentarily by an errant slave (i.e. "void message"), this will cause the I2C peripheral to hang when attempting to master the next transaction.

Devices exhibiting this behavior:  These are the ones I know are affected.  There could be more that have not been checked. OMAP3/4/5, AM35xx, AM37xx, DM37xx, DM816x, DM814x, AM335x, AM437x, AM57xx.

Workaround 1: This is only “detected” by the lack of completion of a transfer, i.e. a software timeout.  The I2C module needs a soft reset through the I2C_SYSC to recover.  This is already handled in drivers for Linux and other high-level operating systems which would reset the I2C and then successfully retry the operation.

Workaround 2: If the I2C never "sees" the void message then it will not lockup.  In the scenarios I've seen this issue, the bad behavior is predictable/deterministic.  For example, the badly behaved slave will pull SDA low shortly after being enabled through a GPIO.  In these circumstances you can avoid the scenario altogether by setting I2C_EN=0 prior to the event that will cause the void message.  This holds the I2C state machine in reset.  It does NOT however reset any of the registers.  In other words you would not need to reprogram prescalers, etc. after re-enabling the I2C.