UNIT 07 · LESSON 2 OF 6

Push-Pull and Open-Drain Outputs

What is different about those pins?

INTERACTIVETwo outputs on one wire
Two outputs sharing one wire with the resulting line levelAwrites 1Bwrites 0shared lineA drives high and B drives low: current flows from 3.3 V through A’s high-side and B’slow-side transistor, about 3.3 V / (50 Ω + 50 Ω) = 33 mAThe line sits at an indeterminate level and the current is limited only by thetransistors, well above what a pin is characterised for. Never connect push-pulloutputs together.
Two outputs sharing one wire with the resulting line levelAwrites 1Bwrites 0shared lineA drives high and B drives low: current flows from3.3 V through A’s high-side and B’s low-sidetransistor, about 3.3 V / (50 Ω + 50 Ω) = 33 mAThe line sits at an indeterminate level and thecurrent is limited only by the transistors, wellabove what a pin is characterised for. Never connectpush-pull outputs together.

Try this

Output type
Device A writes
Device B writes
Pull-up (open-drain)
Choose open-drain outputs to use the pull-up resistor.
Contention: about 33 mA flows between the outputs; the level is indeterminate.

A push-pull output drives the line actively both ways; an open-drain output can only pull it low and leaves the high level to a pull-up resistor. Put two push-pull outputs on one wire and let them disagree, and they short the supply through their transistors. Two open-drain outputs cannot fight: the line is low if either pulls low (a wired-AND). Transistor on-resistance is an illustrative 50 Ω.

What you will be able to do
  • Explain the transistor structure of push-pull and open-drain outputs and which levels each drives actively.
  • Estimate the contention current when two push-pull outputs disagree, and explain why it must never happen.
  • Determine the level of a wired-AND open-drain line from the states of its devices.
  • Compute the rise time of an open-drain line from its pull-up and capacitance, and choose a pull-up.
  • Emulate an open-drain output on a pad without an open-drain mode.
Before you start
  • Pin modes and pad settings (lesson 1).
  • Pull-up resistors and RC charging (unit 1, lessons 3 and 4).
Steps in this lesson
  1. Two ways to drive a wire
  2. Why push-pull outputs must not share a wire
  3. Open-drain: wired-AND and level shifting
  4. The price: a slow rising edge
  5. Open-drain without an open-drain mode
  6. Worked example: sizing an I²C pull-up
  7. Common misconceptions

The puzzle

Two chips need to signal on the same wire: either one may want to say “attention”. If both pins are ordinary outputs, the first time one drives high while the other drives low the board gets warm and the level on the wire is nonsense. I²C puts a whole bus of devices on two wires and nothing ever fights. What is different about those pins?

STEP 1

Two ways to drive a wire

A push-pull output has two transistors: one connects the pin to VDD, the other to ground, and while it drives, exactly one is on (apart from a brief overlap during each transition). It drives both levels hard, so edges are fast and nothing else is needed on the wire.

An open-drain output (open-collector with a bipolar transistor) has only the transistor to ground. Writing 0 turns it on and pulls the wire low; writing 1 turns it off and lets go. Something else, a pull-up resistor, has to bring the wire high.

↑ This step uses the figure at the top of the page.

STEP 2

Why push-pull outputs must not share a wire

When two push-pull outputs disagree, one high-side and one low-side transistor are both on, in series across the supply. The only thing limiting the current is their on-resistance. With an illustrative 50 Ω each:

I≈VDDRon,p+Ron,n=3.3 V100 Ω=33 mAI \approx \frac{V_{DD}}{R_{on,p} + R_{on,n}} = \frac{3.3\ \text{V}}{100\ \Omega} = 33\ \text{mA}

limited only by the transistors, well above the few milliamps a pin is characterised for (unit 1, lesson 5), and the wire sits at an indeterminate level. This is also what happens when a pin is accidentally configured as an output while another device drives it, a common bring-up bug.

STEP 3

Open-drain: wired-AND and level shifting

With open-drain outputs nobody can fight. The wire is low if any device pulls it low and high only if all let go: a wired-AND. That is why I²C, interrupt lines shared by several chips and reset lines use open-drain drivers: any device can assert the signal, and a device can also see that someone else is holding it (I²C clock stretching and arbitration rely on this).

Because the pull-up sets the high level, an open-drain output can also drive a line pulled up to a different voltage, within the pin’s voltage rating: that is one simple way to signal between chips on different supplies.

STEP 4

The price: a slow rising edge

The falling edge is driven by a transistor and is fast. The rising edge is only the pull-up charging the wire’s capacitance (every pin, trace and cable on it), an RC curve:

v(t)=VDD (1−e−t/RC),v(t) = V_{DD}\,\bigl(1 - e^{-t/RC}\bigr), t0.7=RC ln⁡10.3≈1.2 RCt_{0.7} = RC\,\ln\frac{1}{0.3} \approx 1.2\,RC
INTERACTIVEOpen-drain edges are slow on the way up
The RC rising edge of an open-drain line and the time it takes to reach the high threshold3.300.7 × VDDτ = RC = 470 ns; reaching 0.7 × VDD takes 566 ns after releasea clock whose high and low halves are each at least that long runs below about 884kHz; a stronger (smaller) pull-up is faster but sinks more current when low
The RC rising edge of an open-drain line and the time it takes to reach the high threshold3.300.7 × VDDτ = RC = 470 ns; reaching 0.7 × VDD takes 566 nsafter releasea clock whose high and low halves are each at leastthat long runs below about 884 kHz; a stronger(smaller) pull-up is faster but sinks more currentwhen low
R = 4.7 kΩ, C = 100 pF: τ = 470 ns, 0.7 VDD after 566 ns.

The falling edge of an open-drain line is driven by a transistor; the rising edge is only the pull-up resistor charging the wire’s capacitance, an RC curve. The time to reach a receiver’s high threshold, taken here as 0.7 × VDD, is RC · ln(1/0.3) ≈ 1.2RC. Capacitance counts every pin, trace and cable on the line.

The I²C specification defines rise time between 30 % and 70 % of VDD, which is 0.8473·RC, and limits it to 1000 ns in Standard-mode and 300 ns in Fast-mode. A smaller pull-up is faster but sinks more current whenever the line is low, so the resistor is a compromise between speed and the current the drivers can sink.

STEP 5

Open-drain without an open-drain mode

The STM32F4 has an open-drain output type in OTYPER. The RP2040’s pads do not (its pad bit OD is output disable). Open-drain is emulated by keeping the output value at 0 and switching the output enable: enabled means “pull low”, disabled means “let go”. The pin must be under software control first (gpio_init()), and the pad’s reset pull-down stays on unless disabled, slightly loading the external pull-up.

gpio_put(pin, 0);                 /* the value is always 0 */
gpio_set_dir(pin, GPIO_OUT);      /* assert: drive low */
gpio_set_dir(pin, GPIO_IN);       /* release: the pull-up takes the line high */

Never emulate open-drain by writing 1 with the output enabled: that is push-pull high, and it will fight any device that pulls the line low.

STEP 6

Worked example: sizing an I²C pull-up

A Fast-mode I²C bus has 150 pF of capacitance and runs at 3.3 V.

Upper limit from rise time: Rmax=300 ns0.8473×150 pF≈2.36 kΩR_{max} = \dfrac{300\ \text{ns}}{0.8473 \times 150\ \text{pF}} \approx 2.36\ \text{k}\Omega.

Lower limit from drive strength (VOL ≤ 0.4 V at 3 mA): Rmin=3.3−0.43 mA≈967 ΩR_{min} = \dfrac{3.3 - 0.4}{3\ \text{mA}} \approx 967\ \Omega.

Any value between about 1 kΩ and 2.2 kΩ works; 2.2 kΩ gives a 30–70 % rise time of 0.8473 × 2.2 kΩ × 150 pF ≈ 280 ns and sinks 1.5 mA when low. A 10 kΩ pull-up, fine for a slow interrupt line, would give about 1.3 µs here and break Fast-mode timing.

MYTHS AND FACTS

Common misconceptions

Any output can drive a shared line

Only open-drain (or tri-state outputs that are carefully enabled one at a time) can; push-pull outputs fight.

Open-drain outputs cannot drive high

They cannot drive it; the pull-up does, slowly.

Smaller pull-ups are always better

They are faster but draw more current when low, and may exceed what the weakest driver on the bus can sink.

Writing 1 to an emulated open-drain pin releases it

Only if the output is disabled; with the output enabled a 1 drives high.

Check yourself

Answer in your head, then open the card.

Three open-drain devices share an interrupt line with a pull-up. Device B pulls low; A and C have let go. What level is the line, and can A tell someone is asserting it?

Low. Yes: A reads its own pin (the input still works with the output off) and sees 0 although it is not pulling.

A 10 kΩ pull-up drives a line with 50 pF. How long does the line take to reach 0.7 × VDD?

1.2 × RC = 1.2 × 10 kΩ × 50 pF = 0.6 µs.

During bring-up a pin that should be an input is left as a push-pull output driving 0, while a sensor drives the line high. What happens?

Contention: the sensor's high-side and the MCU's low-side transistor conduct in series; tens of milliamps may flow, the level is indeterminate, and one or both drivers can be damaged.

Why does the I²C specification put a minimum on the pull-up resistance?

When a device pulls low it must sink the pull-up current and still meet VOL; R must be at least (VDD − VOL) / IOL, about 967 Ω at 3.3 V with 0.4 V at 3 mA.

Sources (3)
  1. STMicroelectronics, stm32f4xx-hal-driver, Inc/stm32f4xx_hal_gpio.h and cmsis-device-f4 stm32f407xx.h — GPIO_MODE_OUTPUT_PP “Output Push Pull Mode”, GPIO_MODE_OUTPUT_OD “Output Open Drain Mode”, GPIO_MODE_AF_OD; OTYPER (offset 0x04) selects the output type per pin; BSRR (0x18) sets and resets pins atomically
  2. Raspberry Pi Ltd, pico-sdk 1.5.1, hardware_gpio/gpio.h and hardware_regs pads_bank0.h, sio.h — the pad has no open-drain type (its OD bit is “Output disable”); SIO GPIO_OE_SET/CLR and GPIO_OUT_SET/CLR (sio.h offsets 0x24, 0x28, 0x14, 0x18) set output enable and value per pin atomically; gpio_set_dir, gpio_put
  3. NXP, UM10204 “I²C-bus specification and user manual”, Rev. 7.0 (1 October 2021), §7.1 “Pull-up resistor sizing”, p. 50; Tables 9 and 10 — Rp(min) = (VDD − VOL(max)) / IOL with VOL ≤ 0.4 V at 3 mA; Rp(max) = t_r / (0.8473 · Cb); rise time ≤ 1000 ns (Standard-mode) and ≤ 300 ns (Fast-mode); bus capacitance ≤ 400 pF (as cited in unit 1, lesson 3)