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
107impl Read for &dyn Uart {
108 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
109 ConsoleExt::read(&**self, buf).map_err(io::Error::other)
110 }
111}
112
113#[derive(Error, Debug, Serialize, Deserialize)]
115pub enum UartError {
116 #[error("Enumerating: {0}")]
117 EnumerationError(String),
118 #[error("Opening: {0}")]
119 OpenError(String),
120 #[error("Invalid option: {0}")]
121 InvalidOption(String),
122 #[error("Invalid speed: {0}")]
123 InvalidSpeed(u32),
124 #[error("Reading: {0}")]
125 ReadError(String),
126 #[error("Writing: {0}")]
127 WriteError(String),
128 #[error("{0}")]
129 GenericError(String),
130}
131impl_serializable_error!(UartError);