1use embedded_hal as hal;
8use hal::blocking::i2c;
9use std::error::Error as StdError;
10use std::result;
11use std::str;
12use std::str::Utf8Error;
13use std::thread;
14use std::time::Duration;
15use thiserror::Error;
16
17#[derive(Error, Debug)]
18pub enum EzoBoardError<E: StdError + 'static> {
19 #[error(transparent)]
21 I2c(#[from] E),
22 #[error(transparent)]
24 Utf8Error(Utf8Error),
25 #[error("Read buffer is not ready")]
27 NotReady,
28 #[error("No Data To Send")]
30 NoDataToSend,
31 #[error("Syntax Error")]
33 SyntaxError,
34
35 #[error("unknown EzoReadError")]
36 Unknown,
37}
38
39pub struct EzoBoard<I2C> {
41 i2c: I2C,
42 address: u8,
43}
44impl<I2C, E> EzoBoard<I2C>
48where
49 I2C: i2c::Read<Error = E> + i2c::Write<Error = E>,
50 E: std::error::Error,
51{
52 pub fn new(i2c: I2C, address: u8) -> Self {
53 EzoBoard { i2c, address }
54 }
55 pub fn send_command(
57 &mut self,
58 command: &[u8],
59 delay: Duration,
60 ) -> result::Result<(), EzoBoardError<E>> {
61 self.i2c.write(self.address, command)?;
62 if delay != Duration::new(0, 0) {
63 thread::sleep(delay);
64 }
65 Ok(())
66 }
67 pub fn read_response(&mut self) -> result::Result<String, EzoBoardError<E>> {
69 let mut buff: [u8; 40] = [0; 40];
70 self.i2c.read(self.address, &mut buff[..])?;
71 match &buff[0] {
72 1 => Ok(str::from_utf8(&buff[1..])
73 .map_err(EzoBoardError::Utf8Error)?
74 .to_string()),
75 2 => Err(EzoBoardError::SyntaxError),
76 254 => Err(EzoBoardError::NotReady),
77 255 => Err(EzoBoardError::NoDataToSend),
78 _ => Err(EzoBoardError::Unknown),
79 }
80 }
81}