This commit is contained in:
Robin Appelman 2024-02-18 12:03:49 +01:00
commit 83ea02403f
3 changed files with 135 additions and 73 deletions

100
Cargo.lock generated
View file

@ -2,27 +2,6 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "CoreFoundation-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0e9889e6db118d49d88d84728d0e964d973a5680befb5f85f55141beea5c20b"
dependencies = [
"libc",
"mach",
]
[[package]]
name = "IOKit-sys"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99696c398cbaf669d2368076bdb3d627fb0ce51a26899d7c61228c5c0af3bf4a"
dependencies = [
"CoreFoundation-sys",
"libc",
"mach",
]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "1.1.2" version = "1.1.2"
@ -70,15 +49,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.0.2" version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1" checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.14.0" version = "1.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f"
dependencies = [ dependencies = [
"bytemuck_derive", "bytemuck_derive",
] ]
@ -100,6 +79,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]] [[package]]
name = "either" name = "either"
version = "1.9.0" version = "1.9.0"
@ -116,6 +101,16 @@ dependencies = [
"termion", "termion",
] ]
[[package]]
name = "io-kit-sys"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4769cb30e5dcf1710fc6730d3e94f78c47723a014a567de385e113c737394640"
dependencies = [
"core-foundation-sys",
"mach2",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.150" version = "0.2.150"
@ -128,7 +123,7 @@ version = "0.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607"
dependencies = [ dependencies = [
"bitflags 2.0.2", "bitflags 2.4.2",
"libc", "libc",
"redox_syscall", "redox_syscall",
] ]
@ -153,15 +148,6 @@ dependencies = [
"pkg-config", "pkg-config",
] ]
[[package]]
name = "mach"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "mach2" name = "mach2"
version = "0.4.1" version = "0.4.1"
@ -276,19 +262,20 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]] [[package]]
name = "serialport" name = "serialport"
version = "4.2.2" version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c32634e2bd4311420caa504404a55fad2131292c485c97014cbed89a5899885f" checksum = "8f5a15d0be940df84846264b09b51b10b931fb2f275becb80934e3568a016828"
dependencies = [ dependencies = [
"CoreFoundation-sys", "bitflags 2.4.2",
"IOKit-sys",
"bitflags 2.0.2",
"cfg-if", "cfg-if",
"core-foundation-sys",
"io-kit-sys",
"libudev", "libudev",
"mach2", "mach2",
"nix", "nix",
"regex", "regex",
"scopeguard", "scopeguard",
"unescaper",
"winapi", "winapi",
] ]
@ -316,9 +303,9 @@ dependencies = [
[[package]] [[package]]
name = "termion" name = "termion"
version = "2.0.3" version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4648c7def6f2043b2568617b9f9b75eae88ca185dbc1f1fda30e95a85d49d7d" checksum = "417813675a504dfbbf21bfde32c03e5bf9f2413999962b479023c02848c1c7a5"
dependencies = [ dependencies = [
"libc", "libc",
"libredox", "libredox",
@ -326,6 +313,35 @@ dependencies = [
"redox_termios", "redox_termios",
] ]
[[package]]
name = "thiserror"
version = "1.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e3de26b0965292219b4287ff031fcba86837900fe9cd2b34ea8ad893c0953d2"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "268026685b2be38d7103e9e507c938a1fcb3d7e6eb15e87870b617bf37b6d581"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "unescaper"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0adf6ad32eb5b3cadff915f7b770faaac8f7ff0476633aa29eb0d9584d889d34"
dependencies = [
"thiserror",
]
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.12" version = "1.0.12"

View file

@ -2,13 +2,13 @@
name = "hlk_ld6002" name = "hlk_ld6002"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
description = "A library for interfacing with the HLK-LD6002 respiratory and heartbeat radar module"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
bytemuck = { version = "1.14.0", features = ["derive"] } bytemuck = { version = "1.14.3", features = ["derive"] }
binrw = { version = "0.13.3" } binrw = { version = "0.13.3", default-features = false }
[dev-dependencies] [dev-dependencies]
serialport = "4.2.2" binrw = { version = "0.13.3", features = ["std"] }
termion = "2.0.3" serialport = "4.3.0"
termion = "3.0.0"

View file

@ -1,11 +1,18 @@
use std::io::{Read}; #![no_std]
use binrw::io::NoSeek;
use binrw::error::Error as RwError;
use binrw::io::{NoSeek, Read, Seek};
use binrw::prelude::*; use binrw::prelude::*;
use binrw::{Endian, VecArgs};
use bytemuck::{cast, cast_slice}; use bytemuck::{cast, cast_slice};
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
InvalidDataLength { expected: u16, got: u16, ty: MessageType }, InvalidDataLength {
expected: u16,
got: u16,
ty: MessageType,
},
} }
#[derive(Debug, Clone, BinRead, Copy)] #[derive(Debug, Clone, BinRead, Copy)]
@ -34,19 +41,61 @@ impl MessageType {
#[allow(dead_code)] #[allow(dead_code)]
struct Frame { struct Frame {
id: u16, id: u16,
#[br(assert(length <= 16))]
length: u16, length: u16,
ty: MessageType, ty: MessageType,
header_checksum: u8, header_checksum: u8,
#[br(count = length)] #[br(count = length)]
data: Vec<u8>, data: FrameData<16>,
data_checksum: u8, data_checksum: u8,
} }
#[derive(Debug, Clone)]
struct FrameData<const N: usize> {
data: [u8; N],
len: usize,
}
impl<const N: usize> FrameData<N> {
pub fn len(&self) -> usize {
self.len
}
}
impl<const N: usize> AsRef<[u8]> for FrameData<N> {
fn as_ref(&self) -> &[u8] {
&self.data[0..self.len]
}
}
impl<const N: usize> BinRead for FrameData<N> {
type Args<'a> = VecArgs<u8>;
fn read_options<R: Read + Seek>(
reader: &mut R,
_endian: Endian,
args: Self::Args<'_>,
) -> BinResult<Self> {
if args.count > N {
return Err(RwError::AssertFail {
pos: 0,
message: "".into(),
});
}
let mut data = [0u8; N];
for byte in data.iter_mut().take(args.count) {
*byte = reader.read_be()?;
}
Ok(FrameData {
data,
len: args.count,
})
}
}
impl Frame { impl Frame {
fn body(&self) -> Result<MessageBody, Error> { fn body(&self) -> Result<MessageBody, Error> {
let numbers = cast_slice::<_, u32>(&self.data); let numbers = cast_slice::<_, u32>(self.data.as_ref());
match (self.ty, self.data.len()) { match (self.ty, self.data.len()) {
(MessageType::Phase, 12) => { (MessageType::Phase, 12) => {
@ -56,23 +105,21 @@ impl Frame {
(MessageType::Respiratory, 4) => { (MessageType::Respiratory, 4) => {
Ok(MessageBody::Respiratory(f32::from_bits(numbers[0]))) Ok(MessageBody::Respiratory(f32::from_bits(numbers[0])))
} }
(MessageType::Heartbeat, 4) => { (MessageType::Heartbeat, 4) => Ok(MessageBody::Heartbeat(f32::from_bits(numbers[0]))),
Ok(MessageBody::Heartbeat(f32::from_bits(numbers[0])))
}
(MessageType::Distance, 8) => { (MessageType::Distance, 8) => {
let distance = if numbers[0] == 1 { f32::from_bits(numbers[1]) } else { 0.0 }; let distance = if numbers[0] == 1 {
f32::from_bits(numbers[1])
} else {
0.0
};
Ok(MessageBody::Distance(Some(distance))) Ok(MessageBody::Distance(Some(distance)))
} }
(MessageType::Distance, 4) => { (MessageType::Distance, 4) => Ok(MessageBody::Distance(None)),
Ok(MessageBody::Distance(None)) _ => Err(Error::InvalidDataLength {
} got: self.data.len() as u16,
_ => { expected: self.ty.expected_length(),
Err(Error::InvalidDataLength { ty: self.ty,
got: self.data.len() as u16, }),
expected: self.ty.expected_length(),
ty: self.ty,
})
}
} }
} }
} }
@ -86,13 +133,13 @@ pub enum MessageBody {
} }
pub struct MessageStream<R> { pub struct MessageStream<R> {
reader: NoSeek<R>, reader: NoSeek<R>,
} }
impl<R: Read> MessageStream<R> { impl<R: Read> MessageStream<R> {
pub fn new(reader: R) -> Self { pub fn new(reader: R) -> Self {
Self{ Self {
reader:NoSeek::new(reader) reader: NoSeek::new(reader),
} }
} }
@ -101,13 +148,12 @@ impl<R: Read> MessageStream<R> {
loop { loop {
self.reader.read(&mut byte).ok(); self.reader.read(&mut byte).ok();
if byte[0] == 0x01 { if byte[0] == 0x01 {
return Frame::read(&mut self.reader) return Frame::read(&mut self.reader);
} }
} }
} }
} }
impl<R: Read> Iterator for MessageStream<R> { impl<R: Read> Iterator for MessageStream<R> {
type Item = MessageBody; type Item = MessageBody;
@ -140,4 +186,4 @@ impl Data {
_ => {} _ => {}
} }
} }
} }