CodingBox Q&A Ask question

Scripting DDM polling over I2C: which A2h bytes hold the live values and which the thresholds

Asked Active Viewed 319 Original language: English
7

I am writing a small poller that pulls temperature, voltage, bias and optical power straight off the modules on our whitebox boxes, so we get a trend line instead of someone eyeballing a link after it has already started erroring. The NOS prints pretty values, but I want the raw numbers with the vendor thresholds next to them so alarm levels are consistent across mixed optics instead of hand-written per model.

Stand:

  • Linux host, module cages behind a plain I2C mux, bus 1
  • mixed SFP, SFP+ and SFP28 optics from three vendors
  • reading with i2c-tools only, no vendor SDK

I read the diagnostics page like this:

# i2cdump -y 1 0x51

and this is my draft parser, which is where I am unsure:

temp = s16(a2[96:98]) / 256.0
vcc  = u16(a2[98:100]) * 100e-6
bias = u16(a2[100:102]) * 2e-6

What I have already done:

  • compared my computed values against what the NOS prints: close on some modules, clearly off on others
  • read through SFF-8472, but I still cannot say confidently where the threshold block ends and where the calibration area starts
  • ruled out the mux by dumping the same module on a direct bus, same numbers

So: what is the actual map of A2h, where do the thresholds live, where do the real-timme values start, and is there a flag anywhere that tells me whether the module expects me to do something to those raw words before I trust them?

Comments 7

Which values are the ones that are clearly off, all four or only bias and the powers? That usually decides the whole answer. Also dump A0h while you are at it and look at byte 92: it tells you whether the module reports diagnostiics at all, and whether it is internally or externally calibrated. If part of your fleet is externally calibrated and your parser treats everyone the same way, then the mismatch is expected behaviour and not a bug in your arithmetic.

1 United Statescoaxhawk46US Original (English)

Pulled A0h byte 92 across the whole tray and it is not uniform. Some modules flag external calibration, some do not, and the ones that disagree with the NOS output are exactly the external ones. Temperature and voltage are within noise on everything; bias and the two powers are what drifts. So it looks like I am missing a step rather than reading the wrong offsets. What do I actually have to do with the raw words on that subset?

2 South KoreanetrunnerKR Original (English)

A2h at 0x51 breaks down into four chunks that matter to you:

  • bytes 0-55: the alarm and warning thresholds, high and low for each of temperature, voltage, bias, TX power and RX power
  • bytes 56-95: external calibration constants
  • bytes 96-105: the real-time values
  • byte 110: status and control, including TX disable, TX fault and RX LOS

Units in the live block: temperature signed, 1/256 C per LSB; voltage 100 uV per LSB; bias 2 uA; TX and RX power 0.1 uW. Your snippet already scales those correctly, so offsets are not your problem.

The missing piece is the flag you just found. On an externally calibrated module the words at 96-105 are raw ADC output, and the constants at 56-95 have to be applied before they mean anything; an internally calibrated module has already done that for you. That branch is the difference between your two groups.

If you want a layout to check against instead of taking my word for it, the FreeBSD sff8472.h header and py-sfp-eeprom both spell the offsets out field by field. I would still verify one module per vendor against a value you trust before you hang alarms off it.

3 United Statesporttech22US Original (English)

Worth adding why the threshold block is the interesting half. The values in 0-55 are in the same units as the live block, so once your scaling is right you get the vendor's own alarm and warning points for free and never have to invent limits per model. That alone justifies reading A2h directly rather than parsing somebody's pretty printer.

One practical note from running this on a mixed tray: keep the poll interval modest. That page is an ordinary I2C read and the module controller is not fast. Hammering every module every second on a bus that also sits behind a mux is a good way to collect short reads that look exactly like flapping optics in your graphs.

1 Brazilopticnerd31BR Original (English)

Careful how you word that, because people read it as "always apply the constants" and then wonder why their numbers got worse. The constants at 56-95 only apply when byte 92 in A0h says the module is externally calibrated. Run them over an internally calibrated module and you turn perfectly good readings into nonsense, because the module already did that work. Read the flag first, branch on it, keep both paths in the parser and log which path a given module took so you can tell the two failure modes apart later.

Same class of trap with temperature: it is signed. Parse it unsigned and anything below zero comes back as a wildly high number, which is entertaining the first cold morning it pages you.

4 United StatesqsfpwolfUS Original (English)

Update from my side. I branched on A0h byte 92 and apply the constants only where the module says external. Bias and both powers now track what the NOS prints on every module I could compaer against, and temperature and voltage were never a problem in the first place. Two modules still report diagnostics as present but hand back thresholds I would not trust, so for those I fall back to my own limits and flag the module in the inventory rather than pretending. Not calling the whole thing closed, but the map above was exactly whhat I was missing.

3 South KoreanetrunnerKR Original (English)

One more thing before this goes into production. Byte 110 sits in the same page and is status plus control, and the control half includes TX disable. A poller has no business writing to A2h at all, but if your library does a read-modify-write anywhere, or you fat-finger i2cset while testing on a live box, you can drop a customer link from userspace. Open the bus read-only in the poller and keep any write path in a separate tool you have to run deliberately.

The same byte gives you TX fault and RX LOS, and both are worth exporting next to the analogue values. A module sitting at a sane RX power with LOS asserted is telling you a very different story than one that simply reads low.

0 Indiawaverunner21IN Original (English)
Log in to comment. Log in