Skip to main content

embassy_rp/uart/
buffered.rs

1//! Buffered UART driver.
2use core::future::Future;
3use core::slice;
4use core::sync::atomic::{AtomicU8, Ordering};
5
6use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
7
8use super::*;
9
10pub struct State {
11    tx_waker: AtomicWaker,
12    tx_buf: RingBuffer,
13    rx_waker: AtomicWaker,
14    rx_buf: RingBuffer,
15    rx_error: AtomicU8,
16}
17
18// these must match bits 8..11 in UARTDR
19const RXE_OVERRUN: u8 = 8;
20const RXE_BREAK: u8 = 4;
21const RXE_PARITY: u8 = 2;
22const RXE_FRAMING: u8 = 1;
23
24impl State {
25    pub const fn new() -> Self {
26        Self {
27            rx_buf: RingBuffer::new(),
28            tx_buf: RingBuffer::new(),
29            rx_waker: AtomicWaker::new(),
30            tx_waker: AtomicWaker::new(),
31            rx_error: AtomicU8::new(0),
32        }
33    }
34}
35
36/// Buffered UART driver.
37pub struct BufferedUart {
38    pub(super) rx: BufferedUartRx,
39    pub(super) tx: BufferedUartTx,
40}
41
42/// Buffered UART RX handle.
43pub struct BufferedUartRx {
44    pub(super) info: &'static Info,
45    pub(super) state: &'static State,
46}
47
48/// Buffered UART TX handle.
49pub struct BufferedUartTx {
50    pub(super) info: &'static Info,
51    pub(super) state: &'static State,
52}
53
54pub(super) fn init_buffers<'d>(
55    info: &Info,
56    state: &State,
57    tx_buffer: Option<&'d mut [u8]>,
58    rx_buffer: Option<&'d mut [u8]>,
59) {
60    if let Some(tx_buffer) = tx_buffer {
61        let len = tx_buffer.len();
62        unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
63    }
64
65    if let Some(rx_buffer) = rx_buffer {
66        let len = rx_buffer.len();
67        unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
68    }
69
70    // From the datasheet:
71    // "The transmit interrupt is based on a transition through a level, rather
72    // than on the level itself. When the interrupt and the UART is enabled
73    // before any data is written to the transmit FIFO the interrupt is not set.
74    // The interrupt is only set, after written data leaves the single location
75    // of the transmit FIFO and it becomes empty."
76    //
77    // This means we can leave the interrupt enabled the whole time as long as
78    // we clear it after it happens. The downside is that the we manually have
79    // to pend the ISR when we want data transmission to start.
80    info.regs.uartimsc().write(|w| {
81        w.set_rxim(true);
82        w.set_rtim(true);
83        w.set_txim(true);
84    });
85
86    info.interrupt.unpend();
87    unsafe { info.interrupt.enable() };
88}
89
90impl BufferedUart {
91    /// Create a buffered UART instance.
92    pub fn new<'d, T: Instance>(
93        _uart: Peri<'d, T>,
94        tx: Peri<'d, impl TxPin<T>>,
95        rx: Peri<'d, impl RxPin<T>>,
96        _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
97        tx_buffer: &'d mut [u8],
98        rx_buffer: &'d mut [u8],
99        config: Config,
100    ) -> Self {
101        super::Uart::<'d, Async>::init(T::info(), Some(tx.into()), Some(rx.into()), None, None, config);
102        init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), Some(rx_buffer));
103
104        Self {
105            rx: BufferedUartRx {
106                info: T::info(),
107                state: T::buffered_state(),
108            },
109            tx: BufferedUartTx {
110                info: T::info(),
111                state: T::buffered_state(),
112            },
113        }
114    }
115
116    /// Create a buffered UART instance with flow control.
117    pub fn new_with_rtscts<'d, T: Instance>(
118        _uart: Peri<'d, T>,
119        tx: Peri<'d, impl TxPin<T>>,
120        rx: Peri<'d, impl RxPin<T>>,
121        rts: Peri<'d, impl RtsPin<T>>,
122        cts: Peri<'d, impl CtsPin<T>>,
123        _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
124        tx_buffer: &'d mut [u8],
125        rx_buffer: &'d mut [u8],
126        config: Config,
127    ) -> Self {
128        super::Uart::<'d, Async>::init(
129            T::info(),
130            Some(tx.into()),
131            Some(rx.into()),
132            Some(rts.into()),
133            Some(cts.into()),
134            config,
135        );
136        init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), Some(rx_buffer));
137
138        Self {
139            rx: BufferedUartRx {
140                info: T::info(),
141                state: T::buffered_state(),
142            },
143            tx: BufferedUartTx {
144                info: T::info(),
145                state: T::buffered_state(),
146            },
147        }
148    }
149
150    /// Write to UART TX buffer blocking execution until done.
151    pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<usize, Error> {
152        self.tx.blocking_write(buffer)
153    }
154
155    /// Flush UART TX blocking execution until done.
156    pub fn blocking_flush(&mut self) -> Result<(), Error> {
157        self.tx.blocking_flush()
158    }
159
160    /// Read from UART RX buffer blocking execution until done.
161    pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
162        self.rx.blocking_read(buffer)
163    }
164
165    /// Check if UART is busy transmitting.
166    pub fn busy(&self) -> bool {
167        self.tx.busy()
168    }
169
170    /// Wait until TX is empty and send break condition.
171    pub async fn send_break(&mut self, bits: u32) {
172        self.tx.send_break(bits).await
173    }
174
175    /// sets baudrate on runtime
176    pub fn set_baudrate<'d>(&mut self, baudrate: u32) {
177        super::Uart::<'d, Async>::set_baudrate_inner(self.rx.info, baudrate);
178    }
179
180    /// Split into separate RX and TX handles.
181    pub fn split(self) -> (BufferedUartTx, BufferedUartRx) {
182        (self.tx, self.rx)
183    }
184
185    /// Split the Uart into a transmitter and receiver by mutable reference,
186    /// which is particularly useful when having two tasks correlating to
187    /// transmitting and receiving.
188    pub fn split_ref(&mut self) -> (&mut BufferedUartTx, &mut BufferedUartRx) {
189        (&mut self.tx, &mut self.rx)
190    }
191}
192
193impl BufferedUartRx {
194    /// Create a new buffered UART RX.
195    pub fn new<'d, T: Instance>(
196        _uart: Peri<'d, T>,
197        _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
198        rx: Peri<'d, impl RxPin<T>>,
199        rx_buffer: &'d mut [u8],
200        config: Config,
201    ) -> Self {
202        super::Uart::<'d, Async>::init(T::info(), None, Some(rx.into()), None, None, config);
203        init_buffers(T::info(), T::buffered_state(), None, Some(rx_buffer));
204
205        Self {
206            info: T::info(),
207            state: T::buffered_state(),
208        }
209    }
210
211    /// Create a new buffered UART RX with flow control.
212    pub fn new_with_rts<'d, T: Instance>(
213        _uart: Peri<'d, T>,
214        _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
215        rx: Peri<'d, impl RxPin<T>>,
216        rts: Peri<'d, impl RtsPin<T>>,
217        rx_buffer: &'d mut [u8],
218        config: Config,
219    ) -> Self {
220        super::Uart::<'d, Async>::init(T::info(), None, Some(rx.into()), Some(rts.into()), None, config);
221        init_buffers(T::info(), T::buffered_state(), None, Some(rx_buffer));
222
223        Self {
224            info: T::info(),
225            state: T::buffered_state(),
226        }
227    }
228
229    fn read<'a>(
230        info: &'static Info,
231        state: &'static State,
232        buf: &'a mut [u8],
233    ) -> impl Future<Output = Result<usize, Error>> + 'a {
234        poll_fn(move |cx| {
235            if let Poll::Ready(r) = Self::try_read(info, state, buf) {
236                return Poll::Ready(r);
237            }
238            state.rx_waker.register(cx.waker());
239            Poll::Pending
240        })
241    }
242
243    fn get_rx_error(state: &State) -> Option<Error> {
244        let errs = critical_section::with(|_| {
245            let val = state.rx_error.load(Ordering::Relaxed);
246            state.rx_error.store(0, Ordering::Relaxed);
247            val
248        });
249        if errs & RXE_OVERRUN != 0 {
250            Some(Error::Overrun)
251        } else if errs & RXE_BREAK != 0 {
252            Some(Error::Break)
253        } else if errs & RXE_PARITY != 0 {
254            Some(Error::Parity)
255        } else if errs & RXE_FRAMING != 0 {
256            Some(Error::Framing)
257        } else {
258            None
259        }
260    }
261
262    fn try_read(info: &Info, state: &State, buf: &mut [u8]) -> Poll<Result<usize, Error>> {
263        if buf.is_empty() {
264            return Poll::Ready(Ok(0));
265        }
266
267        let mut rx_reader = unsafe { state.rx_buf.reader() };
268        let n = rx_reader.pop(|data| {
269            let n = data.len().min(buf.len());
270            buf[..n].copy_from_slice(&data[..n]);
271            n
272        });
273
274        let result = if n == 0 {
275            match Self::get_rx_error(state) {
276                None => return Poll::Pending,
277                Some(e) => Err(e),
278            }
279        } else {
280            Ok(n)
281        };
282
283        // (Re-)Enable the interrupt to receive more data in case it was
284        // disabled because the buffer was full or errors were detected.
285        info.regs.uartimsc().write_set(|w| {
286            w.set_rxim(true);
287            w.set_rtim(true);
288        });
289
290        Poll::Ready(result)
291    }
292
293    /// Read from UART RX buffer blocking execution until done.
294    pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
295        loop {
296            match Self::try_read(self.info, self.state, buf) {
297                Poll::Ready(res) => return res,
298                Poll::Pending => continue,
299            }
300        }
301    }
302
303    fn fill_buf<'a>(state: &'static State) -> impl Future<Output = Result<&'a [u8], Error>> {
304        poll_fn(move |cx| {
305            let mut rx_reader = unsafe { state.rx_buf.reader() };
306            let (p, n) = rx_reader.pop_buf();
307            let result = if n == 0 {
308                match Self::get_rx_error(state) {
309                    None => {
310                        state.rx_waker.register(cx.waker());
311                        return Poll::Pending;
312                    }
313                    Some(e) => Err(e),
314                }
315            } else {
316                let buf = unsafe { slice::from_raw_parts(p, n) };
317                Ok(buf)
318            };
319
320            Poll::Ready(result)
321        })
322    }
323
324    fn consume(info: &Info, state: &State, amt: usize) {
325        let mut rx_reader = unsafe { state.rx_buf.reader() };
326        rx_reader.pop_done(amt);
327
328        // (Re-)Enable the interrupt to receive more data in case it was
329        // disabled because the buffer was full or errors were detected.
330        info.regs.uartimsc().write_set(|w| {
331            w.set_rxim(true);
332            w.set_rtim(true);
333        });
334    }
335
336    /// we are ready to read if there is data in the buffer
337    fn read_ready(state: &State) -> Result<bool, Error> {
338        Ok(!state.rx_buf.is_empty())
339    }
340}
341
342impl BufferedUartTx {
343    /// Create a new buffered UART TX.
344    pub fn new<'d, T: Instance>(
345        _uart: Peri<'d, T>,
346        _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
347        tx: Peri<'d, impl TxPin<T>>,
348        tx_buffer: &'d mut [u8],
349        config: Config,
350    ) -> Self {
351        super::Uart::<'d, Async>::init(T::info(), Some(tx.into()), None, None, None, config);
352        init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), None);
353
354        Self {
355            info: T::info(),
356            state: T::buffered_state(),
357        }
358    }
359
360    /// Create a new buffered UART TX with flow control.
361    pub fn new_with_cts<'d, T: Instance>(
362        _uart: Peri<'d, T>,
363        _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
364        tx: Peri<'d, impl TxPin<T>>,
365        cts: Peri<'d, impl CtsPin<T>>,
366        tx_buffer: &'d mut [u8],
367        config: Config,
368    ) -> Self {
369        super::Uart::<'d, Async>::init(T::info(), Some(tx.into()), None, None, Some(cts.into()), config);
370        init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), None);
371
372        Self {
373            info: T::info(),
374            state: T::buffered_state(),
375        }
376    }
377
378    fn write<'d>(
379        info: &'static Info,
380        state: &'static State,
381        buf: &'d [u8],
382    ) -> impl Future<Output = Result<usize, Error>> + 'd {
383        poll_fn(move |cx| {
384            if buf.is_empty() {
385                return Poll::Ready(Ok(0));
386            }
387
388            let mut tx_writer = unsafe { state.tx_buf.writer() };
389            let n = tx_writer.push(|data| {
390                let n = data.len().min(buf.len());
391                data[..n].copy_from_slice(&buf[..n]);
392                n
393            });
394            if n == 0 {
395                state.tx_waker.register(cx.waker());
396                return Poll::Pending;
397            }
398
399            // The TX interrupt only triggers when the there was data in the
400            // FIFO and the number of bytes drops below a threshold. When the
401            // FIFO was empty we have to manually pend the interrupt to shovel
402            // TX data from the buffer into the FIFO.
403            info.interrupt.pend();
404            Poll::Ready(Ok(n))
405        })
406    }
407
408    fn flush(state: &'static State) -> impl Future<Output = Result<(), Error>> {
409        poll_fn(move |cx| {
410            if !state.tx_buf.is_empty() {
411                state.tx_waker.register(cx.waker());
412                return Poll::Pending;
413            }
414
415            Poll::Ready(Ok(()))
416        })
417    }
418
419    /// Write to UART TX buffer blocking execution until done.
420    pub fn blocking_write(&mut self, buf: &[u8]) -> Result<usize, Error> {
421        if buf.is_empty() {
422            return Ok(0);
423        }
424
425        loop {
426            let mut tx_writer = unsafe { self.state.tx_buf.writer() };
427            let n = tx_writer.push(|data| {
428                let n = data.len().min(buf.len());
429                data[..n].copy_from_slice(&buf[..n]);
430                n
431            });
432
433            if n != 0 {
434                // The TX interrupt only triggers when the there was data in the
435                // FIFO and the number of bytes drops below a threshold. When the
436                // FIFO was empty we have to manually pend the interrupt to shovel
437                // TX data from the buffer into the FIFO.
438                self.info.interrupt.pend();
439                return Ok(n);
440            }
441        }
442    }
443
444    /// Flush UART TX blocking execution until done.
445    pub fn blocking_flush(&mut self) -> Result<(), Error> {
446        loop {
447            if self.state.tx_buf.is_empty() {
448                return Ok(());
449            }
450        }
451    }
452
453    /// Check if UART is busy.
454    pub fn busy(&self) -> bool {
455        self.info.regs.uartfr().read().busy()
456    }
457
458    /// Assert a break condition after waiting for the transmit buffers to empty,
459    /// for the specified number of bit times. This condition must be asserted
460    /// for at least two frame times to be effective, `bits` will adjusted
461    /// according to frame size, parity, and stop bit settings to ensure this.
462    ///
463    /// This method may block for a long amount of time since it has to wait
464    /// for the transmit fifo to empty, which may take a while on slow links.
465    pub async fn send_break(&mut self, bits: u32) {
466        let regs = self.info.regs;
467        let bits = bits.max({
468            let lcr = regs.uartlcr_h().read();
469            let width = lcr.wlen() as u32 + 5;
470            let parity = lcr.pen() as u32;
471            let stops = 1 + lcr.stp2() as u32;
472            2 * (1 + width + parity + stops)
473        });
474        let divx64 = (((regs.uartibrd().read().baud_divint() as u32) << 6)
475            + regs.uartfbrd().read().baud_divfrac() as u32) as u64;
476        let div_clk = clk_peri_freq() as u64 * 64;
477        let wait_usecs = (1_000_000 * bits as u64 * divx64 * 16 + div_clk - 1) / div_clk;
478
479        Self::flush(self.state).await.unwrap();
480        while self.busy() {}
481        regs.uartlcr_h().write_set(|w| w.set_brk(true));
482        Timer::after_micros(wait_usecs).await;
483        regs.uartlcr_h().write_clear(|w| w.set_brk(true));
484    }
485}
486
487impl Drop for BufferedUartRx {
488    fn drop(&mut self) {
489        unsafe { self.state.rx_buf.deinit() }
490
491        // TX is inactive if the buffer is not available.
492        // We can now unregister the interrupt handler
493        if !self.state.tx_buf.is_available() {
494            self.info.interrupt.disable();
495        }
496    }
497}
498
499impl Drop for BufferedUartTx {
500    fn drop(&mut self) {
501        unsafe { self.state.tx_buf.deinit() }
502
503        // RX is inactive if the buffer is not available.
504        // We can now unregister the interrupt handler
505        if !self.state.rx_buf.is_available() {
506            self.info.interrupt.disable();
507        }
508    }
509}
510
511/// Interrupt handler.
512pub struct BufferedInterruptHandler<T: Instance> {
513    _uart: PhantomData<T>,
514}
515
516impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for BufferedInterruptHandler<T> {
517    unsafe fn on_interrupt() {
518        let r = T::info().regs;
519        if r.uartdmacr().read().rxdmae() {
520            return;
521        }
522
523        let s = T::buffered_state();
524
525        // Clear TX and error interrupt flags
526        // RX interrupt flags are cleared by reading from the FIFO.
527        let ris = r.uartris().read();
528        r.uarticr().write(|w| {
529            w.set_txic(ris.txris());
530            w.set_feic(ris.feris());
531            w.set_peic(ris.peris());
532            w.set_beic(ris.beris());
533            w.set_oeic(ris.oeris());
534        });
535
536        // Errors
537        if ris.feris() {
538            warn!("Framing error");
539        }
540        if ris.peris() {
541            warn!("Parity error");
542        }
543        if ris.beris() {
544            warn!("Break error");
545        }
546        if ris.oeris() {
547            warn!("Overrun error");
548        }
549
550        // RX
551        if s.rx_buf.is_available() {
552            let mut rx_writer = unsafe { s.rx_buf.writer() };
553            let rx_buf = rx_writer.push_slice();
554            let mut n_read = 0;
555            let mut error = false;
556            for rx_byte in rx_buf {
557                if r.uartfr().read().rxfe() {
558                    break;
559                }
560                let dr = r.uartdr().read();
561                if (dr.0 >> 8) != 0 {
562                    critical_section::with(|_| {
563                        let val = s.rx_error.load(Ordering::Relaxed);
564                        s.rx_error.store(val | ((dr.0 >> 8) as u8), Ordering::Relaxed);
565                    });
566                    error = true;
567                    // only fill the buffer with valid characters. the current character is fine
568                    // if the error is an overrun, but if we add it to the buffer we'll report
569                    // the overrun one character too late. drop it instead and pretend we were
570                    // a bit slower at draining the rx fifo than we actually were.
571                    // this is consistent with blocking uart error reporting.
572                    break;
573                }
574                *rx_byte = dr.data();
575                n_read += 1;
576            }
577            if n_read > 0 {
578                rx_writer.push_done(n_read);
579                s.rx_waker.wake();
580            } else if error {
581                s.rx_waker.wake();
582            }
583            // Disable any further RX interrupts when the buffer becomes full or
584            // errors have occurred. This lets us buffer additional errors in the
585            // fifo without needing more error storage locations, and most applications
586            // will want to do a full reset of their uart state anyway once an error
587            // has happened.
588            if s.rx_buf.is_full() || error {
589                r.uartimsc().write_clear(|w| {
590                    w.set_rxim(true);
591                    w.set_rtim(true);
592                });
593            }
594        }
595
596        // TX
597        if s.tx_buf.is_available() {
598            let mut tx_reader = unsafe { s.tx_buf.reader() };
599            let tx_buf = tx_reader.pop_slice();
600            let mut n_written = 0;
601            for tx_byte in tx_buf.iter_mut() {
602                if r.uartfr().read().txff() {
603                    break;
604                }
605                r.uartdr().write(|w| w.set_data(*tx_byte));
606                n_written += 1;
607            }
608            if n_written > 0 {
609                tx_reader.pop_done(n_written);
610                s.tx_waker.wake();
611            }
612            // The TX interrupt only triggers once when the FIFO threshold is
613            // crossed. No need to disable it when the buffer becomes empty
614            // as it does re-trigger anymore once we have cleared it.
615        }
616    }
617}
618
619impl embedded_io::Error for Error {
620    fn kind(&self) -> embedded_io::ErrorKind {
621        embedded_io::ErrorKind::Other
622    }
623}
624
625impl embedded_io_async::ErrorType for BufferedUart {
626    type Error = Error;
627}
628
629impl embedded_io_async::ErrorType for BufferedUartRx {
630    type Error = Error;
631}
632
633impl embedded_io_async::ErrorType for BufferedUartTx {
634    type Error = Error;
635}
636
637impl embedded_io_async::Read for BufferedUart {
638    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
639        BufferedUartRx::read(self.rx.info, self.rx.state, buf).await
640    }
641}
642
643impl embedded_io_async::Read for BufferedUartRx {
644    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
645        Self::read(self.info, self.state, buf).await
646    }
647}
648
649impl embedded_io_async::ReadReady for BufferedUart {
650    fn read_ready(&mut self) -> Result<bool, Self::Error> {
651        BufferedUartRx::read_ready(self.rx.state)
652    }
653}
654
655impl embedded_io_async::ReadReady for BufferedUartRx {
656    fn read_ready(&mut self) -> Result<bool, Self::Error> {
657        Self::read_ready(self.state)
658    }
659}
660
661impl embedded_io_async::BufRead for BufferedUart {
662    async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
663        BufferedUartRx::fill_buf(self.rx.state).await
664    }
665
666    fn consume(&mut self, amt: usize) {
667        BufferedUartRx::consume(self.rx.info, self.rx.state, amt)
668    }
669}
670
671impl embedded_io_async::BufRead for BufferedUartRx {
672    async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
673        Self::fill_buf(self.state).await
674    }
675
676    fn consume(&mut self, amt: usize) {
677        Self::consume(self.info, self.state, amt)
678    }
679}
680
681impl embedded_io_async::Write for BufferedUart {
682    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
683        BufferedUartTx::write(self.tx.info, self.tx.state, buf).await
684    }
685
686    async fn flush(&mut self) -> Result<(), Self::Error> {
687        BufferedUartTx::flush(self.tx.state).await
688    }
689}
690
691impl embedded_io_async::Write for BufferedUartTx {
692    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
693        Self::write(self.info, self.state, buf).await
694    }
695
696    async fn flush(&mut self) -> Result<(), Self::Error> {
697        Self::flush(self.state).await
698    }
699}
700
701impl embedded_io::Read for BufferedUart {
702    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
703        self.rx.blocking_read(buf)
704    }
705}
706
707impl embedded_io::Read for BufferedUartRx {
708    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
709        self.blocking_read(buf)
710    }
711}
712
713impl embedded_io::Write for BufferedUart {
714    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
715        self.tx.blocking_write(buf)
716    }
717
718    fn flush(&mut self) -> Result<(), Self::Error> {
719        self.tx.blocking_flush()
720    }
721}
722
723impl embedded_io::Write for BufferedUartTx {
724    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
725        self.blocking_write(buf)
726    }
727
728    fn flush(&mut self) -> Result<(), Self::Error> {
729        self.blocking_flush()
730    }
731}
732
733impl embedded_hal_02::serial::Read<u8> for BufferedUartRx {
734    type Error = Error;
735
736    fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
737        let r = self.info.regs;
738        if r.uartfr().read().rxfe() {
739            return Err(nb::Error::WouldBlock);
740        }
741
742        let dr = r.uartdr().read();
743
744        if dr.oe() {
745            Err(nb::Error::Other(Error::Overrun))
746        } else if dr.be() {
747            Err(nb::Error::Other(Error::Break))
748        } else if dr.pe() {
749            Err(nb::Error::Other(Error::Parity))
750        } else if dr.fe() {
751            Err(nb::Error::Other(Error::Framing))
752        } else {
753            Ok(dr.data())
754        }
755    }
756}
757
758impl embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx {
759    type Error = Error;
760
761    fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
762        while !buffer.is_empty() {
763            match self.blocking_write(buffer) {
764                Ok(0) => panic!("zero-length write."),
765                Ok(n) => buffer = &buffer[n..],
766                Err(e) => return Err(e),
767            }
768        }
769        Ok(())
770    }
771
772    fn bflush(&mut self) -> Result<(), Self::Error> {
773        self.blocking_flush()
774    }
775}
776
777impl embedded_hal_02::serial::Read<u8> for BufferedUart {
778    type Error = Error;
779
780    fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
781        embedded_hal_02::serial::Read::read(&mut self.rx)
782    }
783}
784
785impl embedded_hal_02::blocking::serial::Write<u8> for BufferedUart {
786    type Error = Error;
787
788    fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
789        while !buffer.is_empty() {
790            match self.blocking_write(buffer) {
791                Ok(0) => panic!("zero-length write."),
792                Ok(n) => buffer = &buffer[n..],
793                Err(e) => return Err(e),
794            }
795        }
796        Ok(())
797    }
798
799    fn bflush(&mut self) -> Result<(), Self::Error> {
800        self.blocking_flush()
801    }
802}
803
804impl embedded_hal_nb::serial::ErrorType for BufferedUartRx {
805    type Error = Error;
806}
807
808impl embedded_hal_nb::serial::ErrorType for BufferedUartTx {
809    type Error = Error;
810}
811
812impl embedded_hal_nb::serial::ErrorType for BufferedUart {
813    type Error = Error;
814}
815
816impl embedded_hal_nb::serial::Read for BufferedUartRx {
817    fn read(&mut self) -> nb::Result<u8, Self::Error> {
818        embedded_hal_02::serial::Read::read(self)
819    }
820}
821
822impl embedded_hal_nb::serial::Write for BufferedUartTx {
823    fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
824        self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
825    }
826
827    fn flush(&mut self) -> nb::Result<(), Self::Error> {
828        self.blocking_flush().map_err(nb::Error::Other)
829    }
830}
831
832impl embedded_hal_nb::serial::Read for BufferedUart {
833    fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
834        embedded_hal_02::serial::Read::read(&mut self.rx)
835    }
836}
837
838impl embedded_hal_nb::serial::Write for BufferedUart {
839    fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
840        self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
841    }
842
843    fn flush(&mut self) -> nb::Result<(), Self::Error> {
844        self.blocking_flush().map_err(nb::Error::Other)
845    }
846}