1. 23
  1.  

  2. 13

    I2C sounds simple and powerful, but I have grown quite resentful of it. This stems from a decade of having to work with it - debugging is the worst.

    There are a myriad of issues with the bus, the worst being that it can get stuck - and there’s no way to get it out of that state. A comment below the article has already mentioned this. Of course you can wire resets to all the bus devices, but that increases pin count from 2 to 3, not counting GND, and is outside of what the I2C bus standard entails. Of course you can try to wiggle the bus a bit and see if this frees it from a stuck state. Maybe now you have an unwanted write to an EEPROM. Or maybe the method doesn’t work because a stuck slave is clock stretching indefinitely. The list can be made to go on for quite a while.

    My personal advice for those considering to use I2C: Don’t, unless you are forced to. If you still think you want to use, the following checklist will help you have a better experience.

    • Have only a single master. I have never seen a trustworthy multi-master system.
    • Have only “simple” slaves. I.e. EEPROMs with hardware implemented I2C interfaces without clock stretching are OK. Microcontrollers are not OK, the program can get stuck and you wind up with that slave stretching the clock indefinitely. Be aware that if you buy, say, “an IMU”, it may actually contain a microcontroller handling the I2C communication. This is the case for a number of more complex devices.
    • No hotplug.
    • Have all devices powered from the same supply.
    • Have few devices on the bus.
    • Have a short bus.
    • Nice to have: Be able to reset slaves from the master.
    1. 2

      Great comment, and your checklist is dead on.

      One thing I will say though: I’ve shipped ~10 CE products, all of them with I2C devices, and have only had problems with one peripheral: Apple’s MFi chip (used to be required for BT accessories).

      So while in practice I2C buses can get stuck, it is not a problem of epidemic proportion as some would have you believe.

      Still - it’s good practice to have a plan to recover in the event the issue crops up. Reset pins & power control are the way to go.

      Last but not least, always make sure the electrical characteristics of your bus are correct. If transition or hold times are violated, you’re going to have a bad time.

      1. 1

        One thing I will say though: I’ve shipped ~10 CE products, all of them with I2C devices, and have only had problems with one peripheral: Apple’s MFi chip (used to be required for BT accessories).

        Out of sheer interest: How well did these products match the checklist?

        How big a problem you have with I2C depends a lot on your design.

        If you have, say, an I2C bus with an imaging sensor, a thermometer and an EEPROM, you might be able do dodge the worst of troubles. If “the bus gets stuck” and you have appropriate measures in place to reset all devices, your device might carry on with only a small hiccup. To do this requires forethought in the hardware design and you have to invest into your software. On the hardware side, you need resets to the chips that support resets, your imaging sensor most certainly. The EEPROM (like 24xx devices) has no reset pin. If the bus interface is not responding, you have to power cycle it. This takes up board space and you have to get the power supply right. On the software side you need to detect that “the bus is stuck” and you need to act. Then your software needs to deal with hardware not always being reachable, maybe even being partially reachable.

        I think that it would be much more sensible to have a communication standard where, if communication with one component fails, only communication with that one component fails.

        One project I worked on had a central processor and several microcontrollers scattered throughout the system, all connected through I2C. One of the microcontrollers was the first to start and controlled power sequencing for startup, standby and shutdown. It also had an IMU connected, the data of which the main processor needs to read. When reading IMU data, bus traffic increases considerably, triggering a (as I believe, still unsolved) preexisting within a minute instead of within hours. The fault was always shortly after some microcontrollers were powered up and hotplugged to the bus. The bug leads to the power sequencing microcontroller not serving I2C anymore, infinitely clock stretching. The main processor canniot reset the power sequencing uC for different reasons: it does not have a connection to it, apart from the stuck I2C and the power sequencing uC has to be the last system part to be powered down.

        Now, clearly this hardware design is bonkers, for a variety of reasons. The power sequencing uC should have fewer responsibilities, i.e. only power sequencing. IMU readout should be ideally with another uC and clearly on a bus where it’s isolated from more critical functions. Also very clearly, the design is bonkers because it violates several points on the I2C checklist and insists on using I2C for vital system parts.

        Last but not least, always make sure the electrical characteristics of your bus are correct. If transition or hold times are violated, you’re going to have a bad time.

        This is true. However, in many cases you don’t have control over all the conditions that you need to control in order to guarantee reliable operation.

        The I2C standard is not really a standard, it’s more like a leisurely application note. This leads to many different interpretations and assumptions about how the bus is driven, assumptions that may not be true. As a result, connecting different, unknown devices together leads to a significant amount of new and exciting bugs.

        To sum this us, my advice remains the same: Don’t use I2C unless you have to. If you have to, fulfill the checklist as good as you are allowed to.