Two-wire interface: addresses, pages, banks & timing
Every pluggable module is managed over the same two wires — a serial clock and a serial data line — using the I²C protocol the specifications call the two-wire interface (TWI). What differs between SFP, QSFP, XFP and CMIS modules is how the address space is organised on top of it: separate devices, paged memory, or banks of pages. This material is the protocol-level view that programmers, hosts and CodingBox all rely on.
Physical layer
- Two open-drain lines, SCL and SDA, pulled up on the host side; 3.3 V logic.
- The module is always the slave; the host (or programmer) is the master and generates the clock.
- Modules may stretch the clock (hold SCL low) while a microcontroller fetches data — the specifications allow up to 500 µs.
- Presence and selection are separate pins, not bus transactions: MOD_ABS (SFP), ModPrsL and ModSelL (QSFP-class and CMIS). ModSelL lets several modules share one bus; SFP has no select pin, so hosts give each cage its own bus or a multiplexer.
Address space by specification
| Family | Device addresses (8-bit write / 7-bit) | Organisation | Page select |
|---|---|---|---|
| SFP, SFP+, SFP28 (SFF-8472) | A0h / 50h identity, A2h / 51h diagnostics | A0h: 256 flat bytes; A2h: 128 flat + optional paged upper half | A2h byte 127, if A0h byte 64 bit 4 set |
| XFP (INF-8077i) | A0h | 128 flat + paged upper "tables" | byte 127 |
| QSFP+, QSFP28 (SFF-8636) | A0h | 128 flat + paged upper 128 | byte 127 |
| QSFP-DD, OSFP, SFP-DD… (CMIS) | A0h | 128 flat + banks × pages of upper 128 | byte 126 bank, byte 127 page |
An SFP therefore needs two device addresses and no paging for the basics; everything after XFP uses one address and paging. Some legacy SFPs set A0h byte 92 bit 2 ("address change required") and need a vendor sequence before A2h responds.
Transactions
| Operation | Sequence | Notes |
|---|---|---|
| Random read | START · device addr+W · byte offset · START · device addr+R · data… · STOP | the everyday read; offset auto-increments |
| Sequential read | continue clocking after the first byte | wraps at 255 → 0 within the current device/page view |
| Current-address read | START · device addr+R · data | continues from the last offset — fragile if another master intervened |
| Byte write | START · addr+W · offset · data · STOP | then wait t_WR |
| Page write | START · addr+W · offset · data × n · STOP | limited by the memory device (typically 4–16 bytes) and must not cross its internal page boundary |
| Acknowledge polling | issue START + addr+W until the module ACKs | the fastest way to know a write cycle finished |
Reading an upper page is always two transactions: write the page-select byte (127, and 126 for CMIS banks), then read 128–255. The selection persists until changed, which is why a stale page select is a classic source of "wrong content" reads.
Speed
| Specification | Clock |
|---|---|
| SFF-8472 (SFP) | 100 kHz baseline; some modules tolerate 400 kHz |
| INF-8077i (XFP) | 100 kHz |
| SFF-8636 rev 2.x (QSFP) | up to 400 kHz |
| CMIS / QSFP-DD / OSFP hardware specs | up to 400 kHz |
Slower is always legal. For writes most programmers drop far below the nominal clock — into the low kilohertz — because EEPROM write cycles and microcontroller-mediated modules are far more sensitive to timing than reads.
Timing that matters
| Parameter | Typical limit | Meaning |
|---|---|---|
| t_init (SFP) | 300 ms | from power-up / TX_DISABLE negation until the module is fully operational and the bus answers |
| t_init (QSFP) | 2 s | until initialisation completes and Data_Not_Ready clears |
| MgmtInit (CMIS) | ≤ 2 s per hardware specs | until the module leaves MgmtInit and identity is valid |
| t_WR | 40 ms | maximum write cycle for a byte or sequential write; poll ACK or wait |
| t_clock_hold | 500 µs | maximum clock stretch by the module |
| ton_IntL | 200 ms | from flag event to IntL asserted |
| Data ready | byte 110 bit 0 (SFP), byte 2 bit 0 (QSFP) | do not trust monitors while set |
Pitfalls and their fixes
| Symptom | Protocol cause | Fix |
|---|---|---|
| All FFh | no ACK — wrong device address, page not implemented, module absent | check A0h vs A2h, page bits, seating |
| Wrong content | stale page/bank select | write 127 (and 126) before every upper-page access |
| Corrupted bytes | clock too fast, long leads, contention with a host polling DDM | slow down, short cable, read on the bench not in a live switch |
| Write "succeeds", reads back old | wrote too fast, ignored t_WR, crossed a page-write boundary | byte writes or small chunks with waits; ACK polling |
| Bus hangs, SCL or SDA stuck low | interrupted transaction | clock out nine SCL pulses, then STOP; power-cycle the module |
| Works in switch, dead on programmer | module expects LPMode released or a select pin | respect ModSelL/LPMode; allow t_init |
The bench-side diagnostics for these are collected in EEPROM read & write errors; protection schemes that ride on top of the bus (passwords, hardware WP, save commands) are in Write-protection types.
Reading in a live system
A host polls DDM every few seconds and reacts to flags; a second master on the same bus (a programmer clip, an in-band tool) causes collisions, mis-addressed writes and, at worst, a module bricked by a page write landing on the wrong offset. Read in place if you must; write on the bench.
In CodingBox
CodingBox handles the address model per form factor automatically — A0h/A2h for SFP, paging for QSFP and XFP, bank + page for CMIS — lets you set the bus speed and write timing per programmer profile, and verifies each write by reading back (Writing a module).