Hauksbee

Evidence

The Raspberry Pi 4 USB-C fault, re-derived

Finding 19 of the bug-hunt record, published here on its own: the hunt’s other findings examine a board that is not public. File paths and test names in the text point into the repository.

This is the public half of the bug hunt: the other findings examine a board that is not public, so they are not reproduced here. The exercise is to take a famous, published hardware fault, reconstruct it from public design data, and have hauksbee's generic USB-C classifier, which contains no RPi-specific logic, flag it from topology and spec thresholds alone. The one bug-aware human step is the transcription of the CC subcircuit from RPi's published PDF (no native CAD exists); everything downstream of the transcription is generic physics. The target is the Raspberry Pi 4 Model B (rev 1.0/1.1) USB-C power-in, the most famous USB-C design fault ever shipped (tens of millions of units, acknowledged publicly by RPi CEO Eben Upton, fixed in rev 1.2).

Claim. On RPi 4 rev 1.0/1.1 the USB-C receptacle's CC1 (pin A5) and CC2 (pin B5) are tied to a single shared net terminated by one 5.1 kOhm pulldown, R79, to GND. USB-C requires an independent 5.1 kOhm Rd on each CC pin. With a plain (non-e-marked) cable the board charges, because a passive cable wires only one CC line through, so the lone shared R79 looks like a normal single Rd. With an electronically marked cable, the cable presents Ra (800-1200 Ohm, per spec) on the VCONN CC line; because R79 shorts CC1 to CC2, the source ends up seeing an Ra-band voltage on both CC pins, which is the exact signature of an Audio Adapter Accessory, and a compliant source then withholds VBUS. The board appears dead.

Reconstruction (honest provenance). RPi does not release native CAD, only a reduced-schematic PDF. The CC subcircuit was transcribed by hand from that PDF's "USB-C POWER IN" block into two small KiCad schematics.

Those two files are maintainer-corpus-only and not redistributable, so this derivation is readable here but not re-runnable from this repository. They are a hand transcription rather than an upstream release, which means there is no upstream to pin and nothing we have the right to publish; corpus.toml's "Local-only boards" section lists them among the assets deliberately kept out for that reason. What is reproducible is the physics: the CC classifier, its spec constants and the 2x2 outcome matrix are all exercised by crates/hauksbee-engine/tests/usb_c_rpi4.rs, which needs no board on disk. Anyone wanting to reproduce the extraction end-to-end can transcribe the same block from the public PDF; the two schematics are:

Derivation (numbers from the solver, not hand arithmetic). A generic USB-C source + cable model lives in crates/hauksbee-engine/src/checks/usb_c.rs. It asserts Rp on each CC pin (the spec's current-source model, Default 80 uA per Table 4-20), attaches a cable (passive, or e-marked presenting Ra = 1.0 kOhm per Table 4-22), builds the source+cable+sink resistor network as a Circuit, solves the DC operating point with the production MNA solver, and classifies the two CC voltages against the source-side spec windows (Table 4-28, Default USB: below 0.20 V = Ra, 0.20 to 1.60 V = Rd, at/above 1.65 V = open) into the Table 4-10 port state.

Solved CC voltages (the 2x2 matrix, Default Rp, from the solver):

board cable CC1 (V) CC2 (V) states port state VBUS
as-designed (shared R79) passive 0.4080 open (1.65) Rd / Open SinkAttached applied
as-designed (shared R79) e-marked 0.1338 0.1338 Ra / Ra AudioAccessory withheld
repaired (indep Rd) passive 0.4080 open (1.65) Rd / Open SinkAttached applied
repaired (indep Rd) e-marked 0.4080 0.0669 Rd / Ra PoweredCableWithSink applied

The famous failure is the second row: both CC pins land at 0.1338 V, below the 0.20 V vRa threshold, so the source reads Ra on both, declares an Audio Adapter Accessory, and never applies VBUS. The repaired board (last two rows) classifies correctly and powers with both cable types. The single difference between fault and fix is shared_net, and it flips exactly the e-marked-cable outcome.

Independent cross-check (hand arithmetic, to better than 1%). These are divider solves, so they can be checked by hand:

The tests assert the solver outputs against these hand values to within 1 mV (tests/usb_c_rpi4.rs, plus solver-vs-hand cross-checks in the checks::usb_c::tests unit module).

Spec thresholds used, with sources (verified against two independent sources). Primary source is the USB Type-C Cable and Connector Specification Release 1.3 (July 2017), read directly from the spec PDF:

Second, independent confirmation of the resistor values and the fault mechanism: Tyler Ward's root-cause writeup (R79 shared, Ra 800-1200, ~836 Ohm parallel, Audio Adapter Accessory, VBUS withheld) and Benson Leung's "how to design a proper USB-C power sink"; the Hackaday in-depth piece carries Eben Upton's admission. The hackaday.com USB-C resistors explainer independently quotes Rd = 5.1 kOhm, Ra = 800-1200 Ohm, and the ~840 Ohm parallel pulldown that takes the CC line "out of the 5.1k expectation".

Spec sources:

Repair. Give each CC pin its own 5.1 kOhm Rd, as rev 1.2 did. The repaired schematic is in the corpus and classifies correctly with both cable types.

What this proves. hauksbee re-derives, cold, a famous fault that shipped on tens of millions of units, from a five-component reconstruction and the USB Type-C spec thresholds, with no knowledge of the bug baked into the classifier. The classifier is generic (any USB-C receptacle's CC termination, any of the three Rp levels, passive or e-marked cable); the RPi 4 is just the first board fed to it. The only step that is not "hauksbee ingests the vendor's CAD" is the hand transcription of the CC subcircuit from RPi's published PDF, because RPi releases no native CAD; that limitation is stated openly in the corpus README and here.

How to reproduce.

cd hauksbee
# The pure-physics 2x2 matrix + the end-to-end-from-schematic derivation.
cargo test -p hauksbee-engine --test usb_c_rpi4 -- --nocapture
# The classifier threshold + spec-constant unit tests.
cargo test -p hauksbee-engine --lib checks::usb_c

Independent verification recorded. Every solved voltage was recomputed by hand from the spec resistor/current values and matched the solver to the digit: 5.1k || 1.0k = 836.066 Ohm; single Rd = 80 uA x 5.1k = 0.40800 V; shared e-marked node = 2 x 80 uA x 836.066 = 0.13377 V; repaired e-marked Ra pin = 80 uA x 836.066 = 0.06689 V. All agreements are better than 0.01% (well inside the 1% bar), and the unit tests assert the same. The spec thresholds were taken from the USB Type-C spec PDF directly (Tables 4-20, 4-21, 4-22, 4-28) and cross-checked against two independent secondary sources (Tyler Ward and the Hackaday USB-C resistors explainer), which agree on Rd = 5.1 kOhm, Ra = 800-1200 Ohm, the ~836 Ohm parallel value, and the Audio Adapter Accessory verdict.