Skip to content

feat: packet protocol for the state-report uplink/downlink (PR 9/10) - #44

Merged
thePunderWoman merged 1 commit into
mainfrom
firmware-rewrite/pr9-packet-protocol
Sep 8, 2026
Merged

feat: packet protocol for the state-report uplink/downlink (PR 9/10)#44
thePunderWoman merged 1 commit into
mainfrom
firmware-rewrite/pr9-packet-protocol

Conversation

@thePunderWoman

Copy link
Copy Markdown
Owner

Summary

PR 9 of the firmware rewrite (PR 1: #35 ... PR 8: #43). Adds Snips' own application-level payload format — defined fresh since Amidala has no existing schema for this controller type (tracked as thePunderWoman/Amidala#204). This is the second half of the original plan's PR 8 ("XBee SPI transport + packet protocol"), split out once that grew large enough on its own (see PR 8, #43).

  • xbee_frame.h/.cpp gains Transmit Request (0x10) / Receive Packet (0x90) frame build/parse, symmetric to PR 8's AT Command support — generic XBee envelope logic, pure and round-trip tested. Defaults to addressing the coordinator (64-bit 0, 16-bit 0x0000, per Digi's "unknown 64-bit, route by 16-bit" convention) — flagged for real-hardware validation like the rest of this PR's protocol-level assumptions.
  • packet.h/.cpp: fixed-width, big-endian encode/decode for UplinkPacket (button mask, calibrated trigger/stick, battery %, charge state — 7 bytes) and DownlinkPacket (handedness + Left/Right slot label+value — 33 bytes). Pure, round-trip tested including truncation/padding edge cases on the string fields.
  • xbee_spi.cpp gains sendPacket()/pollForPacket(), thin wrappers using the new frame types; XbeeControl exposes both as passthroughs so it stays the single facade over the one physical XBee connection rather than SnipsController.ino owning a second XbeeSpi.
  • SnipsController.ino sends the uplink every 50ms (faster than the 1s human-readable Serial telemetry, which stays as a separate bring-up aid) and polls for downlink packets every tick. Nothing consumes handedness or the Left/Right label+value yet — that's the complications system, PR 10 — so for now a decoded downlink just gets logged to prove the round trip works.

Test plan

  • pio test -e native — all 164 test cases pass
  • gcovr --exclude 'src/SnipsController\.ino' --exclude 'src/oled\.cpp' --exclude 'src/rgb_led\.cpp' --exclude 'src/calibration_store\.cpp' --exclude 'src/droid_persistence\.cpp' --exclude 'src/xbee_spi\.cpp' --exclude 'src/xbee_control\.cpp' --fail-under-line 90 — 98.6% line coverage
  • pio run -e esp32s3 — builds successfully
  • Flash to real hardware once boards arrive (and Amidala's coordinator side has something to receive with — Support Snips Controllers: gesture classification, alt-modifier, pairing, handedness, and packet protocol Amidala#204): confirm uplink packets arrive and decode correctly on the coordinator side; confirm a downlink packet round-trips and logs correctly over Serial

🤖 Generated with Claude Code

Adds Snips' own application-level payload format, defined fresh since
Amidala has no existing schema for this controller type (tracked as
thePunderWoman/Amidala#204) — this was split out of the original PR 8
once that grew large enough on its own (see PR 8, #43).

- xbee_frame.h/.cpp gains Transmit Request (0x10) / Receive Packet
  (0x90) frame build/parse, symmetric to PR 8's AT Command support —
  generic XBee envelope logic, pure and round-trip tested. Defaults to
  addressing the coordinator (64-bit 0, 16-bit 0x0000 per Digi's
  "unknown 64-bit, route by 16-bit" convention) — flagged for
  real-hardware validation like the rest of this PR's protocol-level
  assumptions.
- packet.h/.cpp: fixed-width, big-endian encode/decode for UplinkPacket
  (button mask, calibrated trigger/stick, battery %, charge state — 7
  bytes) and DownlinkPacket (handedness + Left/Right slot label+value —
  33 bytes). Pure, round-trip tested including truncation/padding edge
  cases on the string fields.
- xbee_spi.cpp gains sendPacket()/pollForPacket(), thin wrappers using
  the new frame types; XbeeControl exposes both as passthroughs so it
  stays the single facade over the one physical XBee connection.
- SnipsController.ino sends the uplink every 50ms (faster than the 1s
  human-readable Serial telemetry, which stays as a bring-up aid) and
  polls for downlink packets every tick. Nothing consumes handedness or
  the Left/Right label+value yet — that's the complications system,
  PR 10 — so for now a decoded downlink just gets logged to prove the
  round trip works.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@thePunderWoman
thePunderWoman merged commit 38afecd into main Sep 8, 2026
2 checks passed
@thePunderWoman
thePunderWoman deleted the firmware-rewrite/pr9-packet-protocol branch September 8, 2026 01:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant