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}