stm32f3xx_hal/serial/
config.rs

1//! Types for configuring a serial interface.
2
3use crate::pac::usart1::cr2::STOP_A;
4use crate::time::rate::{Baud, Extensions};
5
6/// Stop Bit configuration parameter for serial.
7///
8/// Wrapper around [`STOP_A`]
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10#[cfg_attr(feature = "defmt", derive(defmt::Format))]
11pub enum StopBits {
12    /// 0.5 stop bit
13    Stop0P5,
14    /// 1 stop bit
15    Stop1,
16    /// 1.5 stop bit
17    Stop1P5,
18    /// 2 stop bit
19    Stop2,
20}
21
22impl From<StopBits> for STOP_A {
23    fn from(stopbit: StopBits) -> Self {
24        match stopbit {
25            StopBits::Stop0P5 => STOP_A::Stop0p5,
26            StopBits::Stop1 => STOP_A::Stop1,
27            StopBits::Stop1P5 => STOP_A::Stop1p5,
28            StopBits::Stop2 => STOP_A::Stop2,
29        }
30    }
31}
32
33impl From<STOP_A> for StopBits {
34    fn from(stopbit: STOP_A) -> Self {
35        match stopbit {
36            STOP_A::Stop0p5 => StopBits::Stop0P5,
37            STOP_A::Stop1 => StopBits::Stop1,
38            STOP_A::Stop1p5 => StopBits::Stop1P5,
39            STOP_A::Stop2 => StopBits::Stop2,
40        }
41    }
42}
43
44/// Parity generation and checking. If odd or even parity is selected, the
45/// underlying USART will be configured to send/receive the parity bit in
46/// addtion to the data bits.
47#[cfg_attr(feature = "defmt", derive(defmt::Format))]
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49pub enum Parity {
50    /// No parity bit will be added/checked.
51    None,
52    /// The MSB transmitted/received will be generated/checked to have a
53    /// even number of bits set.
54    Even,
55    /// The MSB transmitted/received will be generated/checked to have a
56    /// odd number of bits set.
57    Odd,
58}
59
60/// Configuration struct for [`Serial`](super::Serial) providing all
61/// communication-related / parameters. [`Serial`](super::Serial) always uses eight data
62/// bits plus the parity bit - if selected.
63///
64/// Create a configuration by using `default` in combination with the
65/// builder methods. The following snippet shows creating a configuration
66/// for 19,200 Baud, 8N1 by deriving it from the default value:
67/// ```
68/// # use stm32f3xx_hal::serial::config::*;
69/// # use stm32f3xx_hal::time::rate::{Baud, Extensions};
70/// let config = Config::default().baudrate(19_200.Bd());
71///
72/// assert!(config.baudrate == 19_200.Bd());
73/// assert!(config.parity == Parity::None);
74/// assert!(config.stopbits == StopBits::STOP1);
75/// ```
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
77#[non_exhaustive]
78pub struct Config {
79    /// Serial interface baud rate
80    pub baudrate: Baud,
81    /// Whether and how to generate/check a parity bit
82    pub parity: Parity,
83    /// The number of stop bits to follow the last data bit or the parity
84    /// bit
85    pub stopbits: StopBits,
86}
87
88impl Config {
89    /// Sets the given baudrate.
90    #[must_use]
91    pub fn baudrate(mut self, baudrate: impl Into<Baud>) -> Self {
92        self.baudrate = baudrate.into();
93        self
94    }
95
96    /// Sets the given parity.
97    #[must_use]
98    pub fn parity(mut self, parity: Parity) -> Self {
99        self.parity = parity;
100        self
101    }
102
103    /// Sets the stop bits to `stopbits`.
104    #[must_use]
105    pub fn stopbits(mut self, stopbits: StopBits) -> Self {
106        self.stopbits = stopbits;
107        self
108    }
109}
110
111impl Default for Config {
112    /// Creates a new configuration with typically used parameters: 115,200
113    /// Baud 8N1.
114    fn default() -> Config {
115        Config {
116            baudrate: 115_200.Bd(),
117            parity: Parity::None,
118            stopbits: StopBits::Stop1,
119        }
120    }
121}
122
123impl<T: Into<Baud>> From<T> for Config {
124    fn from(b: T) -> Config {
125        Config {
126            baudrate: b.into(),
127            ..Default::default()
128        }
129    }
130}
131
132#[cfg(feature = "defmt")]
133impl defmt::Format for Config {
134    fn format(&self, f: defmt::Formatter) {
135        // Omitting pins makes it:
136        // 1. Easier.
137        // 2. Not to specialized to use it ergonimically for users
138        //    even in a generic context.
139        // 3. Not require specialization.
140        defmt::write!(
141            f,
142            "Serial {{ baudrate: {} Bd , parity: {} , stopbits: {} }}",
143            self.baudrate.0,
144            self.parity,
145            self.stopbits,
146        );
147    }
148}