xref: /aosp_15_r20/system/usb_info_tools/typec_connector_class_helper/src/usb_pd_utils.rs (revision c6808bf1d92d62e809b5d71fe00befd40d32d6f9)
1 // Copyright 2024 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! usb_pd_utils
16 
17 /// Contains information for decoding a specific piece of data from a
18 /// Vendor Data Object (VDO).
19 pub struct VdoField {
20     pub index: i32,
21     pub mask: u32,
22     pub description: &'static str,
23 }
24 
25 impl VdoField {
26     /// Returns the "description: field_value" string for a VDO field.
decode_vdo(&self, vdo: u32) -> String27     pub fn decode_vdo(&self, vdo: u32) -> String {
28         let field_val: u32 = (vdo & self.mask) >> self.index;
29         [self.description, &format!(": 0x{:x}", field_val)].concat()
30     }
31 }
32 
33 // Masks for id_header fields.
34 pub const UFP_PRODUCT_TYPE_MASK: u32 = 0x38000000;
35 pub const DFP_PRODUCT_TYPE_MASK: u32 = 0x03800000;
36 
37 #[derive(Debug, PartialEq)]
38 pub enum PdRev {
39     None,
40     Pd20,
41     Pd30,
42     Pd31,
43 }
44 
45 #[derive(Debug, PartialEq)]
46 pub enum CableType {
47     Passive,
48     Active,
49     Vpd,
50 }
51 
52 #[derive(Debug, PartialEq)]
53 pub enum PortType {
54     Ufp,
55     Dfp,
56     Drd,
57 }
58 
59 #[derive(Debug, PartialEq)]
60 pub enum ProductType {
61     Cable((CableType, PdRev)),
62     Ama(PdRev),
63     Vpd(PdRev),
64     Port((PortType, PdRev)),
65     Other,
66 }
67 
68 /// Constants specific to USB PD revision 2.0.
69 pub mod pd20_data {
70     use super::VdoField;
71 
72     // Expected product identifiers extracted from id_header VDO.
73     pub const AMA_COMP: u32 = 0x28000000;
74     // Expected id_header field results.
75     pub const PASSIVE_CABLE_COMP: u32 = 0x20000000;
76     pub const ACTIVE_CABLE_COMP: u32 = 0x18000000;
77 
78     // Vendor Data Objects (VDO) decoding information (source: USB PD spec).
79     pub const ID_HEADER_VDO: &[VdoField] = &[
80         VdoField { index: 0, mask: 0x0000ffff, description: "USB Vendor ID" },
81         VdoField { index: 16, mask: 0x03ff0000, description: "Reserved" },
82         VdoField { index: 26, mask: 0x04000000, description: "Modal Operation Supported" },
83         VdoField { index: 27, mask: 0x38000000, description: "Product Type" },
84         VdoField { index: 30, mask: 0x40000000, description: "USB Capable as a USB Device" },
85         VdoField { index: 31, mask: 0x80000000, description: "USB Capable as a USB Host" },
86     ];
87 
88     pub const CERT_STAT_VDO: &[VdoField] =
89         &[VdoField { index: 0, mask: 0xffffffff, description: "XID" }];
90 
91     pub const PRODUCT_VDO: &[VdoField] = &[
92         VdoField { index: 0, mask: 0x0000ffff, description: "bcdDevice" },
93         VdoField { index: 16, mask: 0xffff0000, description: "USB Product ID" },
94     ];
95 
96     pub const AMA_VDO: &[VdoField] = &[
97         VdoField { index: 0, mask: 0x00000007, description: "USB SS Signaling Support" },
98         VdoField { index: 3, mask: 0x00000008, description: "Vbus Required" },
99         VdoField { index: 4, mask: 0x00000010, description: "Vconn Required" },
100         VdoField { index: 5, mask: 0x000000e0, description: "Vconn Power" },
101         VdoField { index: 8, mask: 0x00000100, description: "SSRX2 Directionality Support" },
102         VdoField { index: 9, mask: 0x00000200, description: "SSRX1 Directionality Support" },
103         VdoField { index: 10, mask: 0x00000400, description: "SSTX2 Directionality Support" },
104         VdoField { index: 11, mask: 0x00000800, description: "SSTX1 Directionality Support" },
105         VdoField { index: 12, mask: 0x00fff000, description: "Reserved" },
106         VdoField { index: 24, mask: 0x0f000000, description: "Firmware Version" },
107         VdoField { index: 28, mask: 0xf0000000, description: "Hardware Version" },
108     ];
109 
110     pub const PASSIVE_VDO: &[VdoField] = &[
111         VdoField { index: 0, mask: 0x00000007, description: "USB Speed" },
112         VdoField { index: 3, mask: 0x00000008, description: "Reserved" },
113         VdoField { index: 4, mask: 0x00000010, description: "Vbus Through Cable" },
114         VdoField { index: 5, mask: 0x00000060, description: "Vbus Current Handling" },
115         VdoField { index: 7, mask: 0x00000080, description: "SSRX2 Directionality Support" },
116         VdoField { index: 8, mask: 0x00000100, description: "SSRX1 Directionality Support" },
117         VdoField { index: 9, mask: 0x00000200, description: "SSTX2 Directionality Support" },
118         VdoField { index: 10, mask: 0x00000400, description: "SSTX1 Directionality Support" },
119         VdoField { index: 11, mask: 0x00001800, description: "Cable Termination Type" },
120         VdoField { index: 13, mask: 0x0001e000, description: "Cable Latency" },
121         VdoField { index: 17, mask: 0x00020000, description: "Reserved" },
122         VdoField { index: 18, mask: 0x000c0000, description: "USB Type-C Plug to USB Type" },
123         VdoField { index: 20, mask: 0x00f00000, description: "Reserved" },
124         VdoField { index: 24, mask: 0x0f000000, description: "Firmware Version" },
125         VdoField { index: 28, mask: 0xf0000000, description: "HW Version" },
126     ];
127 
128     pub const ACTIVE_VDO: &[VdoField] = &[
129         VdoField { index: 0, mask: 0x00000007, description: "USB Speed" },
130         VdoField { index: 3, mask: 0x00000008, description: "SOP'' Controller Present" },
131         VdoField { index: 4, mask: 0x00000010, description: "Vbus Through Cable" },
132         VdoField { index: 5, mask: 0x00000060, description: "Vbus Current Handling" },
133         VdoField { index: 7, mask: 0x00000080, description: "SSRX2 Directionality Support" },
134         VdoField { index: 8, mask: 0x00000100, description: "SSRX1 Directionality Support" },
135         VdoField { index: 9, mask: 0x00000200, description: "SSTX2 Directionality Support" },
136         VdoField { index: 10, mask: 0x00000400, description: "SSTX1 Directionality Support" },
137         VdoField { index: 11, mask: 0x00001800, description: "Cable Termination Type" },
138         VdoField { index: 13, mask: 0x0001e000, description: "Cable Latency" },
139         VdoField { index: 17, mask: 0x00020000, description: "Reserved" },
140         VdoField { index: 18, mask: 0x000c0000, description: "USB Type-C Plug to USB Type" },
141         VdoField { index: 20, mask: 0x00f00000, description: "Reserved" },
142         VdoField { index: 24, mask: 0x0f000000, description: "Firmware Version" },
143         VdoField { index: 28, mask: 0xf0000000, description: "HW Version" },
144     ];
145 }
146 
147 /// Constants specific to USB PD revision 3.0.
148 pub mod pd30_data {
149     use super::VdoField;
150 
151     pub const AMA_COMP: u32 = 0x28000000;
152     pub const VPD_COMP: u32 = 0x30000000;
153     pub const HUB_COMP: u32 = 0x08000000;
154     pub const PERIPHERAL_COMP: u32 = 0x10000000;
155     pub const DFP_HUB_COMP: u32 = 0x00800000;
156     pub const DFP_HOST_COMP: u32 = 0x01000000;
157     pub const POWER_BRICK_COMP: u32 = 0x01800000;
158     // Expected id_header field results.
159     pub const PASSIVE_CABLE_COMP: u32 = 0x18000000;
160     pub const ACTIVE_CABLE_COMP: u32 = 0x20000000;
161 
162     pub const ID_HEADER_VDO: &[VdoField] = &[
163         VdoField { index: 0, mask: 0x0000ffff, description: "USB Vendor ID" },
164         VdoField { index: 16, mask: 0x007f0000, description: "Reserved" },
165         VdoField { index: 23, mask: 0x03800000, description: "Product Type (DFP)" },
166         VdoField { index: 26, mask: 0x04000000, description: "Modal Operation Supported" },
167         VdoField { index: 27, mask: 0x38000000, description: "Product Type (UFP/Cable Plug)" },
168         VdoField { index: 30, mask: 0x40000000, description: "USB Capable as a USB Device" },
169         VdoField { index: 31, mask: 0x80000000, description: "USB Capable as a USB Host" },
170     ];
171 
172     pub const CERT_STAT_VDO: &[VdoField] =
173         &[VdoField { index: 0, mask: 0xffffffff, description: "XID" }];
174 
175     pub const PRODUCT_VDO: &[VdoField] = &[
176         VdoField { index: 0, mask: 0x0000ffff, description: "bcdDevice" },
177         VdoField { index: 16, mask: 0xffff0000, description: "USB Product ID" },
178     ];
179 
180     pub const AMA_VDO: &[VdoField] = &[
181         VdoField { index: 0, mask: 0x00000007, description: "USB Highest Speed" },
182         VdoField { index: 3, mask: 0x00000008, description: "Vbus Required" },
183         VdoField { index: 4, mask: 0x00000010, description: "Vconn Required" },
184         VdoField { index: 5, mask: 0x000000e0, description: "Vconn Power" },
185         VdoField { index: 8, mask: 0x001fff00, description: "Reserved" },
186         VdoField { index: 21, mask: 0x00e00000, description: "VDO Version" },
187         VdoField { index: 24, mask: 0x0f000000, description: "Firmware Version" },
188         VdoField { index: 28, mask: 0xf0000000, description: "Hardware Version" },
189     ];
190 
191     pub const VPD_VDO: &[VdoField] = &[
192         VdoField { index: 0, mask: 0x00000001, description: "Charge Through Support" },
193         VdoField { index: 1, mask: 0x0000007e, description: "Ground Impedance" },
194         VdoField { index: 7, mask: 0x00001f80, description: "Vbus Impedance" },
195         VdoField { index: 13, mask: 0x00002000, description: "Reserved" },
196         VdoField { index: 14, mask: 0x00004000, description: "Charge Through Current Support" },
197         VdoField { index: 15, mask: 0x00018000, description: "Maximum Vbus Voltage" },
198         VdoField { index: 17, mask: 0x001e0000, description: "Reserved" },
199     ];
200 
201     pub const PASSIVE_VDO: &[VdoField] = &[
202         VdoField { index: 0, mask: 0x00000007, description: "USB Speed" },
203         VdoField { index: 3, mask: 0x00000018, description: "Reserved" },
204         VdoField { index: 5, mask: 0x00000060, description: "Vbus Current Handling" },
205         VdoField { index: 7, mask: 0x00000180, description: "Reserved" },
206         VdoField { index: 9, mask: 0x00000600, description: "Maximum Vbus Voltage" },
207         VdoField { index: 11, mask: 0x00001800, description: "Cable Termination Type" },
208         VdoField { index: 13, mask: 0x0001e000, description: "Cable Latency" },
209         VdoField { index: 17, mask: 0x00020000, description: "Reserved" },
210         VdoField { index: 18, mask: 0x000c0000, description: "USB Type-C Plug to USB Type" },
211         VdoField { index: 20, mask: 0x00100000, description: "Reserved" },
212         VdoField { index: 21, mask: 0x00e00000, description: "VDO Version" },
213         VdoField { index: 24, mask: 0x0f000000, description: "Firmware Version" },
214         VdoField { index: 28, mask: 0xf0000000, description: "HW Version" },
215     ];
216 
217     pub const UFP_VDO1: &[VdoField] = &[
218         VdoField { index: 0, mask: 0x00000007, description: "USB Highest Speed" },
219         VdoField { index: 3, mask: 0x00000038, description: "Alternate Modes" },
220         VdoField { index: 6, mask: 0x00ffffc0, description: "Reserved" },
221         VdoField { index: 24, mask: 0x0f000000, description: "Device Capability" },
222         VdoField { index: 28, mask: 0x10000000, description: "Reserved" },
223         VdoField { index: 29, mask: 0xe0000000, description: "UFP VDO Version" },
224     ];
225 
226     pub const UFP_VDO2: &[VdoField] = &[
227         VdoField { index: 0, mask: 0x0000007f, description: "USB3 Max Power" },
228         VdoField { index: 7, mask: 0x00003f80, description: "USB3 Min Power" },
229         VdoField { index: 14, mask: 0x0000c000, description: "Reserved" },
230         VdoField { index: 16, mask: 0x007f0000, description: "USB4 Max Power" },
231         VdoField { index: 23, mask: 0x3f800000, description: "USB4 Min Power" },
232         VdoField { index: 30, mask: 0xc0000000, description: "Reserved" },
233     ];
234 
235     pub const DFP_VDO: &[VdoField] = &[
236         VdoField { index: 0, mask: 0x0000001f, description: "Port Number" },
237         VdoField { index: 5, mask: 0x00ffffe0, description: "Reserved" },
238         VdoField { index: 24, mask: 0x07000000, description: "Host Capability" },
239         VdoField { index: 27, mask: 0x18000000, description: "Reserved" },
240         VdoField { index: 29, mask: 0xe0000000, description: "DFP VDO Version" },
241         VdoField { index: 21, mask: 0x00e00000, description: "VDO Version" },
242         VdoField { index: 24, mask: 0x0f000000, description: "Firmware Version" },
243         VdoField { index: 28, mask: 0xf0000000, description: "HW Version" },
244     ];
245 
246     pub const ACTIVE_VDO1: &[VdoField] = &[
247         VdoField { index: 0, mask: 0x00000007, description: "USB Speed" },
248         VdoField { index: 3, mask: 0x00000008, description: "SOP'' Controller Present" },
249         VdoField { index: 4, mask: 0x00000010, description: "Vbus Through Cable" },
250         VdoField { index: 5, mask: 0x00000060, description: "Vbus Current Handling" },
251         VdoField { index: 7, mask: 0x00000080, description: "SBU Type" },
252         VdoField { index: 8, mask: 0x00000100, description: "SBU Supported" },
253         VdoField { index: 9, mask: 0x00000600, description: "Maximum Vbus Voltage" },
254         VdoField { index: 11, mask: 0x00001800, description: "Cable Termination Type" },
255         VdoField { index: 13, mask: 0x0001e000, description: "Cable Latency" },
256         VdoField { index: 17, mask: 0x00020000, description: "Reserved" },
257         VdoField { index: 18, mask: 0x000c0000, description: "Connector Type" },
258         VdoField { index: 20, mask: 0x00100000, description: "Reserved" },
259     ];
260 
261     pub const ACTIVE_VDO2: &[VdoField] = &[
262         VdoField { index: 0, mask: 0x00000001, description: "USB Gen" },
263         VdoField { index: 1, mask: 0x00000002, description: "Reserved" },
264         VdoField { index: 2, mask: 0x00000004, description: "Optically Insulated Active Cable" },
265         VdoField { index: 3, mask: 0x00000008, description: "USB Lanes Supported" },
266         VdoField { index: 4, mask: 0x00000010, description: "USB 3.2 Supported" },
267         VdoField { index: 5, mask: 0x00000020, description: "USB 2.0 Supported" },
268         VdoField { index: 6, mask: 0x000000c0, description: "USB 2.0 Hub Hops Command" },
269         VdoField { index: 8, mask: 0x00000100, description: "USB4 Supported" },
270         VdoField { index: 9, mask: 0x00000200, description: "Active Element" },
271         VdoField { index: 10, mask: 0x00000400, description: "Physical Connection" },
272         VdoField { index: 11, mask: 0x00000800, description: "U3 to U0 Transition Mode" },
273         VdoField { index: 12, mask: 0x00007000, description: "U3/CLd Power" },
274         VdoField { index: 15, mask: 0x00008000, description: "Reserved" },
275         VdoField { index: 16, mask: 0x00ff0000, description: "Shutdown Tempurature" },
276         VdoField { index: 24, mask: 0xff000000, description: "Max Operating Tempurature" },
277     ];
278 }
279 
280 /// Constants specific to USB PD revision 3.1.
281 pub mod pd31_data {
282     use super::VdoField;
283 
284     pub const HUB_COMP: u32 = 0x08000000;
285     pub const PERIPHERAL_COMP: u32 = 0x10000000;
286     pub const DFP_HUB_COMP: u32 = 0x00800000;
287     pub const DFP_HOST_COMP: u32 = 0x01000000;
288     pub const POWER_BRICK_COMP: u32 = 0x01800000;
289     // Expected id_header field results.
290     pub const PASSIVE_CABLE_COMP: u32 = 0x18000000;
291     pub const ACTIVE_CABLE_COMP: u32 = 0x20000000;
292     pub const VPD_COMP: u32 = 0x30000000;
293 
294     pub const ID_HEADER_VDO: &[VdoField] = &[
295         VdoField { index: 0, mask: 0x0000ffff, description: "USB Vendor ID" },
296         VdoField { index: 16, mask: 0x001f0000, description: "Reserved" },
297         VdoField { index: 21, mask: 0x00600000, description: "Connector Type" },
298         VdoField { index: 23, mask: 0x03800000, description: "Product Type (DFP)" },
299         VdoField { index: 26, mask: 0x04000000, description: "Modal Operation Supported" },
300         VdoField { index: 27, mask: 0x38000000, description: "Product Type (UFP/Cable Plug)" },
301         VdoField { index: 30, mask: 0x40000000, description: "USB Capable as a USB Device" },
302         VdoField { index: 31, mask: 0x80000000, description: "USB Capable as a USB Host" },
303     ];
304 
305     pub const CERT_STAT_VDO: &[VdoField] =
306         &[VdoField { index: 0, mask: 0xffffffff, description: "XID" }];
307 
308     pub const PRODUCT_VDO: &[VdoField] = &[
309         VdoField { index: 0, mask: 0x0000ffff, description: "bcdDevice" },
310         VdoField { index: 16, mask: 0xffff0000, description: "USB Product ID" },
311     ];
312 
313     pub const UFP_VDO: &[VdoField] = &[
314         VdoField { index: 0, mask: 0x00000007, description: "USB Highest Speed" },
315         VdoField { index: 3, mask: 0x00000038, description: "Alternate Modes" },
316         VdoField { index: 6, mask: 0x00000040, description: "Vbus Required" },
317         VdoField { index: 7, mask: 0x00000080, description: "Vconn Required" },
318         VdoField { index: 8, mask: 0x00000700, description: "Vconn Power" },
319         VdoField { index: 11, mask: 0x003ff800, description: "Reserved" },
320         VdoField { index: 22, mask: 0x00c00000, description: "Connector Type (Legacy)" },
321         VdoField { index: 24, mask: 0x0f000000, description: "Device Capability" },
322         VdoField { index: 28, mask: 0x10000000, description: "Reserved" },
323         VdoField { index: 29, mask: 0xe0000000, description: "UFP VDO Version" },
324     ];
325 
326     pub const DFP_VDO: &[VdoField] = &[
327         VdoField { index: 0, mask: 0x0000001f, description: "Port Number" },
328         VdoField { index: 5, mask: 0x003fffe0, description: "Reserved" },
329         VdoField { index: 22, mask: 0x00c00000, description: "Connector Type (Legacy)" },
330         VdoField { index: 24, mask: 0x07000000, description: "Host Capability" },
331         VdoField { index: 27, mask: 0x18000000, description: "Reserved" },
332         VdoField { index: 29, mask: 0xe0000000, description: "DFP VDO Version" },
333     ];
334 
335     pub const PASSIVE_VDO: &[VdoField] = &[
336         VdoField { index: 0, mask: 0x00000007, description: "USB Speed" },
337         VdoField { index: 3, mask: 0x00000018, description: "Reserved" },
338         VdoField { index: 5, mask: 0x00000060, description: "Vbus Current Handling" },
339         VdoField { index: 7, mask: 0x00000180, description: "Reserved" },
340         VdoField { index: 9, mask: 0x00000600, description: "Maximum Vbus Voltage" },
341         VdoField { index: 11, mask: 0x00001800, description: "Cable Termination Type" },
342         VdoField { index: 13, mask: 0x0001e000, description: "Cable Latency" },
343         VdoField { index: 17, mask: 0x00020000, description: "EPR Mode Cable" },
344         VdoField { index: 18, mask: 0x000c0000, description: "USB Type-C Plug to USB Type" },
345         VdoField { index: 20, mask: 0x00100000, description: "Reserved" },
346         VdoField { index: 21, mask: 0x00e00000, description: "VDO Version" },
347         VdoField { index: 24, mask: 0x0f000000, description: "Firmware Version" },
348         VdoField { index: 28, mask: 0xf0000000, description: "HW Version" },
349     ];
350 
351     pub const ACTIVE_VDO1: &[VdoField] = &[
352         VdoField { index: 0, mask: 0x00000007, description: "USB Speed" },
353         VdoField { index: 3, mask: 0x00000008, description: "SOP'' Controller Present" },
354         VdoField { index: 4, mask: 0x00000010, description: "Vbus Through Cable" },
355         VdoField { index: 5, mask: 0x00000060, description: "Vbus Current Handling" },
356         VdoField { index: 7, mask: 0x00000080, description: "SBU Type" },
357         VdoField { index: 8, mask: 0x00000100, description: "SBU Supported" },
358         VdoField { index: 9, mask: 0x00000600, description: "Maximum Vbus Voltage" },
359         VdoField { index: 11, mask: 0x00001800, description: "Cable Termination Type" },
360         VdoField { index: 13, mask: 0x0001e000, description: "Cable Latency" },
361         VdoField { index: 17, mask: 0x00020000, description: "EPR Mode Cable" },
362         VdoField { index: 18, mask: 0x000c0000, description: "USB Type-C Plug to USB Type" },
363         VdoField { index: 20, mask: 0x00100000, description: "Reserved" },
364         VdoField { index: 21, mask: 0x00e00000, description: "VDO Version" },
365         VdoField { index: 24, mask: 0x0f000000, description: "Firmware Version" },
366         VdoField { index: 28, mask: 0xf0000000, description: "HW Version" },
367     ];
368 
369     pub const ACTIVE_VDO2: &[VdoField] = &[
370         VdoField { index: 0, mask: 0x00000001, description: "USB Gen" },
371         VdoField { index: 1, mask: 0x00000002, description: "Reserved" },
372         VdoField { index: 2, mask: 0x00000004, description: "Optically Insulated Active Cable" },
373         VdoField { index: 3, mask: 0x00000008, description: "USB Lanes Supported" },
374         VdoField { index: 4, mask: 0x00000010, description: "USB 3.2 Supported" },
375         VdoField { index: 5, mask: 0x00000020, description: "USB 2.0 Supported" },
376         VdoField { index: 6, mask: 0x000000c0, description: "USB 2.0 Hub Hops Command" }, // Corrected mask
377         VdoField { index: 8, mask: 0x00000100, description: "USB4 Supported" },
378         VdoField { index: 9, mask: 0x00000200, description: "Active Element" },
379         VdoField { index: 10, mask: 0x00000400, description: "Physical Connection" },
380         VdoField { index: 11, mask: 0x00000800, description: "U3 to U0 Transition Mode" },
381         VdoField { index: 12, mask: 0x00007000, description: "U3/CLd Power" },
382         VdoField { index: 15, mask: 0x00008000, description: "Reserved" },
383         VdoField { index: 16, mask: 0x00ff0000, description: "Shutdown Tempurature" },
384         VdoField { index: 24, mask: 0xff000000, description: "Max Operating Tempurature" },
385     ];
386 
387     pub const VPD_VDO: &[VdoField] = &[
388         VdoField { index: 0, mask: 0x00000001, description: "Charge Through Support" },
389         VdoField { index: 1, mask: 0x0000007e, description: "Ground Impedance" },
390         VdoField { index: 7, mask: 0x00001f80, description: "Vbus Impedance" },
391         VdoField { index: 13, mask: 0x00002000, description: "Reserved" },
392         VdoField { index: 14, mask: 0x00004000, description: "Charge Through Current Support" },
393         VdoField { index: 15, mask: 0x00018000, description: "Maximum Vbus Voltage" },
394         VdoField { index: 17, mask: 0x001e0000, description: "Reserved" },
395         VdoField { index: 21, mask: 0x00e00000, description: "VDO Version" },
396         VdoField { index: 24, mask: 0x0f000000, description: "Firmware Version" },
397         VdoField { index: 28, mask: 0xf0000000, description: "HW Version" },
398     ];
399 }
400 
401 #[cfg(test)]
402 mod tests {
403     use super::*;
404 
405     #[test]
test_decode_vdo()406     fn test_decode_vdo() {
407         let vdo: u32 = 0x12341234;
408         let field = VdoField {
409             index: 4,
410             mask: 0x000000f0,
411             description: "Value of the 2nd least significant byte",
412         };
413         assert_eq!(field.decode_vdo(vdo), "Value of the 2nd least significant byte: 0x3")
414     }
415 }
416