Hi everybody,
we are using the I2C interface of an MPC5645 to communicate with some external slaves (2 EEPROMs, ADC, RTC). The MPC5645 always acts as the master on the I2C bus, and the communication is based on interrupts. The application contains a brushed motor which under heavy load conditions creates electromagnetical disturbances which can also be seen on the I2C lines SCL and SDA.
We observed the issue that during an ongoing transfer and when the disturbances are present, when the I2C interrupt is called, the IAAS (Adressed-as-slave) flag is sometimes set, and the MPC ignores the NOACK setting in the configuration register and sends an ACK, which in some cases leads to a bus lock (as the slave keeps on sending data and holds SDA low). It seems that the peripheral somehow undergoes an internal reset and begins to act as a slave.
Question is: Is that a known behaviour, and what can I do to unlock the bus?
My guess is to keep transmitting data (to toggle the SCL line) and try to free the bus, which seems to work reasonably good.
Thanks and best regards,
Mario
Hi,
the behavior can be caused when master lost arbitration. I2C switch over to slave mode and stop driving the SDA output. In this case, the transition from master to slave mode does not generate a STOP condition. But you should see a status bit set by hardware to indicate loss of arbitration (IBAL).
Hi Petr,
thanks for the quick response
I checked all the flags in the status register, and in case the error occurs, only the IAAS flag is set - the IBAL flag is not set. The IAAS flag gets set during an ongoing (master) transfer, when the preceding data sent by the slave at random matches the IBAD register (which is 0x00 in my case, as it is not changed after reset).
In my case, a bus lock occurs when this happens at the second-to-last data byte, when - immediately after the IAAS flag occurs - I reset the NOACK bit to zero, to stop the transfer after the upcoming last data byte. In this case, the master seems to go into slave mode, it (erroneously) sends an ACK after the last byte, then releases the SDA line and sends a single clock cycle (I guess this is toggled by the last read access to the data register); the slave then keeps on sending data and holds SDA low. This is when the lock occurs.
So I'm going to try your suggested solution to get the bus unlocked.
Thank you and best regards,
Mario