Skip to main content

Module msp

Module msp 

Source
Expand description

MSP (MultiWii Serial Protocol) v1 + v2 codec.

The agent’s MAVLink router already exposes a raw MSP byte pipe on /run/ados/msp.sock (it forwards bytes to and from a Betaflight / iNav / KISS flight controller’s serial link), but nothing in the tree could build or parse an MSP frame. This module is that codec: the wire framing for both MSP versions plus the one command a companion needs to fly a rate-control FC, MSP_SET_RAW_RC (200), with the stick scaling the GCS already standardized.

Two frame formats, both little-endian:

  • MSPv1 $M<: '$' 'M' <dir> <size:u8> <cmd:u8> <payload...> <crc:u8> where crc is the XOR of size, cmd, and every payload byte. size is the payload length, so a v1 command id and a single payload byte cannot exceed 255. <dir> is < for a request to the FC, > for a reply, ! for an error reply.
  • MSPv2 $X<: '$' 'X' <dir> <flag:u8> <cmd:u16 LE> <size:u16 LE> <payload...> <crc:u8> where crc is CRC8/DVB-S2 (poly 0xD5) accumulated over flag, the two command bytes, the two size bytes, and every payload byte. v2 lifts the 8-bit command/size ceiling (needed for the full command space and larger settings payloads).

The codec is transport-agnostic: it produces and consumes byte buffers, and the plugin host / MSP client move those over the socket. It never opens the socket or the FC itself.

Structs§

MspFrame
A decoded MSP frame: its command id, direction/marker byte, and payload.

Enums§

MspDecodeError
Why a byte buffer could not be decoded as a single complete MSP frame.

Constants§

DIR_ERROR
The v1 marker for an error reply from the FC (!).
DIR_FROM_FC
The v1 marker for a normal reply from the FC (>).
DIR_TO_FC
The v1 direction/marker byte for a request to the FC (<).
MSP_SET_RAW_RC
MSP_SET_RAW_RC — write raw RC channel values (PWM microseconds) to the FC. Payload is N little-endian u16 channels. This is the command a companion uses to fly an FC in a rate mode (ACRO), the FC treating the values as if they came from a receiver.

Functions§

bipolar_to_pwm
Map a bipolar stick axis (roll / pitch / yaw), -1.0..=1.0, to a PWM value 1000..=2000 with centre 1500. Out-of-range inputs clamp. This matches the GCS bipolarToPwm mapping so a companion and the GCS scale sticks identically.
crc8_dvb_s2
Accumulate one byte into a CRC8/DVB-S2 running value (polynomial 0xD5). Seed with 0 and fold every byte of the v2 header+payload.
crc8_dvb_s2_buf
CRC8/DVB-S2 over a slice, seeded at 0.
decode_frame
Decode exactly one MSP frame from the START of buf (v1 or v2, auto-detected from the $M / $X preamble). Returns the frame and the number of bytes it consumed, so a caller streaming from the socket can advance past it. Verifies the CRC and fails closed on a mismatch — a corrupt FC reply must never be handed on as if it were valid (a status surface reports verified data).
encode_v1
Encode an MSPv1 request $M<. cmd and payload.len() must each fit in a byte; a command or payload that does not is a v2-only frame, so this returns None rather than truncating (a silent truncation would corrupt the FC command — fail loudly instead).
encode_v2
Encode an MSPv2 request $X< with flag = 0 (the common case).
encode_v2_flagged
Encode an MSPv2 request $X< with an explicit flag byte.
set_raw_rc
Encode an MSP_SET_RAW_RC command carrying channels PWM microsecond values as little-endian u16s. v2 selects the framing (v2 is the safe default for a modern FC; v1 is offered for a legacy target). A v1 encode of more than 127 channels overflows the byte size field and returns None.
throttle_to_pwm
Map a throttle input, 0.0..=1.0, to a PWM value 1000..=2000 with idle at 1000 (NOT centre — a throttle at rest is idle, not mid-stick). Matches the GCS throttleToPwm mapping.