I have noticed while checking out a prototype board that the I2C devices occasionally hang the bus (SDA held low) preventing any further bus transactions. My only fix is to cycle power to the board. That leads me to wonder whether adding a fet power switch feeding the I2C devices controlled by the micro might be of benefit - when the micro detects a hung bus, it can "reset" the I2C devices.
Not personally, but you'll find some application notes on Phillip's web site where they discuss the problem and propose various solutions. They make "bus splitter" ICs that can be used to isolate "hung" portions of the bus, generate error signals that can be used to reset processors, etc.
Part of the trick, though, is deciding how long SDA should be able to camp low before you decide the bus is hung. I've heard of people sometimes using SDA as a form of handshaking and allowing up to ten seconds before they time out the bus!
I mentioned this problem in a thread on hot swap systems. I've done systems with dozens of I2C endpoints, and the solution was to use a SMBus controller.
I2C is specified to DC, whereas SMBus (same bus protocol) is not, and therefore implements a timeout. Note that provided the bus master implements the SMBus timeout, you'll be ok. It gets more complicated if you have multiple masters, but the principle is the same.
I never use pure I2C now simply because of this issue. Most processors with internal I2C can implement the timeout (using internal timers).
We''ve also seen the same lockup where we share an I2C LCD display driver between 2 micro's, and the user rather crudly has a switch between micro A and micro B.
The fix in both cases was as Piotr suggested, if bus is at fault, cycle the clock up to 9 times stopping when SDA goes high, then the bus is recovered.
This is usually a deadlock, caused by improper master control of the bus. Usually, the slave is waiting for you to clock something, and you are waiting for the slave to do something. If, for example, you forget to NACK the last read, you can get stuck in a state in which the slave thinks it's still talking.
If this is happening, clocking the bus will eventually cause the slave to release SDA, because it wants to see your ack after 8 bits. If you leave SDA alone, it'll think it's a nack, and stop trying to write data to you.
If the slave is holding SCL low, you are probably screwed.
If the slave devices have a reset, use that instead of power. The FET thing makes sense if there isn't a reset pin. Note that if the device doesn't take too much power, you can just run it off of the microcontroller pin. I believe PICs have a limit of 20mA, which may be fine. I've done this with LCD displays before with no problem.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.