1use core::fmt;
5
6#[derive(Copy, Clone, Debug, PartialEq, Eq)]
10#[cfg_attr(feature = "defmt", derive(defmt::Format))]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub enum RegMode {
13 ConstantVoltage,
14 ConstantCurrent,
15}
16
17impl RegMode {
18 pub const fn from_reg(v: u16) -> Self {
19 match v {
20 0 => Self::ConstantVoltage,
21 _ => Self::ConstantCurrent,
22 }
23 }
24}
25
26#[derive(Copy, Clone, Debug, PartialEq, Eq)]
30#[cfg_attr(feature = "defmt", derive(defmt::Format))]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32pub enum TempUnit {
33 Celsius,
34 Fahrenheit,
35}
36
37impl TempUnit {
38 pub const fn from_reg(v: u16) -> Self {
39 match v {
40 0 => Self::Celsius,
41 _ => Self::Fahrenheit,
42 }
43 }
44 pub const fn to_reg(self) -> u16 {
45 match self {
46 Self::Celsius => 0,
47 Self::Fahrenheit => 1,
48 }
49 }
50}
51
52#[derive(Copy, Clone, Debug, PartialEq, Eq)]
59#[cfg_attr(feature = "defmt", derive(defmt::Format))]
60#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
61pub enum ProtectionStatus {
62 Normal,
64 Ovp,
68 Ocp,
70 Opp,
72 Lvp,
74 Oah,
76 Ohp,
78 Otp,
80 Oep,
82 Owh,
84 Icp,
86 Unknown(u16),
88}
89
90impl ProtectionStatus {
91 pub const fn from_reg(raw: u16) -> Self {
92 match raw {
93 0 => Self::Normal,
94 1 => Self::Ovp,
95 2 => Self::Ocp,
96 3 => Self::Opp,
97 4 => Self::Lvp,
98 5 => Self::Oah,
99 6 => Self::Ohp,
100 7 => Self::Otp,
101 8 => Self::Oep,
102 9 => Self::Owh,
103 10 => Self::Icp,
104 other => Self::Unknown(other),
105 }
106 }
107}
108
109impl fmt::Display for ProtectionStatus {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 f.write_str(match self {
112 Self::Normal => "normal",
113 Self::Ovp => "ovp",
114 Self::Ocp => "ocp",
115 Self::Opp => "opp",
116 Self::Lvp => "lvp",
117 Self::Oah => "oah",
118 Self::Ohp => "ohp",
119 Self::Otp => "otp",
120 Self::Oep => "oep",
121 Self::Owh => "owh",
122 Self::Icp => "icp",
123 Self::Unknown(v) => return write!(f, "unknown({v})"),
124 })
125 }
126}
127
128#[derive(Copy, Clone, Debug, PartialEq, Eq)]
136#[cfg_attr(feature = "defmt", derive(defmt::Format))]
137#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
138pub enum BaudRate {
139 B9600,
140 B14400,
141 B19200,
142 B38400,
143 B56000,
144 B57600,
145 B115200,
146 B2400,
147 B4800,
148 Unknown(u16),
150}
151
152impl BaudRate {
153 pub const fn code(self) -> u16 {
155 match self {
156 Self::B9600 => 0,
157 Self::B14400 => 1,
158 Self::B19200 => 2,
159 Self::B38400 => 3,
160 Self::B56000 => 4,
161 Self::B57600 => 5,
162 Self::B115200 => 6,
163 Self::B2400 => 7,
164 Self::B4800 => 8,
165 Self::Unknown(c) => c,
166 }
167 }
168 pub const fn from_code(code: u16) -> Self {
169 match code {
170 0 => Self::B9600,
171 1 => Self::B14400,
172 2 => Self::B19200,
173 3 => Self::B38400,
174 4 => Self::B56000,
175 5 => Self::B57600,
176 6 => Self::B115200,
177 7 => Self::B2400,
178 8 => Self::B4800,
179 c => Self::Unknown(c),
180 }
181 }
182 pub const fn baud(self) -> Option<u32> {
184 Some(match self {
185 Self::B2400 => 2400,
186 Self::B4800 => 4800,
187 Self::B9600 => 9600,
188 Self::B14400 => 14400,
189 Self::B19200 => 19200,
190 Self::B38400 => 38400,
191 Self::B56000 => 56000,
192 Self::B57600 => 57600,
193 Self::B115200 => 115200,
194 Self::Unknown(_) => return None,
195 })
196 }
197}
198
199#[cfg(test)]
200mod tests {
201 extern crate std;
202 use super::*;
203 use std::format;
204
205 #[test]
209 fn protection_status_from_reg_full_mapping() {
210 let cases = [
211 (0, ProtectionStatus::Normal),
212 (1, ProtectionStatus::Ovp),
213 (2, ProtectionStatus::Ocp),
214 (3, ProtectionStatus::Opp),
215 (4, ProtectionStatus::Lvp),
216 (5, ProtectionStatus::Oah),
217 (6, ProtectionStatus::Ohp),
218 (7, ProtectionStatus::Otp),
219 (8, ProtectionStatus::Oep),
220 (9, ProtectionStatus::Owh),
221 (10, ProtectionStatus::Icp),
222 (11, ProtectionStatus::Unknown(11)),
223 (0xFFFF, ProtectionStatus::Unknown(0xFFFF)),
224 ];
225 for (raw, expected) in cases {
226 assert_eq!(ProtectionStatus::from_reg(raw), expected);
227 }
228 }
229
230 #[test]
232 fn protection_status_display_strings() {
233 assert_eq!(format!("{}", ProtectionStatus::Normal), "normal");
234 assert_eq!(format!("{}", ProtectionStatus::Ovp), "ovp");
235 assert_eq!(format!("{}", ProtectionStatus::Icp), "icp");
236 assert_eq!(format!("{}", ProtectionStatus::Unknown(42)), "unknown(42)");
237 }
238
239 #[test]
243 fn baud_rate_full_table() {
244 let cases = [
245 (0, BaudRate::B9600, 9600),
246 (1, BaudRate::B14400, 14400),
247 (2, BaudRate::B19200, 19200),
248 (3, BaudRate::B38400, 38400),
249 (4, BaudRate::B56000, 56000),
250 (5, BaudRate::B57600, 57600),
251 (6, BaudRate::B115200, 115200),
252 (7, BaudRate::B2400, 2400),
253 (8, BaudRate::B4800, 4800),
254 ];
255 for (code, variant, bps) in cases {
256 assert_eq!(BaudRate::from_code(code), variant);
257 assert_eq!(variant.code(), code);
258 assert_eq!(variant.baud(), Some(bps));
259 }
260 assert_eq!(BaudRate::from_code(99), BaudRate::Unknown(99));
261 assert_eq!(BaudRate::Unknown(99).code(), 99);
262 assert_eq!(BaudRate::Unknown(99).baud(), None);
263 }
264
265 #[test]
266 fn temp_unit_round_trip() {
267 assert_eq!(TempUnit::from_reg(0), TempUnit::Celsius);
268 assert_eq!(TempUnit::from_reg(1), TempUnit::Fahrenheit);
269 assert_eq!(TempUnit::from_reg(99), TempUnit::Fahrenheit);
271 assert_eq!(TempUnit::Celsius.to_reg(), 0);
272 assert_eq!(TempUnit::Fahrenheit.to_reg(), 1);
273 }
274}