e-bike-tracker-device/src/serial.rs

106 lines
2.9 KiB
Rust
Raw Normal View History

use std::error::Error;
use std::io;
use std::thread;
2022-11-29 15:19:42 +01:00
use std::time::Duration;
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),
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>;
pub struct SerialIO<UART: serial::Uart> {
2022-11-29 15:19:42 +01:00
pub rx: Rx<UART>,
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-11-29 15:19:42 +01:00
pub fn write_bytes(&mut self, payload: &[u8]) -> Result<usize> {
let mut num_bytes = 0;
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)))?;
num_bytes += 1;
}
if num_bytes == payload.len() {
2022-11-29 15:19:42 +01:00
Ok(num_bytes)
}
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-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-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-11-29 15:19:42 +01:00
const READ_MAX_RETRIES: usize = 5;
const READ_WAIT_TIME: u64 = 50;
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))?;
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))
.map_err(|_| io::Error::from(io::ErrorKind::Other))
}
fn flush(&mut self) -> io::Result<()> {
self.tx.flush()
.map_err(|_| io::Error::from(io::ErrorKind::Other))
}
}