1use std::io::{self, Read};
6use std::rc::Rc;
7use std::task::{Context, Poll};
8use std::time::Duration;
9
10use anyhow::Result;
11use clap::Args;
12use serde::{Deserialize, Serialize};
13pub use serialport::Parity;
14use thiserror::Error;
15
16use crate::app::TransportWrapper;
17use crate::impl_serializable_error;
18use crate::io::console::ConsoleDevice;
19use crate::transport::TransportError;
20
21#[derive(Clone, Debug, Args, Serialize, Deserialize)]
22pub struct UartParams {
23 #[arg(long, default_value = "CONSOLE")]
25 uart: String,
26
27 #[arg(long)]
29 baudrate: Option<u32>,
30
31 #[arg(long)]
33 flow_control: bool,
34}
35
36impl UartParams {
37 pub fn create(&self, transport: &TransportWrapper) -> Result<Rc<dyn Uart>> {
38 let uart = transport.uart(&self.uart)?;
39 if let Some(baudrate) = self.baudrate {
40 uart.set_baudrate(baudrate)?;
41 }
42 log::info!("set_flow_control to {}", self.flow_control);
43 uart.set_flow_control(self.flow_control)?;
44 Ok(uart)
45 }
46}
47
48#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
49#[repr(u8)]
50pub enum FlowControl {
51 None = 0,
53 Pause = 19,
55 Resume = 17,
57}
58
59pub trait Uart {
61 fn get_baudrate(&self) -> Result<u32>;
63
64 fn set_baudrate(&self, baudrate: u32) -> Result<()>;
66
67 fn get_flow_control(&self) -> Result<FlowControl> {
69 unimplemented!();
70 }
71
72 fn set_flow_control(&self, flow_control: bool) -> Result<()> {
74 if flow_control {
75 unimplemented!();
76 }
77 Ok(())
78 }
79
80 fn get_device_path(&self) -> Result<String> {
83 Err(TransportError::UnsupportedOperation.into())
84 }
85
86 fn read(&self, buf: &mut [u8]) -> Result<usize> {
89 crate::util::runtime::block_on(std::future::poll_fn(|cx| self.poll_read(cx, buf)))
90 }
91
92 fn read_timeout(&self, buf: &mut [u8], timeout: Duration) -> Result<usize> {
96 crate::util::runtime::block_on(async {
97 tokio::time::timeout(timeout, std::future::poll_fn(|cx| self.poll_read(cx, buf))).await
98 })
99 .unwrap_or(Ok(0))
100 }
101
102 fn poll_read(&self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<Result<usize>>;
107
108 fn write(&self, buf: &[u8]) -> Result<()>;
110
111 fn clear_rx_buffer(&self) -> Result<()> {
113 const TIMEOUT: Duration = Duration::from_millis(5);
116 let mut buf = [0u8; 256];
117 while self.read_timeout(&mut buf, TIMEOUT)? > 0 {}
118 Ok(())
119 }
120
121 fn set_break(&self, _enable: bool) -> Result<()> {
122 Err(TransportError::UnsupportedOperation.into())
123 }
124
125 fn set_parity(&self, _parity: Parity) -> Result<()> {
126 Err(TransportError::UnsupportedOperation.into())
127 }
128
129 fn get_parity(&self) -> Result<Parity> {
130 Err(TransportError::UnsupportedOperation.into())
131 }
132}
133
134impl Read for &dyn Uart {
135 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
136 Uart::read(&**self, buf).map_err(io::Error::other)
137 }
138}
139
140impl<'a> ConsoleDevice for dyn Uart + 'a {
141 fn console_poll_read(
142 &self,
143 cx: &mut std::task::Context<'_>,
144 buf: &mut [u8],
145 ) -> std::task::Poll<Result<usize>> {
146 self.poll_read(cx, buf)
147 }
148
149 fn console_write(&self, buf: &[u8]) -> Result<()> {
150 self.write(buf)
151 }
152
153 fn set_break(&self, enable: bool) -> Result<()> {
154 <Self as Uart>::set_break(self, enable)
155 }
156}
157
158#[derive(Error, Debug, Serialize, Deserialize)]
160pub enum UartError {
161 #[error("Enumerating: {0}")]
162 EnumerationError(String),
163 #[error("Opening: {0}")]
164 OpenError(String),
165 #[error("Invalid option: {0}")]
166 InvalidOption(String),
167 #[error("Invalid speed: {0}")]
168 InvalidSpeed(u32),
169 #[error("Reading: {0}")]
170 ReadError(String),
171 #[error("Writing: {0}")]
172 WriteError(String),
173 #[error("{0}")]
174 GenericError(String),
175}
176impl_serializable_error!(UartError);