modbus_rtu/common/
baudrate.rs

1/// Represents supported baudrates for Modbus communication.
2///
3/// Each variant maps to an internal ID used within the protocol.
4/// The actual baudrate values (e.g., 9600, 115200) can be obtained via conversion.
5/// 
6#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
7#[repr(u16)]
8pub enum Baudrate {
9    BR1200 = 0,
10    BR2400 = 1,
11    BR4800 = 2,
12    BR9600 = 3,
13    BR19200 = 4,
14    BR38400 = 5,
15    BR57600 = 6,
16    BR115200 = 7,
17}
18
19
20impl Baudrate {
21    /// Attempts to create a `Baudrate` from its internal ID.
22    ///
23    /// This is used when a baudrate needs to be reconstructed from a stored or transmitted ID.
24    ///
25    /// ---
26    /// # Args
27    /// - `id`: The internal identifier corresponding to a `Baudrate`.
28    ///
29    /// ---
30    /// # Returns
31    /// `Some(Baudrate)` if the ID matches a known baudrate, otherwise `None`.
32    ///
33    /// ---
34    /// # Examples
35    /// ```
36    /// use modbus_rtu::common::Baudrate;
37    ///
38    /// assert_eq!(Baudrate::from_id(3), Some(Baudrate::BR9600));
39    /// assert_eq!(Baudrate::from_id(99), None);
40    /// ```
41    /// 
42    pub fn from_id(id: u16) -> Option<Baudrate> {
43        use Baudrate::*;
44        match id {
45            val if val == BR1200 as u16 => Some(BR1200),
46            val if val == BR2400 as u16 => Some(BR2400),
47            val if val == BR4800 as u16 => Some(BR4800),
48            val if val == BR9600 as u16 => Some(BR9600),
49            val if val == BR19200 as u16 => Some(BR19200),
50            val if val == BR38400 as u16 => Some(BR38400),
51            val if val == BR57600 as u16 => Some(BR57600),
52            val if val == BR115200 as u16 => Some(BR115200),
53            _ => None,
54        }
55    }
56
57    /// Converts the `Baudrate` variant into its internal ID representation.
58    ///
59    /// This ID can be stored or transmitted and later converted back using `from_id`.
60    ///
61    /// ---
62    /// # Returns
63    /// The internal `u16` ID associated with the baudrate.
64    ///
65    /// ---
66    /// # Examples
67    /// ```
68    /// use modbus_rtu::common::Baudrate;
69    ///
70    /// let baud = Baudrate::BR19200;
71    /// assert_eq!(baud.to_id(), 4);
72    /// ```
73    /// 
74    pub fn to_id(&self) -> u16 {
75        *self as u16
76    }
77
78    /// Calculates the packet end timeout in microseconds based on the baudrate.
79    ///
80    /// In Modbus RTU communication, this value defines the idle time required to consider a packet as ended. (3.5 char time)
81    ///
82    /// ---
83    /// # Returns
84    /// The idle time (in microseconds) required to delimit the end of a Modbus RTU packet at this baudrate.
85    ///
86    /// ---
87    /// # Examples
88    /// ```
89    /// use modbus_rtu::common::Baudrate;
90    ///
91    /// let baud = Baudrate::BR9600;
92    /// let packet_end_us: u32 = baud.packet_end_us();
93    /// ```
94    /// 
95    pub fn packet_end_us(&self) -> u32 {
96        let bps: u32 = self.into();
97        (35_000_000 + bps - 1) / bps
98    }
99}
100
101
102impl TryFrom<u32> for Baudrate {
103    type Error = ();
104
105    fn try_from(value: u32) -> Result<Self, Self::Error> {
106        use Baudrate::*;
107        match value {
108              1_200 => Ok(BR1200),
109              2_400 => Ok(BR2400),
110              4_800 => Ok(BR4800),
111              9_600 => Ok(BR9600),
112             19_200 => Ok(BR19200),
113             38_400 => Ok(BR38400),
114             57_600 => Ok(BR57600),
115            115_200 => Ok(BR115200),
116            _ => Err(())
117        }
118    }
119}
120
121
122impl From<Baudrate> for u32 {
123    fn from(value: Baudrate) -> Self {
124        match value {
125            Baudrate::BR1200   =>   1_200,
126            Baudrate::BR2400   =>   2_400,
127            Baudrate::BR4800   =>   4_800,
128            Baudrate::BR9600   =>   9_600,
129            Baudrate::BR19200  =>  19_200,
130            Baudrate::BR38400  =>  38_400,
131            Baudrate::BR57600  =>  57_600,
132            Baudrate::BR115200 => 115_200,
133        }
134    }
135}
136
137
138impl From<&Baudrate> for u32 {
139    fn from(value: &Baudrate) -> Self {
140        match value {
141            Baudrate::BR1200   =>   1_200,
142            Baudrate::BR2400   =>   2_400,
143            Baudrate::BR4800   =>   4_800,
144            Baudrate::BR9600   =>   9_600,
145            Baudrate::BR19200  =>  19_200,
146            Baudrate::BR38400  =>  38_400,
147            Baudrate::BR57600  =>  57_600,
148            Baudrate::BR115200 => 115_200,
149        }
150    }
151}