I've reviewed the registers, and the app notes for Kinetis' i2c implementation. Looks great, and for the most part works. What I don't see is how to detect / clock out of and recover from a stalled or hung i2c slave on the bus. Any ideas on how we do that? Just check the state of the SDA pin manually, and then switch modes and manually toggle the SCL? We want to have a way of catching and handling / clearing bus errors in case they happen instead of just permanently killing the bus. There doesn't seem to be a good solution for handling this, and I wanted to know if anyone at Freescale or elsewhere has got an answer for this. Most of the discussions talk about using an interrupt driven MQX driver - or disabling it because a part hangs on start and there is no recovery.
@Todd, did you get anywhere with this? I've got the situation where a buggy slave puts a junk pulse on the I2C SCL line as it comes out of reset. The K60 I2C peripheral just seems to lock up until I hard reset the processor :smileysad:
The Kinetis I2C module does support the SMBus SCL low and SCL high timeouts. Have you tried using the SCL low timeout functionality for this purpose?
In a normal I2C bus hang, a device holds SDA low indefinitely. To recover, the controller usually clocks SCL until SDA clears.. How would having an SCL low timeout help..?
Excuse me. I made a mistake. The SCL high timeout 2 interrupt might help in this case. This bit generates an interrupt when SDA is low and SCL is high for some user specified amount of time. This will allow you to detect the bus hang that you are referring to. The recovery might be a bit more difficult and may depend on how many clock cycles it takes for your slave to recover.
Hope this helps,
Actually - to be more clear - We have a polled version of the driver, implemented and used in an environment where we cannot hang. I think we can use the SHFT2 flag, with the SLTH/SLTL timeout.. And then if set at end of transaction, recover by clocking read byte - check / clear sticky SHFT2 flag - repeat until we no longer get the flag set.. Sound about right to you?
Yes, this sounds like what I would expect. Be careful, as you might have to wait for the timeout to occur a second time after clearing the flag. But the procedure sounds correct.
Sounds good, appreciate the help. Any chance there is an example of such an ISR / fault recovery for the part? Sounds like it would be a good thing to have in a robust driver, but didn't see it in the posted versions (MQX, etc.)