opentitanlib/io/uart/
mod.rs1use std::io::{self, Read};
6use std::rc::Rc;
7use std::time::Duration;
8
9use anyhow::Result;
10use clap::Args;
11use serde::{Deserialize, Serialize};
12pub use serialport::Parity;
13use thiserror::Error;
14
15use crate::app::TransportWrapper;
16use crate::impl_serializable_error;
17use crate::io::console::{ConsoleDevice, ConsoleExt};
18use crate::transport::TransportError;
19
20pub mod flow;
21pub mod serial;
22
23#[derive(Clone, Debug, Args, Serialize, Deserialize)]
24pub struct UartParams {
25 #[arg(long, default_value = "CONSOLE")]
27 uart: String,
28
29 #[arg(long)]
31 baudrate: Option<u32>,
32
33 #[arg(long)]
35 flow_control: bool,
36}
37
38impl UartParams {
39 pub fn create(&self, transport: &TransportWrapper) -> Result<Rc<dyn Uart>> {
40 let uart = transport.uart(&self.uart)?;
41 if let Some(baudrate) = self.baudrate {
42 uart.set_baudrate(baudrate)?;
43 }
44 log::info!("set_flow_control to {}", self.flow_control);
45 uart.set_flow_control(self.flow_control)?;
46 Ok(uart)
47 }
48}
49
50#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
51#[repr(u8)]
52pub enum FlowControl {
53 None = 0,
55 Pause = 19,
57 Resume = 17,
59}
60
61pub trait Uart: ConsoleDevice {
63 fn get_baudrate(&self) -> Result<u32>;
65
66 fn set_baudrate(&self, baudrate: u32) -> Result<()>;
68
69 fn get_flow_control(&self) -> Result<FlowControl> {
71 unimplemented!();
72 }
73
74 fn set_flow_control(&self, flow_control: bool) -> Result<()> {
76 if flow_control {
77 unimplemented!();
78 }
79 Ok(())
80 }
81
82 fn get_device_path(&self) -> Result<String> {
85 Err(TransportError::UnsupportedOperation.into())
86 }
87
88 fn clear_rx_buffer(&self) -> Result<()> {
90 const TIMEOUT: Duration = Duration::from_millis(5);
93 let mut buf = [0u8; 256];
94 while self.read_timeout(&mut buf, TIMEOUT)? > 0 {}
95 Ok(())
96 }
97
98 fn set_parity(&self, _parity: Parity) -> Result<()> {
99 Err(TransportError::UnsupportedOperation.into())
100 }
101
102 fn get_parity(&self) -> Result<Parity> {
103 Err(TransportError::UnsupportedOperation.into())
104 }
105
106 fn set_break(&self, _enable: bool) -> Result<()> {
107 Err(TransportError::UnsupportedOperation.into())
108 }
109}
110
111impl<T: Uart + ?Sized> Uart for &T {
112 fn get_baudrate(&self) -> Result<u32> {
113 T::get_baudrate(self)
114 }
115
116 fn set_baudrate(&self, baudrate: u32) -> Result<()> {
117 T::set_baudrate(self, baudrate)
118 }
119
120 fn get_flow_control(&self) -> Result<FlowControl> {
121 T::get_flow_control(self)
122 }
123
124 fn set_flow_control(&self, flow_control: bool) -> Result<()> {
125 T::set_flow_control(self, flow_control)
126 }
127
128 fn get_device_path(&self) -> Result<String> {
129 T::get_device_path(self)
130 }
131
132 fn clear_rx_buffer(&self) -> Result<()> {
133 T::clear_rx_buffer(self)
134 }
135
136 fn set_parity(&self, parity: Parity) -> Result<()> {
137 T::set_parity(self, parity)
138 }
139
140 fn get_parity(&self) -> Result<Parity> {
141 T::get_parity(self)
142 }
143
144 fn set_break(&self, enable: bool) -> Result<()> {
145 T::set_break(self, enable)
146 }
147}
148
149impl<T: Uart + ?Sized> Uart for Rc<T> {
150 fn get_baudrate(&self) -> Result<u32> {
151 T::get_baudrate(self)
152 }
153
154 fn set_baudrate(&self, baudrate: u32) -> Result<()> {
155 T::set_baudrate(self, baudrate)
156 }
157
158 fn get_flow_control(&self) -> Result<FlowControl> {
159 T::get_flow_control(self)
160 }
161
162 fn set_flow_control(&self, flow_control: bool) -> Result<()> {
163 T::set_flow_control(self, flow_control)
164 }
165
166 fn get_device_path(&self) -> Result<String> {
167 T::get_device_path(self)
168 }
169
170 fn clear_rx_buffer(&self) -> Result<()> {
171 T::clear_rx_buffer(self)
172 }
173
174 fn set_parity(&self, parity: Parity) -> Result<()> {
175 T::set_parity(self, parity)
176 }
177
178 fn get_parity(&self) -> Result<Parity> {
179 T::get_parity(self)
180 }
181
182 fn set_break(&self, enable: bool) -> Result<()> {
183 T::set_break(self, enable)
184 }
185}
186
187impl Read for &dyn Uart {
188 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
189 ConsoleExt::read(&**self, buf).map_err(io::Error::other)
190 }
191}
192
193#[derive(Error, Debug, Serialize, Deserialize)]
195pub enum UartError {
196 #[error("Enumerating: {0}")]
197 EnumerationError(String),
198 #[error("Opening: {0}")]
199 OpenError(String),
200 #[error("Invalid option: {0}")]
201 InvalidOption(String),
202 #[error("Invalid speed: {0}")]
203 InvalidSpeed(u32),
204 #[error("Reading: {0}")]
205 ReadError(String),
206 #[error("Writing: {0}")]
207 WriteError(String),
208 #[error("{0}")]
209 GenericError(String),
210}
211impl_serializable_error!(UartError);