diff --git a/docs/micromate_protocol_reference.md b/docs/micromate_protocol_reference.md index 88e45f5..be516a2 100644 --- a/docs/micromate_protocol_reference.md +++ b/docs/micromate_protocol_reference.md @@ -362,6 +362,53 @@ are DLE-stuffed**, so a parser must destuff before applying field offsets. --- +## A/B: Blastware build vs Thor build (2026-09-23) + +UM12947 (`11.0CB`) and UM20147 (`11.0BD`) were each put on the bench and given +the identical read-only sweep. **Both answer Series III command frames.** + +| | UM12947 `11.0CB` | UM20147 `11.0BD` | +|---|---|---| +| POLL answers | ✓ | ✓ | +| All 10 read SUBs answer | ✓ | ✓ | +| `response_SUB = 0xFF − req` | ✓ | ✓ | +| DLE-aware checksum valid | ✓ | ✓ | +| Two-step probe/data read | ✓ | ✓ | +| ID string | `MM/ISEE/S/IO` | `MM/ISEE/S` | +| **flags byte** | **`0xC5`** | **`0x03`** | +| **`0x1C` length** | **`0x2C`** | **`0x30`** | + +**The firmware line does not change the wire protocol.** One protocol stack +can drive the whole fleet regardless of which build a unit is on. This is the +single most consequential finding so far: "standardise the fleet on one +firmware" becomes an *optional* convenience rather than a prerequisite for +building a call-home receiver. + +### The two differences that do exist + +**1. The flags byte identifies the build.** Response `payload[1]` is `0xC5` +on the Blastware line and `0x03` on the Thor line, constant across all ten +SUBs on both units. That makes firmware line detectable from *any* response, +without reading device info. ⚠ Two units, one each — treat as a strong +hypothesis, not a proven encoding. + +Note `0x03` is ETX, so on Thor-line units it arrives DLE-escaped as `10 03`. +A parser that fails to destuff will mis-locate every field by one byte on +exactly half your fleet. + +**2. `SUB 0x1C` (monitor status) is 4 bytes longer on the Thor line** — +`0x30` vs `0x2C` — with four extra trailing bytes (`0f a0 00 00`, purpose +unknown). + +⚠ **This breaks relative-to-end parsing.** Series III reads battery and +memory from the *end* of the `0x1C` block (`[-10:-8]`, `[-8:-4]`, `[-4:]`). +Those offsets are correct on `11.0CB` and wrong on `11.0BD` — applying them +blindly to UM20147 yields a battery reading of **577.92 V**. Parse forward +from the declared length instead of backward from the end. + +With the offsets shifted by 4, UM20147 reads correctly: battery **3.81 V**, +memory 15,000,000 total and free (no events stored). + ## Divergences from Series III (running list) 1. **No `DLE` prefix on responses** — bare `STX`. @@ -372,6 +419,8 @@ are DLE-stuffed**, so a parser must destuff before applying field offsets. 4c. **`1E`/`1F` return the event size**, where Series III returns an offset. 4d. **`0x0A` vs `0x0C` split by record type**, not by the `0x46`/`0x2C` length discriminator Series III uses. +4e. **Response `payload[1]` (flags) encodes the firmware line** — `0xC5` + Blastware, `0x03` Thor — where Series III has a constant `0x10`. 5. **Modem serial rate is 115200**, not 38400 (per TMI provisioning practice; not independently verified here).