diff --git a/Cargo.toml b/Cargo.toml index 75dc960..b05ba2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,3 @@ ftdi = "0.1.3" log = "0.4.8" thiserror = "1.0.15" serialport="=4.6.1" -anyhow = "1.0.97" diff --git a/src/device/elm327.rs b/src/device/elm327.rs index 9b8d9e9..8dd3513 100644 --- a/src/device/elm327.rs +++ b/src/device/elm327.rs @@ -1,116 +1,27 @@ use log::{debug, info, trace}; use std::{ collections::VecDeque, - io::{Read, Write}, thread, time, }; -use std::time::Duration; -use super::{Error, Obd2BaseDevice, Obd2Reader, Result}; - -trait SerialDevice { - fn write_all(&mut self, data: &[u8]) -> Result<()>; - fn read(&mut self, data: &mut [u8]) -> Result; - fn set_baud_rate(&mut self, baud_rate: u32) -> Result<()>; - fn purge_buffers(&mut self) -> Result<()>; -} - -pub struct SerialPort { - device: Box -} - -impl SerialPort { - pub fn new(path: &str) -> Result { - let port = serialport::new(path, 38_400) - .timeout(Duration::from_millis(10)) - .parity(serialport::Parity::None) - .data_bits(serialport::DataBits::Eight) - .stop_bits(serialport::StopBits::One) - .path(path) - .open()?; - - let device = SerialPort { - device: port - }; - - Ok(device) - } -} - -impl SerialDevice for SerialPort { - fn write_all(&mut self, data: &[u8]) -> Result<()> { - Ok(self.device.write_all(data)?) - } - - fn read(&mut self, data: &mut [u8]) -> Result { - Ok(self.device.read(data)?) - } - - fn set_baud_rate(&mut self, baud_rate: u32) -> Result<()> { - Ok(self.device.set_baud_rate(baud_rate)?) - } - - fn purge_buffers(&mut self) -> Result<()> { - Ok(self.device.clear(serialport::ClearBuffer::All)?) - } -} - -pub struct FTDIDevice { - device: ftdi::Device -} - -impl FTDIDevice { - pub fn new() -> Result { - let mut ftdi_device = ftdi::find_by_vid_pid(0x0404, 0x6001) - .interface(ftdi::Interface::A) - .open()?; - - ftdi_device.set_baud_rate(38400)?; - ftdi_device.configure(ftdi::Bits::Eight, ftdi::StopBits::One, ftdi::Parity::None)?; - ftdi_device.usb_reset()?; - - let device = FTDIDevice { - device: ftdi_device - }; - - Ok(device) - } -} - -impl SerialDevice for FTDIDevice { - fn write_all(&mut self, data: &[u8]) -> Result<()> { - Ok(self.device.write_all(data)?) - } - - fn read(&mut self, data: &mut [u8]) -> Result { - Ok(self.device.read(data)?) - } - - fn set_baud_rate(&mut self, baud_rate: u32) -> Result<()> { - Ok(self.device.set_baud_rate(baud_rate)?) - } - - fn purge_buffers(&mut self) -> Result<()> { - Ok(self.device.usb_purge_buffers()?) - } -} +use super::{Error, Obd2BaseDevice, Obd2Reader, Result, serial_comm::SerialComm}; /// An ELM327 OBD-II adapter /// -/// It communicates with the computer over UART using an FTDI FT232R USB-to-UART converter. +/// It communicates with the computer or UART using an FTDI FT232R USB-to-UART converter. /// Commands to the device itself are indicated by sending "AT" followed by the command, while /// plain strings of hex data indicate OBD-II requests to be sent to the vehicle. The responses of /// the vehicle are echoed back as hex characters. Capitalization and spaces are always ignored. /// /// [Datasheet for v1.4b](https://github.com/rsammelson/obd2/blob/master/docs/ELM327DSH.pdf), and /// the [source](https://www.elmelectronics.com/products/dsheets/). -pub struct Elm327 { +pub struct Elm327 { device: T, buffer: VecDeque, baud_rate: u32, } -impl Obd2BaseDevice for Elm327 { +impl Obd2BaseDevice for Elm327 { fn reset(&mut self) -> Result<()> { self.flush_buffers()?; self.reset_ic()?; @@ -130,7 +41,7 @@ impl Obd2BaseDevice for Elm327 { } } -impl Obd2Reader for Elm327 { +impl Obd2Reader for Elm327 { fn get_line(&mut self) -> Result>> { self.get_until(b'\n', false) } @@ -146,7 +57,9 @@ impl Obd2Reader for Elm327 { } } -impl Elm327 { +impl Elm327 { + /// Creates a new Elm327 adapter with the given + /// unserlying Serial Communication device pub fn new(serial_device: T) -> Result { let mut device = Elm327 { device: serial_device, diff --git a/src/device/mod.rs b/src/device/mod.rs index cff2463..96fca1c 100644 --- a/src/device/mod.rs +++ b/src/device/mod.rs @@ -1,7 +1,10 @@ //! Lower level OBD-II interfacing structures mod elm327; -pub use elm327::{Elm327, SerialPort, FTDIDevice}; +pub use elm327::Elm327; + +mod serial_comm; +pub use serial_comm::{SerialPort, FTDIDevice}; type Result = std::result::Result; @@ -54,6 +57,7 @@ pub enum Error { #[error("FTDI error: `{0:?}`")] Ftdi(ftdi::Error), + /// An error with the underlying [serialport device](serialport::SerialPort) #[error("Serialport error: `{0:?}`")] Serialport(serialport::Error), diff --git a/src/error.rs b/src/error.rs index 725427f..3498595 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,3 +1,6 @@ +//! Error types for OBD-II related errors + +/// Result type defaulted with this library's error type pub type Result = std::result::Result; /// An error with OBD-II communication @@ -16,6 +19,7 @@ pub enum Error { Other(String), } +/// An error with the ELM327 device #[derive(Debug)] pub struct DeviceError(pub crate::device::Error); @@ -27,12 +31,12 @@ impl From for Error { impl From for Error { fn from(e: std::num::ParseIntError) -> Self { - Error::Other(format!("invalid data recieved: {:?}", e)) + Error::Other(format!("invalid data received: {:?}", e)) } } impl From for Error { fn from(e: std::string::FromUtf8Error) -> Self { - Error::Other(format!("invalid string recieved: {:?}", e)) + Error::Other(format!("invalid string received: {:?}", e)) } } diff --git a/src/interface.rs b/src/interface.rs index cc083dd..ae728fa 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -40,7 +40,8 @@ impl Obd2Device for Obd2 { } impl Obd2 { - pub fn new(dev: T) -> ::anyhow::Result { + /// Creates a new instance of an Obd device + pub fn new(dev: T) -> Result { let device = Obd2 { device: dev }; @@ -48,6 +49,7 @@ impl Obd2 { Ok(device) } + /// Resets the device pub fn reset(&mut self) -> Result<()> { Ok(self.device.reset()?) }