1use alloc::boxed::Box;
11use core::future::Future;
12use core::pin::Pin;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, defmt::Format)]
16pub enum UartError {
17 BufferFull,
18 InvalidBaudRate,
19 Overrun,
20 Break,
21 Parity,
22 Framing,
23 Other,
25}
26
27impl core::fmt::Display for UartError {
28 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
29 write!(f, "{:?}", self)
30 }
31}
32
33impl core::error::Error for UartError {}
34
35impl embedded_io_async::Error for UartError {
36 fn kind(&self) -> embedded_io_async::ErrorKind {
37 embedded_io_async::ErrorKind::Other
38 }
39}
40
41impl From<embassy_rp::uart::Error> for UartError {
42 fn from(error: embassy_rp::uart::Error) -> Self {
43 match error {
44 embassy_rp::uart::Error::Overrun => Self::Overrun,
45 embassy_rp::uart::Error::Break => Self::Break,
46 embassy_rp::uart::Error::Parity => Self::Parity,
47 embassy_rp::uart::Error::Framing => Self::Framing,
48 _ => Self::Other,
49 }
50 }
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq, defmt::Format)]
55pub enum UartBusVersion {
56 Hardware,
58 Pio,
60 BitBang,
62}
63
64pub trait DynUartBus: Send {
66 fn write<'a>(
67 &'a mut self,
68 buf: &'a [u8],
69 ) -> Pin<Box<dyn Future<Output = Result<usize, UartError>> + 'a>>;
70 fn read<'a>(
71 &'a mut self,
72 buf: &'a mut [u8],
73 ) -> Pin<Box<dyn Future<Output = Result<usize, UartError>> + 'a>>;
74 fn flush<'a>(&'a mut self) -> Pin<Box<dyn Future<Output = Result<(), UartError>> + 'a>>;
75}
76
77#[must_use = "dropping a bus handle does not return its startup resources"]
82pub struct UartBusHandle {
83 inner: Box<dyn DynUartBus>,
84 version: UartBusVersion,
85}
86
87impl UartBusHandle {
88 pub fn new(inner: Box<dyn DynUartBus>, version: UartBusVersion) -> Self {
90 Self { inner, version }
91 }
92
93 pub fn version(&self) -> UartBusVersion {
95 self.version
96 }
97}
98
99impl embedded_io_async::ErrorType for UartBusHandle {
100 type Error = UartError;
101}
102
103impl embedded_io_async::Read for UartBusHandle {
104 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
105 self.inner.read(buf).await
106 }
107}
108
109impl embedded_io_async::Write for UartBusHandle {
110 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
111 self.inner.write(buf).await
112 }
113
114 async fn flush(&mut self) -> Result<(), Self::Error> {
115 self.inner.flush().await
116 }
117}
118
119impl<T> DynUartBus for T
120where
121 T: embedded_io_async::Read<Error = UartError> + embedded_io_async::Write<Error = UartError>,
122 T: Send,
123{
124 fn write<'a>(
125 &'a mut self,
126 buf: &'a [u8],
127 ) -> Pin<Box<dyn Future<Output = Result<usize, UartError>> + 'a>> {
128 Box::pin(async move { embedded_io_async::Write::write(self, buf).await })
129 }
130
131 fn read<'a>(
132 &'a mut self,
133 buf: &'a mut [u8],
134 ) -> Pin<Box<dyn Future<Output = Result<usize, UartError>> + 'a>> {
135 Box::pin(async move { embedded_io_async::Read::read(self, buf).await })
136 }
137
138 fn flush<'a>(&'a mut self) -> Pin<Box<dyn Future<Output = Result<(), UartError>> + 'a>> {
139 Box::pin(async move { embedded_io_async::Write::flush(self).await })
140 }
141}