What Cascade does · How it works
There is no published description of the USB traffic, so the method has been:
One example, to show the level of detail. A register write looks like 8A <module> <register> <value>, and a read looks like EB <module> <register>. Channel A's level comes from two reads, a mantissa (EB 02 1C) and a range "octave" (EB 02 02), combined as:
dBV = 20·log10(mantissa) + 0.0058841·octave + cal
The constant cal is measured at every connect against the AP's own generator through GenMon. The low 10 bits of the octave register turned out to be status flags, not part of the value. Reading them as value caused a 4.61 dB offset in sweeps until it was found.
The generator level runs the other way: the app computes the bytes from the level you ask for, with a closed-form formula fitted to APWIN's own writes. It was confirmed on hardware at 43 levels, worst error 0.037 dB.
The wire itself (the USB adapter, every opcode, timing, and what an Ethernet version would take) is on its own page: The USB–APIB link, byte by byte.
The safety rule. The 2522 is not a sandbox, and the project's oldest rule is still its strictest: never send a write with a guessed value. Every write the app sends was either seen verbatim in an APWIN capture or comes from a formula validated against captures.
Ranging and settling. Most of the hard bugs were not arithmetic. The analyzer picks its own input range (autoranging). The app lets it settle, waits until the range code repeats and the reading is out of overload on both channels, then freezes that range for the measurement. The first reading after a range change is treated as suspect.