12.8 Open Collector / Open Drain: Wired Logic on Shared Lines

Explain how open-collector/open-drain outputs work, why they require an external pull-up, and how they implement wired-AND behavior on shared buses like I2C.

An open-collector output (bipolar) or open-drain output (MOSFET) is a gate output built with only the pull-down half of a normal output stage — it can actively sink current to pull the line LOW, but it has no active pull-up transistor at all. Left disconnected from anything else, such an output simply cannot produce a HIGH level; it needs an external pull-up resistor (or occasionally an internal weak one) to establish a valid HIGH whenever the output isn't actively pulling LOW. This asymmetric structure isn't a limitation so much as a deliberate design feature: it is exactly what makes wired-AND buses like I2C possible.

Core concept: pull-down only, by design

In an open-collector TTL gate, the output stage's pull-up transistor (and its associated internal resistor/diode network) is simply left out, leaving the collector of the final output transistor unconnected ('open') — hence the name. An open-drain CMOS output is the equivalent structure with the PMOS pull-up omitted, leaving only the NMOS pull-down connected to the output pad. In both cases, the active transistor can pull the line firmly to a LOW voltage when it is on, but when it is off, the output pin is left floating (electrically similar to a tri-state Z, though the *mechanism* — a permanently missing pull-up rather than a disabled complementary pair — and the *intended use* are different).

Because the pull-up path doesn't exist internally, the designer must supply one externally — a resistor from the output line to VCC (or, on some parts, a switchable internal pull-up can be enabled). Without that resistor, the line has no way to reach a valid HIGH level at all: it will simply float whenever every open-collector/open-drain device on it is inactive, exactly the spec's tricky-problem point that an open-drain output generally needs an external/internal pull-up to obtain a logic-high level.

Wired-AND: why multiple open-drain outputs can share one line safely

The critical advantage over tri-state sharing (previous lesson) is that open-collector/open-drain outputs can be tied together on the same physical line *permanently*, with no enable-mutual-exclusivity logic required, because none of them can ever actively drive the line HIGH — only LOW, or not-at-all. With N such outputs tied to a single shared pull-up resistor, the line reads HIGH only when every device on it is inactive (letting the pull-up win), and reads LOW the instant *any* device pulls it LOW — logically, the shared line is the AND of all the individual (active-low) outputs' inactive states, which is why this configuration is called 'wired-AND' (or, viewed from the active-low perspective, a shared open-drain interrupt or acknowledgment line is frequently described as 'wired-OR' for the active condition). Unlike tri-state contention, there is no electrical hazard if two devices pull the line LOW simultaneously — both are simply sinking current into the same already-LOW node, which is exactly the intended, safe behavior.

This wired-AND behavior is the electrical foundation of the I2C bus: both SDA (data) and SCL (clock) lines are open-drain on every device attached to the bus, with a single shared pull-up resistor per line. Any device — master or any slave — can pull either line LOW at will without needing to coordinate exclusive bus ownership the way a tri-state bus would require, which is what allows I2C's clock-stretching (a slave can hold SCL LOW to pause the master) and multi-master arbitration (any master pulling SDA LOW during arbitration simply 'wins' that bit) to work safely with simple, contention-free hardware.

Open-drain pull-up sizing (conceptual)

Real I2C pull-up selection uses the bus capacitance and the target speed grade (Standard/Fast/Fast-mode+) to bound the resistor between a minimum (current-limited) and maximum (rise-time-limited) value.

Line HIGH  ⇐  every device inactive  ⇒  pull-up resistor wins, line rises to VCC
Line LOW   ⇐  any device active     ⇒  that device sinks current, overpowering the pull-up

Pull-up resistor value is a trade-off:
  too large (weak pull-up)  → slow rise time, may not reach valid HIGH before next
                               device tries to read it, especially with more bus
                               capacitance (more devices/longer wires)
  too small (strong pull-up)→ higher current draw whenever a device pulls LOW,
                               and can push output sink current past its rated IOL

Code Examples

SDA reads HIGH only in the single case where every device releases the line; any one (or more) device pulling LOW forces the shared line LOW, with zero electrical hazard even when multiple devices pull LOW at the same instant, unlike tri-state bus contention. This is precisely why I2C, a true multi-master, multi-slave shared bus, is built on open-drain outputs rather than tri-state push-pull outputs.

Open-drain lines are safe to tie together permanently — only tri-state push-pull outputs require enable-based mutual exclusivity.

3 devices (A, B, C) share SDA, pulled up to VCC via one resistor:

  A inactive, B inactive, C inactive  → SDA = HIGH  (pull-up wins)
  A pulls LOW, B inactive, C inactive → SDA = LOW
  A pulls LOW, B pulls LOW, C inactive→ SDA = LOW   (no contention — both sink safely)
  A inactive, B inactive, C pulls LOW → SDA = LOW

Important Rules

An open-collector/open-drain output can only actively pull the line LOW — it can never actively drive it HIGH.

An external (or switchable internal) pull-up resistor is required to establish a valid HIGH level whenever no device is pulling LOW.

Multiple open-drain outputs can be tied together safely and permanently, implementing wired-AND logic — no enable arbitration is needed, unlike tri-state buses.

Pull-up resistor value trades off rise time (too weak) against sink-current/power draw (too strong) and must respect the driving transistor's IOL rating.

I2C, SMBus, and shared interrupt lines

Beyond I2C/SMBus data lines, open-drain outputs are the standard choice for shared interrupt lines in multi-chip systems: several peripheral chips can each be wired to the same interrupt pin on a microcontroller, all open-drain with one shared pull-up, so that any peripheral asserting an interrupt (pulling the line LOW) is safely detected without needing to know or coordinate with what any other peripheral on the same line is doing.

Wiring an open-drain output directly to a receiving input with no pull-up resistor, expecting it to read a valid HIGH when the output is inactive.

Always add an appropriately-sized pull-up resistor (or enable an available internal one) on any open-drain/open-collector line.

Without a pull-up, the line has no path to VCC at all when the driving transistor is off — the input will float, read an indeterminate level, and behave unreliably (or, on a CMOS receiver, risk the shoot-through issue from floating inputs covered in the CMOS lesson).

Tricky problem (from the spec): why does an open-drain output generally need an external or internal pull-up resistor to produce a valid logic-HIGH level? A. Because open-drain outputs are simply lower quality than push-pull outputs B. Because the output stage physically omits the pull-up transistor — it can only actively sink current to LOW, so nothing internally can pull the line up to VCC when the active transistor is off C. Because pull-up resistors are required by international standards for all digital outputs D. Because open-drain outputs can drive HIGH but not LOW without a resistor

B. Because the output stage physically omits the pull-up transistor — it can only actively sink current to LOW, so nothing internally can pull the line up to VCC when the active transistor is off — The defining structural feature of open-collector/open-drain is the *absence* of a pull-up transistor in the output stage. With no internal path to VCC, an external (or an enabled internal) pull-up resistor is the only way the line can ever reach a valid HIGH level once the active pull-down transistor releases it.

Interview question: why is I2C built on open-drain outputs rather than ordinary tri-state push-pull outputs, given that both could in principle let multiple devices share one line? A. Open-drain is simply cheaper to manufacture, which was the only consideration B. Open-drain outputs can be permanently tied together with zero risk of contention (any number can pull LOW simultaneously with no hazard), enabling simple multi-master arbitration and clock-stretching without needing enable-based mutual-exclusivity logic that a tri-state bus would require C. Tri-state outputs cannot physically be connected to more than one device D. I2C does not actually use open-drain outputs; that is a common misconception

B. Open-drain outputs can be permanently tied together with zero risk of contention (any number can pull LOW simultaneously with no hazard), enabling simple multi-master arbitration and clock-stretching without needing enable-based mutual-exclusivity logic that a tri-state bus would require — A tri-state bus requires careful, mutually-exclusive enable logic to avoid the genuine electrical hazard of contention when two drivers disagree. Open-drain outputs sidestep that entirely — since no device can ever actively drive HIGH, any number of devices can safely pull LOW at once with no contention risk — which is exactly what allows I2C's simple multi-master arbitration and slave clock-stretching to work reliably with minimal coordination hardware.

Explain, in terms of wired-AND behavior, why an active-LOW shared interrupt line built from open-drain outputs correctly reports 'at least one device has an interrupt pending' without any coordination logic between the devices.

The shared line reads HIGH only when every device releases it (no interrupt pending anywhere), and reads LOW the instant any single device (or several) pulls it LOW to assert an interrupt — which is exactly the desired 'OR of interrupt-pending conditions, expressed as an active-LOW AND of inactive states' behavior. Because no device can ever force the line HIGH, there is no possibility of one device's 'no interrupt' state overriding another device's genuine interrupt assertion — the pull-up only wins when literally nothing is holding the line LOW, so the combined line inherently and correctly reflects 'is anyone asserting?' with zero coordination required between the devices.

Think about what the shared line's voltage is in every possible combination of device states, using the wired-AND rule from this lesson.