2022-07-11 20:13:52 +02:00
|
|
|
use std::error::Error;
|
|
|
|
use std::io;
|
|
|
|
use std::thread;
|
2022-11-29 15:19:42 +01:00
|
|
|
use std::time::Duration;
|
2022-07-11 20:13:52 +02:00
|
|
|
use embedded_hal::serial::{Read, Write};
|
|
|
|
use esp_idf_hal::serial::{self, Rx, Tx};
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum SerialError {
|
2022-11-29 15:19:42 +01:00
|
|
|
ReadError(String),
|
|
|
|
WriteError(String),
|
2022-07-11 20:13:52 +02:00
|
|
|
TimeoutError,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Error for SerialError {}
|
|
|
|
|
|
|
|
impl std::fmt::Display for SerialError {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
|
|
write!(f, "{:?}", self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-29 15:19:42 +01:00
|
|
|
pub type Result<T> = nb::Result<T, SerialError>;
|
2022-07-11 20:13:52 +02:00
|
|
|
|
|
|
|
pub struct SerialIO<UART: serial::Uart> {
|
2022-11-29 15:19:42 +01:00
|
|
|
pub rx: Rx<UART>,
|
2022-07-11 20:13:52 +02:00
|
|
|
pub tx: Tx<UART>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<UART: serial::Uart> SerialIO<UART> {
|
|
|
|
pub fn new(tx: Tx<UART>, rx: Rx<UART>) -> Self {
|
2022-11-29 15:19:42 +01:00
|
|
|
Self { rx, tx }
|
2022-07-11 20:13:52 +02:00
|
|
|
}
|
|
|
|
|
2022-11-29 15:19:42 +01:00
|
|
|
pub fn write_bytes(&mut self, payload: &[u8]) -> Result<usize> {
|
2022-07-20 12:20:17 +02:00
|
|
|
let mut num_bytes = 0;
|
2022-07-11 20:13:52 +02:00
|
|
|
for b in payload.iter() {
|
2022-11-29 15:19:42 +01:00
|
|
|
self.tx.write(*b)
|
|
|
|
.map_err(|err| SerialError::WriteError(
|
|
|
|
format!("Error writing in serial port ({:?})", err)))?;
|
2022-07-20 12:20:17 +02:00
|
|
|
num_bytes += 1;
|
|
|
|
}
|
|
|
|
if num_bytes == payload.len() {
|
2022-11-29 15:19:42 +01:00
|
|
|
Ok(num_bytes)
|
2022-07-20 12:20:17 +02:00
|
|
|
}
|
|
|
|
else {
|
2022-11-29 15:19:42 +01:00
|
|
|
Err(nb::Error::Other(
|
|
|
|
SerialError::WriteError(
|
|
|
|
"Written bytes shorter than payload length (write_bytes)".to_string()
|
|
|
|
)
|
|
|
|
))
|
2022-07-11 20:13:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-29 15:19:42 +01:00
|
|
|
fn read_bytes(&mut self, buf: &mut [u8]) -> Result<usize> {
|
|
|
|
let mut started_reading = false;
|
|
|
|
let mut count = 0;
|
|
|
|
let mut retries = 0;
|
2022-07-11 20:13:52 +02:00
|
|
|
|
2022-11-29 15:19:42 +01:00
|
|
|
loop {
|
|
|
|
match self.rx.read() {
|
|
|
|
Ok(b) => {
|
|
|
|
started_reading = true;
|
|
|
|
if count < buf.len() {
|
|
|
|
buf[count] = b;
|
|
|
|
count += 1;
|
|
|
|
}
|
|
|
|
else { break }
|
|
|
|
},
|
|
|
|
Err(nb::Error::WouldBlock) => {
|
|
|
|
if started_reading || retries > READ_MAX_RETRIES { break }
|
|
|
|
else {
|
|
|
|
thread::sleep(Duration::from_millis(READ_WAIT_TIME));
|
|
|
|
retries += 1;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Err(nb::Error::Other(err)) => println!("Serial read error :: {:?}", err),
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Ok(count)
|
2022-07-11 20:13:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-29 15:19:42 +01:00
|
|
|
const READ_MAX_RETRIES: usize = 5;
|
|
|
|
const READ_WAIT_TIME: u64 = 50;
|
|
|
|
|
2022-07-11 20:13:52 +02:00
|
|
|
impl<UART: serial::Uart> io::Read for SerialIO<UART> {
|
|
|
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
2022-11-29 15:19:42 +01:00
|
|
|
let count = nb::block!(self.read_bytes(buf))
|
|
|
|
.map_err(|_| io::Error::from(io::ErrorKind::Other))?;
|
2022-07-11 20:13:52 +02:00
|
|
|
Ok(count)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<UART: serial::Uart> io::Write for SerialIO<UART> {
|
|
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
2022-11-29 15:19:42 +01:00
|
|
|
nb::block!(self.write_bytes(buf))
|
2022-07-11 20:13:52 +02:00
|
|
|
.map_err(|_| io::Error::from(io::ErrorKind::Other))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
|
|
self.tx.flush()
|
2022-07-12 19:10:04 +02:00
|
|
|
.map_err(|_| io::Error::from(io::ErrorKind::Other))
|
2022-07-11 20:13:52 +02:00
|
|
|
}
|
|
|
|
}
|