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