5
\$\begingroup\$

My understanding is that I2C lines use pull-up resistors to passively pull up the bus to logic high because the drivers used on the bus are active drivers, namely open collector/open-drain. Since open collector/open-drain drivers can drive the line low but not high, the issue of bus contention is mitigated.

My question is however, why does the I2C protocol use these drivers as opposed to tri-state drivers? If you have multiple tri-state output drivers connected to the same bus, as long as the enable signals for the tri-states are mutually exclusive, shouldn't we be able to take care of bus contention and also achieve faster rise times in comparison to open-collector/open-drain topologies?

\$\endgroup\$
  • 4
    \$\begingroup\$ Clock-Stretching for one reason. And how your you ensure that the tri-state enables are mutually exclusive among multiple different devices? \$\endgroup\$ – brhans Feb 15 '17 at 17:12
  • \$\begingroup\$ Alsonote that the problem with rise times can be somewhat resolved using current sources instead of plain pull-up resistors. \$\endgroup\$ – anrieff Feb 15 '17 at 17:18
11
\$\begingroup\$

...as long as the enable signals for the tri-states are mutually exclusive...

The trick is how to do this without adding another wire, or multiple wires to tell each peripheral when it is allowed to drive the bus.

The main advantage of I2C is that it only uses two wires, and two pins on each chip connected to the bus.

If you're willing to trade pins for speed, consider using SPI, which can generally achieve higher speed than I2C, but needs 3 or 4 pins per device.

\$\endgroup\$
  • 3
    \$\begingroup\$ +also multi-master negotiation is quite transparent on wired-OR busses (to @athedcha: which pulled up open collector is one of). \$\endgroup\$ – Asmyldof Feb 15 '17 at 17:59
  • \$\begingroup\$ @Asmyldof, true, but what % of I2C applications do you think actually use multi-master? \$\endgroup\$ – The Photon Feb 15 '17 at 18:23
  • 1
    \$\begingroup\$ Way too few. Multi-master is cool. But it is a decent part of the spec, so as a reason of "why not different" it is quite relevant. \$\endgroup\$ – Asmyldof Feb 15 '17 at 18:27
  • \$\begingroup\$ @Asmyldof: Multi-master has some cool features, but has no clean way of handling certain scenarios. For example, if two masters simultaneously issue an "increment counter" request to a slave, each may think its request succeeded but the counter will only be advanced by one rather than two. \$\endgroup\$ – supercat Feb 15 '17 at 20:21
  • \$\begingroup\$ @supercat in which this "increment counter" is some form of a command someone implemented ontop it. Commands and transactions can quite easily be designed such that these occurrences do not harm the command protocol layer of either master. \$\endgroup\$ – Asmyldof Feb 15 '17 at 21:40
4
\$\begingroup\$

There are two specific features that require open-drain lines. The first is clock-stretching, where a slave can hold the clock (SCL) low to delay the transaction while it processes data. The second is multi-master arbitration, where two or more masters try to transmit at the same time. The arbitration is done by having a master stop transmitting when it sees the data line held low by another master.

The arbitration is the big one, I think. You could probably replace clock-stretching with something protocol-based, but if you want multiple masters on the same bus, you need to avoid contention somehow. Unless you can add another wire, you're stuck with open-drain. (See also: the CAN physical layer, which uses a similar arbitration scheme.)

\$\endgroup\$
2
\$\begingroup\$

as long as the enable signals for the tri-states are mutually exclusive

There is no way to make sure of this in I2C. You would need one enable signal per device - now you have invented a cousin to SPI.

\$\endgroup\$
  • \$\begingroup\$ Not invented, implemented. It already exists and is widely used differently by everyone implementing it. \$\endgroup\$ – Asmyldof Feb 15 '17 at 17:57
0
\$\begingroup\$

Protocols that involve multiple devices communicating on a common bus using three-state drivers generally require either the addition of an external control wire to prevent bus contention or current-limiting drivers to prevent damage if bus contention occurs. While the level of fault current one can tolerate in case of bus contention may be higher than level of current one could tolerate any time a line is low, bidirectional current-limited drivers are more complicated than open-collector drivers combined with passive pull-ups.

If one is willing to accept the added expense of current-limited drivers, that will allow the design of protocols which are faster and more robust than I2C. On the other hand, adding active-high drivers to an I2C master may allow similar advantages to be obtained even with I2C. Achieving such advantages safely may require adding series resistors on the SDA line between the master and slaves, but if one uses a separate resistor between the master and each slave, the ability of the master to drive high the SDA line as seen by any slave that isn't actively driving it low may allow the master to recover from scenarios which might otherwise cause the bus to lock up permanently (no single device can hold SCL low continuously for more than 9 cycles of SCL, so a master would be able to generate a stop condition for any device within 9 cycles, but if two devices could each hold down the SCL line seen by each other, they could get into a state where they took turns pulling down SCL such that it would never ever get released, leaving the master unable to generate a stop condition.

\$\endgroup\$
0
\$\begingroup\$

The REAL answer to this question, as with most similar questions, is because this is the way it was designed. Clock-stretching, bus arbitration are certainly valid, but the solution is adequate for its design purpose, which is short distance (often on-board) low speed communication.

There are many newer, faster protocols, which trade off some complexity for speed and distance. If you need this use one of these protocols.

While I²C is a relatively modern (~1982) protocol, before Tri-State or TTL (~1963) the early ICs used RTL and open-collector was the standard bus design for early computers. (And I might add a real challenge to designers.)

\$\endgroup\$
-2
\$\begingroup\$

Open drain is a form of tried state driver. It is needed here to avoid logic conflict - thee slave holding onto the bus for example.

\$\endgroup\$
  • 3
    \$\begingroup\$ Open-drain has two states. \$\endgroup\$ – CL. Feb 15 '17 at 18:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.