Automotive Ethernet from the register up.
An MDIO toolkit for a simulated 100BASE-T1 PHY with cable-fault injection and register-only link diagnosis, plus a pcap analyser for DoIP and SOME/IP.
Scope: Simulated PHY and generated traffic only; no real PHY part; the SQI and cable-fault register is illustrative. Personal portfolio project, not affiliated with any employer.
When an automotive Ethernet link is down, the first answers come from PHY registers: is it powered, is the role right, is the cable open or shorted, how clean is the signal. This tool reads only what host software could read over MDIO and turns it into a diagnosis.
Small Python toolkit I wrote to learn automotive Ethernet from the register and frame level, coming from a CAN/UDS background. Two parts:
- MDIO/SMI register toolkit for a simulated, generic IEEE 802.3bw 100BASE-T1 PHY: Clause 22 frame encode/decode, Clause 45 access through registers 13/14, a YAML register map, a link state machine with MASTER/SLAVE configuration and cable fault injection, and a link diagnosis that uses only MDIO register reads.
- Frame analyser for pcap/pcapng that decodes DoIP (ISO 13400-2: vehicle identification, routing activation, diagnostic messages carrying UDS) and SOME/IP headers.
pip install -e .[test]
pytest -q # 33 tests
python -m t1phy.samples # regenerate samples/*.pcap(ng)
t1phy diag [--role master|slave] [--partner master|slave|none] [--fault none|open|short] [--noise 0..1]
t1phy read REG | write REG VALUE | read45 DEVAD REG (same simulation options)
t1phy decode REG VALUE decode a value against the register map
t1phy frame WORD decode a 32-bit MDIO frame and print the wire bits
t1phy pcap FILE DoIP / SOME/IP summary
Each command builds a fresh simulated PHY at address 0, applies the options and runs the
state machine for --ticks steps (default 10).
$ t1phy diag --fault open
PHY ID 0000:0010
Type 100BASE-T1
Role MASTER
Link DOWN
SQI 0/7 (illustrative register)
Verdict FAIL
- cable fault OPEN: check connector and harness continuity
State history: LINK_DOWN
$ t1phy read45 1 0x0835
1.2101 (0x0835) = 0xC000 BASE_T1_PMA_PMD_CONTROL
MASTER_SLAVE_MANUAL 1
MASTER_SLAVE_VALUE 1
TYPE_SELECT 0
$ t1phy pcap samples/doip_uds.pcap
#3 TCP 50001->13400 DoIP Routing activation request version=2 source_address=0x0E80 activation_type=0
#4 TCP 13400->50001 DoIP Routing activation response ... response_code=routing successfully activated
#5 TCP 50001->13400 DoIP Diagnostic message ... uds=ReadDataByIdentifier request did=0xF190
#8 TCP 13400->50001 DoIP Diagnostic message ... uds=NegativeResponse req_sid=SecurityAccess nrc=securityAccessDenied
Totals: DoIP 9
UDS negative responses: 1; SOME/IP errors or malformed PDUs: 0
| File | Content |
|---|---|
t1phy/mdio.py |
Clause 22 frame, MDIO bus, Clause 45 indirect access (reg 13/14) |
t1phy/regmap.yaml, regmap.py |
Register map and bit field helpers |
t1phy/phy.py |
Simulated PHY and link state machine |
t1phy/diag.py |
Link diagnosis from register reads |
t1phy/frames.py |
DoIP / SOME/IP / UDS decoding of pcap and pcapng |
t1phy/samples.py |
Generator for the synthetic sample captures |
- Simulation only. The PHY is a simplified model. It has not been run against any real PHY, switch or MDIO master, NXP or otherwise. Training time, SQI thresholds and the PHY ID are invented. Link status is a live bit, not latching-low as in IEEE 802.3.
- Register map. Clause 22 registers 0 to 3, 13 and 14 follow IEEE 802.3 Clause 22. The MMD 1 BASE-T1 registers (1.2100 to 1.2102) follow my reading of IEEE 802.3 Clause 45 and should be checked against the standard. PCS (MMD 3) registers are not modelled. Register 0x1F (SQI, cable fault) is illustrative: its location and layout are made up; only the 0 to 7 SQI scale follows the publicly described OPEN Alliance TC1 diagnostics concept. Real devices use vendor registers.
- Clause 45 direct frames (ST=00) are not supported, only indirect access through Clause 22.
- Traffic is generated, not captured from a vehicle or ECU. TCP streams are not reassembled (one segment is decoded on its own), SOME/IP is detected by port only, and SOME/IP-SD entries are not decoded.
- Not affiliated with or endorsed by NXP or any other vendor.
