Skip to content

Commit

Permalink
Merge pull request #28 from peterkrull/refactor
Browse files Browse the repository at this point in the history
PR containing many things
  • Loading branch information
tact1m4n3 authored May 18, 2024
2 parents 7f491a1 + aa14493 commit a129e57
Show file tree
Hide file tree
Showing 11 changed files with 933 additions and 596 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ repository = "https://github.com/tact1m4n3/crsf-rs"
documentation = "https://docs.rs/crsf"

[dependencies]
bitflags = "2.5.0"
crc = "3.2"
defmt = { version = "0.3.6", optional = true }
num_enum = { version = "0.7.2", default-features = false }
Expand Down
36 changes: 17 additions & 19 deletions examples/local_serial.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{env, io, time::Duration};

use crsf::{Packet, PacketPayload, PacketReader};
use crsf::{Packet, PacketReader};

fn main() {
let path = env::args().nth(1).expect("no serial port supplied");
Expand All @@ -13,27 +13,25 @@ fn main() {
let mut reader = PacketReader::new();
loop {
match port.read(buf.as_mut_slice()) {
Ok(n) => {
if n > 0 {
let mut remaining = &buf[..n];
while let (Some(raw_packet), consumed) = reader.push_bytes(remaining) {
match Packet::parse(raw_packet) {
Ok(packet) => match packet.payload {
PacketPayload::LinkStatistics(link_statistics) => {
println!("{:?}", link_statistics);
}
PacketPayload::RcChannels(channels) => {
println!("{:?}", channels);
}
_ => {}
},
Err(err) => eprintln!("{err}"),
};

remaining = &remaining[consumed..];
Ok(n @ 1..) => {
for result in reader.iter_packets(&buf[..n]) {
match result {
Ok(Packet::LinkStatistics(link_stats)) => {
println!("{:?}", link_stats);
}
Ok(Packet::RcChannelsPacked(rc_channels)) => {
println!("{:?}", rc_channels);
}
_ => {
eprintln!("Unknown packet");
}
}
}
}
Ok(0) => {
eprintln!("EOF");
break;
}
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (),
Err(e) => {
eprintln!("{}", e);
Expand Down
69 changes: 69 additions & 0 deletions src/address.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use num_enum::TryFromPrimitive;

/// Represents all CRSF packet addresses
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq, TryFromPrimitive)]
#[repr(u8)]
pub enum PacketAddress {
Broadcast = 0x00,
Usb = 0x10,
Bluetooth = 0x12,
TbsCorePnpPro = 0x80,
Reserved1 = 0x8A,
CurrentSensor = 0xC0,
Gps = 0xC2,
TbsBlackbox = 0xC4,
FlightController = 0xC8,
Reserved2 = 0xCA,
RaceTag = 0xCC,
Handset = 0xEA,
Receiver = 0xEC,
Transmitter = 0xEE,
}

bitflags::bitflags! {
pub(crate) struct PacketAddressFlags: u16 {
const BROADCAST = 1;
const USB = 1 << 1;
const BLUETOOTH = 1 << 2;
const TBS_CORE_PNP_PRO = 1 << 3;
const RESERVED1 = 1 << 4;
const CURRENT_SENSOR = 1 << 5;
const GPS = 1 << 6;
const TBS_BLACKBOX = 1 << 7;
const FLIGHT_CONTROLLER = 1 << 8;
const RESERVED2 = 1 << 9;
const RACE_TAG = 1 << 10;
const HANDSET = 1 << 11;
const RECEIVER = 1 << 12;
const TRANSMITTER = 1 << 13;
}
}

impl PacketAddressFlags {
pub(crate) fn from_address(address: PacketAddress) -> Self {
use PacketAddress::*;

match address {
Broadcast => PacketAddressFlags::BROADCAST,
Usb => PacketAddressFlags::USB,
Bluetooth => PacketAddressFlags::BLUETOOTH,
TbsCorePnpPro => PacketAddressFlags::TBS_CORE_PNP_PRO,
Reserved1 => PacketAddressFlags::RESERVED1,
CurrentSensor => PacketAddressFlags::CURRENT_SENSOR,
Gps => PacketAddressFlags::GPS,
TbsBlackbox => PacketAddressFlags::TBS_BLACKBOX,
FlightController => PacketAddressFlags::FLIGHT_CONTROLLER,
Reserved2 => PacketAddressFlags::RESERVED2,
RaceTag => PacketAddressFlags::RACE_TAG,
Handset => PacketAddressFlags::HANDSET,
Receiver => PacketAddressFlags::RECEIVER,
Transmitter => PacketAddressFlags::TRANSMITTER,
}
}

pub(crate) fn contains_u8(&self, value: u8) -> bool {
PacketAddress::try_from(value)
.map_or(false, |address| self.contains(Self::from_address(address)))
}
}
47 changes: 4 additions & 43 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ impl<'a> BytesReader<'a> {
Self { buf, idx: 0 }
}

pub fn consumed(&self) -> usize {
self.idx
// Get a slice of the remaining part of the buffer
pub fn remaining(&self) -> &'a [u8] {
debug_assert!(self.idx <= self.buf.len());
self.buf.get(self.idx..).unwrap_or(&[])
}

pub fn is_empty(&self) -> bool {
Expand All @@ -33,44 +35,3 @@ impl<'a> BytesReader<'a> {
data
}
}

pub(crate) struct Buf<const C: usize> {
buf: [u8; C],
len: usize,
}

impl<const C: usize> Buf<C> {
pub const fn new() -> Self {
Self {
buf: [0; C],
len: 0,
}
}

pub fn len(&self) -> usize {
self.len
}

pub fn push(&mut self, c: u8) -> bool {
if let Some(v) = self.buf.get_mut(self.len) {
*v = c;
self.len += 1;
true
} else {
false
}
}

pub fn push_bytes(&mut self, data: &[u8]) {
self.buf[self.len..self.len + data.len()].copy_from_slice(data);
self.len += data.len();
}

pub fn data(&self) -> &[u8; C] {
&self.buf
}

pub fn clear(&mut self) {
self.len = 0;
}
}
54 changes: 54 additions & 0 deletions src/crc8.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/// Create a new look-up table for the CRC8 algorithm.
pub const fn new_crc8_lut() -> [u8; 256] {
let mut crc_table = [0u8; 256];

let mut i = 0;
while i < 256 {
let mut crc = i as u8;
let mut j = 0;
while j < 8 {
if crc & 0x80 != 0 {
crc = (crc << 1) ^ 0xd5;
} else {
crc <<= 1;
}
j += 1;
}
crc_table[i] = crc;
i += 1;
}

crc_table
}

const CRC8_LUT: [u8; 256] = new_crc8_lut();

/// Software based CRC8 implementation.
#[derive(Debug)]
pub struct Crc8 {
crc_val: u8,
crc_table: &'static [u8; 256],
}

impl Crc8 {
pub const fn new() -> Self {
Crc8 {
crc_table: &CRC8_LUT,
crc_val: 0,
}
}

pub fn compute(&mut self, data: &[u8]) {
for e in data {
self.crc_val = self.crc_table[(self.crc_val ^ e) as usize];
}
}

pub fn reset(&mut self) {
self.crc_val = 0;
}

pub fn get_checksum(&self) -> u8 {
self.crc_val
}
}
Loading

0 comments on commit a129e57

Please sign in to comment.