serial_async/
lib.rs

1#![cfg_attr(not(test), no_std)]
2
3extern crate alloc;
4
5use alloc::sync::Arc;
6use core::{
7    sync::atomic::{AtomicBool, Ordering},
8    task::Poll,
9};
10use futures::task::AtomicWaker;
11
12#[derive(Debug, Clone, Copy, Default)]
13pub struct IrqEvent {
14    pub can_get: bool,
15    pub can_put: bool,
16}
17
18/// Serial error kind.
19///
20/// This represents a common set of serial operation errors. HAL implementations are
21/// free to define more specific or additional error types. However, by providing
22/// a mapping to these common serial errors, generic code can still react to them.
23#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
24#[non_exhaustive]
25pub enum ErrorKind {
26    /// The peripheral receive buffer was overrun.
27    Overrun,
28    /// Received data does not conform to the peripheral configuration.
29    /// Can be caused by a misconfigured device on either end of the serial line.
30    FrameFormat,
31    /// Parity check failed.
32    Parity,
33    /// Serial line is too noisy to read valid data.
34    Noise,
35    /// Device was closed.
36    Closed,
37    /// A different error occurred. The original error may contain more information.
38    Other,
39}
40
41impl core::error::Error for ErrorKind {}
42
43impl core::fmt::Display for ErrorKind {
44    #[inline]
45    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
46        match self {
47            Self::Overrun => write!(f, "The peripheral receive buffer was overrun"),
48            Self::Parity => write!(f, "Parity check failed"),
49            Self::Noise => write!(f, "Serial line is too noisy to read valid data"),
50            Self::FrameFormat => write!(
51                f,
52                "Received data does not conform to the peripheral configuration"
53            ),
54            Self::Closed => write!(f, "Device was closed"),
55            Self::Other => write!(
56                f,
57                "A different error occurred. The original error may contain more information"
58            ),
59        }
60    }
61}
62
63pub trait Registers: Clone + 'static {
64    fn can_put(&self) -> bool;
65    fn put(&self, c: u8) -> Result<(), ErrorKind>;
66    fn can_get(&self) -> bool;
67    fn get(&self) -> Result<u8, ErrorKind>;
68    fn get_irq_event(&self) -> IrqEvent;
69    fn clean_irq_event(&self, event: IrqEvent);
70}
71
72pub struct Serial<R: Registers> {
73    registers: R,
74    tx: ChData,
75    rx: ChData,
76    pub irq_handler: Option<IrqHandler<R>>,
77}
78
79impl<R: Registers> Serial<R> {
80    pub fn new(registers: R) -> Self {
81        let tx = ChData::new();
82        let rx = ChData::new();
83
84        Self {
85            registers: registers.clone(),
86            tx: tx.clone(),
87            rx: rx.clone(),
88            irq_handler: Some(IrqHandler { registers, tx, rx }),
89        }
90    }
91
92    pub fn try_take_tx(&mut self) -> Option<Sender<R>> {
93        self.tx.try_take()?;
94
95        Some(Sender {
96            registers: self.registers.clone(),
97            data: self.tx.clone(),
98        })
99    }
100
101    pub fn try_take_rx(&mut self) -> Option<Receiver<R>> {
102        self.rx.try_take()?;
103
104        Some(Receiver {
105            registers: self.registers.clone(),
106            data: self.rx.clone(),
107        })
108    }
109
110    /// Returns the irq state of this [`Serial`].
111    ///
112    /// # Safety
113    ///
114    /// Only used in interrupt handler.
115    pub unsafe fn get_irq_event(&self) -> IrqEvent {
116        self.registers.get_irq_event()
117    }
118
119    /// Cleans the irq state of this [`Serial`].
120    ///
121    /// # Safety
122    ///
123    /// Only used in interrupt handler.
124    pub unsafe fn clean_irq_event(&self, state: IrqEvent) {
125        self.registers.clean_irq_event(state);
126    }
127}
128
129pub struct IrqHandler<R: Registers> {
130    registers: R,
131    tx: ChData,
132    rx: ChData,
133}
134
135unsafe impl<R: Registers> Sync for IrqHandler<R> {}
136
137impl<R: Registers> IrqHandler<R> {
138    /// Handle interrupt
139    ///
140    /// #  Safety
141    /// Only used in interrupt handler.
142    pub unsafe fn handle_irq(&self) {
143        let state = self.registers.get_irq_event();
144
145        if state.can_get {
146            self.rx.waker.wake();
147        }
148        if state.can_put {
149            self.tx.waker.wake();
150        }
151
152        self.registers.clean_irq_event(state);
153    }
154}
155
156unsafe impl<R: Registers> Send for Serial<R> {}
157unsafe impl<R: Registers> Send for Sender<R> {}
158unsafe impl<R: Registers> Send for Receiver<R> {}
159
160#[derive(Clone)]
161struct ChData {
162    taken: Arc<AtomicBool>,
163    waker: Arc<AtomicWaker>,
164}
165
166impl ChData {
167    fn new() -> Self {
168        Self {
169            taken: Arc::new(AtomicBool::new(false)),
170            waker: Arc::new(AtomicWaker::new()),
171        }
172    }
173
174    fn try_take(&self) -> Option<()> {
175        match self
176            .taken
177            .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
178        {
179            Ok(taken) => {
180                if taken {
181                    None
182                } else {
183                    Some(())
184                }
185            }
186            Err(_) => None,
187        }
188    }
189}
190
191pub struct Sender<R: Registers> {
192    registers: R,
193    data: ChData,
194}
195
196impl<R: Registers> Sender<R> {
197    pub fn write(&mut self, buf: &[u8]) -> Result<usize, ErrorKind> {
198        let mut written = 0;
199        for &byte in buf {
200            if !self.registers.can_put() {
201                break;
202            }
203            self.registers.put(byte)?;
204            written += 1;
205        }
206        Ok(written)
207    }
208
209    pub fn can_put(&self) -> bool {
210        self.registers.can_put()
211    }
212
213    pub fn write_all(&mut self, buf: &[u8]) -> impl Future<Output = Result<(), ErrorKind>> {
214        WaitForWriteAll {
215            waiter: self.data.waker.clone(),
216            sender: self,
217            buf,
218        }
219    }
220}
221
222impl<R: Registers> Drop for Sender<R> {
223    fn drop(&mut self) {
224        self.data.taken.store(false, Ordering::Release);
225    }
226}
227
228pub struct Receiver<R: Registers> {
229    registers: R,
230    data: ChData,
231}
232
233impl<R: Registers> Receiver<R> {
234    pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, ErrorKind> {
235        let mut read = 0;
236        for byte in buf {
237            if !self.registers.can_get() {
238                break;
239            }
240            *byte = self.registers.get()?;
241            read += 1;
242        }
243        Ok(read)
244    }
245
246    pub fn read_all(&mut self, buf: &mut [u8]) -> impl Future<Output = Result<(), ErrorKind>> {
247        WaitForReadAll {
248            waiter: self.data.waker.clone(),
249            rx: self,
250            buf,
251            i: 0,
252        }
253    }
254}
255
256impl<R: Registers> Drop for Receiver<R> {
257    fn drop(&mut self) {
258        self.data.taken.store(false, Ordering::Release);
259    }
260}
261
262struct WaitForWriteAll<'a, 'b, R: Registers> {
263    waiter: Arc<AtomicWaker>,
264    sender: &'a mut Sender<R>,
265    buf: &'b [u8],
266}
267
268impl<'a, 'b, R: Registers> Future for WaitForWriteAll<'a, 'b, R> {
269    type Output = Result<(), ErrorKind>;
270
271    fn poll(
272        mut self: core::pin::Pin<&mut Self>,
273        cx: &mut core::task::Context<'_>,
274    ) -> core::task::Poll<Self::Output> {
275        self.waiter.register(cx.waker());
276
277        let buf = self.buf;
278        match self.sender.write(buf) {
279            Ok(n) => {
280                self.buf = &buf[n..];
281                if n < buf.len() {
282                    Poll::Pending
283                } else {
284                    Poll::Ready(Ok(()))
285                }
286            }
287            Err(e) => Poll::Ready(Err(e)),
288        }
289    }
290}
291
292struct WaitForReadAll<'a, 'b, R: Registers> {
293    waiter: Arc<AtomicWaker>,
294    rx: &'a mut Receiver<R>,
295    buf: &'b mut [u8],
296    i: usize,
297}
298
299impl<'a, 'b, R: Registers> Future for WaitForReadAll<'a, 'b, R> {
300    type Output = Result<(), ErrorKind>;
301
302    fn poll(
303        mut self: core::pin::Pin<&mut Self>,
304        cx: &mut core::task::Context<'_>,
305    ) -> core::task::Poll<Self::Output> {
306        self.waiter.register(cx.waker());
307        let begin = self.i;
308        for i in begin..self.buf.len() {
309            if self.rx.registers.can_get() {
310                match self.rx.registers.get() {
311                    Ok(b) => {
312                        self.buf[i] = b;
313                        self.i += 1;
314                    }
315                    Err(e) => {
316                        return Poll::Ready(Err(e));
317                    }
318                }
319            } else {
320                return Poll::Pending;
321            }
322        }
323        Poll::Ready(Ok(()))
324    }
325}