sifli_hal/usart/
buffered.rs

1// The following code is modified from embassy-stm32 under MIT license
2// https://github.com/embassy-rs/embassy/tree/main/embassy-stm32
3// Special thanks to the Embassy Project and its contributors for their work!
4
5use core::future::poll_fn;
6use core::marker::PhantomData;
7use core::slice;
8use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
9use core::task::Poll;
10
11use embassy_embedded_hal::SetConfig;
12use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
13use embassy_hal_internal::{Peripheral, PeripheralRef};
14use embassy_sync::waitqueue::AtomicWaker;
15
16use super::{
17    clear_interrupt_flags, configure, half_duplex_set_rx_tx_before_write, reconfigure, send_break, set_baudrate,
18    Config, ConfigError, CtsPin, Duplex, Error, HalfDuplexConfig, HalfDuplexReadback, Instance, Regs,
19    RtsPin, RxdPin, TxdPin,
20};
21
22use crate::gpio::{AfType, AnyPin, Pull, SealedPin as _};
23use crate::interrupt::{self, InterruptExt, typelevel::Interrupt as _};
24use crate::rcc;
25use crate::time::Hertz;
26use crate::pac::usart::regs;
27
28/// Interrupt handler.
29pub struct InterruptHandler<T: Instance> {
30    _phantom: PhantomData<T>,
31}
32
33impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
34    unsafe fn on_interrupt() {
35        on_interrupt(T::regs(), T::buffered_state())
36    }
37}
38
39unsafe fn on_interrupt(r: Regs, state: &'static State) {
40    // RX
41    let sr_val = r.isr().read();
42    // On v1 & v2 (stm32):
43    // reading DR clears the rxne, error and idle interrupt
44    // flags. Keep this close to the SR read to reduce the chance of a
45    // flag being set in-between.
46    // TODO Marked
47    let dr = if sr_val.rxne() || (sr_val.ore() || sr_val.idle()) {
48        Some(r.rdr().as_ptr().read_volatile().0 as u8)
49    } else {
50        None
51    };
52    clear_interrupt_flags(r, sr_val);
53
54    if sr_val.pe() {
55        warn!("Parity error");
56    }
57    if sr_val.fe() {
58        warn!("Framing error");
59    }
60    if sr_val.ore() {
61        warn!("Overrun error");
62    }
63    if sr_val.rxne() {
64        let mut rx_writer = state.rx_buf.writer();
65        let buf = rx_writer.push_slice();
66        if !buf.is_empty() {
67            if let Some(byte) = dr {
68                buf[0] = byte;
69                rx_writer.push_done(1);
70            }
71        } else {
72            // FIXME: Should we disable any further RX interrupts when the buffer becomes full.
73        }
74
75        if !state.rx_buf.is_empty() {
76            state.rx_waker.wake();
77        }
78    }
79
80    if sr_val.idle() {
81        state.rx_waker.wake();
82    }
83
84    // With `usart_v4` hardware FIFO is enabled and Transmission complete (TC)
85    // indicates that all bytes are pushed out from the FIFO.
86    // For other usart variants it shows that last byte from the buffer was just sent.
87    if sr_val.tc() {
88        // For others it is cleared above with `clear_interrupt_flags`.
89        // TODO Marked
90        r.isr().modify(|w| w.set_tc(false));
91
92        r.cr1().modify(|w| {
93            w.set_tcie(false);
94        });
95
96        state.tx_done.store(true, Ordering::Release);
97        state.tx_waker.wake();
98    }
99
100    // TX
101    if r.isr().read().txe() {
102        let mut tx_reader = state.tx_buf.reader();
103        let buf = tx_reader.pop_slice();
104        if !buf.is_empty() {
105            r.cr1().modify(|w| {
106                w.set_txeie(true);
107            });
108
109            // Enable transmission complete interrupt when last byte is going to be sent out.
110            if buf.len() == 1 {
111                r.cr1().modify(|w| {
112                    w.set_tcie(true);
113                });
114            }
115
116            half_duplex_set_rx_tx_before_write(&r, state.half_duplex_readback.load(Ordering::Relaxed));
117
118            r.tdr().as_ptr().write_volatile(regs::Tdr(buf[0].into()));
119            tx_reader.pop_done(1);
120        } else {
121            // Disable interrupt until we have something to transmit again.
122            r.cr1().modify(|w| {
123                w.set_txeie(false);
124            });
125        }
126    }
127}
128
129pub(super) struct State {
130    rx_waker: AtomicWaker,
131    rx_buf: RingBuffer,
132    tx_waker: AtomicWaker,
133    tx_buf: RingBuffer,
134    tx_done: AtomicBool,
135    tx_rx_refcount: AtomicU8,
136    half_duplex_readback: AtomicBool,
137}
138
139impl State {
140    pub(super) const fn new() -> Self {
141        Self {
142            rx_buf: RingBuffer::new(),
143            tx_buf: RingBuffer::new(),
144            rx_waker: AtomicWaker::new(),
145            tx_waker: AtomicWaker::new(),
146            tx_done: AtomicBool::new(true),
147            tx_rx_refcount: AtomicU8::new(0),
148            half_duplex_readback: AtomicBool::new(false),
149        }
150    }
151}
152
153/// Bidirectional buffered UART
154pub struct BufferedUart<'d, T: Instance> {
155    rx: BufferedUartRx<'d, T>,
156    tx: BufferedUartTx<'d, T>,
157}
158
159/// Tx-only buffered UART
160///
161/// Created with [BufferedUart::split]
162pub struct BufferedUartTx<'d, T: Instance> {
163    state: &'static State,
164    kernel_clock: Hertz,
165    tx: Option<PeripheralRef<'d, AnyPin>>,
166    cts: Option<PeripheralRef<'d, AnyPin>>,
167    is_borrowed: bool,
168    _phantom: PhantomData<T>,
169}
170
171/// Rx-only buffered UART
172///
173/// Created with [BufferedUart::split]
174pub struct BufferedUartRx<'d, T: Instance> {
175    state: &'static State,
176    kernel_clock: Hertz,
177    rx: Option<PeripheralRef<'d, AnyPin>>,
178    rts: Option<PeripheralRef<'d, AnyPin>>,
179    is_borrowed: bool,
180    _phantom: PhantomData<T>,
181}
182
183impl<'d, T: Instance> SetConfig for BufferedUart<'d, T> {
184    type Config = Config;
185    type ConfigError = ConfigError;
186
187    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
188        self.set_config(config)
189    }
190}
191
192impl<'d, T: Instance> SetConfig for BufferedUartRx<'d, T> {
193    type Config = Config;
194    type ConfigError = ConfigError;
195
196    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
197        self.set_config(config)
198    }
199}
200
201impl<'d, T: Instance> SetConfig for BufferedUartTx<'d, T> {
202    type Config = Config;
203    type ConfigError = ConfigError;
204
205    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
206        self.set_config(config)
207    }
208}
209
210impl<'d, T: Instance> BufferedUart<'d, T> {
211    /// Create a new bidirectional buffered UART driver
212    pub fn new(
213        peri: impl Peripheral<P = T> + 'd,
214        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
215        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
216        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
217        tx_buffer: &'d mut [u8],
218        rx_buffer: &'d mut [u8],
219        config: Config,
220    ) -> Result<Self, ConfigError> {
221        Self::new_inner(
222            peri,
223            new_pin!(rx, AfType::new(config.rx_pull)),
224            new_pin!(tx, AfType::new(Pull::Up)),
225            None,
226            None,
227            tx_buffer,
228            rx_buffer,
229            config,
230        )
231    }
232
233    /// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins
234    pub fn new_with_rtscts(
235        peri: impl Peripheral<P = T> + 'd,
236        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
237        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
238        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
239        rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
240        cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
241        tx_buffer: &'d mut [u8],
242        rx_buffer: &'d mut [u8],
243        config: Config,
244    ) -> Result<Self, ConfigError> {
245        Self::new_inner(
246            peri,
247            // TODO: verify these pull is correct
248            new_pin!(rx, AfType::new(Pull::None)),
249            new_pin!(tx, AfType::new(Pull::Up)),
250            new_pin!(rts, AfType::new(Pull::Up)),
251            new_pin!(cts, AfType::new(Pull::None)),
252            tx_buffer,
253            rx_buffer,
254            config,
255        )
256    }
257
258    /// Create a new bidirectional buffered UART driver with only the request-to-send pin
259    pub fn new_with_rts(
260        peri: impl Peripheral<P = T> + 'd,
261        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
262        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
263        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
264        rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
265        tx_buffer: &'d mut [u8],
266        rx_buffer: &'d mut [u8],
267        config: Config,
268    ) -> Result<Self, ConfigError> {
269        Self::new_inner(
270            peri,
271            new_pin!(rx, AfType::new(Pull::None)),
272            new_pin!(tx, AfType::new(Pull::Up)),
273            new_pin!(rts, AfType::new(Pull::None)),
274            None, // no CTS
275            tx_buffer,
276            rx_buffer,
277            config,
278        )
279    }
280
281    /// Create a single-wire half-duplex Uart transceiver on a single Tx pin.
282    ///
283    /// See [`new_half_duplex_on_rx`][`Self::new_half_duplex_on_rx`] if you would prefer to use an Rx pin
284    /// (when it is available for your chip). There is no functional difference between these methods, as both
285    /// allow bidirectional communication.
286    ///
287    /// The TX pin is always released when no data is transmitted. Thus, it acts as a standard
288    /// I/O in idle or in reception. It means that the I/O must be configured so that TX is
289    /// configured as alternate function open-drain with an external pull-up
290    /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
291    /// on the line must be managed by software (for instance by using a centralized arbiter).
292    #[doc(alias("HDSEL"))]
293    pub fn new_half_duplex(
294        peri: impl Peripheral<P = T> + 'd,
295        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
296        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
297        tx_buffer: &'d mut [u8],
298        rx_buffer: &'d mut [u8],
299        mut config: Config,
300        readback: HalfDuplexReadback,
301        half_duplex: HalfDuplexConfig,
302    ) -> Result<Self, ConfigError> {
303        config.duplex = Duplex::Half(readback);
304
305        Self::new_inner(
306            peri,
307            None,
308            new_pin!(tx, half_duplex.af_type()),
309            None,
310            None,
311            tx_buffer,
312            rx_buffer,
313            config,
314        )
315    }
316
317    /// Create a single-wire half-duplex Uart transceiver on a single Rx pin.
318    ///
319    /// See [`new_half_duplex`][`Self::new_half_duplex`] if you would prefer to use an Tx pin.
320    /// There is no functional difference between these methods, as both allow bidirectional communication.
321    ///
322    /// The pin is always released when no data is transmitted. Thus, it acts as a standard
323    /// I/O in idle or in reception.
324    /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
325    /// on the line must be managed by software (for instance by using a centralized arbiter).
326    #[doc(alias("HDSEL"))]
327    pub fn new_half_duplex_on_rx(
328        peri: impl Peripheral<P = T> + 'd,
329        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
330        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
331        tx_buffer: &'d mut [u8],
332        rx_buffer: &'d mut [u8],
333        mut config: Config,
334        readback: HalfDuplexReadback,
335        half_duplex: HalfDuplexConfig,
336    ) -> Result<Self, ConfigError> {
337        config.duplex = Duplex::Half(readback);
338
339        Self::new_inner(
340            peri,
341            new_pin!(rx, half_duplex.af_type()),
342            None,
343            None,
344            None,
345            tx_buffer,
346            rx_buffer,
347            config,
348        )
349    }
350
351    fn new_inner(
352        _peri: impl Peripheral<P = T> + 'd,
353        rx: Option<PeripheralRef<'d, AnyPin>>,
354        tx: Option<PeripheralRef<'d, AnyPin>>,
355        rts: Option<PeripheralRef<'d, AnyPin>>,
356        cts: Option<PeripheralRef<'d, AnyPin>>,
357        tx_buffer: &'d mut [u8],
358        rx_buffer: &'d mut [u8],
359        config: Config,
360    ) -> Result<Self, ConfigError> {
361        let state = T::buffered_state();
362        let kernel_clock = T::frequency().unwrap();
363
364        state.half_duplex_readback.store(
365            config.duplex == Duplex::Half(HalfDuplexReadback::Readback),
366            Ordering::Relaxed,
367        );
368
369        let mut this = Self {
370            rx: BufferedUartRx {
371                state,
372                kernel_clock,
373                rx,
374                rts,
375                is_borrowed: false,
376                _phantom: PhantomData,
377            },
378            tx: BufferedUartTx {
379                state,
380                kernel_clock,
381                tx,
382                cts,
383                is_borrowed: false,
384                _phantom: PhantomData,
385            },
386        };
387        this.enable_and_configure(tx_buffer, rx_buffer, &config)?;
388        Ok(this)
389    }
390
391    fn enable_and_configure(
392        &mut self,
393        tx_buffer: &'d mut [u8],
394        rx_buffer: &'d mut [u8],
395        config: &Config,
396    ) -> Result<(), ConfigError> {
397        let state = self.rx.state;
398        state.tx_rx_refcount.store(2, Ordering::Relaxed);
399
400        rcc::enable_and_reset::<T>();
401
402        let len = tx_buffer.len();
403        unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
404        let len = rx_buffer.len();
405        unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
406
407        T::regs().cr3().write(|w| {
408            w.set_rtse(self.rx.rts.is_some());
409            w.set_ctse(self.tx.cts.is_some());
410            w.set_hdsel(config.duplex.is_half());
411        });
412        configure::<T>(self.rx.kernel_clock, &config, true, true)?;
413
414        T::regs().cr1().modify(|w| {
415            w.set_rxneie(true);
416            w.set_idleie(true);
417
418            if config.duplex.is_half() {
419                // The te and re bits will be set by write, read and flush methods.
420                // Receiver should be enabled by default for Half-Duplex.
421                w.set_te(false);
422                w.set_re(true);
423            }
424        });
425
426        T::Interrupt::unpend();
427        unsafe { T::Interrupt::enable() };
428
429        Ok(())
430    }
431
432    /// Split the driver into a Tx and Rx part (useful for sending to separate tasks)
433    pub fn split(self) -> (BufferedUartTx<'d, T>, BufferedUartRx<'d, T>) {
434        (self.tx, self.rx)
435    }
436
437    /// Split the Uart into a transmitter and receiver,
438    /// which is particularly useful when having two tasks correlating to
439    /// transmitting and receiving.
440    pub fn split_ref(&mut self) -> (BufferedUartTx<'_, T>, BufferedUartRx<'_, T>) {
441        (
442            BufferedUartTx {
443                state: self.tx.state,
444                kernel_clock: self.tx.kernel_clock,
445                tx: self.tx.tx.as_mut().map(PeripheralRef::reborrow),
446                cts: self.tx.cts.as_mut().map(PeripheralRef::reborrow),
447                is_borrowed: true,
448                _phantom: PhantomData,
449            },
450            BufferedUartRx {
451                state: self.rx.state,
452                kernel_clock: self.rx.kernel_clock,
453                rx: self.rx.rx.as_mut().map(PeripheralRef::reborrow),
454                rts: self.rx.rts.as_mut().map(PeripheralRef::reborrow),
455                is_borrowed: true,
456                _phantom: PhantomData,
457            },
458        )
459    }
460
461    /// Reconfigure the driver
462    pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
463        reconfigure::<T>(self.rx.kernel_clock, config)?;
464
465        T::regs().cr1().modify(|w| {
466            w.set_rxneie(true);
467            w.set_idleie(true);
468        });
469
470        Ok(())
471    }
472
473    /// Send break character
474    pub fn send_break(&self) {
475        self.tx.send_break()
476    }
477
478    /// Set baudrate
479    pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError> {
480        self.tx.set_baudrate(baudrate)?;
481        self.rx.set_baudrate(baudrate)?;
482        Ok(())
483    }
484}
485
486impl<'d, T: Instance> BufferedUartRx<'d, T> {
487    async fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
488        poll_fn(move |cx| {
489            let state = self.state;
490            let mut rx_reader = unsafe { state.rx_buf.reader() };
491            let data = rx_reader.pop_slice();
492
493            if !data.is_empty() {
494                let len = data.len().min(buf.len());
495                buf[..len].copy_from_slice(&data[..len]);
496
497                let do_pend = state.rx_buf.is_full();
498                rx_reader.pop_done(len);
499
500                if do_pend {
501                    T::interrupt().pend();
502                }
503
504                return Poll::Ready(Ok(len));
505            }
506
507            state.rx_waker.register(cx.waker());
508            Poll::Pending
509        })
510        .await
511    }
512
513    fn blocking_read(&self, buf: &mut [u8]) -> Result<usize, Error> {
514        loop {
515            let state = self.state;
516            let mut rx_reader = unsafe { state.rx_buf.reader() };
517            let data = rx_reader.pop_slice();
518
519            if !data.is_empty() {
520                let len = data.len().min(buf.len());
521                buf[..len].copy_from_slice(&data[..len]);
522
523                let do_pend = state.rx_buf.is_full();
524                rx_reader.pop_done(len);
525
526                if do_pend {
527                    T::interrupt().pend();
528                }
529
530                return Ok(len);
531            }
532        }
533    }
534
535    async fn fill_buf(&self) -> Result<&[u8], Error> {
536        poll_fn(move |cx| {
537            let state = self.state;
538            let mut rx_reader = unsafe { state.rx_buf.reader() };
539            let (p, n) = rx_reader.pop_buf();
540            if n == 0 {
541                state.rx_waker.register(cx.waker());
542                return Poll::Pending;
543            }
544
545            let buf = unsafe { slice::from_raw_parts(p, n) };
546            Poll::Ready(Ok(buf))
547        })
548        .await
549    }
550
551    fn consume(&self, amt: usize) {
552        let state = self.state;
553        let mut rx_reader = unsafe { state.rx_buf.reader() };
554        let full = state.rx_buf.is_full();
555        rx_reader.pop_done(amt);
556        if full {
557            T::interrupt().pend();
558        }
559    }
560
561    /// we are ready to read if there is data in the buffer
562    fn read_ready(&mut self) -> Result<bool, Error> {
563        let state = self.state;
564        Ok(!state.rx_buf.is_empty())
565    }
566
567    /// Reconfigure the driver
568    pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
569        reconfigure::<T>(self.kernel_clock, config)?;
570
571        T::regs().cr1().modify(|w| {
572            w.set_rxneie(true);
573            w.set_idleie(true);
574        });
575
576        Ok(())
577    }
578
579    /// Set baudrate
580    pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError> {
581        set_baudrate::<T>(self.kernel_clock, baudrate)
582    }
583}
584
585impl<'d, T: Instance> BufferedUartTx<'d, T> {
586    async fn write(&self, buf: &[u8]) -> Result<usize, Error> {
587        poll_fn(move |cx| {
588            let state = self.state;
589            state.tx_done.store(false, Ordering::Release);
590
591            let empty = state.tx_buf.is_empty();
592
593            let mut tx_writer = unsafe { state.tx_buf.writer() };
594            let data = tx_writer.push_slice();
595            if data.is_empty() {
596                state.tx_waker.register(cx.waker());
597                return Poll::Pending;
598            }
599
600            let n = data.len().min(buf.len());
601            data[..n].copy_from_slice(&buf[..n]);
602            tx_writer.push_done(n);
603
604            if empty {
605                T::Interrupt::pend();
606            }
607
608            Poll::Ready(Ok(n))
609        })
610        .await
611    }
612
613    async fn flush(&self) -> Result<(), Error> {
614        poll_fn(move |cx| {
615            let state = self.state;
616
617            if !state.tx_done.load(Ordering::Acquire) {
618                state.tx_waker.register(cx.waker());
619                return Poll::Pending;
620            }
621
622            Poll::Ready(Ok(()))
623        })
624        .await
625    }
626
627    fn blocking_write(&self, buf: &[u8]) -> Result<usize, Error> {
628        loop {
629            let state = self.state;
630            let empty = state.tx_buf.is_empty();
631
632            let mut tx_writer = unsafe { state.tx_buf.writer() };
633            let data = tx_writer.push_slice();
634            if !data.is_empty() {
635                let n = data.len().min(buf.len());
636                data[..n].copy_from_slice(&buf[..n]);
637                tx_writer.push_done(n);
638
639                if empty {
640                    T::Interrupt::pend();
641                }
642
643                return Ok(n);
644            }
645        }
646    }
647
648    fn blocking_flush(&self) -> Result<(), Error> {
649        loop {
650            let state = self.state;
651            if state.tx_buf.is_empty() {
652                return Ok(());
653            }
654        }
655    }
656
657    /// Reconfigure the driver
658    pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
659        reconfigure::<T>(self.kernel_clock, config)?;
660
661        T::regs().cr1().modify(|w| {
662            w.set_rxneie(true);
663            w.set_idleie(true);
664        });
665
666        Ok(())
667    }
668
669    /// Send break character
670    pub fn send_break(&self) {
671        send_break(&T::regs());
672    }
673
674    /// Set baudrate
675    pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError> {
676        set_baudrate::<T>(self.kernel_clock, baudrate)
677    }
678}
679
680impl<'d, T: Instance> Drop for BufferedUartRx<'d, T> {
681    fn drop(&mut self) {
682        if !self.is_borrowed {
683            let state = self.state;
684            unsafe {
685                state.rx_buf.deinit();
686
687                // TX is inactive if the buffer is not available.
688                // We can now unregister the interrupt handler
689                if state.tx_buf.len() == 0 {
690                    T::Interrupt::disable();
691                }
692            }
693
694            self.rx.as_ref().map(|x| x.set_as_disconnected());
695            self.rts.as_ref().map(|x| x.set_as_disconnected());
696            drop_tx_rx::<T>(state);
697        }
698    }
699}
700
701impl<'d, T: Instance> Drop for BufferedUartTx<'d, T> {
702    fn drop(&mut self) {
703        if !self.is_borrowed {
704            let state = self.state;
705            unsafe {
706                state.tx_buf.deinit();
707
708                // RX is inactive if the buffer is not available.
709                // We can now unregister the interrupt handler
710                if state.rx_buf.len() == 0 {
711                    T::Interrupt::disable();
712                }
713            }
714
715            self.tx.as_ref().map(|x| x.set_as_disconnected());
716            self.cts.as_ref().map(|x| x.set_as_disconnected());
717            drop_tx_rx::<T>(state);
718        }
719    }
720}
721
722fn drop_tx_rx<T: Instance>(state: &State) {
723    // We cannot use atomic subtraction here, because it's not supported for all targets
724    let is_last_drop = critical_section::with(|_| {
725        let refcount = state.tx_rx_refcount.load(Ordering::Relaxed);
726        assert!(refcount >= 1);
727        state.tx_rx_refcount.store(refcount - 1, Ordering::Relaxed);
728        refcount == 1
729    });
730    if is_last_drop {
731        rcc::disable::<T>();
732    }
733}
734
735impl<'d, T: Instance> embedded_io_async::ErrorType for BufferedUart<'d, T> {
736    type Error = Error;
737}
738
739impl<'d, T: Instance> embedded_io_async::ErrorType for BufferedUartRx<'d, T> {
740    type Error = Error;
741}
742
743impl<'d, T: Instance> embedded_io_async::ErrorType for BufferedUartTx<'d, T> {
744    type Error = Error;
745}
746
747impl<'d, T: Instance> embedded_io_async::Read for BufferedUart<'d, T> {
748    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
749        self.rx.read(buf).await
750    }
751}
752
753impl<'d, T: Instance> embedded_io_async::Read for BufferedUartRx<'d, T> {
754    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
755        Self::read(self, buf).await
756    }
757}
758
759impl<'d, T: Instance> embedded_io_async::ReadReady for BufferedUart<'d, T> {
760    fn read_ready(&mut self) -> Result<bool, Self::Error> {
761        BufferedUartRx::<'d, T>::read_ready(&mut self.rx)
762    }
763}
764
765impl<'d, T: Instance> embedded_io_async::ReadReady for BufferedUartRx<'d, T> {
766    fn read_ready(&mut self) -> Result<bool, Self::Error> {
767        Self::read_ready(self)
768    }
769}
770
771impl<'d, T: Instance> embedded_io_async::BufRead for BufferedUart<'d, T> {
772    async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
773        self.rx.fill_buf().await
774    }
775
776    fn consume(&mut self, amt: usize) {
777        self.rx.consume(amt)
778    }
779}
780
781impl<'d, T: Instance> embedded_io_async::BufRead for BufferedUartRx<'d, T> {
782    async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
783        Self::fill_buf(self).await
784    }
785
786    fn consume(&mut self, amt: usize) {
787        Self::consume(self, amt)
788    }
789}
790
791impl<'d, T: Instance> embedded_io_async::Write for BufferedUart<'d, T> {
792    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
793        self.tx.write(buf).await
794    }
795
796    async fn flush(&mut self) -> Result<(), Self::Error> {
797        self.tx.flush().await
798    }
799}
800
801impl<'d, T: Instance> embedded_io_async::Write for BufferedUartTx<'d, T> {
802    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
803        Self::write(self, buf).await
804    }
805
806    async fn flush(&mut self) -> Result<(), Self::Error> {
807        Self::flush(self).await
808    }
809}
810
811impl<'d, T: Instance> embedded_io::Read for BufferedUart<'d, T> {
812    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
813        self.rx.blocking_read(buf)
814    }
815}
816
817impl<'d, T: Instance> embedded_io::Read for BufferedUartRx<'d, T> {
818    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
819        self.blocking_read(buf)
820    }
821}
822
823impl<'d, T: Instance> embedded_io::Write for BufferedUart<'d, T> {
824    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
825        self.tx.blocking_write(buf)
826    }
827
828    fn flush(&mut self) -> Result<(), Self::Error> {
829        self.tx.blocking_flush()
830    }
831}
832
833impl<'d, T: Instance> embedded_io::Write for BufferedUartTx<'d, T> {
834    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
835        Self::blocking_write(self, buf)
836    }
837
838    fn flush(&mut self) -> Result<(), Self::Error> {
839        Self::blocking_flush(self)
840    }
841}
842
843impl<'d, T: Instance> embedded_hal_02::serial::Read<u8> for BufferedUartRx<'d, T> {
844    type Error = Error;
845
846    fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
847        let r = T::regs();
848        unsafe {
849            let sr = r.isr().read();
850            if sr.pe() {
851                r.rdr().as_ptr().read_volatile().0 as u8;
852                Err(nb::Error::Other(Error::Parity))
853            } else if sr.fe() {
854                r.rdr().as_ptr().read_volatile().0 as u8;
855                Err(nb::Error::Other(Error::Framing))
856            } else if sr.ore() {
857                r.rdr().as_ptr().read_volatile().0 as u8;
858                Err(nb::Error::Other(Error::Overrun))
859            } else if sr.rxne() {
860                Ok(r.rdr().as_ptr().read_volatile().0 as u8)
861            } else {
862                Err(nb::Error::WouldBlock)
863            }
864        }
865    }
866}
867
868impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx<'d, T> {
869    type Error = Error;
870
871    fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
872        while !buffer.is_empty() {
873            match self.blocking_write(buffer) {
874                Ok(0) => panic!("zero-length write."),
875                Ok(n) => buffer = &buffer[n..],
876                Err(e) => return Err(e),
877            }
878        }
879        Ok(())
880    }
881
882    fn bflush(&mut self) -> Result<(), Self::Error> {
883        self.blocking_flush()
884    }
885}
886
887impl<'d, T: Instance> embedded_hal_02::serial::Read<u8> for BufferedUart<'d, T> {
888    type Error = Error;
889
890    fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
891        embedded_hal_02::serial::Read::read(&mut self.rx)
892    }
893}
894
895impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUart<'d, T> {
896    type Error = Error;
897
898    fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
899        while !buffer.is_empty() {
900            match self.tx.blocking_write(buffer) {
901                Ok(0) => panic!("zero-length write."),
902                Ok(n) => buffer = &buffer[n..],
903                Err(e) => return Err(e),
904            }
905        }
906        Ok(())
907    }
908
909    fn bflush(&mut self) -> Result<(), Self::Error> {
910        self.tx.blocking_flush()
911    }
912}
913
914impl<'d, T: Instance> embedded_hal_nb::serial::ErrorType for BufferedUart<'d, T> {
915    type Error = Error;
916}
917
918impl<'d, T: Instance> embedded_hal_nb::serial::ErrorType for BufferedUartTx<'d, T> {
919    type Error = Error;
920}
921
922impl<'d, T: Instance> embedded_hal_nb::serial::ErrorType for BufferedUartRx<'d, T> {
923    type Error = Error;
924}
925
926impl<'d, T: Instance> embedded_hal_nb::serial::Read for BufferedUartRx<'d, T> {
927    fn read(&mut self) -> nb::Result<u8, Self::Error> {
928        embedded_hal_02::serial::Read::read(self)
929    }
930}
931
932impl<'d, T: Instance> embedded_hal_nb::serial::Write for BufferedUartTx<'d, T> {
933    fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
934        self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
935    }
936
937    fn flush(&mut self) -> nb::Result<(), Self::Error> {
938        self.blocking_flush().map_err(nb::Error::Other)
939    }
940}
941
942impl<'d, T: Instance> embedded_hal_nb::serial::Read for BufferedUart<'d, T> {
943    fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
944        embedded_hal_02::serial::Read::read(&mut self.rx)
945    }
946}
947
948impl<'d, T: Instance> embedded_hal_nb::serial::Write for BufferedUart<'d, T> {
949    fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
950        self.tx.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
951    }
952
953    fn flush(&mut self) -> nb::Result<(), Self::Error> {
954        self.tx.blocking_flush().map_err(nb::Error::Other)
955    }
956}