From 6d89245f2c190ee8a116508f25b9a0d862b60e18 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 18 Dec 2022 18:04:18 +0100 Subject: [PATCH] create macro for more convenient usart reading --- src/b15f.rs | 29 ++++++++++------------------- src/lib.rs | 2 +- src/usart.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 src/usart.rs diff --git a/src/b15f.rs b/src/b15f.rs index e23f560..221e823 100644 --- a/src/b15f.rs +++ b/src/b15f.rs @@ -6,7 +6,7 @@ use std::{process::Command, time::Duration, fmt::Debug, thread::sleep}; use rand::Rng; use serialport::SerialPort; -use crate::{assert::assert_in_range, error::Error, request::Request, build_request}; +use crate::{assert::assert_in_range, error::Error, request::Request, usart::read_sized, build_request, read_typed}; macro_rules! log { ($text: literal, $($arg:tt)*) => (println!(concat!("[B15F] ", $text), $($arg)*)); @@ -150,10 +150,8 @@ impl B15F { self.usart.write(build_request![request, reversed])?; - let mut aw: [u8; 1] = [0; 1]; - self.usart.read(&mut aw)?; - - if aw[0] != B15F::MSG_OK { + let aw: u8 = read_typed!(self.usart, u8); + if aw != B15F::MSG_OK { return Err(format!("Setting Port {} failed", PORT).into()); } @@ -195,10 +193,8 @@ impl B15F { self.usart.clear(serialport::ClearBuffer::Input)?; self.usart.write(build_request![request])?; - let mut aw: [u8; 1] = [0; 1]; - self.usart.read(&mut aw)?; - - Ok(u8::reverse_bits(aw[0])) + let aw: u8 = read_typed!(self.usart, u8); + Ok(u8::reverse_bits(aw)) } /// Yields information about the installed firmware on the B15 @@ -251,11 +247,9 @@ impl B15F { data_count[0] -= 1; } - let mut aw: [u8; 1] = [0; 1]; - self.usart.read(&mut aw)?; - - if aw[0] != B15F::MSG_OK { - return Err(format!("Board info is faulty: code {}", aw[0]).into()); + let aw: u8 = read_typed!(self.usart, u8); + if aw != B15F::MSG_OK { + return Err(format!("Board info is faulty: code {}", aw).into()); } Ok(info) @@ -285,11 +279,8 @@ impl B15F { self.usart.write(build_request!(Request::IntTest, dummy & 0xFF, dummy >> 8))?; - let mut aw: [u8; 2] = [0; 2]; - self.usart.read(&mut aw)?; - - let result = u16::from_le_bytes(aw); - if result != dummy * 3 { + let aw: u16 = read_typed!(self.usart, u16); + if aw != dummy * 3 { return Err("Int conversion failed".into()); } diff --git a/src/lib.rs b/src/lib.rs index 84b63dd..7c4ef49 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,6 @@ #![deny(missing_docs, missing_debug_implementations, trivial_casts, - unsafe_code, unstable_features, unused_import_braces, unused_qualifications)] @@ -14,6 +13,7 @@ //! [`original`]: https://github.com/devfix/b15f pub mod b15f; +mod usart; mod request; mod error; mod assert; diff --git a/src/usart.rs b/src/usart.rs new file mode 100644 index 0000000..41e5b77 --- /dev/null +++ b/src/usart.rs @@ -0,0 +1,27 @@ +use serialport::SerialPort; +use crate::error::Error; + +/// Reads from a USART connecction and casts the result into the specified type +/// +/// # Errors +/// This macro may throw an `error::Error` when reading from the connection fails. +/// Due to the implementation of this macro, an erroneous result is returned early +/// with the `?` operator, and not unwrapped. +/// +/// # Unsafe +/// This macro makes use of `std::mem::transmute`. +#[macro_export] +macro_rules! read_typed { + ($usart: expr, $T: ty) => { + unsafe { + std::mem::transmute(read_sized::<{ std::mem::size_of::<$T>() }>(&mut $usart)?) + } + }; +} + +pub fn read_sized (usart: &mut Box) -> Result<[u8; N], Error> { + let mut buf: [u8; N] = [0; N]; + + usart.read(&mut buf)?; + Ok(buf) +} \ No newline at end of file