sifli_hal/usart/
mod.rs

1//! Universal Synchronous/Asynchronous Receiver Transmitter (USART, UART, LPUART)
2#![macro_use]
3#![warn(missing_docs)]
4
5// The following code is modified from embassy-stm32 under MIT license
6// https://github.com/embassy-rs/embassy/tree/main/embassy-stm32
7// Special thanks to the Embassy Project and its contributors for their work!
8
9use core::future::poll_fn;
10use core::marker::PhantomData;
11use core::sync::atomic::{compiler_fence, AtomicU8, Ordering};
12use core::task::Poll;
13
14use embassy_embedded_hal::SetConfig;
15use embassy_hal_internal::drop::OnDrop;
16use embassy_hal_internal::PeripheralRef;
17use embassy_sync::waitqueue::AtomicWaker;
18use futures_util::future::{select, Either};
19
20use crate::dma::ChannelAndRequest;
21use crate::gpio::{AfType, AnyPin, Pull, SealedPin};
22use crate::interrupt::{self, Interrupt, typelevel::Interrupt as _};
23use crate::mode::{Async, Blocking, Mode};
24use crate::time::Hertz;
25use crate::{rcc, Peripheral};
26
27use crate::pac::usart::Usart as Regs;
28use crate::pac::usart::{regs, vals};
29
30
31/// Interrupt handler.
32pub struct InterruptHandler<T: Instance> {
33    _phantom: PhantomData<T>,
34}
35
36impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
37    unsafe fn on_interrupt() {
38        on_interrupt(T::regs(), T::state())
39    }
40}
41
42unsafe fn on_interrupt(r: Regs, s: &'static State) {
43    let (sr, cr1, cr3) = (r.isr().read(), r.cr1().read(), r.cr3().read());
44
45    let has_errors = (sr.pe() && cr1.peie()) || ((sr.fe() || sr.ore()) && cr3.eie());
46    if has_errors {
47        // clear all interrupts and DMA Rx Request
48        r.cr1().modify(|w| {
49            // disable RXNE interrupt
50            w.set_rxneie(false);
51            // disable parity interrupt
52            w.set_peie(false);
53            // disable idle line interrupt
54            w.set_idleie(false);
55        });
56        r.cr3().modify(|w| {
57            // disable Error Interrupt: (Frame error, Noise error, Overrun error)
58            w.set_eie(false);
59            // disable DMA Rx Request
60            w.set_dmar(false);
61        });
62    } else if cr1.idleie() && sr.idle() {
63        // IDLE detected: no more data will come
64        r.cr1().modify(|w| {
65            // disable idle line detection
66            w.set_idleie(false);
67        });
68    } else if cr1.tcie() && sr.tc() {
69        // Transmission complete detected
70        r.cr1().modify(|w| {
71            // disable Transmission complete interrupt
72            w.set_tcie(false);
73        });
74    } else if cr1.rxneie() {
75        // We cannot check the RXNE flag as it is auto-cleared by the DMA controller
76
77        // It is up to the listener to determine if this in fact was a RX event and disable the RXNE detection
78    } else {
79        return;
80    }
81
82    compiler_fence(Ordering::SeqCst);
83    s.rx_waker.wake();
84}
85
86#[derive(Clone, Copy, PartialEq, Eq, Debug)]
87#[cfg_attr(feature = "defmt", derive(defmt::Format))]
88/// Number of data bits
89pub enum DataBits {
90    /// 6 Data Bits
91    DataBits6,
92    /// 7 Data Bits
93    DataBits7,
94    /// 8 Data Bits
95    DataBits8,
96    /// 9 Data Bits
97    DataBits9,
98}
99
100#[derive(Clone, Copy, PartialEq, Eq, Debug)]
101#[cfg_attr(feature = "defmt", derive(defmt::Format))]
102/// Parity
103pub enum Parity {
104    /// No parity
105    ParityNone,
106    /// Even Parity
107    ParityEven,
108    /// Odd Parity
109    ParityOdd,
110}
111
112#[derive(Clone, Copy, PartialEq, Eq, Debug)]
113#[cfg_attr(feature = "defmt", derive(defmt::Format))]
114/// Number of stop bits
115pub enum StopBits {
116    #[doc = "1 stop bit"]
117    STOP1,
118    // #[doc = "0.5 stop bits"]
119    // STOP0P5,
120    #[doc = "2 stop bits"]
121    STOP2,
122    // #[doc = "1.5 stop bits"]
123    // STOP1P5,
124}
125
126#[derive(Clone, Copy, PartialEq, Eq, Debug)]
127#[cfg_attr(feature = "defmt", derive(defmt::Format))]
128/// Enables or disables receiver so written data are read back in half-duplex mode
129pub enum HalfDuplexReadback {
130    /// Disables receiver so written data are not read back
131    NoReadback,
132    /// Enables receiver so written data are read back
133    Readback,
134}
135
136#[derive(Clone, Copy, PartialEq, Eq, Debug)]
137#[cfg_attr(feature = "defmt", derive(defmt::Format))]
138/// Duplex mode
139pub enum Duplex {
140    /// Full duplex
141    Full,
142    /// Half duplex with possibility to read back written data
143    Half(HalfDuplexReadback),
144}
145
146impl Duplex {
147    /// Returns true if half-duplex
148    fn is_half(&self) -> bool {
149        matches!(self, Duplex::Half(_))
150    }
151}
152
153#[non_exhaustive]
154#[derive(Clone, Copy, PartialEq, Eq, Debug)]
155#[cfg_attr(feature = "defmt", derive(defmt::Format))]
156/// Config Error
157pub enum ConfigError {
158    /// Baudrate too low
159    BaudrateTooLow,
160    /// Baudrate too high
161    BaudrateTooHigh,
162    /// Rx or Tx not enabled
163    RxOrTxNotEnabled,
164    /// Data bits and parity combination not supported
165    DataParityNotSupported,
166}
167
168#[non_exhaustive]
169#[derive(Clone, Copy, PartialEq, Eq, Debug)]
170/// Config
171pub struct Config {
172    /// Baud rate
173    pub baudrate: u32,
174    /// Number of data bits
175    pub data_bits: DataBits,
176    /// Number of stop bits
177    pub stop_bits: StopBits,
178    /// Parity type
179    pub parity: Parity,
180
181    /// If true: on a read-like method, if there is a latent error pending,
182    /// the read will abort and the error will be reported and cleared
183    ///
184    /// If false: the error is ignored and cleared
185    pub _detect_previous_overrun: bool,
186
187    /// Set this to true if the line is considered noise free.
188    /// This will increase the receiver’s tolerance to clock deviations,
189    /// but will effectively disable noise detection.
190    pub assume_noise_free: bool,
191
192    /// Set the pull configuration for the RX pin.
193    pub rx_pull: Pull,
194
195    // private: set by new_half_duplex, not by the user.
196    duplex: Duplex,
197}
198
199impl Config {
200    fn tx_af(&self) -> AfType {
201        AfType::new(Pull::Up)
202    }
203
204    fn rx_af(&self) -> AfType {
205        AfType::new(self.rx_pull)
206    }
207}
208
209impl Default for Config {
210    fn default() -> Self {
211        Self {
212            baudrate: 115200,
213            data_bits: DataBits::DataBits8,
214            stop_bits: StopBits::STOP1,
215            parity: Parity::ParityNone,
216            // historical behavior
217            _detect_previous_overrun: false,
218            assume_noise_free: false,
219            rx_pull: Pull::None,
220            duplex: Duplex::Full,
221        }
222    }
223}
224
225#[derive(Clone, Copy, PartialEq, Eq, Debug)]
226/// Half duplex IO mode
227pub struct HalfDuplexConfig {
228    // TODO
229    pull: Pull,
230}
231
232impl HalfDuplexConfig {
233    fn af_type(self) -> AfType {
234        AfType::new(self.pull)
235    }
236}
237
238/// Serial error
239#[derive(Debug, Eq, PartialEq, Copy, Clone)]
240#[cfg_attr(feature = "defmt", derive(defmt::Format))]
241#[non_exhaustive]
242pub enum Error {
243    /// Framing error
244    Framing,
245    /// Noise error
246    Noise,
247    /// RX buffer overrun
248    Overrun,
249    /// Parity check error
250    Parity,
251    /// Buffer too large for DMA
252    BufferTooLong,
253}
254
255enum ReadCompletionEvent {
256    // DMA Read transfer completed first
257    DmaCompleted,
258    // Idle line detected first
259    Idle(usize),
260}
261
262/// Bidirectional UART Driver, which acts as a combination of [`UartTx`] and [`UartRx`].
263///
264/// ### Notes on [`embedded_io::Read`]
265///
266/// `embedded_io::Read` requires guarantees that the base [`UartRx`] cannot provide.
267///
268/// See [`UartRx`] for more details, and see [`BufferedUart`] and [`RingBufferedUartRx`]
269/// as alternatives that do provide the necessary guarantees for `embedded_io::Read`.
270pub struct Uart<'d, T: Instance, M: Mode> {
271    tx: UartTx<'d, T, M>,
272    rx: UartRx<'d, T, M>,
273}
274
275impl<'d, T: Instance, M: Mode> SetConfig for Uart<'d, T, M> {
276    type Config = Config;
277    type ConfigError = ConfigError;
278
279    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
280        self.tx.set_config(config)?;
281        self.rx.set_config(config)
282    }
283}
284
285/// Tx-only UART Driver.
286///
287/// Can be obtained from [`Uart::split`], or can be constructed independently,
288/// if you do not need the receiving half of the driver.
289pub struct UartTx<'d, T: Instance, M: Mode> {
290    state: &'static State,
291    kernel_clock: Hertz,
292    tx: Option<PeripheralRef<'d, AnyPin>>,
293    cts: Option<PeripheralRef<'d, AnyPin>>,
294    tx_dma: Option<ChannelAndRequest<'d>>,
295    duplex: Duplex,
296    _phantom: PhantomData<(T, M)>,
297}
298
299impl<'d, T: Instance, M: Mode> SetConfig for UartTx<'d, T, M> {
300    type Config = Config;
301    type ConfigError = ConfigError;
302
303    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
304        self.set_config(config)
305    }
306}
307
308/// Rx-only UART Driver.
309///
310/// Can be obtained from [`Uart::split`], or can be constructed independently,
311/// if you do not need the transmitting half of the driver.
312///
313/// ### Notes on [`embedded_io::Read`]
314///
315/// `embedded_io::Read` requires guarantees that this struct cannot provide:
316///
317/// - Any data received between calls to [`UartRx::read`] or [`UartRx::blocking_read`]
318/// will be thrown away, as `UartRx` is unbuffered.
319/// Users of `embedded_io::Read` are likely to not expect this behavior
320/// (for instance if they read multiple small chunks in a row).
321/// - [`UartRx::read`] and [`UartRx::blocking_read`] only return once the entire buffer has been
322/// filled, whereas `embedded_io::Read` requires us to fill the buffer with what we already
323/// received, and only block/wait until the first byte arrived.
324/// <br />
325/// While [`UartRx::read_until_idle`] does return early, it will still eagerly wait for data until
326/// the buffer is full or no data has been transmitted in a while,
327/// which may not be what users of `embedded_io::Read` expect.
328///
329/// [`UartRx::into_ring_buffered`] can be called to equip `UartRx` with a buffer,
330/// that it can then use to store data received between calls to `read`,
331/// provided you are using DMA already.
332///
333/// Alternatively, you can use [`BufferedUartRx`], which is interrupt-based and which can also
334/// store data received between calls.
335///
336/// Also see [this github comment](https://github.com/embassy-rs/embassy/pull/2185#issuecomment-1810047043).
337pub struct UartRx<'d, T: Instance, M: Mode> {
338    state: &'static State,
339    kernel_clock: Hertz,
340    rx: Option<PeripheralRef<'d, AnyPin>>,
341    rts: Option<PeripheralRef<'d, AnyPin>>,
342    rx_dma: Option<ChannelAndRequest<'d>>,
343    _detect_previous_overrun: bool,
344    _phantom: PhantomData<(T, M)>,
345}
346
347impl<'d, T: Instance, M: Mode> SetConfig for UartRx<'d, T, M> {
348    type Config = Config;
349    type ConfigError = ConfigError;
350
351    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
352        self.set_config(config)
353    }
354}
355
356impl<'d, T: Instance> UartTx<'d, T, Async> {
357    /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power.
358    pub fn new(
359        peri: impl Peripheral<P = T> + 'd,
360        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
361        tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd,
362        config: Config,
363    ) -> Result<Self, ConfigError> {
364        Self::new_inner(
365            peri,
366            new_pin!(tx, AfType::new(Pull::Up)),
367            None,
368            new_dma!(tx_dma),
369            config,
370        )
371    }
372
373    /// Create a new tx-only UART with a clear-to-send pin
374    pub fn new_with_cts(
375        peri: impl Peripheral<P = T> + 'd,
376        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
377        cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
378        tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd,
379        config: Config,
380    ) -> Result<Self, ConfigError> {
381        Self::new_inner(
382            peri,
383            new_pin!(tx, AfType::new(Pull::Up)),
384            new_pin!(cts, AfType::new(Pull::None)),
385            new_dma!(tx_dma),
386            config,
387        )
388    }
389
390    /// Initiate an asynchronous UART write
391    pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
392        let r = T::regs();
393
394        half_duplex_set_rx_tx_before_write(&r, self.duplex == Duplex::Half(HalfDuplexReadback::Readback));
395
396        let ch = self.tx_dma.as_mut().unwrap();
397        r.cr3().modify(|reg| {
398            reg.set_dmat(true);
399        });
400        // If we don't assign future to a variable, the data register pointer
401        // is held across an await and makes the future non-Send.
402        let transfer = unsafe { ch.write(buffer, r.tdr().as_ptr() as _, Default::default()) };
403        transfer.await;
404        Ok(())
405    }
406
407    /// Wait until transmission complete
408    pub async fn flush(&mut self) -> Result<(), Error> {
409        flush::<T>(&self.state).await
410    }
411}
412
413impl<'d, T: Instance> UartTx<'d, T, Blocking> {
414    /// Create a new blocking tx-only UART with no hardware flow control.
415    ///
416    /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power.
417    pub fn new_blocking(
418        peri: impl Peripheral<P = T> + 'd,
419        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
420        config: Config,
421    ) -> Result<Self, ConfigError> {
422        Self::new_inner(
423            peri,
424            new_pin!(tx, AfType::new(Pull::Up)),
425            None,
426            None,
427            config,
428        )
429    }
430
431    /// Create a new blocking tx-only UART with a clear-to-send pin
432    pub fn new_blocking_with_cts(
433        peri: impl Peripheral<P = T> + 'd,
434        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
435        cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
436        config: Config,
437    ) -> Result<Self, ConfigError> {
438        Self::new_inner(
439            peri,
440            new_pin!(tx, AfType::new(Pull::Up)),
441            new_pin!(cts, AfType::new(config.rx_pull)),
442            None,
443            config,
444        )
445    }
446}
447
448impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
449    fn new_inner(
450        _peri: impl Peripheral<P = T> + 'd,
451        tx: Option<PeripheralRef<'d, AnyPin>>,
452        cts: Option<PeripheralRef<'d, AnyPin>>,
453        tx_dma: Option<ChannelAndRequest<'d>>,
454        config: Config,
455    ) -> Result<Self, ConfigError> {
456        let mut this = Self {
457            state: T::state(),
458            kernel_clock: T::frequency().unwrap(),
459            tx,
460            cts,
461            tx_dma,
462            duplex: config.duplex,
463            _phantom: PhantomData,
464        };
465        this.enable_and_configure(&config)?;
466        Ok(this)
467    }
468
469    fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> {
470        let state = self.state;
471        state.tx_rx_refcount.store(1, Ordering::Relaxed);
472
473        rcc::enable_and_reset::<T>();
474
475        T::regs().cr3().modify(|w| {
476            w.set_ctse(self.cts.is_some());
477        });
478        configure::<T>(self.kernel_clock, config, false, true)?;
479
480        Ok(())
481    }
482
483    /// Reconfigure the driver
484    pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
485        reconfigure::<T>(self.kernel_clock, config)
486    }
487
488    /// Perform a blocking UART write
489    pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
490        let r = T::regs();
491
492        half_duplex_set_rx_tx_before_write(&r, self.duplex == Duplex::Half(HalfDuplexReadback::Readback));
493
494        for &b in buffer {
495            while !r.isr().read().txe() {}
496            r.tdr().write_value(regs::Tdr(b as _));
497        }
498        Ok(())
499    }
500
501    /// Block until transmission complete
502    pub fn blocking_flush(&mut self) -> Result<(), Error> {
503        blocking_flush::<T>()
504    }
505
506    /// Send break character
507    pub fn send_break(&self) {
508        send_break(&T::regs());
509    }
510
511    /// Set baudrate
512    pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError> {
513        set_baudrate::<T>(self.kernel_clock, baudrate)
514    }
515}
516
517/// Wait until transmission complete
518async fn flush<T: Instance>(state: &State) -> Result<(), Error> {
519    let r = T::regs();
520    if r.cr1().read().te() && !r.isr().read().tc() {
521        r.cr1().modify(|w| {
522            // enable Transmission Complete interrupt
523            w.set_tcie(true);
524        });
525
526        compiler_fence(Ordering::SeqCst);
527
528        // future which completes when Transmission complete is detected
529        let abort = poll_fn(move |cx| {
530            state.rx_waker.register(cx.waker());
531
532            let sr = r.isr().read();
533            if sr.tc() {
534                // Transmission complete detected
535                return Poll::Ready(());
536            }
537
538            Poll::Pending
539        });
540
541        abort.await;
542    }
543
544    Ok(())
545}
546
547fn blocking_flush<T: Instance>() -> Result<(), Error> {
548    let r = T::regs();
549    if r.cr1().read().te() {
550        while !r.isr().read().tc() {}
551    }
552
553    Ok(())
554}
555
556/// Send break character
557pub fn send_break(regs: &Regs) {
558    // Busy wait until previous break has been sent
559    while regs.isr().read().sbkf() {}
560
561    // Send break right after completing the current character transmission
562    regs.rqr().write(|w| w.set_sbkrq(true));
563}
564
565/// Enable Transmitter and disable Receiver for Half-Duplex mode
566/// In case of readback, keep Receiver enabled
567fn half_duplex_set_rx_tx_before_write(r: &Regs, enable_readback: bool) {
568    let mut cr1 = r.cr1().read();
569    if r.cr3().read().hdsel() && !cr1.te() {
570        cr1.set_te(true);
571        cr1.set_re(enable_readback);
572        r.cr1().write_value(cr1);
573    }
574}
575
576impl<'d, T: Instance> UartRx<'d, T, Async> {
577    /// Create a new rx-only UART with no hardware flow control.
578    ///
579    /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
580    pub fn new(
581        peri: impl Peripheral<P = T> + 'd,
582        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
583        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
584        rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd,
585        config: Config,
586    ) -> Result<Self, ConfigError> {
587        Self::new_inner(
588            peri,
589            new_pin!(rx, AfType::new(config.rx_pull)),
590            None,
591            new_dma!(rx_dma),
592            config,
593        )
594    }
595
596    /// Create a new rx-only UART with a request-to-send pin
597    pub fn new_with_rts(
598        peri: impl Peripheral<P = T> + 'd,
599        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
600        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
601        rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
602        rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd,
603        config: Config,
604    ) -> Result<Self, ConfigError> {
605        Self::new_inner(
606            peri,
607            new_pin!(rx, AfType::new(config.rx_pull)),
608            new_pin!(rts, AfType::new(Pull::Up)),
609            new_dma!(rx_dma),
610            config,
611        )
612    }
613
614    /// Initiate an asynchronous UART read
615    pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
616        self.inner_read(buffer, false).await?;
617
618        Ok(())
619    }
620
621    /// Initiate an asynchronous read with idle line detection enabled
622    pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
623        self.inner_read(buffer, true).await
624    }
625
626    async fn inner_read_run(
627        &mut self,
628        buffer: &mut [u8],
629        enable_idle_line_detection: bool,
630    ) -> Result<ReadCompletionEvent, Error> {
631        let r = T::regs();
632
633        // Call flush for Half-Duplex mode if some bytes were written and flush was not called.
634        // It prevents reading of bytes which have just been written.
635        if r.cr3().read().hdsel() && r.cr1().read().te() {
636            flush::<T>(&self.state).await?;
637
638            // Disable Transmitter and enable Receiver after flush
639            r.cr1().modify(|reg| {
640                reg.set_re(true);
641                reg.set_te(false);
642            });
643        }
644
645        // make sure USART state is restored to neutral state when this future is dropped
646        let on_drop = OnDrop::new(move || {
647            // defmt::trace!("Clear all USART interrupts and DMA Read Request");
648            // clear all interrupts and DMA Rx Request
649            r.cr1().modify(|w| {
650                // disable RXNE interrupt
651                w.set_rxneie(false);
652                // disable parity interrupt
653                w.set_peie(false);
654                // disable idle line interrupt
655                w.set_idleie(false);
656            });
657            r.cr3().modify(|w| {
658                // disable Error Interrupt: (Frame error, Noise error, Overrun error)
659                w.set_eie(false);
660                // disable DMA Rx Request
661                w.set_dmar(false);
662            });
663        });
664
665        let ch = self.rx_dma.as_mut().unwrap();
666
667        let buffer_len = buffer.len();
668
669        // Start USART DMA
670        // will not do anything yet because DMAR is not yet set
671        // future which will complete when DMA Read request completes
672        let transfer = unsafe { ch.read(r.rdr().as_ptr() as _, buffer, Default::default()) };
673
674        // clear ORE flag just before enabling DMA Rx Request: can be mandatory for the second transfer
675        if !self._detect_previous_overrun {
676            let sr = r.isr().read();
677            // This read also clears the error and idle interrupt flags on v1.
678            unsafe { r.rdr().as_ptr().read_volatile() };
679            clear_interrupt_flags(r, sr);
680        }
681
682        r.cr1().modify(|w| {
683            // disable RXNE interrupt
684            w.set_rxneie(false);
685            // enable parity interrupt if not ParityNone
686            w.set_peie(w.pce());
687        });
688
689        r.cr3().modify(|w| {
690            // enable Error Interrupt: (Frame error, Noise error, Overrun error)
691            w.set_eie(true);
692            // enable DMA Rx Request
693            w.set_dmar(true);
694        });
695
696        compiler_fence(Ordering::SeqCst);
697
698        // In case of errors already pending when reception started, interrupts may have already been raised
699        // and lead to reception abortion (Overrun error for instance). In such a case, all interrupts
700        // have been disabled in interrupt handler and DMA Rx Request has been disabled.
701
702        let cr3 = r.cr3().read();
703
704        if !cr3.dmar() {
705            // something went wrong
706            // because the only way to get this flag cleared is to have an interrupt
707
708            // DMA will be stopped when transfer is dropped
709
710            let sr = r.isr().read();
711            // This read also clears the error and idle interrupt flags on v1.
712            unsafe { r.rdr().as_ptr().read_volatile() };
713            clear_interrupt_flags(r, sr);
714
715            if sr.pe() {
716                return Err(Error::Parity);
717            }
718            if sr.fe() {
719                return Err(Error::Framing);
720            }
721            if sr.nf() {
722                return Err(Error::Noise);
723            }
724            if sr.ore() {
725                return Err(Error::Overrun);
726            }
727
728            unreachable!();
729        }
730
731        if enable_idle_line_detection {
732            // clear idle flag
733            let sr = r.isr().read();
734            // This read also clears the error and idle interrupt flags on v1.
735            unsafe { r.rdr().as_ptr().read_volatile() };
736            clear_interrupt_flags(r, sr);
737
738            // enable idle interrupt
739            r.cr1().modify(|w| {
740                w.set_idleie(true);
741            });
742        }
743
744        compiler_fence(Ordering::SeqCst);
745
746        // future which completes when idle line or error is detected
747        let s = self.state;
748        let abort = poll_fn(move |cx| {
749            s.rx_waker.register(cx.waker());
750
751            let sr = r.isr().read();
752
753            // This read also clears the error and idle interrupt flags on v1.
754            unsafe { r.rdr().as_ptr().read_volatile() };
755            clear_interrupt_flags(r, sr);
756
757            if enable_idle_line_detection {
758                // enable idle interrupt
759                r.cr1().modify(|w| {
760                    w.set_idleie(true);
761                });
762            }
763
764            compiler_fence(Ordering::SeqCst);
765
766            let has_errors = sr.pe() || sr.fe() || sr.nf() || sr.ore();
767
768            if has_errors {
769                // all Rx interrupts and Rx DMA Request have already been cleared in interrupt handler
770
771                if sr.pe() {
772                    return Poll::Ready(Err(Error::Parity));
773                }
774                if sr.fe() {
775                    return Poll::Ready(Err(Error::Framing));
776                }
777                if sr.nf() {
778                    return Poll::Ready(Err(Error::Noise));
779                }
780                if sr.ore() {
781                    return Poll::Ready(Err(Error::Overrun));
782                }
783            }
784
785            if enable_idle_line_detection && sr.idle() {
786                // Idle line detected
787                return Poll::Ready(Ok(()));
788            }
789
790            Poll::Pending
791        });
792
793        // wait for the first of DMA request or idle line detected to completes
794        // select consumes its arguments
795        // when transfer is dropped, it will stop the DMA request
796        let r = match select(transfer, abort).await {
797            // DMA transfer completed first
798            Either::Left(((), _)) => Ok(ReadCompletionEvent::DmaCompleted),
799
800            // Idle line detected first
801            Either::Right((Ok(()), transfer)) => Ok(ReadCompletionEvent::Idle(
802                buffer_len - transfer.get_remaining_transfers() as usize,
803            )),
804
805            // error occurred
806            Either::Right((Err(e), _)) => Err(e),
807        };
808
809        drop(on_drop);
810
811        r
812    }
813
814    async fn inner_read(&mut self, buffer: &mut [u8], enable_idle_line_detection: bool) -> Result<usize, Error> {
815        if buffer.is_empty() {
816            return Ok(0);
817        } else if buffer.len() > 0xFFFF {
818            return Err(Error::BufferTooLong);
819        }
820
821        let buffer_len = buffer.len();
822
823        // wait for DMA to complete or IDLE line detection if requested
824        let res = self.inner_read_run(buffer, enable_idle_line_detection).await;
825
826        match res {
827            Ok(ReadCompletionEvent::DmaCompleted) => Ok(buffer_len),
828            Ok(ReadCompletionEvent::Idle(n)) => Ok(n),
829            Err(e) => Err(e),
830        }
831    }
832}
833
834impl<'d, T: Instance> UartRx<'d, T, Blocking> {
835    /// Create a new rx-only UART with no hardware flow control.
836    ///
837    /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
838    pub fn new_blocking(
839        peri: impl Peripheral<P = T> + 'd,
840        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
841        config: Config,
842    ) -> Result<Self, ConfigError> {
843        Self::new_inner(peri,
844            new_pin!(rx, AfType::new(config.rx_pull)),
845            None,
846            None,
847            config
848        )
849    }
850
851    /// Create a new rx-only UART with a request-to-send pin
852    pub fn new_blocking_with_rts(
853        peri: impl Peripheral<P = T> + 'd,
854        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
855        rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
856        config: Config,
857    ) -> Result<Self, ConfigError> {
858        Self::new_inner(
859            peri,
860            new_pin!(rx, AfType::new(config.rx_pull)),
861            new_pin!(rts, AfType::new(Pull::Up)),
862            None,
863            config,
864        )
865    }
866}
867
868impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> {
869    fn new_inner(
870        _peri: impl Peripheral<P = T> + 'd,
871        rx: Option<PeripheralRef<'d, AnyPin>>,
872        rts: Option<PeripheralRef<'d, AnyPin>>,
873        rx_dma: Option<ChannelAndRequest<'d>>,
874        config: Config,
875    ) -> Result<Self, ConfigError> {
876        let mut this = Self {
877            _phantom: PhantomData,
878            state: T::state(),
879            kernel_clock: T::frequency().unwrap(),
880            rx,
881            rts,
882            rx_dma,
883            _detect_previous_overrun: config._detect_previous_overrun,
884        };
885        this.enable_and_configure(&config)?;
886        Ok(this)
887    }
888
889    fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> {
890        let state = self.state;
891        state.tx_rx_refcount.store(1, Ordering::Relaxed);
892
893        rcc::enable_and_reset::<T>();
894
895        T::regs().cr3().write(|w| {
896            w.set_rtse(self.rts.is_some());
897        });
898        configure::<T>(self.kernel_clock, &config, true, false)?;
899
900        T::Interrupt::unpend();
901        unsafe { T::Interrupt::enable() };
902
903        Ok(())
904    }
905
906    /// Reconfigure the driver
907    pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
908        reconfigure::<T>(self.kernel_clock, config)
909    }
910
911    fn check_rx_flags(&mut self) -> Result<bool, Error> {
912        let r = T::regs();
913        let sr = r.isr().read();
914        if sr.pe() {
915            r.icr().write(|w| w.set_pecf(true));
916            return Err(Error::Parity);
917        } else if sr.fe() {
918            r.icr().write(|w| w.set_fecf(true));
919            return Err(Error::Framing);
920        } else if sr.ore() {
921            r.icr().write(|w| w.set_orecf(true));
922            return Err(Error::Overrun);
923        }
924        Ok(sr.rxne())
925    }
926
927    /// Read a single u8 if there is one available, otherwise return WouldBlock
928    pub(crate) fn nb_read(&mut self) -> Result<u8, nb::Error<Error>> {
929        let r = T::regs();
930        if self.check_rx_flags()? {
931            Ok(unsafe { r.rdr().as_ptr().read_volatile().0 as u8 })
932        } else {
933            Err(nb::Error::WouldBlock)
934        }
935    }
936
937    /// Perform a blocking read into `buffer`
938    pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
939        let r = T::regs();
940
941        // Call flush for Half-Duplex mode if some bytes were written and flush was not called.
942        // It prevents reading of bytes which have just been written.
943        if r.cr3().read().hdsel() && r.cr1().read().te() {
944            blocking_flush::<T>()?;
945
946            // Disable Transmitter and enable Receiver after flush
947            r.cr1().modify(|reg| {
948                reg.set_re(true);
949                reg.set_te(false);
950            });
951        }
952
953        for b in buffer {
954            while !self.check_rx_flags()? {}
955            unsafe { *b = r.rdr().as_ptr().read_volatile().0 as u8 }
956        }
957        Ok(())
958    }
959
960    /// Set baudrate
961    pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError> {
962        set_baudrate::<T>(self.kernel_clock, baudrate)
963    }
964}
965
966impl<'d, T: Instance, M: Mode> Drop for UartTx<'d, T, M> {
967    fn drop(&mut self) {
968        self.tx.as_ref().map(|x| x.set_as_disconnected());
969        self.cts.as_ref().map(|x| x.set_as_disconnected());
970        drop_tx_rx::<T>(self.state);
971    }
972}
973
974impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> {
975    fn drop(&mut self) {
976        self.rx.as_ref().map(|x| x.set_as_disconnected());
977        self.rts.as_ref().map(|x| x.set_as_disconnected());
978        drop_tx_rx::<T>(self.state);
979    }
980}
981
982fn drop_tx_rx<T: Instance>(state: &State) {
983    // We cannot use atomic subtraction here, because it's not supported for all targets
984    let is_last_drop = critical_section::with(|_| {
985        let refcount = state.tx_rx_refcount.load(Ordering::Relaxed);
986        assert!(refcount >= 1);
987        state.tx_rx_refcount.store(refcount - 1, Ordering::Relaxed);
988        refcount == 1
989    });
990    if is_last_drop {
991        rcc::disable::<T>();
992    }
993}
994
995impl<'d, T: Instance> Uart<'d, T, Async> {
996    /// Create a new bidirectional UART
997    pub fn new(
998        peri: impl Peripheral<P = T> + 'd,
999        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
1000        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
1001        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1002        tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd,
1003        rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd,
1004        config: Config,
1005    ) -> Result<Self, ConfigError> {
1006        Self::new_inner(
1007            peri,
1008            new_pin!(rx, config.rx_af()),
1009            new_pin!(tx, config.tx_af()),
1010            None,
1011            None,
1012            new_dma!(tx_dma),
1013            new_dma!(rx_dma),
1014            config,
1015        )
1016    }
1017
1018    /// Create a new bidirectional UART with request-to-send and clear-to-send pins
1019    pub fn new_with_rtscts(
1020        peri: impl Peripheral<P = T> + 'd,
1021        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
1022        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
1023        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1024        rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
1025        cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
1026        tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd,
1027        rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd,
1028        config: Config,
1029    ) -> Result<Self, ConfigError> {
1030        Self::new_inner(
1031            peri,
1032            new_pin!(rx, config.rx_af()),
1033            new_pin!(tx, config.tx_af()),
1034            new_pin!(rts, AfType::new(Pull::Up)),
1035            new_pin!(cts, AfType::new(Pull::None)),
1036            new_dma!(tx_dma),
1037            new_dma!(rx_dma),
1038            config,
1039        )
1040    }
1041
1042    /// Create a single-wire half-duplex Uart transceiver on a single Tx pin.
1043    ///
1044    /// See [`new_half_duplex_on_rx`][`Self::new_half_duplex_on_rx`] if you would prefer to use an Rx pin
1045    /// (when it is available for your chip). There is no functional difference between these methods, as both
1046    /// allow bidirectional communication.
1047    ///
1048    /// The TX pin is always released when no data is transmitted. Thus, it acts as a standard
1049    /// I/O in idle or in reception. It means that the I/O must be configured so that TX is
1050    /// configured as alternate function open-drain with an external pull-up
1051    /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
1052    /// on the line must be managed by software (for instance by using a centralized arbiter).
1053    #[doc(alias("HDSEL"))]
1054    pub fn new_half_duplex(
1055        peri: impl Peripheral<P = T> + 'd,
1056        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
1057        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1058        tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd,
1059        rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd,
1060        mut config: Config,
1061        readback: HalfDuplexReadback,
1062        half_duplex: HalfDuplexConfig,
1063    ) -> Result<Self, ConfigError> {
1064        config.duplex = Duplex::Half(readback);
1065
1066        Self::new_inner(
1067            peri,
1068            None,
1069            new_pin!(tx, half_duplex.af_type()),
1070            None,
1071            None,
1072            new_dma!(tx_dma),
1073            new_dma!(rx_dma),
1074            config,
1075        )
1076    }
1077
1078    // TODO: Do we have this?
1079    // embassy_stm32: #[cfg(not(any(usart_v1, usart_v2)))]
1080    //
1081    /// Create a single-wire half-duplex Uart transceiver on a single Rx pin.
1082    ///
1083    /// See [`new_half_duplex`][`Self::new_half_duplex`] if you would prefer to use an Tx pin.
1084    /// There is no functional difference between these methods, as both allow bidirectional communication.
1085    ///
1086    /// The pin is always released when no data is transmitted. Thus, it acts as a standard
1087    /// I/O in idle or in reception.
1088    /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
1089    /// on the line must be managed by software (for instance by using a centralized arbiter).
1090    #[doc(alias("HDSEL"))]
1091    pub fn new_half_duplex_on_rx(
1092        peri: impl Peripheral<P = T> + 'd,
1093        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
1094        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1095        tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd,
1096        rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd,
1097        mut config: Config,
1098        readback: HalfDuplexReadback,
1099        half_duplex: HalfDuplexConfig,
1100    ) -> Result<Self, ConfigError> {
1101        config.duplex = Duplex::Half(readback);
1102
1103        Self::new_inner(
1104            peri,
1105            None,
1106            None,
1107            new_pin!(rx, half_duplex.af_type()),
1108            None,
1109            new_dma!(tx_dma),
1110            new_dma!(rx_dma),
1111            config,
1112        )
1113    }
1114
1115    /// Perform an asynchronous write
1116    pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
1117        self.tx.write(buffer).await
1118    }
1119
1120    /// Wait until transmission complete
1121    pub async fn flush(&mut self) -> Result<(), Error> {
1122        self.tx.flush().await
1123    }
1124
1125    /// Perform an asynchronous read into `buffer`
1126    pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
1127        self.rx.read(buffer).await
1128    }
1129
1130    /// Perform an an asynchronous read with idle line detection enabled
1131    pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
1132        self.rx.read_until_idle(buffer).await
1133    }
1134}
1135
1136impl<'d, T: Instance> Uart<'d, T, Blocking> {
1137    /// Create a new blocking bidirectional UART.
1138    pub fn new_blocking(
1139        peri: impl Peripheral<P = T> + 'd,
1140        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
1141        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
1142        config: Config,
1143    ) -> Result<Self, ConfigError> {
1144        Self::new_inner(
1145            peri,
1146            new_pin!(rx, config.rx_af()),
1147            new_pin!(tx, config.tx_af()),
1148            None,
1149            None,
1150            None,
1151            None,
1152            config,
1153        )
1154    }
1155
1156    /// Create a new bidirectional UART with request-to-send and clear-to-send pins
1157    pub fn new_blocking_with_rtscts(
1158        peri: impl Peripheral<P = T> + 'd,
1159        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
1160        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
1161        rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
1162        cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
1163        config: Config,
1164    ) -> Result<Self, ConfigError> {
1165        Self::new_inner(
1166            peri,
1167            new_pin!(rx, config.rx_af()),
1168            new_pin!(tx, config.tx_af()),
1169            new_pin!(rts, AfType::new(Pull::Up)),
1170            new_pin!(cts, AfType::new(Pull::None)),
1171            None,
1172            None,
1173            config,
1174        )
1175    }
1176
1177    /// Create a single-wire half-duplex Uart transceiver on a single Tx pin.
1178    ///
1179    /// See [`new_half_duplex_on_rx`][`Self::new_half_duplex_on_rx`] if you would prefer to use an Rx pin
1180    /// (when it is available for your chip). There is no functional difference between these methods, as both
1181    /// allow bidirectional communication.
1182    ///
1183    /// The pin is always released when no data is transmitted. Thus, it acts as a standard
1184    /// I/O in idle or in reception.
1185    /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
1186    /// on the line must be managed by software (for instance by using a centralized arbiter).
1187    #[doc(alias("HDSEL"))]
1188    pub fn new_blocking_half_duplex(
1189        peri: impl Peripheral<P = T> + 'd,
1190        tx: impl Peripheral<P = impl TxdPin<T>> + 'd,
1191        mut config: Config,
1192        readback: HalfDuplexReadback,
1193        half_duplex: HalfDuplexConfig,
1194    ) -> Result<Self, ConfigError> {
1195        config.duplex = Duplex::Half(readback);
1196
1197        Self::new_inner(
1198            peri,
1199            None,
1200            new_pin!(tx, half_duplex.af_type()),
1201            None,
1202            None,
1203            None,
1204            None,
1205            config,
1206        )
1207    }
1208
1209    /// Create a single-wire half-duplex Uart transceiver on a single Rx pin.
1210    ///
1211    /// See [`new_half_duplex`][`Self::new_half_duplex`] if you would prefer to use an Tx pin.
1212    /// There is no functional difference between these methods, as both allow bidirectional communication.
1213    ///
1214    /// The pin is always released when no data is transmitted. Thus, it acts as a standard
1215    /// I/O in idle or in reception.
1216    /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
1217    /// on the line must be managed by software (for instance by using a centralized arbiter).
1218    #[doc(alias("HDSEL"))]
1219    pub fn new_blocking_half_duplex_on_rx(
1220        peri: impl Peripheral<P = T> + 'd,
1221        rx: impl Peripheral<P = impl RxdPin<T>> + 'd,
1222        mut config: Config,
1223        readback: HalfDuplexReadback,
1224        half_duplex: HalfDuplexConfig,
1225    ) -> Result<Self, ConfigError> {
1226        config.duplex = Duplex::Half(readback);
1227
1228        Self::new_inner(
1229            peri,
1230            None,
1231            None,
1232            new_pin!(rx, half_duplex.af_type()),
1233            None,
1234            None,
1235            None,
1236            config,
1237        )
1238    }
1239}
1240
1241impl<'d, T: Instance, M: Mode> Uart<'d, T, M> {
1242    fn new_inner(
1243        _peri: impl Peripheral<P = T> + 'd,
1244        rx: Option<PeripheralRef<'d, AnyPin>>,
1245        tx: Option<PeripheralRef<'d, AnyPin>>,
1246        rts: Option<PeripheralRef<'d, AnyPin>>,
1247        cts: Option<PeripheralRef<'d, AnyPin>>,
1248        tx_dma: Option<ChannelAndRequest<'d>>,
1249        rx_dma: Option<ChannelAndRequest<'d>>,
1250        config: Config,
1251    ) -> Result<Self, ConfigError> {
1252        let state = T::state();
1253        let kernel_clock = T::frequency().unwrap();
1254
1255        let mut this = Self {
1256            tx: UartTx {
1257                _phantom: PhantomData,
1258                state,
1259                kernel_clock,
1260                tx,
1261                cts,
1262                tx_dma,
1263                duplex: config.duplex,
1264            },
1265            rx: UartRx {
1266                _phantom: PhantomData,
1267                state,
1268                kernel_clock,
1269                rx,
1270                rts,
1271                rx_dma,
1272                _detect_previous_overrun: config._detect_previous_overrun,
1273            },
1274        };
1275        this.enable_and_configure(&config)?;
1276        Ok(this)
1277    }
1278
1279    fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> {
1280        let state = self.rx.state;
1281        state.tx_rx_refcount.store(2, Ordering::Relaxed);
1282
1283        rcc::enable_and_reset::<T>();
1284
1285        T::regs().cr3().write(|w| {
1286            w.set_rtse(self.rx.rts.is_some());
1287            w.set_ctse(self.tx.cts.is_some());
1288        });
1289        configure::<T>(self.rx.kernel_clock, config, true, true)?;
1290
1291        T::Interrupt::unpend();
1292        unsafe { T::Interrupt::enable() };
1293
1294        Ok(())
1295    }
1296
1297    /// Perform a blocking write
1298    pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
1299        self.tx.blocking_write(buffer)
1300    }
1301
1302    /// Block until transmission complete
1303    pub fn blocking_flush(&mut self) -> Result<(), Error> {
1304        self.tx.blocking_flush()
1305    }
1306
1307    /// Read a single `u8` or return `WouldBlock`
1308    pub(crate) fn nb_read(&mut self) -> Result<u8, nb::Error<Error>> {
1309        self.rx.nb_read()
1310    }
1311
1312    /// Perform a blocking read into `buffer`
1313    pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
1314        self.rx.blocking_read(buffer)
1315    }
1316
1317    /// Split the Uart into a transmitter and receiver, which is
1318    /// particularly useful when having two tasks correlating to
1319    /// transmitting and receiving.
1320    pub fn split(self) -> (UartTx<'d, T, M>, UartRx<'d, T, M>) {
1321        (self.tx, self.rx)
1322    }
1323
1324    /// Split the Uart into a transmitter and receiver by mutable reference,
1325    /// which is particularly useful when having two tasks correlating to
1326    /// transmitting and receiving.
1327    pub fn split_ref(&mut self) -> (&mut UartTx<'d, T, M>, &mut UartRx<'d, T, M>) {
1328        (&mut self.tx, &mut self.rx)
1329    }
1330
1331    /// Send break character
1332    pub fn send_break(&self) {
1333        self.tx.send_break();
1334    }
1335
1336    /// Set baudrate
1337    pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError> {
1338        self.tx.set_baudrate(baudrate)?;
1339        self.rx.set_baudrate(baudrate)?;
1340        Ok(())
1341    }
1342}
1343
1344fn reconfigure<T: Instance>(kernel_clock: Hertz, config: &Config) -> Result<(), ConfigError> {
1345    T::Interrupt::disable();
1346    let r = T::regs();
1347
1348    let cr = r.cr1().read();
1349    configure::<T>(kernel_clock, config, cr.re(), cr.te())?;
1350
1351    T::Interrupt::unpend();
1352    unsafe {  T::Interrupt::enable() };
1353
1354    Ok(())
1355}
1356
1357fn calculate_brr(baud: u32, pclk: u32, presc: u32, mul: u32) -> u32 {
1358    // The calculation to be done to get the BRR is `mul * pclk / presc / baud`
1359    // To do this in 32-bit only we can't multiply `mul` and `pclk`
1360    let clock = pclk / presc;
1361
1362    // The mul is applied as the last operation to prevent overflow
1363    let brr = clock / baud * mul;
1364
1365    // The BRR calculation will be a bit off because of integer rounding.
1366    // Because we multiplied our inaccuracy with mul, our rounding now needs to be in proportion to mul.
1367    let rounding = ((clock % baud) * mul + (baud / 2)) / baud;
1368
1369    brr + rounding
1370}
1371
1372fn set_baudrate<T: Instance>(kernel_clock: Hertz, baudrate: u32) -> Result<(), ConfigError> {
1373    T::Interrupt::disable();
1374
1375    set_usart_baudrate::<T>(kernel_clock, baudrate)?;
1376
1377    T::Interrupt::unpend();
1378    unsafe { T::Interrupt::enable() };
1379
1380    Ok(())
1381}
1382
1383fn find_and_set_brr(r: Regs, kind: Kind, kernel_clock: Hertz, baudrate: u32) -> Result<bool, ConfigError> {
1384    static DIVS: [(u16, ()); 1] = [(1, ())];
1385
1386    let (mul, brr_min, brr_max) = match kind {
1387        // Kind::Lpuart => {
1388        //     trace!("USART: Kind::Lpuart");
1389        //     (256, 0x300, 0x10_0000)
1390        // }
1391        Kind::Uart => {
1392            trace!("USART: Kind::Uart");
1393            (1, 0x10, 0x1_0000)
1394        }
1395    };
1396
1397    let mut found_brr = None;
1398    let mut over8 = false;
1399
1400    for &(presc, _presc_val) in &DIVS {
1401        let brr = calculate_brr(baudrate, kernel_clock.0, presc as u32, mul);
1402        trace!(
1403            "USART: presc={}, div=0x{:08x} (mantissa = {}, fraction = {})",
1404            presc,
1405            brr,
1406            brr >> 4,
1407            brr & 0x0F
1408        );
1409
1410        if brr < brr_min {
1411            if brr * 2 >= brr_min && kind == Kind::Uart {
1412                over8 = true;
1413                r.brr().write_value(regs::Brr(((brr << 1) & !0xF) | (brr & 0x07)));
1414                found_brr = Some(brr);
1415                break;
1416            }
1417            return Err(ConfigError::BaudrateTooHigh);
1418        }
1419
1420        if brr < brr_max {
1421            r.brr().write_value(regs::Brr(brr));
1422            found_brr = Some(brr);
1423            break;
1424        }
1425    }
1426
1427    match found_brr {
1428        Some(brr) => {
1429            let oversampling = if over8 { "8 bit" } else { "16 bit" };
1430            trace!(
1431                "Using {} oversampling, desired baudrate: {}, actual baudrate: {}",
1432                oversampling,
1433                baudrate,
1434                kernel_clock.0 / brr * mul
1435            );
1436            Ok(over8)
1437        }
1438        None => Err(ConfigError::BaudrateTooLow),
1439    }
1440}
1441
1442fn set_usart_baudrate<T: Instance>(kernel_clock: Hertz, baudrate: u32) -> Result<(), ConfigError> {
1443    let r = T::regs();
1444    r.cr1().modify(|w| {
1445        // disable uart
1446        w.set_ue(false);
1447    });
1448
1449    let over8 = find_and_set_brr(r, T::kind(), kernel_clock, baudrate)?;
1450
1451    r.cr1().modify(|w| {
1452        // enable uart
1453        w.set_ue(true);
1454
1455        w.set_over8(vals::OVER8::from_bits(over8 as _));
1456    });
1457
1458    Ok(())
1459}
1460
1461fn configure<T: Instance>(
1462    kernel_clock: Hertz,
1463    config: &Config,
1464    enable_rx: bool,
1465    enable_tx: bool,
1466) -> Result<(), ConfigError> {
1467    let r = T::regs();
1468    let kind = T::kind();
1469
1470    if !enable_rx && !enable_tx {
1471        return Err(ConfigError::RxOrTxNotEnabled);
1472    }
1473
1474    // UART must be disabled during configuration.
1475    r.cr1().modify(|w| {
1476        w.set_ue(false);
1477    });
1478
1479    let over8 = find_and_set_brr(r, kind, kernel_clock, config.baudrate)?;
1480
1481    r.cr2().write(|w| {
1482        w.set_stop(match config.stop_bits {
1483            // StopBits::STOP0P5 => vals::STOP::STOP0P5,
1484            StopBits::STOP1 => vals::STOP::Stop1,
1485            // StopBits::STOP1P5 => vals::STOP::STOP1P5,
1486            StopBits::STOP2 => vals::STOP::Stop2,
1487        });
1488    });
1489
1490    r.cr3().modify(|w| {
1491        w.set_onebit(config.assume_noise_free);
1492        w.set_hdsel(config.duplex.is_half());
1493    });
1494
1495    r.cr1().write(|w| {
1496        // enable uart
1497        w.set_ue(true);
1498
1499        if config.duplex.is_half() {
1500            // The te and re bits will be set by write, read and flush methods.
1501            // Receiver should be enabled by default for Half-Duplex.
1502            w.set_te(false);
1503            w.set_re(true);
1504        } else {
1505            // enable transceiver
1506            w.set_te(enable_tx);
1507            // enable receiver
1508            w.set_re(enable_rx);
1509        }
1510
1511        // configure word size and parity, since the parity bit is inserted into the MSB position,
1512        // it increases the effective word size
1513        match (config.parity, config.data_bits) {
1514            (Parity::ParityNone, DataBits::DataBits8) => {
1515                trace!("USART: m: 8 data bits, no parity");
1516                w.set_m(vals::M::Bit8);
1517                w.set_pce(false);
1518            }
1519            (Parity::ParityNone, DataBits::DataBits9) => {
1520                trace!("USART: m: 9 data bits, no parity");
1521                w.set_m(vals::M::Bit9);
1522                w.set_pce(false);
1523            }
1524            (Parity::ParityNone, DataBits::DataBits7) => {
1525                trace!("USART: m: 7 data bits, no parity");
1526                w.set_m(vals::M::Bit8);
1527                w.set_pce(false);
1528            }
1529            (Parity::ParityEven, DataBits::DataBits8) => {
1530                trace!("USART: m: 8 data bits, even parity");
1531                w.set_m(vals::M::Bit9);
1532                w.set_pce(true);
1533                w.set_ps(vals::PS::Even);
1534            }
1535            (Parity::ParityEven, DataBits::DataBits7) => {
1536                trace!("USART: m: 7 data bits, even parity");
1537                w.set_m(vals::M::Bit8);
1538                w.set_pce(true);
1539                w.set_ps(vals::PS::Even);
1540            }
1541            (Parity::ParityOdd, DataBits::DataBits8) => {
1542                trace!("USART: m: 8 data bits, odd parity");
1543                w.set_m(vals::M::Bit9);
1544                w.set_pce(true);
1545                w.set_ps(vals::PS::Odd);
1546            }
1547            (Parity::ParityOdd, DataBits::DataBits7) => {
1548                trace!("USART: m 7 data bits, odd parity");
1549                w.set_m(vals::M::Bit8);
1550                w.set_pce(true);
1551                w.set_ps(vals::PS::Odd);
1552            }
1553            (_, DataBits::DataBits6) => {
1554                todo!()
1555            }
1556            _ => {
1557                return Err(ConfigError::DataParityNotSupported);
1558            }
1559        }
1560        w.set_over8(vals::OVER8::from_bits(over8 as _));
1561
1562        Ok(())
1563    })?;
1564
1565    Ok(())
1566}
1567
1568impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Read<u8> for UartRx<'d, T, M> {
1569    type Error = Error;
1570    fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
1571        self.nb_read()
1572    }
1573}
1574
1575impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, T, M> {
1576    type Error = Error;
1577    fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
1578        self.blocking_write(buffer)
1579    }
1580    fn bflush(&mut self) -> Result<(), Self::Error> {
1581        self.blocking_flush()
1582    }
1583}
1584
1585impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Read<u8> for Uart<'d, T, M> {
1586    type Error = Error;
1587    fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
1588        self.nb_read()
1589    }
1590}
1591
1592impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, T, M> {
1593    type Error = Error;
1594    fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
1595        self.blocking_write(buffer)
1596    }
1597    fn bflush(&mut self) -> Result<(), Self::Error> {
1598        self.blocking_flush()
1599    }
1600}
1601
1602impl embedded_hal_nb::serial::Error for Error {
1603    fn kind(&self) -> embedded_hal_nb::serial::ErrorKind {
1604        match *self {
1605            Self::Framing => embedded_hal_nb::serial::ErrorKind::FrameFormat,
1606            Self::Noise => embedded_hal_nb::serial::ErrorKind::Noise,
1607            Self::Overrun => embedded_hal_nb::serial::ErrorKind::Overrun,
1608            Self::Parity => embedded_hal_nb::serial::ErrorKind::Parity,
1609            Self::BufferTooLong => embedded_hal_nb::serial::ErrorKind::Other,
1610        }
1611    }
1612}
1613
1614impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::ErrorType for Uart<'d, T, M> {
1615    type Error = Error;
1616}
1617
1618impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::ErrorType for UartTx<'d, T, M> {
1619    type Error = Error;
1620}
1621
1622impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::ErrorType for UartRx<'d, T, M> {
1623    type Error = Error;
1624}
1625
1626impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for UartRx<'d, T, M> {
1627    fn read(&mut self) -> nb::Result<u8, Self::Error> {
1628        self.nb_read()
1629    }
1630}
1631
1632impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Write for UartTx<'d, T, M> {
1633    fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
1634        self.blocking_write(&[char]).map_err(nb::Error::Other)
1635    }
1636
1637    fn flush(&mut self) -> nb::Result<(), Self::Error> {
1638        self.blocking_flush().map_err(nb::Error::Other)
1639    }
1640}
1641
1642impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for Uart<'d, T, M> {
1643    fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
1644        self.nb_read()
1645    }
1646}
1647
1648impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Write for Uart<'d, T, M> {
1649    fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
1650        self.blocking_write(&[char]).map_err(nb::Error::Other)
1651    }
1652
1653    fn flush(&mut self) -> nb::Result<(), Self::Error> {
1654        self.blocking_flush().map_err(nb::Error::Other)
1655    }
1656}
1657
1658impl embedded_io::Error for Error {
1659    fn kind(&self) -> embedded_io::ErrorKind {
1660        embedded_io::ErrorKind::Other
1661    }
1662}
1663
1664impl<T:Instance, M: Mode> embedded_io::ErrorType for Uart<'_, T, M> {
1665    type Error = Error;
1666}
1667
1668impl<T:Instance, M: Mode> embedded_io::ErrorType for UartTx<'_, T, M> {
1669    type Error = Error;
1670}
1671
1672impl<T:Instance, M: Mode> embedded_io::Write for Uart<'_, T, M> {
1673    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1674        self.blocking_write(buf)?;
1675        Ok(buf.len())
1676    }
1677
1678    fn flush(&mut self) -> Result<(), Self::Error> {
1679        self.blocking_flush()
1680    }
1681}
1682
1683impl<T:Instance, M: Mode> embedded_io::Write for UartTx<'_, T, M> {
1684    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1685        self.blocking_write(buf)?;
1686        Ok(buf.len())
1687    }
1688
1689    fn flush(&mut self) -> Result<(), Self::Error> {
1690        self.blocking_flush()
1691    }
1692}
1693
1694impl<T:Instance> embedded_io_async::Write for Uart<'_, T, Async> {
1695    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1696        self.write(buf).await?;
1697        Ok(buf.len())
1698    }
1699
1700    async fn flush(&mut self) -> Result<(), Self::Error> {
1701        self.flush().await
1702    }
1703}
1704
1705impl<T:Instance> embedded_io_async::Write for UartTx<'_, T, Async> {
1706    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1707        self.write(buf).await?;
1708        Ok(buf.len())
1709    }
1710
1711    async fn flush(&mut self) -> Result<(), Self::Error> {
1712        self.flush().await
1713    }
1714}
1715
1716pub use buffered::*;
1717
1718pub use crate::usart::buffered::InterruptHandler as BufferedInterruptHandler;
1719mod buffered;
1720
1721mod ringbuffered;
1722pub use ringbuffered::RingBufferedUartRx;
1723
1724fn clear_interrupt_flags(r: Regs, sr: regs::Isr) {
1725    r.icr().write(|w| *w = regs::Icr(sr.0));
1726}
1727
1728#[derive(Clone, Copy, PartialEq, Eq)]
1729enum Kind {
1730    Uart,
1731    // #[allow(unused)]
1732    // Lpuart,
1733}
1734
1735struct State {
1736    rx_waker: AtomicWaker,
1737    tx_rx_refcount: AtomicU8,
1738}
1739
1740impl State {
1741    const fn new() -> Self {
1742        Self {
1743            rx_waker: AtomicWaker::new(),
1744            tx_rx_refcount: AtomicU8::new(0),
1745        }
1746    }
1747}
1748
1749#[allow(private_interfaces)]
1750pub(crate) trait SealedInstance: crate::rcc::RccEnableReset + crate::rcc::RccGetFreq {
1751    fn regs() -> Regs;
1752    fn interrupt() -> Interrupt;
1753    fn kind() -> Kind;
1754    fn state() -> &'static State;
1755    fn buffered_state() -> &'static buffered::State;
1756}
1757
1758/// USART peripheral instance trait.
1759#[allow(private_bounds)]
1760pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send {
1761    /// Interrupt for this peripheral.
1762    type Interrupt: interrupt::typelevel::Interrupt;
1763}
1764
1765pin_trait!(RxdPin, Instance);
1766pin_trait!(TxdPin, Instance);
1767pin_trait!(CtsPin, Instance);
1768pin_trait!(RtsPin, Instance);
1769pin_trait!(CkPin, Instance);
1770
1771dma_trait!(TxDma, Instance);
1772dma_trait!(RxDma, Instance);
1773
1774macro_rules! impl_usart {
1775    ($inst:ident, $irq:ident, $kind:expr) => {
1776        #[allow(private_interfaces)]
1777        impl SealedInstance for crate::peripherals::$inst {
1778            fn regs() -> Regs {
1779                crate::pac::$inst
1780            }
1781
1782            fn interrupt() -> Interrupt {
1783                crate::interrupt::$irq
1784            }
1785
1786            fn kind() -> Kind {
1787                $kind
1788            }
1789
1790            fn state() -> &'static State {
1791                static STATE: State = State::new();
1792                &STATE
1793            }
1794
1795            fn buffered_state() -> &'static buffered::State {
1796                static BUFFERED_STATE: buffered::State = buffered::State::new();
1797                &BUFFERED_STATE
1798            }
1799        }
1800
1801        impl Instance for crate::peripherals::$inst {
1802            type Interrupt = crate::interrupt::typelevel::$irq;
1803        }
1804    };
1805}
1806
1807// TODO: move to _generated.rs
1808impl_usart!(USART1, USART1, Kind::Uart);
1809impl_usart!(USART2, USART2, Kind::Uart);
1810impl_usart!(USART3, USART3, Kind::Uart);