opentitanlib/io/uart/
flow.rs1use std::cell::{Cell, RefCell};
6use std::collections::VecDeque;
7use std::task::{Context, Poll, Waker, ready};
8use std::time::Duration;
9
10use anyhow::{Context as _, Result};
11
12use super::{FlowControl, Parity, Uart};
13use crate::io::console::ConsoleDevice;
14
15pub struct SoftwareFlowControl<T> {
19 inner: T,
20 flow_control: Cell<FlowControl>,
21 rxbuf: RefCell<VecDeque<u8>>,
22}
23
24impl<T: Uart> SoftwareFlowControl<T> {
25 pub fn new(inner: T) -> Self {
27 SoftwareFlowControl {
28 inner,
29 flow_control: Cell::new(FlowControl::None),
30 rxbuf: RefCell::default(),
31 }
32 }
33
34 fn poll_read_to_buffer(&self, cx: &mut Context<'_>) -> Poll<Result<()>> {
38 let mut buf = [0u8; 256];
39 let len = ready!(self.inner.poll_read(cx, &mut buf)).context("UART read error")?;
40
41 for &ch in &buf[..len] {
42 if self.flow_control.get() != FlowControl::None {
43 if ch == FlowControl::Resume as u8 {
44 log::debug!("Got RESUME");
45 self.flow_control.set(FlowControl::Resume);
46 continue;
47 } else if ch == FlowControl::Pause as u8 {
48 log::debug!("Got PAUSE");
49 self.flow_control.set(FlowControl::Pause);
50 continue;
51 }
52 }
53 self.rxbuf.borrow_mut().push_back(ch);
54 }
55 Poll::Ready(Ok(()))
56 }
57}
58
59impl<T: Uart> ConsoleDevice for SoftwareFlowControl<T> {
60 fn poll_read(&self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<Result<usize>> {
61 let mut rxbuf = self.rxbuf.borrow_mut();
62
63 while rxbuf.is_empty() {
64 drop(rxbuf);
65 ready!(self.poll_read_to_buffer(cx))?;
66 rxbuf = self.rxbuf.borrow_mut();
67 }
68
69 let (front, back) = rxbuf.as_slices();
71
72 let front_copy = std::cmp::min(buf.len(), front.len());
73 buf[..front_copy].copy_from_slice(&front[..front_copy]);
74
75 let back_copy = std::cmp::min(buf.len() - front_copy, back.len());
76 buf[front_copy..][..back_copy].copy_from_slice(&back[..back_copy]);
77
78 let copy_len = front_copy + back_copy;
79 rxbuf.drain(..copy_len);
80 Poll::Ready(Ok(copy_len))
81 }
82
83 fn write(&self, buf: &[u8]) -> Result<()> {
85 if self.flow_control.get() == FlowControl::None {
86 return self.inner.write(buf);
87 }
88
89 let pacing = Duration::from_nanos(10 * 1_000_000_000u64 / (self.get_baudrate()? as u64));
91 log::debug!(
92 "flow control: {:?}, pacing = {:?}",
93 self.flow_control.get(),
94 pacing
95 );
96
97 for b in buf.iter() {
98 loop {
101 let _ = self.poll_read_to_buffer(&mut Context::from_waker(Waker::noop()))?;
102 if self.flow_control.get() == FlowControl::Resume {
104 break;
105 }
106 std::thread::sleep(pacing);
108 }
109 self.inner
110 .write(std::slice::from_ref(b))
111 .context("UART write error")?;
112 std::thread::sleep(pacing);
117 }
118 Ok(())
119 }
120
121 fn set_break(&self, enable: bool) -> Result<()> {
122 self.inner.set_break(enable)
123 }
124}
125
126impl<T: Uart> Uart for SoftwareFlowControl<T> {
127 fn get_baudrate(&self) -> Result<u32> {
128 self.inner.get_baudrate()
129 }
130
131 fn set_baudrate(&self, baudrate: u32) -> Result<()> {
133 self.inner.set_baudrate(baudrate)
134 }
135
136 fn get_flow_control(&self) -> Result<FlowControl> {
137 Ok(self.flow_control.get())
138 }
139
140 fn set_flow_control(&self, flow_control: bool) -> Result<()> {
141 self.flow_control.set(match flow_control {
142 false => FlowControl::None,
143 true => FlowControl::Resume,
146 });
147 Ok(())
148 }
149
150 fn get_device_path(&self) -> Result<String> {
151 self.inner.get_device_path()
152 }
153
154 fn set_parity(&self, parity: Parity) -> Result<()> {
155 self.inner.set_parity(parity)
156 }
157
158 fn clear_rx_buffer(&self) -> Result<()> {
160 self.rxbuf.borrow_mut().clear();
161
162 self.inner.clear_rx_buffer()
164 }
165}