stm32f1xx_hal/
serial.rs

1//! # Serial Communication (USART)
2//!
3//! This module contains the functions to utilize the USART (Universal
4//! synchronous asynchronous receiver transmitter)
5//!
6//! ## Note
7//!
8//! When transmitting with the parity enabled, the value written in the MSB
9//! (bit 7 or bit 8 depending on the word length) has no effect because it
10//! is replaced by the parity.
11//! When receiving with the parity enabled, the value read in the MSB
12//! is the received parity bit.
13//!
14//! | Frame format               | Word Length | Parity |
15//! | -------------------------- |:----------- |:------ |
16//! | 7 data bits + 1 parity bit | 8 bits      | V      |
17//! | 8 data bits                | 8 bits      |        |
18//! | 8 data bits + 1 parity bit | 9 bits      | V      |
19//! | 9 data bits                | 9 bits      |        |
20//!
21//! ## Alternate function remapping
22//!
23//! ### USART1
24//!
25//! | Function \ Remap | 0 (default) | 1    |
26//! |------------------|-------------|------|
27//! | TX (A-PP/OD)     | PA9         | PB6  |
28//! | RX (I-F/PU)      | PA10        | PB7  |
29//!
30//! ### USART2
31//!
32//! | Function \ Remap | 0 (default) | 1    |
33//! |------------------|-------------|------|
34//! | TX (A-PP/OD)     | PA2         | PD5  |
35//! | RX (I-F/PU)      | PA3         | PD6  |
36//!
37//! ### USART3
38//!
39//! | Function \ Remap | 0 (default) | 1    | 2   |
40//! |------------------|-------------|------|-----|
41//! | TX (A-PP/OD)     | PB10        | PC10 | PD8 |
42//! | RX (I-F/PU)      | PB11        | PC11 | PD9 |
43//!
44//! ### UART4/UART5
45//!
46//! | Function     | UART4 | UART5 |
47//! |--------------|------ | ------|
48//! | TX (A-PP/OD) | PC10  | PC12  |
49//! | RX (I-F/PU)  | PC11  | PD2   |
50//!
51//! ## Example usage:
52//!
53//!  ```rust
54//! let dp = stm32f1xx_hal::Peripherals::take().unwrap();
55//! let mut flash = dp.FLASH.constrain();
56//! let mut rcc = dp.RCC.constrain();
57//! let clocks = rcc.cfgr.freeze(&mut flash.acr);
58//! let mut afio = dp.AFIO.constrain(&mut rcc);
59//! let mut gpioa = dp.GPIOA.split(&mut rcc);
60//!
61//! // USART1 on Pins A9 and A10
62//! let pin_tx = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh);
63//! let pin_rx = gpioa.pa10;
64//! // Create an interface struct for USART1 with 9600 Baud
65//! let serial = Serial::new(
66//!     dp.USART1,
67//!     (pin_tx, pin_rx),
68//!     &mut afio.mapr,
69//!     Config::default()
70//!         .baudrate(9600.bps())
71//!         .wordlength_9bits()
72//!         .parity_none(),
73//!     &clocks,
74//! );
75//!
76//! // Separate into tx and rx channels
77//! let (mut tx, mut rx) = serial.split();
78//!
79//! // Write data (9 bits) to the USART.
80//! // Depending on the configuration, only the lower 7, 8, or 9 bits are used.
81//! block!(tx.write_u16(0x1FF)).unwrap();
82//!
83//! // Write 'R' (8 bits) to the USART
84//! block!(tx.write_u8(b'R')).unwrap();
85//!
86//! // Receive a data (9 bits) from the USART and store it in "received"
87//! let received = block!(rx.read_u16()).unwrap();
88//!
89//! // Receive a data (8 bits) from the USART and store it in "received"
90//! let received = block!(rx.read()).unwrap();
91//!  ```
92
93use core::marker::PhantomData;
94use core::ops::Deref;
95use core::sync::atomic::{self, Ordering};
96use embedded_dma::{ReadBuffer, WriteBuffer};
97
98use crate::afio::{self, RInto, Rmp};
99#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
100use crate::dma::dma2;
101use crate::dma::{self, dma1, CircBuffer, RxDma, Transfer, TxDma};
102use crate::gpio::{Floating, PushPull, UpMode};
103use crate::pac::{self};
104use crate::rcc::{BusClock, Clocks, Enable, Rcc, Reset};
105use crate::time::{Bps, U32Ext};
106
107mod hal_02;
108mod hal_1;
109
110use crate::pacext::uart::{SrR, UartRB};
111
112pub trait SerialExt: Sized + Instance {
113    fn serial<Otype, PULL: UpMode>(
114        self,
115        pins: (
116            impl RInto<Self::Tx<Otype>, 0>,
117            impl RInto<Self::Rx<PULL>, 0>,
118        ),
119        config: impl Into<Config>,
120        rcc: &mut Rcc,
121    ) -> Serial<Self, Otype, PULL>;
122    fn tx<Otype>(
123        self,
124        tx_pin: impl RInto<Self::Tx<Otype>, 0>,
125        config: impl Into<Config>,
126        rcc: &mut Rcc,
127    ) -> Tx<Self>;
128    fn rx<PULL: UpMode>(
129        self,
130        rx_pin: impl RInto<Self::Rx<PULL>, 0>,
131        config: impl Into<Config>,
132        rcc: &mut Rcc,
133    ) -> Rx<Self>;
134}
135
136impl<USART: Instance> SerialExt for USART {
137    fn serial<Otype, PULL: UpMode>(
138        self,
139        pins: (
140            impl RInto<Self::Tx<Otype>, 0>,
141            impl RInto<Self::Rx<PULL>, 0>,
142        ),
143        config: impl Into<Config>,
144        rcc: &mut Rcc,
145    ) -> Serial<Self, Otype, PULL> {
146        Serial::new(self, pins, config, rcc)
147    }
148    fn tx<Otype>(
149        self,
150        tx_pin: impl RInto<Self::Tx<Otype>, 0>,
151        config: impl Into<Config>,
152        rcc: &mut Rcc,
153    ) -> Tx<Self> {
154        Serial::tx(self, tx_pin, config, rcc)
155    }
156    fn rx<PULL: UpMode>(
157        self,
158        rx_pin: impl RInto<Self::Rx<PULL>, 0>,
159        config: impl Into<Config>,
160        rcc: &mut Rcc,
161    ) -> Rx<Self> {
162        Serial::rx(self, rx_pin, config, rcc)
163    }
164}
165
166pub trait RBExt: UartRB {
167    fn set_stopbits(&self, bits: StopBits);
168}
169
170impl RBExt for pac::usart1::RegisterBlock {
171    fn set_stopbits(&self, bits: StopBits) {
172        use crate::pac::usart1::cr2::STOP;
173
174        self.cr2().write(|w| {
175            w.stop().variant(match bits {
176                StopBits::STOP0P5 => STOP::Stop0p5,
177                StopBits::STOP1 => STOP::Stop1,
178                StopBits::STOP1P5 => STOP::Stop1p5,
179                StopBits::STOP2 => STOP::Stop2,
180            })
181        });
182    }
183}
184
185#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
186impl RBExt for pac::uart4::RegisterBlock {
187    fn set_stopbits(&self, bits: StopBits) {
188        use crate::pac::uart4::cr2::STOP;
189
190        // StopBits::STOP0P5 and StopBits::STOP1P5 aren't supported when using UART
191        // STOP_A::STOP1 and STOP_A::STOP2 will be used, respectively
192        self.cr2().write(|w| {
193            w.stop().variant(match bits {
194                StopBits::STOP0P5 | StopBits::STOP1 => STOP::Stop1,
195                StopBits::STOP1P5 | StopBits::STOP2 => STOP::Stop2,
196            })
197        });
198    }
199}
200
201pub trait Instance:
202    crate::Sealed
203    + crate::Ptr<RB: RBExt>
204    + Deref<Target = Self::RB>
205    + Enable
206    + Reset
207    + BusClock
208    + afio::SerialAsync
209{
210}
211
212macro_rules! inst {
213    ($($USARTX:ty;)+) => {
214        $(
215            impl Instance for $USARTX { }
216        )+
217    };
218}
219
220inst! {
221    pac::USART1;
222    pac::USART2;
223    pac::USART3;
224}
225#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
226inst! {
227    pac::UART4;
228    pac::UART5;
229}
230
231/// Serial error
232#[derive(Debug)]
233#[non_exhaustive]
234pub enum Error {
235    /// The peripheral receive buffer was overrun.
236    Overrun,
237    /// Received data does not conform to the peripheral configuration.
238    /// Can be caused by a misconfigured device on either end of the serial line.
239    FrameFormat,
240    /// Parity check failed.
241    Parity,
242    /// Serial line is too noisy to read valid data.
243    Noise,
244    /// A different error occurred. The original error may contain more information.
245    Other,
246}
247
248pub enum WordLength {
249    /// When parity is enabled, a word has 7 data bits + 1 parity bit,
250    /// otherwise 8 data bits.
251    Bits8,
252    /// When parity is enabled, a word has 8 data bits + 1 parity bit,
253    /// otherwise 9 data bits.
254    Bits9,
255}
256
257pub enum Parity {
258    ParityNone,
259    ParityEven,
260    ParityOdd,
261}
262
263pub enum StopBits {
264    /// 1 stop bit
265    STOP1,
266    /// 0.5 stop bits
267    STOP0P5,
268    /// 2 stop bits
269    STOP2,
270    /// 1.5 stop bits
271    STOP1P5,
272}
273
274pub struct Config {
275    pub baudrate: Bps,
276    pub wordlength: WordLength,
277    pub parity: Parity,
278    pub stopbits: StopBits,
279}
280
281impl Config {
282    pub fn baudrate(mut self, baudrate: Bps) -> Self {
283        self.baudrate = baudrate;
284        self
285    }
286
287    pub fn wordlength(mut self, wordlength: WordLength) -> Self {
288        self.wordlength = wordlength;
289        self
290    }
291
292    pub fn wordlength_8bits(mut self) -> Self {
293        self.wordlength = WordLength::Bits8;
294        self
295    }
296
297    pub fn wordlength_9bits(mut self) -> Self {
298        self.wordlength = WordLength::Bits9;
299        self
300    }
301
302    pub fn parity(mut self, parity: Parity) -> Self {
303        self.parity = parity;
304        self
305    }
306
307    pub fn parity_none(mut self) -> Self {
308        self.parity = Parity::ParityNone;
309        self
310    }
311
312    pub fn parity_even(mut self) -> Self {
313        self.parity = Parity::ParityEven;
314        self
315    }
316
317    pub fn parity_odd(mut self) -> Self {
318        self.parity = Parity::ParityOdd;
319        self
320    }
321
322    pub fn stopbits(mut self, stopbits: StopBits) -> Self {
323        self.stopbits = stopbits;
324        self
325    }
326}
327
328impl Default for Config {
329    fn default() -> Config {
330        Config {
331            baudrate: 115_200_u32.bps(),
332            wordlength: WordLength::Bits8,
333            parity: Parity::ParityNone,
334            stopbits: StopBits::STOP1,
335        }
336    }
337}
338
339impl From<Bps> for Config {
340    fn from(baud: Bps) -> Self {
341        Config::default().baudrate(baud)
342    }
343}
344
345/// Serial abstraction
346pub struct Serial<USART: Instance, Otype = PushPull, PULL = Floating> {
347    pub tx: Tx<USART>,
348    pub rx: Rx<USART>,
349    #[allow(clippy::type_complexity)]
350    pub token: ReleaseToken<USART, (Option<USART::Tx<Otype>>, Option<USART::Rx<PULL>>)>,
351}
352
353/// Serial transmitter
354pub struct Tx<USART> {
355    _usart: PhantomData<USART>,
356}
357
358/// Serial receiver
359pub struct Rx<USART> {
360    _usart: PhantomData<USART>,
361}
362
363/// Stores data for release
364pub struct ReleaseToken<USART, PINS> {
365    usart: USART,
366    pins: PINS,
367}
368
369impl<USART: Instance, const R: u8> Rmp<USART, R> {
370    pub fn serial<Otype, PULL: UpMode>(
371        self,
372        pins: (
373            impl RInto<USART::Tx<Otype>, R>,
374            impl RInto<USART::Rx<PULL>, R>,
375        ),
376        config: impl Into<Config>,
377        rcc: &mut Rcc,
378    ) -> Serial<USART, Otype, PULL> {
379        Serial::_new(self.0, (Some(pins.0), Some(pins.1)), config, rcc)
380    }
381    pub fn tx<Otype>(
382        self,
383        tx_pin: impl RInto<USART::Tx<Otype>, R>,
384        config: impl Into<Config>,
385        rcc: &mut Rcc,
386    ) -> Tx<USART> {
387        Serial::_new(
388            self.0,
389            (Some(tx_pin), None::<USART::Rx<Floating>>),
390            config,
391            rcc,
392        )
393        .split()
394        .0
395    }
396    pub fn rx<PULL: UpMode>(
397        self,
398        rx_pin: impl RInto<USART::Rx<PULL>, R>,
399        config: impl Into<Config>,
400        rcc: &mut Rcc,
401    ) -> Rx<USART> {
402        Serial::_new(
403            self.0,
404            (None::<USART::Tx<Floating>>, Some(rx_pin)),
405            config,
406            rcc,
407        )
408        .split()
409        .1
410    }
411}
412
413impl<USART: Instance, Otype> Serial<USART, Otype, Floating> {
414    pub fn tx<const R: u8>(
415        usart: impl Into<Rmp<USART, R>>,
416        tx_pin: impl RInto<USART::Tx<Otype>, R>,
417        config: impl Into<Config>,
418        rcc: &mut Rcc,
419    ) -> Tx<USART> {
420        usart.into().tx(tx_pin, config, rcc)
421    }
422}
423
424impl<USART: Instance, PULL: UpMode> Serial<USART, PushPull, PULL> {
425    pub fn rx<const R: u8>(
426        usart: impl Into<Rmp<USART, R>>,
427        rx_pin: impl RInto<USART::Rx<PULL>, R>,
428        config: impl Into<Config>,
429        rcc: &mut Rcc,
430    ) -> Rx<USART> {
431        usart.into().rx(rx_pin, config, rcc)
432    }
433}
434
435impl<USART: Instance, Otype, PULL: UpMode> Serial<USART, Otype, PULL> {
436    /// Configures the serial interface and creates the interface
437    /// struct.
438    ///
439    /// `Bps` is the baud rate of the interface.
440    ///
441    /// `Clocks` passes information about the current frequencies of
442    /// the clocks.  The existence of the struct ensures that the
443    /// clock settings are fixed.
444    ///
445    /// The `serial` struct takes ownership over the `USARTX` device
446    /// registers and the specified `PINS`
447    ///
448    /// `MAPR` and `APBX` are register handles which are passed for
449    /// configuration. (`MAPR` is used to map the USART to the
450    /// corresponding pins. `APBX` is used to reset the USART.)
451    pub fn new<const R: u8>(
452        usart: impl Into<Rmp<USART, R>>,
453        pins: (
454            impl RInto<USART::Tx<Otype>, R>,
455            impl RInto<USART::Rx<PULL>, R>,
456        ),
457        config: impl Into<Config>,
458        rcc: &mut Rcc,
459    ) -> Self {
460        usart.into().serial(pins, config, rcc)
461    }
462
463    fn _new<const R: u8>(
464        usart: USART,
465        pins: (
466            Option<impl RInto<USART::Tx<Otype>, R>>,
467            Option<impl RInto<USART::Rx<PULL>, R>>,
468        ),
469        config: impl Into<Config>,
470        rcc: &mut Rcc,
471    ) -> Self {
472        // Enable and reset USART
473        USART::enable(rcc);
474        USART::reset(rcc);
475
476        apply_config::<USART>(config.into(), &rcc.clocks);
477
478        let pins = (pins.0.map(RInto::rinto), pins.1.map(RInto::rinto));
479
480        // UE: enable USART
481        // TE: enable transceiver
482        // RE: enable receiver
483        usart.cr1().modify(|_r, w| {
484            w.ue().set_bit();
485            w.te().set_bit();
486            w.re().set_bit();
487            w
488        });
489
490        Serial {
491            tx: Tx {
492                _usart: PhantomData,
493            },
494            rx: Rx {
495                _usart: PhantomData,
496            },
497            token: ReleaseToken { usart, pins },
498        }
499    }
500}
501
502impl<USART: Instance, Otype, PULL> Serial<USART, Otype, PULL> {
503    /// Reconfigure the USART instance.
504    ///
505    /// If a transmission is currently in progress, this returns
506    /// [`nb::Error::WouldBlock`].
507    pub fn reconfigure(
508        &mut self,
509        config: impl Into<Config>,
510        clocks: &Clocks,
511    ) -> nb::Result<(), Error> {
512        reconfigure(&mut self.tx, &mut self.rx, config, clocks)
513    }
514
515    /// Returns ownership of the borrowed register handles
516    ///
517    /// # Examples
518    ///
519    /// Basic usage:
520    ///
521    /// ```
522    /// let mut serial = Serial::new(usart, (tx_pin, rx_pin), &mut afio.mapr, 9600.bps(), &mut rcc);
523    ///
524    /// // You can split the `Serial`
525    /// let Serial { tx, rx, token } = serial;
526    ///
527    /// // You can reunite the `Serial` back
528    /// let serial = Serial { tx, rx, token };
529    ///
530    /// // Release `Serial`
531    /// let (usart, (tx_pin, rx_pin)) = serial.release();
532    /// ```
533    #[allow(clippy::type_complexity)]
534    pub fn release(self) -> (USART, (Option<USART::Tx<Otype>>, Option<USART::Rx<PULL>>)) {
535        (self.token.usart, self.token.pins)
536    }
537
538    /// Separates the serial struct into separate channel objects for sending (Tx) and
539    /// receiving (Rx)
540    ///
541    /// If in the future it will be necessary to free up resources,
542    /// then you need to use a different method of separation:
543    ///
544    /// ```
545    /// let Serial { tx, rx, token } = serial;
546    /// ```
547    pub fn split(self) -> (Tx<USART>, Rx<USART>) {
548        (self.tx, self.rx)
549    }
550}
551
552fn apply_config<USART: Instance>(config: Config, clocks: &Clocks) {
553    let usart = unsafe { &*USART::ptr() };
554
555    // Configure baud rate
556    let brr = USART::clock(clocks).raw() / config.baudrate.0;
557    assert!(brr >= 16, "impossible baud rate");
558    usart.brr().write(|w| unsafe { w.bits(brr as u16) });
559
560    // Configure word
561    usart.cr1().modify(|_r, w| {
562        w.m().bit(match config.wordlength {
563            WordLength::Bits8 => false,
564            WordLength::Bits9 => true,
565        });
566        use crate::pac::usart1::cr1::PS;
567        w.ps().variant(match config.parity {
568            Parity::ParityOdd => PS::Odd,
569            _ => PS::Even,
570        });
571        w.pce().bit(!matches!(config.parity, Parity::ParityNone));
572        w
573    });
574
575    // Configure stop bits
576    usart.set_stopbits(config.stopbits);
577}
578
579/// Reconfigure the USART instance.
580///
581/// If a transmission is currently in progress, this returns
582/// [`nb::Error::WouldBlock`].
583pub fn reconfigure<USART: Instance>(
584    tx: &mut Tx<USART>,
585    #[allow(unused_variables)] rx: &mut Rx<USART>,
586    config: impl Into<Config>,
587    clocks: &Clocks,
588) -> nb::Result<(), Error> {
589    // if we're currently busy transmitting, we have to wait until that is
590    // over -- regarding reception, we assume that the caller -- with
591    // exclusive access to the Serial instance due to &mut self -- knows
592    // what they're doing.
593    tx.flush()?;
594    apply_config::<USART>(config.into(), clocks);
595    Ok(())
596}
597
598impl<USART: Instance> Tx<USART> {
599    /// Writes 9-bit words to the UART/USART
600    ///
601    /// If the UART/USART was configured with `WordLength::Bits9`, the 9 least significant bits will
602    /// be transmitted and the other 7 bits will be ignored. Otherwise, the 8 least significant bits
603    /// will be transmitted and the other 8 bits will be ignored.
604    pub fn write_u16(&mut self, word: u16) -> nb::Result<(), Error> {
605        let usart = unsafe { &*USART::ptr() };
606
607        if usart.sr().read().txe().bit_is_set() {
608            usart.dr().write(|w| w.dr().set(word));
609            Ok(())
610        } else {
611            Err(nb::Error::WouldBlock)
612        }
613    }
614
615    pub fn write_u8(&mut self, word: u8) -> nb::Result<(), Error> {
616        self.write_u16(word as u16)
617    }
618
619    pub fn bwrite_all_u16(&mut self, buffer: &[u16]) -> Result<(), Error> {
620        for &w in buffer {
621            nb::block!(self.write_u16(w))?;
622        }
623        Ok(())
624    }
625
626    pub fn bwrite_all_u8(&mut self, buffer: &[u8]) -> Result<(), Error> {
627        for &w in buffer {
628            nb::block!(self.write_u8(w))?;
629        }
630        Ok(())
631    }
632
633    pub fn flush(&mut self) -> nb::Result<(), Error> {
634        let usart = unsafe { &*USART::ptr() };
635
636        if usart.sr().read().tc().bit_is_set() {
637            Ok(())
638        } else {
639            Err(nb::Error::WouldBlock)
640        }
641    }
642
643    pub fn bflush(&mut self) -> Result<(), Error> {
644        nb::block!(self.flush())
645    }
646
647    /// Start listening for transmit interrupt event
648    pub fn listen(&mut self) {
649        unsafe { (*USART::ptr()).cr1().modify(|_, w| w.txeie().set_bit()) };
650    }
651
652    /// Stop listening for transmit interrupt event
653    pub fn unlisten(&mut self) {
654        unsafe { (*USART::ptr()).cr1().modify(|_, w| w.txeie().clear_bit()) };
655    }
656
657    /// Returns true if the tx register is empty (and can accept data)
658    pub fn is_tx_empty(&self) -> bool {
659        unsafe { (*USART::ptr()).sr().read().txe().bit_is_set() }
660    }
661
662    pub fn is_tx_complete(&self) -> bool {
663        unsafe { (*USART::ptr()).sr().read().tc().bit_is_set() }
664    }
665}
666
667impl<USART: Instance> core::fmt::Write for Tx<USART> {
668    fn write_str(&mut self, s: &str) -> core::fmt::Result {
669        s.bytes()
670            .try_for_each(|c| nb::block!(self.write_u8(c)))
671            .map_err(|_| core::fmt::Error)
672    }
673}
674
675impl<USART: Instance> Rx<USART> {
676    /// Reads 9-bit words from the UART/USART
677    ///
678    /// If the UART/USART was configured with `WordLength::Bits9`, the returned value will contain
679    /// 9 received data bits and all other bits set to zero. Otherwise, the returned value will contain
680    /// 8 received data bits and all other bits set to zero.
681    pub fn read_u16(&mut self) -> nb::Result<u16, Error> {
682        let usart = unsafe { &*USART::ptr() };
683        let sr = usart.sr().read();
684
685        // Check for any errors
686        let err = if sr.pe().bit_is_set() {
687            Some(Error::Parity)
688        } else if sr.fe().bit_is_set() {
689            Some(Error::FrameFormat)
690        } else if sr.nf().bit_is_set() {
691            Some(Error::Noise)
692        } else if sr.ore().bit_is_set() {
693            Some(Error::Overrun)
694        } else {
695            None
696        };
697
698        if let Some(err) = err {
699            // Some error occurred. In order to clear that error flag, you have to
700            // do a read from the sr register followed by a read from the dr register.
701            let _ = usart.sr().read();
702            let _ = usart.dr().read();
703            Err(nb::Error::Other(err))
704        } else {
705            // Check if a byte is available
706            if sr.rxne().bit_is_set() {
707                // Read the received byte
708                Ok(usart.dr().read().dr().bits())
709            } else {
710                Err(nb::Error::WouldBlock)
711            }
712        }
713    }
714
715    pub fn read(&mut self) -> nb::Result<u8, Error> {
716        self.read_u16().map(|word16| word16 as u8)
717    }
718
719    /// Start listening for receive interrupt event
720    pub fn listen(&mut self) {
721        unsafe { (*USART::ptr()).cr1().modify(|_, w| w.rxneie().set_bit()) };
722    }
723
724    /// Stop listening for receive interrupt event
725    pub fn unlisten(&mut self) {
726        unsafe { (*USART::ptr()).cr1().modify(|_, w| w.rxneie().clear_bit()) };
727    }
728
729    /// Start listening for idle interrupt event
730    pub fn listen_idle(&mut self) {
731        unsafe { (*USART::ptr()).cr1().modify(|_, w| w.idleie().set_bit()) };
732    }
733
734    /// Stop listening for idle interrupt event
735    pub fn unlisten_idle(&mut self) {
736        unsafe { (*USART::ptr()).cr1().modify(|_, w| w.idleie().clear_bit()) };
737    }
738
739    /// Returns true if the line idle status is set
740    pub fn is_idle(&self) -> bool {
741        unsafe { (*USART::ptr()).sr().read().idle().bit_is_set() }
742    }
743
744    /// Returns true if the rx register is not empty (and can be read)
745    pub fn is_rx_not_empty(&self) -> bool {
746        unsafe { (*USART::ptr()).sr().read().rxne().bit_is_set() }
747    }
748
749    /// Clear idle line interrupt flag
750    pub fn clear_idle_interrupt(&self) {
751        unsafe {
752            let _ = (*USART::ptr()).sr().read();
753            let _ = (*USART::ptr()).dr().read();
754        }
755    }
756}
757
758/// Interrupt event
759pub enum Event {
760    /// New data can be sent
761    Txe,
762    /// New data has been received
763    Rxne,
764    /// Idle line state detected
765    Idle,
766}
767
768impl<USART: Instance, Otype, PULL> Serial<USART, Otype, PULL> {
769    /// Starts listening to the USART by enabling the _Received data
770    /// ready to be read (RXNE)_ interrupt and _Transmit data
771    /// register empty (TXE)_ interrupt
772    pub fn listen(&mut self, event: Event) {
773        match event {
774            Event::Rxne => self.rx.listen(),
775            Event::Txe => self.tx.listen(),
776            Event::Idle => self.rx.listen_idle(),
777        }
778    }
779
780    /// Stops listening to the USART by disabling the _Received data
781    /// ready to be read (RXNE)_ interrupt and _Transmit data
782    /// register empty (TXE)_ interrupt
783    pub fn unlisten(&mut self, event: Event) {
784        match event {
785            Event::Rxne => self.rx.unlisten(),
786            Event::Txe => self.tx.unlisten(),
787            Event::Idle => self.rx.unlisten_idle(),
788        }
789    }
790
791    /// Returns true if the line idle status is set
792    pub fn is_idle(&self) -> bool {
793        self.rx.is_idle()
794    }
795
796    /// Returns true if the tx register is empty (and can accept data)
797    pub fn is_tx_empty(&self) -> bool {
798        self.tx.is_tx_empty()
799    }
800
801    /// Returns true if the rx register is not empty (and can be read)
802    pub fn is_rx_not_empty(&self) -> bool {
803        self.rx.is_rx_not_empty()
804    }
805
806    /// Clear idle line interrupt flag
807    pub fn clear_idle_interrupt(&self) {
808        self.rx.clear_idle_interrupt();
809    }
810}
811
812impl<USART: Instance, PINS> core::fmt::Write for Serial<USART, PINS> {
813    fn write_str(&mut self, s: &str) -> core::fmt::Result {
814        self.tx.write_str(s)
815    }
816}
817
818pub type Rx1 = Rx<pac::USART1>;
819pub type Tx1 = Tx<pac::USART1>;
820pub type Rx2 = Rx<pac::USART2>;
821pub type Tx2 = Tx<pac::USART2>;
822pub type Rx3 = Rx<pac::USART3>;
823pub type Tx3 = Tx<pac::USART3>;
824
825use crate::dma::{Receive, TransferPayload, Transmit};
826
827macro_rules! serialdma {
828    (
829        $USARTX:ty,
830        $rxdma:ident,
831        $txdma:ident,
832        rx: $dmarxch:ty,
833        tx: $dmatxch:ty
834    ) => {
835        pub type $rxdma = RxDma<Rx<$USARTX>, $dmarxch>;
836        pub type $txdma = TxDma<Tx<$USARTX>, $dmatxch>;
837
838        impl Receive for $rxdma {
839            type RxChannel = $dmarxch;
840            type TransmittedWord = u8;
841        }
842
843        impl Transmit for $txdma {
844            type TxChannel = $dmatxch;
845            type ReceivedWord = u8;
846        }
847
848        impl TransferPayload for $rxdma {
849            fn start(&mut self) {
850                self.channel.start();
851            }
852            fn stop(&mut self) {
853                self.channel.stop();
854            }
855        }
856
857        impl TransferPayload for $txdma {
858            fn start(&mut self) {
859                self.channel.start();
860            }
861            fn stop(&mut self) {
862                self.channel.stop();
863            }
864        }
865
866        impl Rx<$USARTX> {
867            pub fn with_dma(self, channel: $dmarxch) -> $rxdma {
868                unsafe {
869                    (*<$USARTX>::ptr()).cr3().modify(|_, w| w.dmar().set_bit());
870                }
871                RxDma {
872                    payload: self,
873                    channel,
874                }
875            }
876        }
877
878        impl Tx<$USARTX> {
879            pub fn with_dma(self, channel: $dmatxch) -> $txdma {
880                unsafe {
881                    (*<$USARTX>::ptr()).cr3().modify(|_, w| w.dmat().set_bit());
882                }
883                TxDma {
884                    payload: self,
885                    channel,
886                }
887            }
888        }
889
890        impl $rxdma {
891            pub fn release(mut self) -> (Rx<$USARTX>, $dmarxch) {
892                self.stop();
893                unsafe {
894                    (*<$USARTX>::ptr())
895                        .cr3()
896                        .modify(|_, w| w.dmar().clear_bit());
897                }
898                let RxDma { payload, channel } = self;
899                (payload, channel)
900            }
901        }
902
903        impl $txdma {
904            pub fn release(mut self) -> (Tx<$USARTX>, $dmatxch) {
905                self.stop();
906                unsafe {
907                    (*<$USARTX>::ptr())
908                        .cr3()
909                        .modify(|_, w| w.dmat().clear_bit());
910                }
911                let TxDma { payload, channel } = self;
912                (payload, channel)
913            }
914        }
915
916        impl<B> crate::dma::CircReadDma<B, u8> for $rxdma
917        where
918            &'static mut [B; 2]: WriteBuffer<Word = u8>,
919            B: 'static,
920        {
921            fn circ_read(mut self, mut buffer: &'static mut [B; 2]) -> CircBuffer<B, Self> {
922                // NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
923                // until the end of the transfer.
924                let (ptr, len) = unsafe { buffer.write_buffer() };
925                self.channel.set_peripheral_address(
926                    unsafe { (*<$USARTX>::ptr()).dr().as_ptr() as u32 },
927                    false,
928                );
929                self.channel.set_memory_address(ptr as u32, true);
930                self.channel.set_transfer_length(len);
931
932                atomic::compiler_fence(Ordering::Release);
933
934                self.channel.ch().cr().modify(|_, w| {
935                    w.mem2mem().clear_bit();
936                    w.pl().medium();
937                    w.msize().bits8();
938                    w.psize().bits8();
939                    w.circ().set_bit();
940                    w.dir().clear_bit()
941                });
942
943                self.start();
944
945                CircBuffer::new(buffer, self)
946            }
947        }
948
949        impl<B> crate::dma::ReadDma<B, u8> for $rxdma
950        where
951            B: WriteBuffer<Word = u8>,
952        {
953            fn read(mut self, mut buffer: B) -> Transfer<dma::W, B, Self> {
954                // NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
955                // until the end of the transfer.
956                let (ptr, len) = unsafe { buffer.write_buffer() };
957                self.channel.set_peripheral_address(
958                    unsafe { (*<$USARTX>::ptr()).dr().as_ptr() as u32 },
959                    false,
960                );
961                self.channel.set_memory_address(ptr as u32, true);
962                self.channel.set_transfer_length(len);
963
964                atomic::compiler_fence(Ordering::Release);
965                self.channel.ch().cr().modify(|_, w| {
966                    w.mem2mem().clear_bit();
967                    w.pl().medium();
968                    w.msize().bits8();
969                    w.psize().bits8();
970                    w.circ().clear_bit();
971                    w.dir().clear_bit()
972                });
973                self.start();
974
975                Transfer::w(buffer, self)
976            }
977        }
978
979        impl<B> crate::dma::WriteDma<B, u8> for $txdma
980        where
981            B: ReadBuffer<Word = u8>,
982        {
983            fn write(mut self, buffer: B) -> Transfer<dma::R, B, Self> {
984                // NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
985                // until the end of the transfer.
986                let (ptr, len) = unsafe { buffer.read_buffer() };
987
988                self.channel.set_peripheral_address(
989                    unsafe { (*<$USARTX>::ptr()).dr().as_ptr() as u32 },
990                    false,
991                );
992
993                self.channel.set_memory_address(ptr as u32, true);
994                self.channel.set_transfer_length(len);
995
996                atomic::compiler_fence(Ordering::Release);
997
998                self.channel.ch().cr().modify(|_, w| {
999                    w.mem2mem().clear_bit();
1000                    w.pl().medium();
1001                    w.msize().bits8();
1002                    w.psize().bits8();
1003                    w.circ().clear_bit();
1004                    w.dir().set_bit()
1005                });
1006                self.start();
1007
1008                Transfer::r(buffer, self)
1009            }
1010        }
1011    };
1012}
1013
1014serialdma! {
1015    pac::USART1,
1016    RxDma1,
1017    TxDma1,
1018    rx: dma1::C5,
1019    tx: dma1::C4
1020}
1021serialdma! {
1022    pac::USART2,
1023    RxDma2,
1024    TxDma2,
1025    rx: dma1::C6,
1026    tx: dma1::C7
1027}
1028serialdma! {
1029    pac::USART3,
1030    RxDma3,
1031    TxDma3,
1032    rx: dma1::C3,
1033    tx: dma1::C2
1034}
1035#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
1036serialdma! {
1037    pac::UART4,
1038    RxDma4,
1039    TxDma4,
1040    rx: dma2::C3,
1041    tx: dma2::C5
1042}