A no_std
Rust library for parsing the TBS Crossfire protocol, designed for embedded environments without an allocator.
This library provides a two-layer API:
- A low-level layer for raw packet parsing from a byte stream.
- A higher-level layer that converts raw packets into idiomatic Rust structs.
no_std
and allocator-free for embedded systems.- Two-layer API for flexible parsing.
- Supports a wide range of CRSF packets.
- IO and MCU agnostic.
- Minimal dependencies.
Legend:
🟢
- Implemented🔴
- Not Implemented
Packet Name | Packet Address | Status |
---|---|---|
Broadcast Frames | ||
GPS | 0x02 |
🟢 |
GPS Time | 0x03 |
🟢 |
GPS Extended | 0x06 |
🟢 |
Variometer Sensor | 0x07 |
🟢 |
Battery Sensor | 0x08 |
🟢 |
Barometric Altitude & Vertical Speed | 0x09 |
🟢 |
Airspeed | 0x0A |
🟢 |
Heartbeat | 0x0B |
🟢 |
RPM | 0x0C |
🟢 |
TEMP | 0x0D |
🟢 |
Voltages | 0x0E |
🟢 |
Discontinued | 0x0F |
🟢 |
VTX Telemetry | 0x10 |
🟢 |
Link Statistics | 0x14 |
🟢 |
RC Channels Packed Payload | 0x16 |
🟢 |
Subset RC Channels Packed | 0x17 |
🔴 |
RC Channels Packed 11-bits | 0x18 |
🔴 |
Link Statistics RX | 0x1C |
🟢 |
Link Statistics TX | 0x1D |
🟢 |
Attitude | 0x1E |
🟢 |
MAVLink FC | 0x1F |
🟢 |
Flight Mode | 0x21 |
🟢 |
ESP_NOW Messages | 0x22 |
🟢 |
Extended Frames | ||
Parameter Ping Devices | 0x28 |
🟢 |
Parameter Device Information | 0x29 |
🟢 |
Parameter Settings (Entry) | 0x2B |
🔴 |
Parameter Settings (Read) | 0x2C |
🔴 |
Parameter Value (Write) | 0x2D |
🔴 |
Direct Commands | 0x32 |
🟢 |
Logging | 0x34 |
🟢 |
Remote Related Frames | 0x3A |
🟢 |
Game | 0x3C |
🟢 |
KISSFC Reserved | 0x78 - 0x79 |
🔴 |
MSP Request | 0x7A |
🔴 |
MSP Response | 0x7B |
🔴 |
ArduPilot Legacy Reserved | 0x7F |
🔴 |
ArduPilot Reserved Passthrough Frame | 0x80 |
🟢 |
mLRS Reserved | 0x81, 0x82 |
🔴 |
CRSF MAVLink Envelope | 0xAA |
🟢 |
CRSF MAVLink System Status Sensor | 0xAC |
🔴 |
Library is under active development and testing, API might change at any time.
Add uf-crsf
to your Cargo.toml
:
[dependencies]
uf-crsf = "0.1.0"
Or use the command line:
cargo add uf-crsf
Here is a basic example of how to parse a CRSF packet from a byte array:
use uf_crsf::CrsfParser;
fn main() {
let mut parser = CrsfParser::new();
// A sample CRSF packet payload for RC channels
let buf: [u8; 26] = [
0xC8, // Address
0x18, // Length
0x16, // Type (RC Channels)
0x03, 0x1F, 0x58, 0xC0, 0x07, 0x16, 0xB0, 0x80, 0x05, 0x2C, 0x60, 0x01, 0x0B, 0xF8, 0xC0,
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 252, // Packet
0x42, // Crc
];
for item in parser.iter_packets(&buf) {
match item {
Ok(p) => println!("{:?}", p),
Err(e) => eprintln!("Error parsing packet: {:?}", e),
}
}
}
This project is licensed under the Apache 2.0
. See the LICENSE file for details.