The interviewer wanted to know why pull-up resistors are used on SDA and SCL when the opposite logic can also be implemented. Is there an explanation for why pull-up resistor usage is the chosen design?
-
\$\begingroup\$ See previous answer: electronics.stackexchange.com/questions/113009/… \$\endgroup\$– ChuMay 8, 2015 at 10:17
-
\$\begingroup\$ Just as a comment Ultra Fast-mode I2C-bus protocol does operate as push-pull configuration, see nxp.com/documents/user_manual/UM10204.pdf, section 3.2 Ultra Fast-mode I2C-bus protocol \$\endgroup\$– KvegaoroMay 8, 2015 at 15:42
-
\$\begingroup\$ I wonder why NXP didn't specify an ultra-fast I2C protocol which used bidirectional SDA and unidirectional SCK, had the master drive SDA hard when it wanted to output a high, and had the master wait long enough for the line to be pulled high in cases where it would care what a slave had to say? \$\endgroup\$– supercatMay 8, 2015 at 16:37
-
\$\begingroup\$ Did the interviewer give their version of an answer? \$\endgroup\$– copper.hatMay 9, 2015 at 19:44
9 Answers
To expand on Jon's answer a little:
Yes, it is all to do with which MOSFETs you want to use.
N-channel MOSFETs are much better for switching logic than P-channel because:
- They generally have a much lower on resistance (\$R_{DSON}\$)
- They switch on and off faster
So for an open-drain configuration (which is what I2C is) it's much cheaper and easier to create it using an "idle high" arrangement with N-channel MOSFETs rather than "idle low" with P-channel MOSFETs.
A third option would be "idle low" using N-channel MOSFETs, but for that you require a high voltage gate driver to raise the gate voltage far enough above the source voltage for the MOSFET to switch on. Not practical for small communications buses, but this arrangement is actually used quite commonly in H-bridges for motor driving where you want to have the same (or similar) response between the high side and low side of the H-bridge. Using P-channel and N-channel pairs in an H-bridge typically means you have to incorporate a dead zone between switching the P-channel off and switching the N-channel on since it takes so much longer, and that reduces your power efficiency.
But for small communications buses like I2C where you need high speed, low cost, and simplicity of use, the "idle high" with N-channel MOSFETs and pull-up resistors is by far the most cost effective.
-
\$\begingroup\$ I disagree about "high speed" being a consideration in I2C (at least in its initial design). Resistive pull-ups are hardly the way to achieve high speed if that is the goal. \$\endgroup\$ May 8, 2015 at 16:08
-
1\$\begingroup\$ Don't confuse higher speed switching with higher bandwidth. High speed switching gives you much sharper edges which means more reliable communication. \$\endgroup\$– MajenkoMay 8, 2015 at 16:44
-
1\$\begingroup\$ Resistive pull-ups are also not the way to achieve higher switching speed. \$\endgroup\$ May 8, 2015 at 16:58
-
\$\begingroup\$ hich is why selecting the right resistor values for I2C is important' and why Arduino are evil for using the internal pullups by default. \$\endgroup\$– MajenkoMay 8, 2015 at 16:59
-
\$\begingroup\$ Yes you can choose your resistors to get better rise-times. But the whole system is still slower and/or using more power than it would be with totem-pole drivers (which would of course add other costs). \$\endgroup\$ May 8, 2015 at 17:13
Another advantage of passive pull up / active pull down, is that it can work with a range of power voltages. Note that the digital high and low levels are explicitly specified with IIC. Those levels are low enough to work with 3.3 V pullups. Devices can therefore be built that work with both 5 V and 3.3 V power. In fact, the IIC bus lines can be pulled up to 3.3 V, and this will work with a mix of devices on the bus that are separately powered at different voltages.
-
\$\begingroup\$ I am almost 100% this is the answer they were looking for, I have a friend who got asked that at an interview for a big CPU manufactoring company (guess which one) and that was the answer they were looking for. \$\endgroup\$ May 9, 2015 at 18:47
While NMOS does have an advantage over PMOS in terms of speed/area, this difference is really minute when you are talking about a driver on one or two pins. And after all, most output drivers are actually totem-pole types which require both NMOS and PMOS, so whether they had chosen a pull-down or a pull-up configuration, they would have ended up with an output driver smaller than a totem-pole driver.
But there is one benefit of NMOS open drain outputs over PMOS open drain that doesn't apply to I2C directly: when VCC is positive, NMOS open drain allows chips with different VCC levels to be connected to each other. This is (part of) why numerous NMOS open-drain discrete logic ICs are available.
On the other hand, I'm not aware of ANY available PMOS open-drain chips on the market. In fact I don't believe I've ever encountered a PMOS open-drain output on any chip. (I have used ECL many times, which has a NPN open-emitter output with similar behavior to PMOS open drain)
The availability of NMOS open drain discrete logic chips makes NMOS open drain much more familiar to electronic designers than PMOS open drain.
Both familiarity and the availability of the discrete chips (for prototyping, for example), likely influenced the designers of I2C to choose the NMOS open-drain configuration.
I guess the answer goes back to why we use a negative ground convention in the first place (and this was most certainly not ubiquitous before the semiconductor era). The reason for this is that N-Channel devices have better performance than P-Channel devices due to the physics of the types of majority carriers used in them.
In the early days of integrated circuits, this was quite a serious limitation and so there was a preference for using N-Channel (or NPN) transistors to achieve the highest performance possible. From this we got a negative ground system and open collector outputs that necessitated the use of pull-up resistors rather than pull-downs.
Of course the I2C bus is hardly high speed so there is no reason it couldn't be implemented using pull-down resistors, but also no advantage. So we stick with convention and it uses pull-ups.
Here is some (historically grounded) speculation...
When you have pullup (rather than push-pull) you obviously can have multiple devices in contention for the bus without excessive currents flowing (a Good Thing - but you could achieve the same with a pulldown).
In the "old days" of bipolar transistors, the simplest TTL logic used open collectors with NPN transistors - everything is referenced to ground, which makes the trigger levels simple to define regardless of the bus voltage. Also, NPN was faster than PNP.
If I have multiple devices working with their own supply voltage, and that supply voltage is not constant, then having a pull-up rather than a pull down becomes imperative. If multiple devices tried to pull the bus to their respective supply rails, current flow would be unrestricted and something might fry. At least they all agree on the value of ground, so this issue does not arise.
With CMOS, the story changes - now the trigger level is mid rail. But EEs can be a traditional bunch. Certainly, coming from the early transistor days I never even questioned the choice of pull-ups, for the above reasons.
As I said, this is just speculation.
This may be a historical thing.
Old transistors and integrated circuits actually consumed less power when they were at 5 V than at 0 V. Since there was a significant difference between the two levels, designers chose to make the 'idle' state the 5 V one. Then, as time went on, the transistors and ICs improved, making both states consume roughly the same amount of power, but there was no real reason to change the standards.
Now, you see lots of things like this - where idle is 5 V - just because the standards never changed.
-
\$\begingroup\$ It's still true that most IC's can sink more power than they can source, so it's still applicable. \$\endgroup\$– Joel BMay 10, 2015 at 1:50
It has been many years since I read the I2C spec, but I remember when it was first used people often called it the 2-wire-open-collector bus. It made the connections and the collision detection super easy even for bit banging. Even 20 years ago it was not considered a high performance bus, just cheap and easy.
I would say that it's because I2C is defined as a bus where all units connected should be open-drain or open-collector. This means that it can only drive the bus low, not high. (When the output drive transistor is turned off, the pin is in a high-impedance state.)
This scheme provides some nice benefits, for example that you can connect devices with different signaling voltages and that the bus is self-healing from communication errors.
Obviously, the standard could have been defined the other way around, as an idle-low/active-high configuration, and the other answers here touch on that element pretty well.
Source: LabWorX 1, Mastering the I2C Bus, by Vincent Himpe. A really good book about I2C, it's historical background, how to implement it in hardware and how to use it in software and debug implementations.
The real answer that nobody has adequately touched on yet is that it allows you to connect devices which are powered by different voltages (as long as the I/O pins are tolerant). For example a 3.3V device can communicate with a device that is powered off 1.8V as long as the 1.8V device's IO is tolerant of voltages up to 3.3. Of course every device can drive 0V, but not every device might be able to drive up to the voltage at your pull-up resistors.
Additionally, most IC's can sink more current than they can source. This is because of heat dissipation. So sinking current (driving ground) from pull-ups is easier for the part than sourcing current (driving a high voltage) into the pull-downs.