Skip to main content

obd2_core/protocol/
dtc.rs

1//! DTC types, status definitions, and built-in SAE J2012 description table.
2//!
3//! This module includes ~200 universal DTC descriptions covering powertrain (P),
4//! chassis (C), body (B), and network (U) codes. Descriptions are automatically
5//! populated when creating DTCs via [`Dtc::from_bytes`] or [`Dtc::from_code`].
6//!
7//! For vehicle-specific enrichment (severity, notes, related PIDs), use
8//! [`crate::session::diagnostics::enrich_dtcs`] which layers spec-based
9//! descriptions on top of the universal table.
10
11/// A Diagnostic Trouble Code read from the vehicle.
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct Dtc {
14    pub code: String,
15    pub category: DtcCategory,
16    pub status: DtcStatus,
17    pub description: Option<String>,
18    pub severity: Option<Severity>,
19    pub source_module: Option<String>,
20    pub notes: Option<String>,
21}
22
23impl Default for Dtc {
24    fn default() -> Self {
25        Self {
26            code: String::new(),
27            category: DtcCategory::Powertrain,
28            status: DtcStatus::Stored,
29            description: None,
30            severity: None,
31            source_module: None,
32            notes: None,
33        }
34    }
35}
36
37impl Dtc {
38    /// Decode a DTC from two raw bytes (Mode 03/07/0A response).
39    /// Bits 15-14 = category, bits 13-12 = second char, bits 11-8 = third, 7-4 = fourth, 3-0 = fifth.
40    pub fn from_bytes(a: u8, b: u8) -> Self {
41        let category = match (a >> 6) & 0x03 {
42            0 => DtcCategory::Powertrain,
43            1 => DtcCategory::Chassis,
44            2 => DtcCategory::Body,
45            _ => DtcCategory::Network,
46        };
47        let prefix = match category {
48            DtcCategory::Powertrain => 'P',
49            DtcCategory::Chassis => 'C',
50            DtcCategory::Body => 'B',
51            DtcCategory::Network => 'U',
52        };
53        let d2 = (a >> 4) & 0x03;
54        let d3 = a & 0x0F;
55        let d4 = (b >> 4) & 0x0F;
56        let d5 = b & 0x0F;
57        let code = format!("{}{}{:X}{:X}{:X}", prefix, d2, d3, d4, d5);
58
59        let description = universal_dtc_description(&code).map(String::from);
60
61        Self {
62            code,
63            category,
64            status: DtcStatus::Stored,
65            description,
66            severity: None,
67            source_module: None,
68            notes: None,
69        }
70    }
71
72    /// Create a DTC from a code string (e.g., "P0420").
73    pub fn from_code(code: &str) -> Self {
74        let category = match code.chars().next() {
75            Some('P') | Some('p') => DtcCategory::Powertrain,
76            Some('C') | Some('c') => DtcCategory::Chassis,
77            Some('B') | Some('b') => DtcCategory::Body,
78            Some('U') | Some('u') => DtcCategory::Network,
79            _ => DtcCategory::Powertrain,
80        };
81        let upper = code.to_uppercase();
82        let description = universal_dtc_description(&upper).map(String::from);
83        Self {
84            code: upper,
85            category,
86            status: DtcStatus::Stored,
87            description,
88            severity: None,
89            source_module: None,
90            notes: None,
91        }
92    }
93}
94
95/// Category prefix of a DTC (P, C, B, U).
96#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
97pub enum DtcCategory {
98    Powertrain,
99    Chassis,
100    Body,
101    Network,
102}
103
104/// Lifecycle status of a DTC.
105#[derive(Debug, Clone, Copy, PartialEq, Eq)]
106pub enum DtcStatus {
107    Stored,
108    Pending,
109    Permanent,
110}
111
112/// Severity level of a DTC.
113#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize)]
114pub enum Severity {
115    Info,
116    Low,
117    Medium,
118    High,
119    Critical,
120}
121
122/// GM/UDS Mode 19 extended status byte -- 8 flags per DTC.
123#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
124pub struct DtcStatusByte {
125    pub test_failed: bool,
126    pub test_failed_this_cycle: bool,
127    pub pending: bool,
128    pub confirmed: bool,
129    pub test_not_completed_since_clear: bool,
130    pub test_failed_since_clear: bool,
131    pub test_not_completed_this_cycle: bool,
132    pub warning_indicator_requested: bool,
133}
134
135impl DtcStatusByte {
136    /// Decode a Mode 19 DTC status byte into individual flags.
137    pub fn from_byte(b: u8) -> Self {
138        Self {
139            test_failed: (b & 0x01) != 0,
140            test_failed_this_cycle: (b & 0x02) != 0,
141            pending: (b & 0x04) != 0,
142            confirmed: (b & 0x08) != 0,
143            test_not_completed_since_clear: (b & 0x10) != 0,
144            test_failed_since_clear: (b & 0x20) != 0,
145            test_not_completed_this_cycle: (b & 0x40) != 0,
146            warning_indicator_requested: (b & 0x80) != 0,
147        }
148    }
149
150    /// Encode the status flags back into a single byte.
151    pub fn to_byte(&self) -> u8 {
152        let mut b = 0u8;
153        if self.test_failed {
154            b |= 0x01;
155        }
156        if self.test_failed_this_cycle {
157            b |= 0x02;
158        }
159        if self.pending {
160            b |= 0x04;
161        }
162        if self.confirmed {
163            b |= 0x08;
164        }
165        if self.test_not_completed_since_clear {
166            b |= 0x10;
167        }
168        if self.test_failed_since_clear {
169            b |= 0x20;
170        }
171        if self.test_not_completed_this_cycle {
172            b |= 0x40;
173        }
174        if self.warning_indicator_requested {
175            b |= 0x80;
176        }
177        b
178    }
179}
180
181/// Look up the universal (SAE J2012) description for a DTC code.
182///
183/// Covers ~200 common OBD-II codes across powertrain, chassis, body, and network categories.
184pub fn universal_dtc_description(code: &str) -> Option<&'static str> {
185    match code {
186        // VVT / Camshaft
187        "P0010" => Some("Intake Camshaft Position Actuator Circuit (Bank 1)"),
188        "P0011" => Some("Intake Camshaft Position Timing Over-Advanced (Bank 1)"),
189        "P0012" => Some("Intake Camshaft Position Timing Over-Retarded (Bank 1)"),
190        "P0014" => Some("Exhaust Camshaft Position Timing Over-Advanced (Bank 1)"),
191        "P0016" => Some("Crankshaft Position / Camshaft Position Correlation (Bank 1 Sensor A)"),
192        // O2 Sensor Heaters
193        "P0030" => Some("HO2S Heater Control Circuit (Bank 1 Sensor 1)"),
194        "P0036" => Some("HO2S Heater Control Circuit (Bank 1 Sensor 2)"),
195        // Diesel / Fuel Rail
196        "P0087" => Some("Fuel Rail/System Pressure Too Low"),
197        "P0088" => Some("Fuel Rail/System Pressure Too High"),
198        "P0093" => Some("Fuel System Leak Detected (Large)"),
199        // Fuel & Air Metering
200        "P0100" => Some("MAF/VAF Circuit Malfunction"),
201        "P0101" => Some("MAF/VAF Circuit Range/Performance"),
202        "P0102" => Some("MAF/VAF Circuit Low Input"),
203        "P0103" => Some("MAF/VAF Circuit High Input"),
204        "P0106" => Some("MAP/Barometric Pressure Circuit Range/Performance"),
205        "P0107" => Some("MAP/Barometric Pressure Circuit Low Input"),
206        "P0108" => Some("MAP/Barometric Pressure Circuit High Input"),
207        "P0110" => Some("Intake Air Temperature Sensor 1 Circuit"),
208        "P0111" => Some("Intake Air Temperature Sensor 1 Circuit Range/Performance"),
209        "P0112" => Some("Intake Air Temperature Sensor 1 Circuit Low"),
210        "P0113" => Some("Intake Air Temperature Sensor 1 Circuit High"),
211        "P0115" => Some("Engine Coolant Temperature Circuit"),
212        "P0116" => Some("Engine Coolant Temperature Circuit Range/Performance"),
213        "P0117" => Some("Engine Coolant Temperature Circuit Low"),
214        "P0118" => Some("Engine Coolant Temperature Circuit High"),
215        "P0120" => Some("Throttle Position Sensor A Circuit"),
216        "P0121" => Some("Throttle Position Sensor A Circuit Range/Performance"),
217        "P0122" => Some("Throttle Position Sensor A Circuit Low"),
218        "P0123" => Some("Throttle Position Sensor A Circuit High"),
219        "P0125" => Some("Insufficient Coolant Temperature for Closed Loop"),
220        "P0128" => Some("Coolant Thermostat Below Operating Temperature"),
221        "P0130" => Some("O2 Sensor Circuit Bank 1 Sensor 1"),
222        "P0131" => Some("O2 Sensor Circuit Low Voltage B1S1"),
223        "P0132" => Some("O2 Sensor Circuit High Voltage B1S1"),
224        "P0133" => Some("O2 Sensor Circuit Slow Response B1S1"),
225        "P0134" => Some("O2 Sensor Circuit No Activity B1S1"),
226        "P0135" => Some("O2 Sensor Heater Circuit B1S1"),
227        "P0136" => Some("O2 Sensor Circuit Bank 1 Sensor 2"),
228        "P0137" => Some("O2 Sensor Circuit Low Voltage B1S2"),
229        "P0138" => Some("O2 Sensor Circuit High Voltage B1S2"),
230        "P0139" => Some("O2 Sensor Circuit Slow Response B1S2"),
231        "P0140" => Some("O2 Sensor Circuit No Activity B1S2"),
232        "P0141" => Some("O2 Sensor Heater Circuit B1S2"),
233        "P0150" => Some("O2 Sensor Circuit Bank 2 Sensor 1"),
234        "P0151" => Some("O2 Sensor Circuit Low Voltage B2S1"),
235        "P0152" => Some("O2 Sensor Circuit High Voltage B2S1"),
236        "P0153" => Some("O2 Sensor Circuit Slow Response B2S1"),
237        "P0154" => Some("O2 Sensor Circuit No Activity B2S1"),
238        "P0155" => Some("O2 Sensor Heater Circuit B2S1"),
239        "P0156" => Some("O2 Sensor Circuit Bank 2 Sensor 2"),
240        "P0157" => Some("O2 Sensor Circuit Low Voltage B2S2"),
241        "P0158" => Some("O2 Sensor Circuit High Voltage B2S2"),
242        "P0159" => Some("O2 Sensor Circuit Slow Response B2S2"),
243        "P0160" => Some("O2 Sensor Circuit No Activity B2S2"),
244        "P0161" => Some("O2 Sensor Heater Circuit B2S2"),
245        "P0171" => Some("System Too Lean Bank 1"),
246        "P0172" => Some("System Too Rich Bank 1"),
247        "P0174" => Some("System Too Lean Bank 2"),
248        "P0175" => Some("System Too Rich Bank 2"),
249        // Fuel Rail Pressure Sensor
250        "P0192" => Some("Fuel Rail Pressure Sensor Circuit Low"),
251        "P0193" => Some("Fuel Rail Pressure Sensor Circuit High"),
252        // Injector Circuits
253        "P0201" => Some("Injector Circuit/Open Cylinder 1"),
254        "P0202" => Some("Injector Circuit/Open Cylinder 2"),
255        "P0203" => Some("Injector Circuit/Open Cylinder 3"),
256        "P0204" => Some("Injector Circuit/Open Cylinder 4"),
257        "P0205" => Some("Injector Circuit/Open Cylinder 5"),
258        "P0206" => Some("Injector Circuit/Open Cylinder 6"),
259        "P0207" => Some("Injector Circuit/Open Cylinder 7"),
260        "P0208" => Some("Injector Circuit/Open Cylinder 8"),
261        // Turbo / Boost
262        "P0234" => Some("Turbo/Supercharger Overboost Condition"),
263        "P0236" => Some("Turbocharger Boost Sensor A Circuit Range/Performance"),
264        "P0299" => Some("Turbo/Supercharger Underboost"),
265        // Ignition / Misfire
266        "P0300" => Some("Random/Multiple Cylinder Misfire Detected"),
267        "P0301" => Some("Cylinder 1 Misfire Detected"),
268        "P0302" => Some("Cylinder 2 Misfire Detected"),
269        "P0303" => Some("Cylinder 3 Misfire Detected"),
270        "P0304" => Some("Cylinder 4 Misfire Detected"),
271        "P0305" => Some("Cylinder 5 Misfire Detected"),
272        "P0306" => Some("Cylinder 6 Misfire Detected"),
273        "P0307" => Some("Cylinder 7 Misfire Detected"),
274        "P0308" => Some("Cylinder 8 Misfire Detected"),
275        "P0325" => Some("Knock Sensor 1 Circuit Bank 1"),
276        "P0335" => Some("Crankshaft Position Sensor A Circuit"),
277        "P0336" => Some("Crankshaft Position Sensor A Range/Performance"),
278        "P0340" => Some("Camshaft Position Sensor A Circuit Bank 1"),
279        "P0341" => Some("Camshaft Position Sensor A Range/Performance Bank 1"),
280        // Camshaft Position Sensors
281        "P0365" => Some("Camshaft Position Sensor B Circuit (Bank 1)"),
282        "P0366" => Some("Camshaft Position Sensor B Circuit Range/Performance (Bank 1)"),
283        // Glow Plug
284        "P0380" => Some("Glow Plug/Heater Circuit A Malfunction"),
285        // Emission Controls
286        "P0400" => Some("EGR Flow Malfunction"),
287        "P0401" => Some("EGR Flow Insufficient"),
288        "P0402" => Some("EGR Flow Excessive"),
289        "P0404" => Some("EGR System Range/Performance"),
290        "P0405" => Some("EGR Position Sensor A Circuit Low"),
291        "P0406" => Some("EGR Position Sensor A Circuit High"),
292        "P0420" => Some("Catalyst System Efficiency Below Threshold Bank 1"),
293        "P0430" => Some("Catalyst System Efficiency Below Threshold Bank 2"),
294        "P0440" => Some("Evaporative Emission System Malfunction"),
295        "P0441" => Some("Evaporative Emission System Incorrect Purge Flow"),
296        "P0442" => Some("Evaporative Emission System Leak Detected (Small)"),
297        "P0443" => Some("Evaporative Emission System Purge Control Valve Circuit"),
298        "P0446" => Some("Evaporative Emission System Vent Control Circuit"),
299        "P0449" => Some("Evaporative Emission System Vent Valve/Solenoid Circuit"),
300        "P0451" => Some("Evaporative Emission System Pressure Sensor Range/Performance"),
301        "P0455" => Some("Evaporative Emission System Leak Detected (Large)"),
302        "P0456" => Some("Evaporative Emission System Leak Detected (Very Small)"),
303        "P0496" => Some("Evaporative Emission System High Purge Flow"),
304        // Speed / Idle
305        "P0500" => Some("Vehicle Speed Sensor A Malfunction"),
306        "P0503" => Some("Vehicle Speed Sensor Intermittent/Erratic/High"),
307        "P0505" => Some("Idle Air Control System Malfunction"),
308        "P0506" => Some("Idle Air Control System RPM Lower Than Expected"),
309        "P0507" => Some("Idle Air Control System RPM Higher Than Expected"),
310        // Electrical
311        "P0562" => Some("System Voltage Low"),
312        "P0563" => Some("System Voltage High"),
313        // Thermostat
314        "P0597" => Some("Thermostat Heater Control Circuit Open"),
315        "P0598" => Some("Thermostat Heater Control Circuit Low"),
316        "P0599" => Some("Thermostat Heater Control Circuit High"),
317        // ECM
318        "P0600" => Some("Serial Communication Link Malfunction"),
319        "P0601" => Some("Internal Control Module Memory Check Sum Error"),
320        "P0602" => Some("Control Module Programming Error"),
321        "P0606" => Some("ECM/PCM Processor Fault"),
322        // Transmission
323        "P0700" => Some("Transmission Control System Malfunction"),
324        "P0705" => Some("Transmission Range Sensor Circuit Malfunction"),
325        "P0710" => Some("Transmission Fluid Temperature Sensor Circuit"),
326        "P0711" => Some("Transmission Fluid Temperature Sensor Circuit Range/Performance"),
327        "P0715" => Some("Input/Turbine Speed Sensor Circuit"),
328        "P0717" => Some("Input/Turbine Speed Sensor Circuit No Signal"),
329        "P0720" => Some("Output Speed Sensor Circuit"),
330        "P0725" => Some("Engine Speed Input Circuit"),
331        "P0730" => Some("Incorrect Gear Ratio"),
332        "P0731" => Some("Gear 1 Incorrect Ratio"),
333        "P0732" => Some("Gear 2 Incorrect Ratio"),
334        "P0733" => Some("Gear 3 Incorrect Ratio"),
335        "P0734" => Some("Gear 4 Incorrect Ratio"),
336        "P0735" => Some("Gear 5 Incorrect Ratio"),
337        "P0740" => Some("Torque Converter Clutch Circuit Malfunction"),
338        "P0741" => Some("Torque Converter Clutch System Stuck Off"),
339        "P0742" => Some("Torque Converter Clutch System Stuck On"),
340        "P0743" => Some("Torque Converter Clutch System Electrical"),
341        "P0747" => Some("Pressure Control Solenoid A Stuck On"),
342        "P0748" => Some("Pressure Control Solenoid A Electrical"),
343        "P0750" => Some("Shift Solenoid A Malfunction"),
344        "P0751" => Some("Shift Solenoid A Performance/Stuck Off"),
345        "P0752" => Some("Shift Solenoid A Stuck On"),
346        "P0753" => Some("Shift Solenoid A Electrical"),
347        "P0755" => Some("Shift Solenoid B Malfunction"),
348        "P0756" => Some("Shift Solenoid B Performance/Stuck Off"),
349        "P0757" => Some("Shift Solenoid B Stuck On"),
350        "P0758" => Some("Shift Solenoid B Electrical"),
351        // GM-Specific / Manufacturer
352        "P1101" => Some("Intake Airflow System Performance"),
353        "P2097" => Some("Post Catalyst Fuel Trim System Too Rich (Bank 1)"),
354        "P2227" => Some("Barometric Pressure Circuit Range/Performance"),
355        "P2270" => Some("O2 Sensor Signal Stuck Lean (Bank 1 Sensor 2)"),
356        "P2271" => Some("O2 Sensor Signal Stuck Rich (Bank 1 Sensor 2)"),
357        "P2797" => Some("Auxiliary Transmission Fluid Pump Performance"),
358        // Body (B) Codes
359        "B0083" => Some("Left Side/Front Impact Sensor Circuit"),
360        "B0092" => Some("Left Side/Rear Impact Sensor Circuit"),
361        "B0096" => Some("Right Side/Rear Impact Sensor Circuit"),
362        "B0408" => Some("Temperature Control A Circuit"),
363        "B1325" => Some("Control Module General Memory Failure"),
364        "B1517" => Some("Steering Wheel Controls Switch 1 Circuit"),
365        // Chassis (C) Codes
366        "C0035" => Some("Left Front Wheel Speed Sensor Circuit"),
367        "C0040" => Some("Right Front Wheel Speed Sensor Circuit"),
368        "C0045" => Some("Left Rear Wheel Speed Sensor Circuit"),
369        "C0050" => Some("Right Rear Wheel Speed Sensor Circuit"),
370        "C0110" => Some("Pump Motor Circuit Malfunction"),
371        "C0161" => Some("ABS/TCS Brake Switch Circuit Malfunction"),
372        "C0186" => Some("Lateral Accelerometer Circuit"),
373        "C0196" => Some("Yaw Rate Sensor Circuit"),
374        "C0550" => Some("ECU Malfunction (Stability System)"),
375        "C0899" => Some("Device Voltage Low"),
376        "C0900" => Some("Device Voltage High"),
377        // Network (U) Codes
378        "U0001" => Some("High Speed CAN Communication Bus"),
379        "U0073" => Some("Control Module Communication Bus Off"),
380        "U0100" => Some("Lost Communication with ECM/PCM"),
381        "U0101" => Some("Lost Communication with TCM"),
382        "U0121" => Some("Lost Communication with ABS"),
383        "U0140" => Some("Lost Communication with BCM"),
384        "U0146" => Some("Lost Communication with Gateway A"),
385        "U0151" => Some("Lost Communication with SIR Module"),
386        "U0155" => Some("Lost Communication with Instrument Panel Cluster"),
387        "U0168" => Some("Lost Communication with HVAC Control Module"),
388        "U0184" => Some("Lost Communication with Radio"),
389        "U0401" => Some("Invalid Data Received from ECM/PCM A"),
390        _ => None,
391    }
392}
393
394#[cfg(test)]
395mod tests {
396    use super::*;
397
398    #[test]
399    fn test_dtc_default() {
400        let dtc = Dtc::default();
401        assert_eq!(dtc.category, DtcCategory::Powertrain);
402        assert_eq!(dtc.status, DtcStatus::Stored);
403        assert!(dtc.description.is_none());
404    }
405
406    #[test]
407    fn test_severity_ordering() {
408        assert!(Severity::Critical > Severity::High);
409        assert!(Severity::High > Severity::Medium);
410        assert!(Severity::Medium > Severity::Low);
411        assert!(Severity::Low > Severity::Info);
412    }
413
414    #[test]
415    fn test_dtc_status_byte_default() {
416        let status = DtcStatusByte::default();
417        assert!(!status.test_failed);
418        assert!(!status.confirmed);
419        assert!(!status.warning_indicator_requested);
420    }
421
422    #[test]
423    fn test_dtc_from_bytes_powertrain() {
424        let dtc = Dtc::from_bytes(0x04, 0x20);
425        assert_eq!(dtc.code, "P0420");
426        assert_eq!(dtc.category, DtcCategory::Powertrain);
427        assert!(dtc.description.is_some());
428        assert!(dtc.description.unwrap().contains("Catalyst"));
429    }
430
431    #[test]
432    fn test_dtc_from_bytes_chassis() {
433        let dtc = Dtc::from_bytes(0x40, 0x35);
434        assert_eq!(dtc.code, "C0035");
435        assert_eq!(dtc.category, DtcCategory::Chassis);
436    }
437
438    #[test]
439    fn test_dtc_from_bytes_body() {
440        let dtc = Dtc::from_bytes(0x80, 0x83);
441        assert_eq!(dtc.code, "B0083");
442        assert_eq!(dtc.category, DtcCategory::Body);
443    }
444
445    #[test]
446    fn test_dtc_from_bytes_network() {
447        let dtc = Dtc::from_bytes(0xC1, 0x00);
448        assert_eq!(dtc.code, "U0100");
449        assert_eq!(dtc.category, DtcCategory::Network);
450    }
451
452    #[test]
453    fn test_dtc_from_code() {
454        let dtc = Dtc::from_code("P0420");
455        assert_eq!(dtc.code, "P0420");
456        assert_eq!(dtc.category, DtcCategory::Powertrain);
457        assert!(dtc.description.is_some());
458    }
459
460    #[test]
461    fn test_dtc_from_code_lowercase() {
462        let dtc = Dtc::from_code("p0171");
463        assert_eq!(dtc.code, "P0171");
464    }
465
466    #[test]
467    fn test_universal_description_known() {
468        assert!(universal_dtc_description("P0420").is_some());
469        assert!(universal_dtc_description("P0300").unwrap().contains("Misfire"));
470    }
471
472    #[test]
473    fn test_universal_description_unknown() {
474        assert!(universal_dtc_description("P9999").is_none());
475    }
476
477    #[test]
478    fn test_status_byte_decode() {
479        let status = DtcStatusByte::from_byte(0x0B); // bits 0,1,3
480        assert!(status.test_failed);
481        assert!(status.test_failed_this_cycle);
482        assert!(!status.pending);
483        assert!(status.confirmed);
484    }
485
486    #[test]
487    fn test_status_byte_roundtrip() {
488        let original: u8 = 0xAF;
489        let status = DtcStatusByte::from_byte(original);
490        assert_eq!(status.to_byte(), original);
491    }
492
493    #[test]
494    fn test_status_byte_all_flags() {
495        let status = DtcStatusByte::from_byte(0xFF);
496        assert!(status.test_failed);
497        assert!(status.test_failed_this_cycle);
498        assert!(status.pending);
499        assert!(status.confirmed);
500        assert!(status.test_not_completed_since_clear);
501        assert!(status.test_failed_since_clear);
502        assert!(status.test_not_completed_this_cycle);
503        assert!(status.warning_indicator_requested);
504    }
505
506    #[test]
507    fn test_status_byte_mil_on() {
508        let status = DtcStatusByte::from_byte(0x80);
509        assert!(status.warning_indicator_requested); // MIL bit
510        assert!(!status.test_failed);
511    }
512}