i2c-pull-up-split-rail
An I2C net is pulled up to two different rails.
Remedy ¶
Pull the bus to one rail. Where the bus genuinely crosses supply domains, that is a level translator’s job rather than two pull-ups, and the translator’s own pull-ups belong one per side of it.
What it means ¶
An I2C net reaches TWO different rails through its pull-up resistors. One part pulls the bus to one supply and another pulls it to a second.
Why engineers want it ¶
Two pull-ups to two rails tie those rails together through the bus. Whenever one supply is up and the other is not, current flows from the live rail through its pull-up, along the bus, and back through the other pull-up into a rail that is meant to be off. The bus then partially feeds that rail. That is a sequencing fault, and it can hold a supply above its off threshold, back-feed a regulator, or bring a device up in a state that its reset never sees.
It also leaves the bus idling at whichever rail wins, which may exceed the input rating of a device sitting on the lower supply.
On the bench every supply comes up at once and nothing is observed; the fault appears as a board that fails on one particular power-up order, or after a brown-out.
Impact ¶
A supply is fed through a signal bus during sequencing, and the bus idles at a level one side may not tolerate. Neither shows up in a functional test that powers everything simultaneously.
Fires versus fine ¶
fires fine
+3V3 +1V8 +1V8
| | |
R1 R2 R1
| | |
+----+----+ |
| |
SDA SDA
(a bus that crosses domains
gets a level translator, and
one pull-up per side of it)
Scope note ¶
- Only nets matching the I2C naming convention at a token boundary (SDA / SCL).
- When a net’s pull-ups all go to ONE rail,
i2c-redundant-pull-upreports it, not this rule. The two conditions are disjoint, so a bus is reported once. - Rail identity is the rail NET, so two rails that happen to carry the same voltage are still two rails. That is deliberate, because the sequencing question is about which supply and not which voltage.
- The naming lexicon decides what counts as a rail. If the built-in vocabulary does not recognise
a project’s supplies, the project reports nothing here. Declare them in the
conventions:section ofproject.yaml. Therail-not-classifiedrule is a tripwire, and it reports when this is happening. - Severity is
warning, because a bus deliberately pulled to one domain with a translator elsewhere on the net can look like this to a netlist.
Query structure ¶
Enumerate I2C nets; walk out through resistors up to three crossings, collecting every distinct resistor whose far side is a rail, with the rail each reaches; fire when the set of rails has more than one member.
For software readers ¶
Two connection pools onto one socket, each configured against a different endpoint. Nothing is wrong with either pool’s own configuration, and the bug only appears when one endpoint is down and traffic takes the path through the other one. Reachability tells you the socket is connected; only counting the pools and comparing their endpoints tells you it is connected to two things.