sel4_driver_interfaces/serial/
write_buffered.rs1use embedded_hal_nb::nb;
8use embedded_hal_nb::serial;
9use heapless::Deque;
10
11#[derive(Debug, Clone)]
12pub struct WriteBuffered<T, const WRITE_BUF_SIZE: usize = 256> {
13 unbuffered: T,
14 write_buffer: Deque<u8, WRITE_BUF_SIZE>,
15}
16
17impl<T, const WRITE_BUF_SIZE: usize> WriteBuffered<T, WRITE_BUF_SIZE> {
18 pub fn new(unbuffered: T) -> Self {
19 Self {
20 unbuffered,
21 write_buffer: Deque::new(),
22 }
23 }
24
25 fn enqueue<E>(&mut self, v: u8) -> nb::Result<(), E> {
26 match self.write_buffer.push_back(v) {
27 Ok(()) => Ok(()),
28 Err(_) => Err(nb::Error::WouldBlock),
29 }
30 }
31
32 fn enqueue_if_would_block<E>(&mut self, err: nb::Error<E>, v: u8) -> nb::Result<(), E> {
33 match err {
34 err @ nb::Error::Other(_) => Err(err),
35 nb::Error::WouldBlock => self.enqueue(v),
36 }
37 }
38}
39
40impl<T: serial::Write<u8>, const WRITE_BUF_SIZE: usize> WriteBuffered<T, WRITE_BUF_SIZE> {
41 fn write_entire_buffer(&mut self) -> nb::Result<(), <Self as serial::ErrorType>::Error> {
42 loop {
43 if let Some(v) = self.write_buffer.front() {
44 if let err @ Err(_) = self.unbuffered.write(*v) {
45 break err;
46 }
47 } else {
48 break Ok(());
49 }
50 self.write_buffer.pop_front().unwrap();
51 }
52 }
53}
54
55impl<T: serial::ErrorType, const WRITE_BUF_SIZE: usize> serial::ErrorType
56 for WriteBuffered<T, WRITE_BUF_SIZE>
57{
58 type Error = T::Error;
59}
60
61impl<T: serial::Read, const WRITE_BUF_SIZE: usize> serial::Read<u8>
62 for WriteBuffered<T, WRITE_BUF_SIZE>
63{
64 fn read(&mut self) -> nb::Result<u8, Self::Error> {
65 self.unbuffered.read()
66 }
67}
68
69impl<T: serial::Write, const WRITE_BUF_SIZE: usize> serial::Write<u8>
70 for WriteBuffered<T, WRITE_BUF_SIZE>
71{
72 fn write(&mut self, v: u8) -> nb::Result<(), Self::Error> {
73 match self.write_entire_buffer() {
74 Err(err) => self.enqueue_if_would_block(err, v),
75 Ok(()) => match self.unbuffered.write(v) {
76 Err(err) => self.enqueue_if_would_block(err, v),
77 Ok(()) => Ok(()),
78 },
79 }
80 }
81
82 fn flush(&mut self) -> nb::Result<(), Self::Error> {
83 self.write_entire_buffer()?;
84 self.unbuffered.flush()
85 }
86}