feat(protocol): carry HW revision + FW identity in the MSG_OK_READY ack (CAP-02) - #49
Merged
Merged
Conversation
CAP-02. The operation-setup ack previously carried only the CAP-01 2-byte
buffer size. It now carries everything the host needs to gate compatibility
at connect time:
[buffer_size u16 BE][effective_hw_revision u8][ver_len u8][ver bytes]
Motivation: the host must refuse to program chips that route VPP to bus
line 11 (socket pin 21 on the DIP24_2716 / DIP24_2532 pinouts) unless the
attached shield is Rev 2.2 or later -- those parts need the 3-position JP4
header, and driving them on an earlier board is a chip-damage path. The
revision was already computed at boot but only reachable via a separate
CMD_HW_VERSION command or a FLAG_VERBOSE-gated INFO frame.
Folding it into MSG_OK_READY lets the host retire its dedicated
CMD_FW_VERSION pre-probe, removing one full command exchange per connect.
Notes:
- MSG_OK_READY is declared `params = [{ type = "bytes" }]` in the message
catalog, so this needs NO catalog edit and NO codegen regen.
- The revision byte is always emitted; builds without HARDWARE_REVISION send
0xFE (the REVISION_UNKNOWN value -- the symbol itself lives inside that
same #ifdef). The ack's shape therefore never varies by build config, and
"no detection compiled in" reaches the host as a rejectable value rather
than as an absent field.
- Hosts predating CAP-02 test `len(params) == 2`, miss, and fall back to
their 512-byte chunk floor: degraded throughput on Leonardo, never a
misparse.
Cost: +34 bytes flash on uno (23954 -> 23988), no change to static RAM.
The 36-byte pack buffer is stack-local to init_programmer_framed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 6, 2026
feat(safety): refuse pre-Rev-2.2 shields for VPP-on-line-11 chips (CAP-02)
henols/firestarter_app#45
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Firmware half of the CAP-02 pair. Must land together with henols/firestarter_app#45 — a host on this firmware and a host without it are not interchangeable.
What changed
init_programmer_framedextends the operation-setup ack past CAP-01's 2-byte buffer-size region:That is the whole diff — one packed emit replacing
LOG_OK_ID_U16(MSG_OK_READY, DATA_BUFFER_SIZE).Why
The host must refuse to program chips that route VPP to bus line 11 (socket pin 21 on the
DIP24_2716/DIP24_2532pinouts) unless the attached shield is Rev 2.2 or later — those parts need the 3-position JP4 header, and driving them on an earlier board is a chip-damage path.The revision was already computed at boot (
rurp_detect_hardware_revision()insetup()), but only reachable via a separateCMD_HW_VERSIONcommand or aFLAG_VERBOSE-gated INFO frame. Folding it intoMSG_OK_READYlets the host retire its dedicatedCMD_FW_VERSIONpre-probe, removing one full command exchange per connect.Notes for review
MSG_OK_READYis already declaredparams = [{ type = "bytes" }], so the wire shape was already permissive.codegen.py --checkconfirms the catalog is untouched.HARDWARE_REVISIONsend0xFE— theREVISION_UNKNOWNvalue, spelled as a literal because the symbol itself lives inside that same#ifdef. The ack's shape therefore never varies by build configuration, only by version-string length, and "no detection compiled in" reaches the host as a rejectable value rather than an absent field.len(params) == 2, miss, and fall back to their 512-byte chunk floor: degraded throughput on Leonardo, never a misparse.Size
The 36-byte pack buffer is stack-local to
init_programmer_framed, so it does not appear in static RAM — peak stack at that call site grows by ~36 B. Leonardo builds green at 90.9% flash.Not done
build.ymlonly triggers on PRs targetingmain, andbeta-build.ymlonly on push tobeta. Both targets were built locally (pio run -e uno,-e leonardo).🤖 Generated with Claude Code