stm32f3xx_hal/
serial.rs

1//! # Serial
2//!
3//! Asynchronous serial communication using the interal USART peripherals
4//!
5//! The serial modules implement the [`Read`] and [`Write`] traits.
6//!
7//! [`Read`]: embedded_hal::serial::Read
8//! [`Write`]: embedded_hal::serial::Write
9
10use core::{
11    convert::{Infallible, TryFrom},
12    fmt,
13    ops::Deref,
14};
15
16use crate::{
17    gpio::{gpioa, gpiob, gpioc, AF7},
18    hal::{blocking, serial, serial::Write},
19    pac::{
20        rcc::cfgr3::USART1SW_A,
21        usart1::{cr1::M_A, cr1::PCE_A, cr1::PS_A, RegisterBlock},
22        Interrupt, USART1, USART2, USART3,
23    },
24    rcc::{self, Clocks},
25    time::fixed_point::FixedPoint,
26    time::rate::{Baud, Hertz},
27    Switch,
28};
29
30#[allow(unused_imports)]
31use crate::pac::RCC;
32
33use cfg_if::cfg_if;
34#[cfg(feature = "enumset")]
35use enumset::{EnumSet, EnumSetType};
36
37use crate::dma;
38
39/// Interrupt and status events.
40///
41/// All events can be cleared by [`Serial::clear_event`] or [`Serial::clear_events`].
42/// Some events are also cleared on other conditions.
43#[derive(Debug)]
44#[cfg_attr(feature = "defmt", derive(defmt::Format))]
45#[cfg_attr(feature = "enumset", derive(EnumSetType))]
46#[cfg_attr(not(feature = "enumset"), derive(Copy, Clone, PartialEq, Eq))]
47#[non_exhaustive]
48// TODO: Split up in transmission and reception events (RM0316 29.7)
49pub enum Event {
50    /// Transmit data register empty / new data can be sent.
51    ///
52    /// This event is set by hardware when the content of the TDR register has been transferred
53    /// into the shift register. It is cleared by [`Serial`]s [`serial::Write::write()`]
54    /// implementation to the TDR register.
55    #[doc(alias = "TXE")]
56    TransmitDataRegisterEmtpy,
57    /// CTS (Clear to Send) event.
58    ///
59    /// This event is set by hardware when the CTS input toggles, if the CTSE bit is set.
60    #[doc(alias = "CTSIF")]
61    CtsInterrupt,
62    /// Transmission complete
63    ///
64    /// This event is set by hardware if the transmission of a frame containing data is complete and
65    /// if TXE is set.
66    /// It is cleared by [`Serial`]s [`serial::Write::write()`] implementaiton to the USART_TDR register.
67    #[doc(alias = "TC")]
68    TransmissionComplete,
69    /// Read data register not empty / new data has been received.
70    ///
71    /// This event is set by hardware when the content of the RDR shift register has been
72    /// transferred to the RDR register.
73    /// It is cleared by [`Serial`]s [`serial::Read::read()`] to the USART_RDR register.
74    #[doc(alias = "RXNE")]
75    ReceiveDataRegisterNotEmpty,
76    /// Overrun Error detected.
77    ///
78    /// This event is set by hardware when the data currently being received in the shift register
79    /// is ready to be transferred into the RDR register while
80    /// [`Event::ReceiveDataRegisterNotEmpty`] is set.
81    ///
82    /// See [`Error::Overrun`] for a more detailed description.
83    #[doc(alias = "ORE")]
84    OverrunError,
85    /// Idle line state detected.
86    ///
87    /// This event is set by hardware when an Idle Line is detected.
88    Idle,
89    /// Parity error detected.
90    ///
91    /// This event is set by hardware when a parity error occurs in receiver mode.
92    ///
93    /// Parity can be configured by using [`config::Parity`] to create a [`config::Config`].
94    #[doc(alias = "PE")]
95    ParityError,
96    /// Noise error detected.
97    ///
98    /// This event is set by hardware when noise is detected on a received frame.
99    #[doc(alias = "NF")]
100    NoiseError,
101    /// Framing error detected
102    ///
103    /// This event is set by hardware when a de-synchronization, excessive noise or a break character
104    /// is detected.
105    #[doc(alias = "FE")]
106    FramingError,
107    /// LIN break
108    ///
109    /// This bit is set by hardware when the LIN break is detected.
110    #[doc(alias = "LBDF")]
111    LinBreak,
112    /// The received character matched the configured character.
113    ///
114    /// The matching character can be configured with [`Serial::match_character()`]
115    #[doc(alias = "CMF")]
116    CharacterMatch,
117    /// Nothing was received since the last received character for
118    /// [`Serial::receiver_timeout()`] amount of time.
119    ///
120    /// # Note
121    ///
122    /// Never set for UART peripheral, which does not have [`ReceiverTimeoutExt`]
123    /// implemented.
124    #[doc(alias = "RTOF")]
125    ReceiverTimeout,
126    // TODO(Sh3Rm4n): SmartCard Mode not implemented, no use as of now.
127    // EndOfBlock,
128    // TODO(Sh3Rm4n): The wakeup from stop mode is alittle bit more complicated:
129    // - UESM has to be enabled so that it works (RM0316 29.8.1)
130    // - Only works with LSI and HSI (which are not configurable yet)
131    // - ...
132    // /// The peripheral was woken up from "Stop Mode".
133    // ///
134    // /// This event is set by hardware, when a wakeup event is detected.
135    // ///
136    // /// The condition, when it does wake up can be configured via
137    // /// [`Serial::set_wakeup_from_stopmode_reason()`]
138    // #[doc(alias = "WUF")]
139    // WakeupFromStopMode,
140}
141
142/// Serial error
143///
144/// As these are status events, they can be converted to [`Event`]s, via [`Into`].
145#[derive(Copy, Clone, PartialEq, Eq, Debug)]
146#[cfg_attr(feature = "defmt", derive(defmt::Format))]
147#[non_exhaustive]
148pub enum Error {
149    /// Framing error
150    ///
151    /// This error is thrown by hardware when a de-synchronization, excessive noise or a break
152    /// character is detected.
153    Framing,
154    /// Noise error
155    ///
156    /// This error is thrown by hardware when noise is detected on a received frame.
157    Noise,
158    /// RX buffer overrun
159    ///
160    /// # Cause
161    ///
162    /// An overrun error occurs when a character is received when RXNE has not been reset. Data can
163    /// not be transferred from the shift register to the RDR register until the RXNE bit is
164    /// cleared. The RXNE flag is set after every byte received. An overrun error occurs if RXNE
165    /// flag is set when the next data is received or the previous DMA request has not been
166    /// serviced.
167    ///
168    /// # Behavior
169    ///
170    /// - The RDR content will not be lost. The previous data is available when a read to USART_RDR
171    ///   is performed.
172    /// - The shift register will be overwritten. After that point, any data received
173    ///   during overrun is lost
174    Overrun,
175    /// Parity check error
176    ///
177    /// This error is thrown by hardware when a parity error occurs in receiver mode.
178    Parity,
179}
180
181impl From<Error> for Event {
182    fn from(error: Error) -> Self {
183        match error {
184            Error::Framing => Event::FramingError,
185            Error::Overrun => Event::OverrunError,
186            Error::Noise => Event::NoiseError,
187            Error::Parity => Event::ParityError,
188        }
189    }
190}
191
192/// The error type returned when a [`Event`] to [`Error`] conversion failed.
193#[derive(Debug, Copy, Clone, PartialEq, Eq)]
194#[cfg_attr(feature = "defmt", derive(defmt::Format))]
195pub struct TryFromEventError(pub(crate) ());
196
197impl TryFrom<Event> for Error {
198    type Error = TryFromEventError;
199    fn try_from(event: Event) -> Result<Self, Self::Error> {
200        Ok(match event {
201            Event::FramingError => Error::Framing,
202            Event::OverrunError => Error::Overrun,
203            Event::NoiseError => Error::Noise,
204            Event::ParityError => Error::Parity,
205            _ => return Err(TryFromEventError(())),
206        })
207    }
208}
209
210/// An convinicnce enum for the most typical baud rates
211#[derive(Copy, Clone, PartialEq, Eq)]
212#[cfg_attr(feature = "defmt", derive(defmt::Format))]
213#[non_exhaustive]
214#[allow(missing_docs)]
215pub enum BaudTable {
216    Bd1200,
217    Bd9600,
218    Bd19200,
219    Bd38400,
220    Bd57600,
221    Bd115200,
222    Bd230400,
223    Bd460800,
224}
225
226impl From<BaudTable> for Baud {
227    fn from(baud: BaudTable) -> Self {
228        match baud {
229            BaudTable::Bd1200 => Baud(1_200),
230            BaudTable::Bd9600 => Baud(9_600),
231            BaudTable::Bd19200 => Baud(19_200),
232            BaudTable::Bd38400 => Baud(38_400),
233            BaudTable::Bd57600 => Baud(57_600),
234            BaudTable::Bd115200 => Baud(115_200),
235            BaudTable::Bd230400 => Baud(230_400),
236            BaudTable::Bd460800 => Baud(460_800),
237        }
238    }
239}
240
241/// The error type returned when a [`Baud`] to [`BaudTable`] conversion failed.
242#[derive(Debug, Copy, Clone, PartialEq, Eq)]
243#[cfg_attr(feature = "defmt", derive(defmt::Format))]
244pub struct TryFromBaudError(pub(crate) ());
245
246impl TryFrom<Baud> for BaudTable {
247    type Error = TryFromBaudError;
248    fn try_from(baud: Baud) -> Result<Self, Self::Error> {
249        Ok(match baud {
250            Baud(1_200) => BaudTable::Bd1200,
251            Baud(9_600) => BaudTable::Bd9600,
252            Baud(19_200) => BaudTable::Bd19200,
253            Baud(38_400) => BaudTable::Bd38400,
254            Baud(57_600) => BaudTable::Bd57600,
255            Baud(115_200) => BaudTable::Bd115200,
256            Baud(230_400) => BaudTable::Bd230400,
257            Baud(460_800) => BaudTable::Bd460800,
258            _ => return Err(TryFromBaudError(())),
259        })
260    }
261}
262
263/// TX pin
264pub trait TxPin<Usart>: crate::private::Sealed {}
265
266/// RX pin
267pub trait RxPin<Usart>: crate::private::Sealed {}
268
269impl<Otype> TxPin<USART1> for gpioa::PA9<AF7<Otype>> {}
270impl<Otype> TxPin<USART1> for gpiob::PB6<AF7<Otype>> {}
271impl<Otype> TxPin<USART1> for gpioc::PC4<AF7<Otype>> {}
272impl<Otype> RxPin<USART1> for gpioa::PA10<AF7<Otype>> {}
273impl<Otype> RxPin<USART1> for gpiob::PB7<AF7<Otype>> {}
274impl<Otype> RxPin<USART1> for gpioc::PC5<AF7<Otype>> {}
275
276impl<Otype> TxPin<USART2> for gpioa::PA2<AF7<Otype>> {}
277impl<Otype> TxPin<USART2> for gpiob::PB3<AF7<Otype>> {}
278impl<Otype> RxPin<USART2> for gpioa::PA3<AF7<Otype>> {}
279impl<Otype> RxPin<USART2> for gpiob::PB4<AF7<Otype>> {}
280
281impl<Otype> TxPin<USART3> for gpiob::PB10<AF7<Otype>> {}
282impl<Otype> TxPin<USART3> for gpioc::PC10<AF7<Otype>> {}
283impl<Otype> RxPin<USART3> for gpioc::PC11<AF7<Otype>> {}
284
285cfg_if! {
286    if #[cfg(any(feature = "gpio-f303", feature = "gpio-f303e", feature = "gpio-f373"))] {
287        use crate::gpio::{gpiod, gpioe};
288
289        impl<Otype> TxPin<USART1> for gpioe::PE0<AF7<Otype>> {}
290        impl<Otype> RxPin<USART1> for gpioe::PE1<AF7<Otype>> {}
291
292        impl<Otype> TxPin<USART2> for gpiod::PD5<AF7<Otype>> {}
293        impl<Otype> RxPin<USART2> for gpiod::PD6<AF7<Otype>> {}
294
295        impl<Otype> TxPin<USART3> for gpiod::PD8<AF7<Otype>> {}
296        impl<Otype> RxPin<USART3> for gpiod::PD9<AF7<Otype>> {}
297        impl<Otype> RxPin<USART3> for gpioe::PE15<AF7<Otype>> {}
298    }
299}
300
301cfg_if! {
302    if #[cfg(not(feature = "gpio-f373"))] {
303        impl<Otype> TxPin<USART2> for gpioa::PA14<AF7<Otype>> {}
304        impl<Otype> RxPin<USART2> for gpioa::PA15<AF7<Otype>> {}
305
306        impl<Otype> RxPin<USART3> for gpiob::PB11<AF7<Otype>> {}
307    }
308}
309
310cfg_if! {
311    if #[cfg(any(feature = "gpio-f303", feature = "gpio-f303e",))] {
312        use crate::pac::{UART4, UART5};
313        use crate::gpio::AF5;
314
315        impl<Otype> TxPin<UART4> for gpioc::PC10<AF5<Otype>> {}
316        impl<Otype> RxPin<UART4> for gpioc::PC11<AF5<Otype>> {}
317        impl<Otype> TxPin<UART5> for gpioc::PC12<AF5<Otype>> {}
318        impl<Otype> RxPin<UART5> for gpiod::PD2<AF5<Otype>> {}
319    }
320}
321
322pub mod config;
323
324/// Serial abstraction
325///
326/// This is an abstraction of the UART peripheral intended to be
327/// used for standard duplex serial communication.
328pub struct Serial<Usart, Pins> {
329    usart: Usart,
330    pins: Pins,
331}
332
333impl<Usart, Tx, Rx> Serial<Usart, (Tx, Rx)>
334where
335    Usart: Instance,
336{
337    /// Configures a USART peripheral to provide serial communication
338    ///
339    /// # Panics
340    ///
341    /// Panics if the configured baud rate is impossible for the hardware to setup.
342    pub fn new<Config>(
343        usart: Usart,
344        pins: (Tx, Rx),
345        config: Config,
346        clocks: Clocks,
347        apb: &mut <Usart as rcc::RccBus>::Bus,
348    ) -> Self
349    where
350        Usart: Instance,
351        Tx: TxPin<Usart>,
352        Rx: RxPin<Usart>,
353        Config: Into<config::Config>,
354    {
355        use config::Parity;
356
357        let config = config.into();
358
359        // Enable USART peripheral for any further interaction.
360        Usart::enable(apb);
361        Usart::reset(apb);
362        // Disable USART because some configuration bits could only be written
363        // in this state.
364        usart.cr1.modify(|_, w| w.ue().disabled());
365
366        let brr = Usart::clock(&clocks).integer() / config.baudrate.integer();
367        crate::assert!(brr >= 16, "impossible baud rate");
368        usart.brr.write(|w| {
369            w.brr().bits(
370                // SAFETY: safe because of assert before
371                unsafe { u16::try_from(brr).unwrap_unchecked() },
372            )
373        });
374
375        // We currently support only eight data bits as supporting a full-blown
376        // configuration gets complicated pretty fast. The USART counts data
377        // and partiy bits together so the actual amount depends on the parity
378        // selection.
379        let (m0, ps, pce) = match config.parity {
380            Parity::None => (M_A::Bit8, PS_A::Even, PCE_A::Disabled),
381            Parity::Even => (M_A::Bit9, PS_A::Even, PCE_A::Enabled),
382            Parity::Odd => (M_A::Bit9, PS_A::Odd, PCE_A::Enabled),
383        };
384
385        usart
386            .cr2
387            .modify(|_, w| w.stop().variant(config.stopbits.into()));
388        usart.cr1.modify(|_, w| {
389            w.ps().variant(ps); // set parity mode
390            w.pce().variant(pce); // enable parity checking/generation
391            w.m().variant(m0); // set data bits
392            w.re().enabled(); // enable receiver
393            w.te().enabled() // enable transmitter
394        });
395
396        // Finally enable the configured UART.
397        usart.cr1.modify(|_, w| w.ue().enabled());
398
399        Self { usart, pins }
400    }
401
402    /// Get access to the underlying register block.
403    ///
404    /// # Safety
405    ///
406    /// This function is not _memory_ unsafe per se, but does not guarantee
407    /// anything about assumptions of invariants made in this implementation.
408    ///
409    /// Changing specific options can lead to un-expected behavior and nothing
410    /// is guaranteed.
411    pub unsafe fn peripheral(&mut self) -> &mut Usart {
412        &mut self.usart
413    }
414
415    /// Releases the USART peripheral and associated pins
416    pub fn free(self) -> (Usart, (Tx, Rx)) {
417        self.usart
418            .cr1
419            .modify(|_, w| w.ue().disabled().re().disabled().te().disabled());
420        (self.usart, self.pins)
421    }
422}
423
424impl<Usart, Pins> Serial<Usart, Pins>
425where
426    Usart: Instance,
427{
428    /// Serial read out of the read register
429    ///
430    /// No error handling and no additional side-effects, besides the implied
431    /// side-effects when reading out the RDR register.
432    /// Handling errors has to be done manually. This can be done, by checking
433    /// the triggered events via [`Serial::triggered_events`].
434    ///
435    /// Returns `None` if the hardware is busy.
436    ///
437    /// ## Embedded HAL
438    ///
439    /// To have a more managed way to read from the serial use the [`embedded_hal::serial::Read`]
440    /// trait implementation.
441    #[doc(alias = "RDR")]
442    pub fn read_data_register(&self) -> Option<u8> {
443        if self.usart.isr.read().busy().bit_is_set() {
444            return None;
445        }
446        #[allow(clippy::cast_possible_truncation)]
447        Some(self.usart.rdr.read().rdr().bits() as u8)
448    }
449
450    /// Check if the USART peripheral is busy.
451    ///
452    /// This can be useful to block on to synchronize between peripheral and CPU
453    /// because of the asynchronous nature of the peripheral.
454    pub fn is_busy(&mut self) -> bool {
455        self.usart.isr.read().busy().bit_is_set()
456    }
457
458    /// Obtain the associated interrupt number for the serial peripheral.
459    ///
460    /// Used to unmask / enable the interrupt with [`cortex_m::peripheral::NVIC::unmask()`].
461    /// This is useful for all `cortex_m::peripheral::INTERRUPT` functions.
462    ///
463    /// # Note
464    ///
465    /// This is the easier alternative to obatain the interrupt for:
466    ///
467    /// ```
468    /// use cortex_m::peripheral::INTERRUPT;
469    /// use stm32f3xx_hal::pac::USART1;
470    /// use stm32f3xx_hal::interrupt::InterruptNumber;
471    ///
472    /// const INTERRUPT: Interrupt = <USART1 as InterruptNumber>::INTERRUPT;
473    /// ```
474    ///
475    /// though this function can not be used in a const context.
476    #[doc(alias = "unmask")]
477    pub fn interrupt(&self) -> <Usart as crate::interrupts::InterruptNumber>::Interrupt {
478        <Usart as crate::interrupts::InterruptNumber>::INTERRUPT
479    }
480
481    /// Enable the interrupt for the specified [`Event`].
482    #[inline]
483    pub fn enable_interrupt(&mut self, event: Event) {
484        self.configure_interrupt(event, Switch::On);
485    }
486
487    /// Disable the interrupt for the specified [`Event`].
488    #[inline]
489    pub fn disable_interrupt(&mut self, event: Event) {
490        self.configure_interrupt(event, Switch::Off);
491    }
492
493    /// Enable or disable the interrupt for the specified [`Event`].
494    #[inline]
495    pub fn configure_interrupt(&mut self, event: Event, enable: impl Into<Switch>) {
496        // Do a round way trip to be convert Into<Switch> -> bool
497        let enable: Switch = enable.into();
498        let enable: bool = enable.into();
499        match event {
500            Event::TransmitDataRegisterEmtpy => self.usart.cr1.modify(|_, w| w.txeie().bit(enable)),
501            Event::CtsInterrupt => self.usart.cr3.modify(|_, w| w.ctsie().bit(enable)),
502            Event::TransmissionComplete => self.usart.cr1.modify(|_, w| w.tcie().bit(enable)),
503            Event::ReceiveDataRegisterNotEmpty => {
504                self.usart.cr1.modify(|_, w| w.rxneie().bit(enable));
505            }
506            Event::ParityError => self.usart.cr1.modify(|_, w| w.peie().bit(enable)),
507            Event::LinBreak => self.usart.cr2.modify(|_, w| w.lbdie().bit(enable)),
508            Event::NoiseError | Event::OverrunError | Event::FramingError => {
509                self.usart.cr3.modify(|_, w| w.eie().bit(enable));
510            }
511            Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().bit(enable)),
512            Event::CharacterMatch => self.usart.cr1.modify(|_, w| w.cmie().bit(enable)),
513            Event::ReceiverTimeout => self.usart.cr1.modify(|_, w| w.rtoie().bit(enable)),
514            // Event::EndOfBlock => self.usart.cr1.modify(|_, w| w.eobie().bit(enable)),
515            // Event::WakeupFromStopMode => self.usart.cr3.modify(|_, w| w.wufie().bit(enable)),
516        };
517    }
518
519    /// Enable or disable interrupt for the specified [`Event`]s.
520    ///
521    /// Like [`Serial::configure_interrupt`], but instead using an enumset. The corresponding
522    /// interrupt for every [`Event`] in the set will be enabled, every other interrupt will be
523    /// **disabled**.
524    #[cfg(feature = "enumset")]
525    #[cfg_attr(docsrs, doc(cfg(feature = "enumset")))]
526    pub fn configure_interrupts(&mut self, events: EnumSet<Event>) {
527        for event in events.complement().iter() {
528            self.configure_interrupt(event, false);
529        }
530        for event in events.iter() {
531            self.configure_interrupt(event, true);
532        }
533    }
534
535    /// Check if an interrupt is configured for the [`Event`]
536    #[inline]
537    pub fn is_interrupt_configured(&self, event: Event) -> bool {
538        match event {
539            Event::TransmitDataRegisterEmtpy => self.usart.cr1.read().txeie().is_enabled(),
540            Event::CtsInterrupt => self.usart.cr3.read().ctsie().is_enabled(),
541            Event::TransmissionComplete => self.usart.cr1.read().tcie().is_enabled(),
542            Event::ReceiveDataRegisterNotEmpty => self.usart.cr1.read().rxneie().is_enabled(),
543            Event::ParityError => self.usart.cr1.read().peie().is_enabled(),
544            Event::LinBreak => self.usart.cr2.read().lbdie().is_enabled(),
545            Event::NoiseError | Event::OverrunError | Event::FramingError => {
546                self.usart.cr3.read().eie().is_enabled()
547            }
548            Event::Idle => self.usart.cr1.read().idleie().is_enabled(),
549            Event::CharacterMatch => self.usart.cr1.read().cmie().is_enabled(),
550            Event::ReceiverTimeout => self.usart.cr1.read().rtoie().is_enabled(),
551            // Event::EndOfBlock => self.usart.cr1.read().eobie().is_enabled(),
552            // Event::WakeupFromStopMode => self.usart.cr3.read().wufie().is_enabled(),
553        }
554    }
555
556    /// Check which interrupts are enabled for all [`Event`]s
557    #[cfg(feature = "enumset")]
558    #[cfg_attr(docsrs, doc(cfg(feature = "enumset")))]
559    #[inline]
560    pub fn configured_interrupts(&mut self) -> EnumSet<Event> {
561        let mut events = EnumSet::new();
562
563        for event in EnumSet::<Event>::all().iter() {
564            if self.is_interrupt_configured(event) {
565                events |= event;
566            }
567        }
568
569        events
570    }
571
572    /// Check if an interrupt event happend.
573    #[inline]
574    pub fn is_event_triggered(&self, event: Event) -> bool {
575        let isr = self.usart.isr.read();
576        match event {
577            Event::TransmitDataRegisterEmtpy => isr.txe().bit(),
578            Event::CtsInterrupt => isr.ctsif().bit(),
579            Event::TransmissionComplete => isr.tc().bit(),
580            Event::ReceiveDataRegisterNotEmpty => isr.rxne().bit(),
581            Event::OverrunError => isr.ore().bit(),
582            Event::Idle => isr.idle().bit(),
583            Event::ParityError => isr.pe().bit(),
584            Event::LinBreak => isr.lbdf().bit(),
585            Event::NoiseError => isr.nf().bit(),
586            Event::FramingError => isr.fe().bit(),
587            Event::CharacterMatch => isr.cmf().bit(),
588            Event::ReceiverTimeout => isr.rtof().bit(),
589            // Event::EndOfBlock => isr.eobf().bit(),
590            // Event::WakeupFromStopMode => isr.wuf().bit(),
591        }
592    }
593
594    /// Get an [`EnumSet`] of all fired interrupt events.
595    ///
596    /// # Examples
597    ///
598    /// This allows disabling all fired event at once, via the enum set abstraction, like so
599    ///
600    /// ```rust
601    /// for event in serial.events() {
602    ///     serial.listen(event, false);
603    /// }
604    /// ```
605    #[cfg(feature = "enumset")]
606    #[cfg_attr(docsrs, doc(cfg(feature = "enumset")))]
607    pub fn triggered_events(&self) -> EnumSet<Event> {
608        let mut events = EnumSet::new();
609
610        for event in EnumSet::<Event>::all().iter() {
611            if self.is_event_triggered(event) {
612                events |= event;
613            }
614        }
615
616        events
617    }
618
619    /// Clear the given interrupt event flag.
620    #[inline]
621    pub fn clear_event(&mut self, event: Event) {
622        self.usart.icr.write(|w| match event {
623            Event::CtsInterrupt => w.ctscf().clear(),
624            Event::TransmissionComplete => w.tccf().clear(),
625            Event::OverrunError => w.orecf().clear(),
626            Event::Idle => w.idlecf().clear(),
627            Event::ParityError => w.pecf().clear(),
628            Event::LinBreak => w.lbdcf().clear(),
629            Event::NoiseError => w.ncf().clear(),
630            Event::FramingError => w.fecf().clear(),
631            Event::CharacterMatch => w.cmcf().clear(),
632            Event::ReceiverTimeout => w.rtocf().clear(),
633            // Event::EndOfBlock => w.eobcf().clear(),
634            // Event::WakeupFromStopMode => w.wucf().clear(),
635            Event::ReceiveDataRegisterNotEmpty => {
636                // Flush the register data queue, so that this even will not be thrown again.
637                self.usart.rqr.write(|w| w.rxfrq().set_bit());
638                w
639            }
640            // Do nothing with this event (only useful for Smartcard, which is not
641            // supported right now)
642            Event::TransmitDataRegisterEmtpy => w,
643        });
644    }
645
646    /// Clear **all** interrupt events.
647    #[inline]
648    pub fn clear_events(&mut self) {
649        // SAFETY: This atomic write clears all flags and ignores the reserverd bit fields.
650        self.usart.icr.write(|w| unsafe { w.bits(u32::MAX) });
651    }
652
653    /// Enable or disable overrun detection
654    ///
655    /// When overrun detection is disabled and new data is received while the
656    /// [`Event::ReceiveDataRegisterNotEmpty`] flag is still set,
657    /// the [`Event::OverrunError`] flag is not set and the new received data overwrites the
658    /// previous content of the RDR register.
659    #[doc(alias = "OVRDIS")]
660    #[inline]
661    pub fn detect_overrun(&mut self, enable: bool) {
662        let uart_enabled = self.usart.cr1.read().ue().bit();
663        self.usart.cr1.modify(|_, w| w.ue().disabled());
664        self.usart.cr3.modify(|_, w| w.ovrdis().bit(!enable));
665        self.usart.cr1.modify(|_, w| w.ue().bit(uart_enabled));
666    }
667
668    /// Configuring the UART to match each received character,
669    /// with the configured one.
670    ///
671    /// If the character is matched [`Event::CharacterMatch`] is generated,
672    /// which can fire an interrupt, if enabled via [`Serial::configure_interrupt()`]
673    pub fn set_match_character(&mut self, char: u8) {
674        // Note: This bit field can only be written when reception is disabled (RE = 0) or the
675        // USART is disabled
676        let enabled = self.usart.cr1.read().ue().bit_is_set();
677        self.usart.cr1.modify(|_, w| w.ue().disabled());
678        self.usart.cr2.modify(|_, w| w.add().bits(char));
679        self.usart.cr1.modify(|_, w| w.ue().bit(enabled));
680    }
681
682    /// Read out the configured match character.
683    pub fn match_character(&self) -> u8 {
684        self.usart.cr2.read().add().bits()
685    }
686}
687
688impl<Usart, Tx, Rx> Serial<Usart, (Tx, Rx)>
689where
690    Usart: Instance + ReceiverTimeoutExt,
691{
692    /// Set the receiver timeout value.
693    ///
694    /// The RTOF flag ([`Event::ReceiverTimeout`]) is set if, after the last received character,
695    /// no new start bit is detected for more than the receiver timeout value, where the value
696    /// is being a counter, which is decreased by the configured baud rate.
697    ///
698    /// A simple calculation might be `time_per_counter_value = 1 / configured_baud_rate`
699    ///
700    ///
701    /// ## Note
702    ///
703    /// - If the value is None, the receiver timeout feature is disabled.
704    /// - This value must only be programmed once per received character.
705    /// - Can be written on the fly. If the new value is lower than or equal to the counter,
706    ///   the RTOF flag is set.
707    /// - Values higher than 24 bits are truncated to 24 bit max (`16_777_216`).
708    pub fn set_receiver_timeout(&mut self, value: Option<u32>) {
709        if let Some(value) = value {
710            self.usart.cr2.modify(|_, w| w.rtoen().enabled());
711            self.usart.rtor.modify(|_, w| w.rto().bits(value));
712        } else {
713            self.usart.cr2.modify(|_, w| w.rtoen().disabled());
714        }
715    }
716
717    /// Read out the currently set timeout value
718    ///
719    /// The relationship between the unit value and time is described in
720    /// [`Serial::receiver_timeout`].
721    ///
722    /// - If the value is None, the receiver timeout feature is disabled.
723    pub fn receiver_timeout(&self) -> Option<u32> {
724        if self.usart.cr2.read().rtoen().is_enabled() {
725            Some(self.usart.rtor.read().rto().bits())
726        } else {
727            None
728        }
729    }
730}
731
732/// Implementation of the [`embedded_hal::serial::Read`] trait
733/// shared between [`Rx::read()`] and [`Serial::read()`]
734fn eh_read<Usart>(usart: &mut Usart) -> nb::Result<u8, Error>
735where
736    Usart: Instance,
737{
738    let isr = usart.isr.read();
739
740    Err(if isr.pe().bit_is_set() {
741        usart.icr.write(|w| w.pecf().clear());
742        nb::Error::Other(Error::Parity)
743    } else if isr.fe().bit_is_set() {
744        usart.icr.write(|w| w.fecf().clear());
745        nb::Error::Other(Error::Framing)
746    } else if isr.nf().bit_is_set() {
747        usart.icr.write(|w| w.ncf().clear());
748        nb::Error::Other(Error::Noise)
749    } else if isr.ore().bit_is_set() {
750        usart.icr.write(|w| w.orecf().clear());
751        // Flush the receive data
752        //
753        // Imagine a case of an overrun, where 2 or more bytes have been received by the hardware
754        // but haven't been read out yet: An overrun is signaled!
755        //
756        // The current state is: One byte is in the RDR (read data register) one one byte is still
757        // in the hardware pipeline (shift register).
758        //
759        // With this implementation, the overrun flag would be cleared but the data would not be
760        // read out, so there are still to bytes waiting in the pipeline.
761        //
762        // In case the flush wasn't called: The next read would then be successful, as the RDR is
763        // cleared, but the read after that would again report an overrun error, because the byte
764        // still in the hardware shift register would signal it.
765        //
766        // This means, that the overrun error is not completely handled by this read()
767        // implementation and leads to surprising behavior, if one would explicitly check for
768        // Error::Overrun and think, that this error would than be handled, which would not be the
769        // case.
770        //
771        // This is because, with this function signature, the data can not be returned
772        // simultainously with the error.
773        //
774        // To mitigate this and have an implementation without these surprises flush the RDR
775        // register. This leads to loosing a theoretically still receivable data byte! But at least
776        // no cleanup is needed, after an overrun is called.
777        usart.rqr.write(|w| w.rxfrq().set_bit());
778        nb::Error::Other(Error::Overrun)
779    } else if isr.rxne().bit_is_set() {
780        #[allow(clippy::cast_possible_truncation)]
781        return Ok(usart.rdr.read().bits() as u8);
782    } else {
783        nb::Error::WouldBlock
784    })
785}
786
787// TODO: Check if u16 for WORD is feasiable / possible
788impl<Usart, Tx, Rx> serial::Read<u8> for Serial<Usart, (Tx, Rx)>
789where
790    Usart: Instance,
791{
792    type Error = Error;
793
794    /// Getting back an error means that the error is defined as "handled":
795    ///
796    /// This implementation has the side effect for error handling, that the [`Event`] flag of the returned
797    /// [`Error`] is cleared.
798    ///
799    /// This might be a problem, because if an interrupt is enabled for this particular flag, the
800    /// interrupt handler might not have the chance to find out from which flag the interrupt
801    /// originated.
802    ///
803    /// So this function is only intended to be used for direct error handling and not leaving it
804    /// up to the interrupt handler.
805    ///
806    /// To read out the content of the read register without internal error handling, use
807    /// [`embedded_hal::serial::Read`].
808    /// ...
809    // -> According to this API it should be skipped.
810    fn read(&mut self) -> nb::Result<u8, Error> {
811        eh_read(&mut self.usart)
812    }
813}
814
815impl<Usart, Pins> serial::Write<u8> for Serial<Usart, Pins>
816where
817    Usart: Instance,
818{
819    // NOTE(Infallible) See section "29.7 USART interrupts"; the only possible errors during
820    // transmission are: clear to send (which is disabled in this case) errors and
821    // framing errors (which only occur in SmartCard mode); neither of these apply to
822    // our hardware configuration
823    type Error = Infallible;
824
825    fn flush(&mut self) -> nb::Result<(), Infallible> {
826        if self.usart.isr.read().tc().bit_is_set() {
827            Ok(())
828        } else {
829            Err(nb::Error::WouldBlock)
830        }
831    }
832
833    fn write(&mut self, byte: u8) -> nb::Result<(), Infallible> {
834        if self.usart.isr.read().txe().bit_is_set() {
835            self.usart.tdr.write(|w| w.tdr().bits(u16::from(byte)));
836            Ok(())
837        } else {
838            Err(nb::Error::WouldBlock)
839        }
840    }
841}
842
843impl<Usart, Pins> fmt::Write for Serial<Usart, Pins>
844where
845    Serial<Usart, Pins>: serial::Write<u8>,
846{
847    fn write_str(&mut self, s: &str) -> fmt::Result {
848        s.bytes()
849            .try_for_each(|c| nb::block!(self.write(c)))
850            .map_err(|_| fmt::Error)
851    }
852}
853
854impl<USART, TX, RX> blocking::serial::write::Default<u8> for Serial<USART, (TX, RX)> where
855    USART: Instance
856{
857}
858
859impl<Usart, Pins> Serial<Usart, Pins>
860where
861    Usart: Instance + Dma,
862{
863    /// Fill the buffer with received data using DMA.
864    pub fn read_exact<B, C>(self, buffer: B, mut channel: C) -> dma::Transfer<B, C, Self>
865    where
866        Self: dma::OnChannel<C>,
867        B: dma::WriteBuffer<Word = u8> + 'static,
868        C: dma::Channel,
869    {
870        // SAFETY: RDR is valid peripheral address, safe to dereference and pass to the DMA
871        unsafe {
872            channel.set_peripheral_address(
873                core::ptr::addr_of!(self.usart.rdr) as u32,
874                dma::Increment::Disable,
875            );
876        };
877
878        dma::Transfer::start_write(buffer, channel, self)
879    }
880
881    /// Transmit all data in the buffer using DMA.
882    pub fn write_all<B, C>(self, buffer: B, mut channel: C) -> dma::Transfer<B, C, Self>
883    where
884        Self: dma::OnChannel<C>,
885        B: dma::ReadBuffer<Word = u8> + 'static,
886        C: dma::Channel,
887    {
888        // SAFETY: TDR is valid peripheral address, safe to dereference and pass to the DMA
889        unsafe {
890            channel.set_peripheral_address(
891                core::ptr::addr_of!(self.usart.tdr) as u32,
892                dma::Increment::Disable,
893            );
894        };
895
896        dma::Transfer::start_read(buffer, channel, self)
897    }
898}
899
900impl<Usart, Pins> dma::Target for Serial<Usart, Pins>
901where
902    Usart: Instance + Dma,
903{
904    fn enable_dma(&mut self) {
905        self.usart
906            .cr3
907            .modify(|_, w| w.dmar().enabled().dmat().enabled());
908    }
909
910    fn disable_dma(&mut self) {
911        self.usart
912            .cr3
913            .modify(|_, w| w.dmar().disabled().dmat().disabled());
914    }
915}
916
917/// Marker trait for DMA capable UART implementations.
918pub trait Dma: crate::private::Sealed {}
919
920impl Dma for USART1 {}
921impl Dma for USART2 {}
922impl Dma for USART3 {}
923
924/// Marker trait for Receiver Timeout capable UART implementations.
925pub trait ReceiverTimeoutExt: crate::private::Sealed {}
926
927impl ReceiverTimeoutExt for USART1 {}
928#[cfg(not(any(feature = "gpio-f333")))]
929impl ReceiverTimeoutExt for USART2 {}
930#[cfg(not(any(feature = "gpio-f333")))]
931impl ReceiverTimeoutExt for USART3 {}
932
933/// UART instance
934pub trait Instance:
935    Deref<Target = RegisterBlock>
936    + crate::interrupts::InterruptNumber
937    + crate::private::Sealed
938    + rcc::Enable
939    + rcc::Reset
940{
941    #[doc(hidden)]
942    fn clock(clocks: &Clocks) -> Hertz;
943}
944
945macro_rules! usart {
946    (
947        $(
948            $USARTX:ident: ($INTERRUPT:path),
949        )+
950    ) => {
951        $(
952            impl crate::interrupts::InterruptNumber for $USARTX {
953                type Interrupt = Interrupt;
954                const INTERRUPT: Interrupt = $INTERRUPT;
955            }
956
957            #[cfg(feature = "defmt")]
958            impl<Pins> defmt::Format for Serial<$USARTX, Pins> {
959                fn format(&self, f: defmt::Formatter) {
960                    // Omitting pins makes it:
961                    // 1. Easier.
962                    // 2. Not to specialized to use it ergonimically for users
963                    //    even in a generic context.
964                    // 3. Not require specialization.
965                    defmt::write!(
966                        f,
967                        "Serial {{ usart: {}, pins: ? }}",
968                        stringify!($USARTX),
969                    );
970                }
971            }
972
973            impl<Pins> fmt::Debug for Serial<$USARTX, Pins> {
974                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
975                    f.debug_struct(stringify!(Serial))
976                        .field("usart", &stringify!($USARTX))
977                        .field("pins", &"?")
978                        .finish()
979                }
980            }
981        )+
982    };
983
984    ([ $(($X:literal, $INTERRUPT:path)),+ ]) => {
985        paste::paste! {
986            usart!(
987                $(
988                    [<USART $X>]: ($INTERRUPT),
989                )+
990            );
991        }
992    };
993}
994
995/// Generates a clock function for UART Peripherals, where
996/// the only clock source can be the peripheral clock
997#[allow(unused_macros)]
998macro_rules! usart_static_clock {
999    ($($USARTX:ident),+) => {
1000        $(
1001            impl Instance for $USARTX {
1002                fn clock(clocks: &Clocks) -> Hertz {
1003                    <$USARTX as rcc::BusClock>::clock(clocks)
1004                }
1005            }
1006        )+
1007    };
1008    ($($X:literal),+) => {
1009        paste::paste! {
1010            usart_static_clock!(
1011                $([<USART $X>]),+
1012            );
1013        }
1014    };
1015}
1016
1017/// Generates a clock function for UART Peripherals, where
1018/// the clock source can vary.
1019macro_rules! usart_var_clock {
1020    ($($USARTX:ident, $usartXsw:ident),+) => {
1021        $(
1022            impl Instance for $USARTX {
1023                fn clock(clocks: &Clocks) -> Hertz {
1024                    // SAFETY: The read instruction of the RCC.cfgr3 register should be atomic
1025                    match unsafe {(*RCC::ptr()).cfgr3.read().$usartXsw().variant()} {
1026                        USART1SW_A::Pclk => <$USARTX as rcc::BusClock>::clock(clocks),
1027                        USART1SW_A::Hsi => crate::rcc::HSI,
1028                        USART1SW_A::Sysclk => clocks.sysclk(),
1029                        USART1SW_A::Lse => crate::rcc::LSE,
1030                    }
1031                }
1032            }
1033        )+
1034    };
1035    ($($X:literal),+) => {
1036        paste::paste! {
1037            usart_var_clock!(
1038                $([<USART $X>], [<usart $X sw>]),+
1039            );
1040        }
1041    };
1042}
1043
1044cfg_if::cfg_if! {
1045    if #[cfg(any(
1046        feature = "stm32f301x6",
1047        feature = "stm32f301x8",
1048        feature = "stm32f318x8",
1049        feature = "stm32f302x6",
1050        feature = "stm32f302x8",
1051        feature = "stm32f303x6",
1052        feature = "stm32f303x8",
1053        feature = "stm32f328x8",
1054        feature = "stm32f334x4",
1055        feature = "stm32f334x6",
1056        feature = "stm32f334x8",
1057    ))] {
1058        // USART1 is accessed through APB2,
1059        // but USART1SW_A::PCLK will connect its phy to PCLK1.
1060        usart_var_clock!(1);
1061        // These are uart peripherals, where the only clock source
1062        // is the PCLK (peripheral clock).
1063        usart_static_clock!(2, 3);
1064    } else {
1065        usart_var_clock!(1, 2, 3);
1066    }
1067}
1068
1069#[cfg(not(feature = "svd-f373"))]
1070usart!([
1071    (1, Interrupt::USART1_EXTI25),
1072    (2, Interrupt::USART2_EXTI26),
1073    (3, Interrupt::USART3_EXTI28)
1074]);
1075#[cfg(feature = "svd-f373")]
1076usart!([
1077    (1, Interrupt::USART1),
1078    (2, Interrupt::USART2),
1079    (3, Interrupt::USART3)
1080]);
1081
1082cfg_if::cfg_if! {
1083    // See table 29.4 RM0316
1084    if #[cfg(any(feature = "gpio-f303", feature = "gpio-f303e"))] {
1085
1086        macro_rules! uart {
1087            ([ $(($X:literal, $INTERRUPT:path)),+ ]) => {
1088                paste::paste! {
1089                    usart!(
1090                        $(
1091                            [<UART $X>]: ($INTERRUPT),
1092                        )+
1093                    );
1094                }
1095            };
1096        }
1097
1098        macro_rules! uart_var_clock {
1099            ($($X:literal),+) => {
1100                paste::paste! {
1101                    usart_var_clock!(
1102                        $([<UART $X>], [<uart $X sw>]),+
1103                    );
1104                }
1105            };
1106        }
1107
1108        uart_var_clock!(4, 5);
1109        uart!([(4, Interrupt::UART4_EXTI34), (5, Interrupt::UART5_EXTI35)]);
1110
1111        impl Dma for UART4 {}
1112
1113        impl ReceiverTimeoutExt for UART4 {}
1114        impl ReceiverTimeoutExt for UART5 {}
1115    }
1116}