diff --git a/docs/micromate_protocol_reference.md b/docs/micromate_protocol_reference.md index 1e82239..55cf545 100644 --- a/docs/micromate_protocol_reference.md +++ b/docs/micromate_protocol_reference.md @@ -1064,7 +1064,9 @@ Thor re-runs this before *every* operation — three times in this one capture: POLL (0x5B) → SERIAL (0x15) → 0x49 → POLL (0x5B) → ``` -A client should mirror it. Note `POLL` here carries `offset = 0x0030` (its data +⚠ **Whether the unit requires this is untested** — see *Thor's conventions vs +the protocol's requirements*. Thor sends it before trivial reads too, so it may +be habit rather than handshake. Do not assume it is mandatory. Note `POLL` here carries `offset = 0x0030` (its data length), not `0xFFFF` — `POLL` is the one read Thor still addresses by length. ### `SUB 0x96` / `0x97` — start and stop monitoring ✅ @@ -1159,8 +1161,10 @@ Micromate would reject the write. It squares with the earlier finding that a push to the **active** setup overwrites silently — Thor is preventing exactly the footgun the protocol leaves open. -**Any client we write should adopt the same rule**, and it is now cheap to -enforce: check `0x49` data[11] (or `0x1C` data[12]) before offering a write. +The *reason* behind the rule is sound and SFM should honour it — but not +necessarily by copying the greyed-out button. Stop → push → restart as a single +operation is what an operator usually wants, and `0x49` data[11] (or `0x1C` +data[12]) makes the state check cheap either way. ## Static analysis of the firmware (2026-09-23, solo session) @@ -1297,6 +1301,46 @@ Worth noting the histogram (`…81`) and the loudest waveform (`…84`) report the histogram's single 1-minute interval spans the whole thumping session, so its maximum should equal the loudest event in it. +## Thor's conventions vs the protocol's requirements + +**SFM is not meant to reimplement Thor.** Thor is the only available teacher of +the wire protocol, but almost nothing about *how* it sequences its work has been +shown to be required by the device. Those are two different things and this +document should not blur them. + +The distinction matters because several observations above were written as +"a client should do X" when the honest statement is "Thor does X, and we have not +checked whether the unit cares." + +| Thor does this | required? | what it means for SFM | +|---|---|---| +| `POLL → 0x15 → 0x49 → POLL` before **every** operation | **unknown** | Series III needed `POLL`×3 before `5A` *specifically*, so a preamble requirement is plausible — but Thor sends this before trivial reads too. **Testable:** issue one operation cold and see if it answers. | +| Reads with `offset = 0xFFFF`, skipping the probe | **no — the probe works** | We have a genuine choice, and the probe is arguably better: it reports the length instead of making us trust a fixed one. This is the one place Thor's shortcut is probably worse. | +| Sends `0x68` + `0x82` in every setup push | **unknown** | In both setup captures these carried near-zero payloads and **changed nothing**. If they are optional, a setup write is 3 frames instead of 7, with less to get wrong. **Worth testing before we build the writer.** | +| Rewrites the whole 2,090-byte config for a one-field change | **unknown** | No narrower write has been observed. Read-modify-write is safe and known; a targeted write would be nicer but is unevidenced. | +| Reads `0x41` twice in a row (scheduler capture, frames 6 and 8) | **no** | Plainly redundant. A reminder that Thor's sequence is not a minimal one. | +| Greys out send-to-unit while monitoring | **Thor policy** | The *reason* is real — a push to the active setup overwrites silently. But "the button is grey and you figure it out" is a UX choice, not the only answer. SFM could offer stop → push → restart as one operation, which is what an operator actually wants. | +| Names the target with `0xDA` before a config write | **almost certainly required** | The unit has to know which file to write. Closest thing here to a genuine protocol requirement. | + +### What this implies for the build order + +The read path is fully known and needs no Thor-shaped decisions, so a read-only +client can be written now with confidence. **The write path should not be built +by transcribing Thor's sequence** — the `0x68`/`0x82` question above decides +whether our setup write is 3 frames or 7, and it is answerable with one capture +plus one careful experiment. + +Two reliability problems worth designing *against*, both observed rather than +assumed: + +1. **A zero ack does not mean a write applied.** Every ack seen is 11 zero + bytes, across creates and overwrites alike, and no failing write has ever been + observed. Whatever SFM does, it should read back and compare rather than + trust the ack. `0x41` + `0x1A` makes that cheap. +2. **Nothing warns before clobbering a monitoring unit's active setup.** The + device will not stop it and the ack will not distinguish it. That guard has + to live in SFM. + ## ⚠ Untested and unsafe-until-agreed **Nothing below has been sent to a unit by us, and nothing should be without an