linux_gpib_rs/
types.rs

1use crate::error::GpibError;
2use std::fmt;
3use std::os::raw::{c_int, c_short};
4use std::time::Duration;
5
6pub enum IbOption {
7    PAD,
8    SAD,
9    TMO,
10    EOT,
11    PPC,
12    READDR,
13    AUTOPOLL,
14    CICPROT,
15    SC,
16    SRE,
17    EOSrd,
18    EOSwrt,
19    EOScmp,
20    EOSchar,
21    PP2,
22    TIMING,
23    ReadAdjust,
24    WriteAdjust,
25    EventQueue,
26    SPollBit,
27    SendLLO,
28    SPollTime,
29    PPollTime,
30    EndBitIsNormal,
31    UnAddr,
32    HSCableLength,
33    Ist,
34    Rsv,
35    BNA,
36    SevenBitEOS,
37}
38
39impl fmt::Display for IbOption {
40    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41        match self {
42            IbOption::PAD => {
43                write!(f, "IbOption::PAD")
44            }
45            IbOption::SAD => {
46                write!(f, "IbOption::SAD")
47            }
48            IbOption::TMO => {
49                write!(f, "IbOption::TMO")
50            }
51            IbOption::EOT => {
52                write!(f, "IbOption::EOT")
53            }
54            IbOption::PPC => {
55                write!(f, "IbOption::PPC")
56            }
57            IbOption::READDR => {
58                write!(f, "IbOption::READDR")
59            }
60            IbOption::AUTOPOLL => {
61                write!(f, "IbOption::AUTOPOLL")
62            }
63            IbOption::CICPROT => {
64                write!(f, "IbOption::CICPROT")
65            }
66            IbOption::SC => {
67                write!(f, "IbOption::SC")
68            }
69            IbOption::SRE => {
70                write!(f, "IbOption::SRE")
71            }
72            IbOption::EOSrd => {
73                write!(f, "IbOption::EOSrd")
74            }
75            IbOption::EOSwrt => {
76                write!(f, "IbOption::EOSwrt")
77            }
78            IbOption::EOScmp => {
79                write!(f, "IbOption::EOScmp")
80            }
81            IbOption::EOSchar => {
82                write!(f, "IbOption::EOSchar")
83            }
84            IbOption::PP2 => {
85                write!(f, "IbOption::PP2")
86            }
87            IbOption::TIMING => {
88                write!(f, "IbOption::TIMING")
89            }
90            IbOption::ReadAdjust => {
91                write!(f, "IbOption::ReadAdjust")
92            }
93            IbOption::WriteAdjust => {
94                write!(f, "IbOption::WriteAdjust")
95            }
96            IbOption::EventQueue => {
97                write!(f, "IbOption::EventQueue")
98            }
99            IbOption::SPollBit => {
100                write!(f, "IbOption::SPollBit")
101            }
102            IbOption::SendLLO => {
103                write!(f, "IbOption::SendLLO")
104            }
105            IbOption::SPollTime => {
106                write!(f, "IbOption::SPollTime")
107            }
108            IbOption::PPollTime => {
109                write!(f, "IbOption::PPollTime")
110            }
111            IbOption::EndBitIsNormal => {
112                write!(f, "IbOption::EndBitIsNormal")
113            }
114            IbOption::UnAddr => {
115                write!(f, "IbOption::UnAddr")
116            }
117            IbOption::HSCableLength => {
118                write!(f, "IbOption::HSCableLength")
119            }
120            IbOption::Ist => {
121                write!(f, "IbOption::Ist")
122            }
123            IbOption::Rsv => {
124                write!(f, "IbOption::Rsv")
125            }
126            IbOption::BNA => {
127                write!(f, "IbOption::BNA")
128            }
129            IbOption::SevenBitEOS => {
130                write!(f, "IbOption::SevenBitEOS")
131            }
132        }
133    }
134}
135
136impl fmt::Debug for IbOption {
137    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138        match self {
139            IbOption::PAD => {
140                write!(f, "IbOption::PAD (0x1): GPIB primary address")
141            }
142            IbOption::SAD => {
143                write!(
144                    f,
145                    "IbOption::SAD (0x2): GPIB secondary address (0 for none, 0x60 to 0x7e for secondary addresses 0 to 30)"
146                )
147            }
148            IbOption::TMO => {
149                write!(
150                    f,
151                    "IbOption::TMO (0x3): Timeout setting for io operations (a number from 0 to 17). See ibmto()."
152                )
153            }
154            IbOption::EOT => {
155                write!(
156                    f,
157                    "IbOption::EOT (0x4): Nonzero if EOI is asserted with last byte on writes. See ibeot()."
158                )
159            }
160            IbOption::PPC => {
161                write!(
162                    f,
163                    "IbOption::PPC (0x5): Parallel poll configuration. See ibppc()."
164                )
165            }
166            IbOption::READDR => {
167                write!(
168                    f,
169                    "IbOption::READDR (0x6): Useless, included for compatibility only."
170                )
171            }
172            IbOption::AUTOPOLL => {
173                write!(
174                    f,
175                    "IbOption::AUTOPOLL (0x7): Nonzero if automatic serial polling is enabled."
176                )
177            }
178            IbOption::CICPROT => {
179                write!(
180                    f,
181                    "IbOption::CICPROT (0x8): Useless, included for compatibility only."
182                )
183            }
184            IbOption::SC => {
185                write!(
186                    f,
187                    "IbOption::SC (0xa): Nonzero if board is system controller. See ibrsc(). "
188                )
189            }
190            IbOption::SRE => {
191                write!(
192                    f,
193                    "IbOption::SRE (0xb): Nonzero if board autmatically asserts REN line when it becomes the system controller. See ibsre()."
194                )
195            }
196            IbOption::EOSrd => {
197                write!(
198                    f,
199                    "IbOption::EOSrd (0xc): Nonzero if termination of reads on reception of the end-of-string character is enabled. See ibeos(), in particular the REOS bit."
200                )
201            }
202            IbOption::EOSwrt => {
203                write!(
204                    f,
205                    "IbOption::EOSwrt (0xd): Nonzero if EOI is asserted whenever end-of-string character is sent. See ibeos(), in particular the XEOS bit."
206                )
207            }
208            IbOption::EOScmp => {
209                write!(
210                    f,
211                    "IbOption::EOScmp (0xe): Nonzero if all 8 bits are used to match end-of-string character. Zero if only least significant 7 bits are used. See ibeos(), in particular the BIN bit."
212                )
213            }
214            IbOption::EOSchar => {
215                write!(f, "IbOption::EOSchar (0xf): The end-of-string byte.")
216            }
217            IbOption::PP2 => {
218                write!(
219                    f,
220                    "IbOption::PP2 (0x10): Nonzero if in local parallel poll configure mode. Zero if in remote parallel poll configure mode."
221                )
222            }
223            IbOption::TIMING => {
224                write!(
225                    f,
226                    "IbOption::TIMING (0x11): Number indicating T1 delay. 1 for 2 microseconds, 2 for 500 nanoseconds, 3 for 350 nanoseconds. The values are declared in the header files as the constants T1_DELAY_2000ns, T1_DELAY_500ns, and T1_DELAY_350ns."
227                )
228            }
229            IbOption::ReadAdjust => {
230                write!(
231                    f,
232                    "IbOption::ReadAdjust (0x13): Nonzero if byte pairs are automatically swapped during reads."
233                )
234            }
235            IbOption::WriteAdjust => {
236                write!(
237                    f,
238                    "IbOption::WriteAdjust (0x14): Nonzero if byte pairs are automatically swapped during writes."
239                )
240            }
241            IbOption::EventQueue => {
242                write!(
243                    f,
244                    "IbOption::EventQueue (0x15): Nonzero if event queue is enabled."
245                )
246            }
247            IbOption::SPollBit => {
248                write!(
249                    f,
250                    "IbOption::SPollBit (0x16): Nonzero if the use of the SPOLL bit in ibsta is enabled."
251                )
252            }
253            IbOption::SendLLO => {
254                write!(
255                    f,
256                    "IbOption::SendLLO (0x17): Nonzero if devices connected to this board are automatically put into local lockout mode when brought online with ibfind() or ibdev()."
257                )
258            }
259            IbOption::SPollTime => {
260                write!(
261                    f,
262                    "IbOption::SPollTime (0x18): Timeout for serial polls. The value of the result is between 0 and 17, and has the same meaning as in ibtmo()."
263                )
264            }
265            IbOption::PPollTime => {
266                write!(
267                    f,
268                    "IbOption::PPollTime (0x19): Timeout for parallel polls. The value of the result is between 0 and 17, and has the same meaning as in ibtmo()."
269                )
270            }
271            IbOption::EndBitIsNormal => {
272                write!(
273                    f,
274                    "IbOption::EndBitIsNormal (0x1a): Nonzero if END bit of ibsta is set on reception of end-of-string character or EOI. Zero if END bit is only set on EOI."
275                )
276            }
277            IbOption::UnAddr => {
278                write!(
279                    f,
280                    "IbOption::UnAddr (0x1b): Nonzero if UNT (untalk) and UNL (unlisten) commands are automatically sent after a completed io operation using this descriptor."
281                )
282            }
283            IbOption::HSCableLength => {
284                write!(
285                    f,
286                    "IbOption::HSCableLength (0x1f): Useless, included only for compatibility."
287                )
288            }
289            IbOption::Ist => {
290                write!(
291                    f,
292                    "IbOption::Ist (0x20): Individual status bit, a.k.a. 'ist'."
293                )
294            }
295            IbOption::Rsv => {
296                write!(
297                    f,
298                    "IbOption::Rsv (0x21): The current status byte this board will use to respond to serial polls."
299                )
300            }
301            IbOption::BNA => {
302                write!(
303                    f,
304                    "IbOption::BNA (0x200): For a device: the board index (minor number) of interface board through which the device is being accessed. For a board: the board index of the board itself."
305                )
306            }
307            IbOption::SevenBitEOS => {
308                write!(
309                    f,
310                    "IbOption::SevenBitEOS (0x1000): Nonzero if board supports 7 bit EOS comparisons. See ibeos(), in particular the BIN bit. This is a Linux-GPIB extension."
311                )
312            }
313        }
314    }
315}
316
317impl IbOption {
318    pub fn as_option(&self) -> c_int {
319        match self {
320            IbOption::PAD => 0x1,
321            IbOption::SAD => 0x2,
322            IbOption::TMO => 0x3,
323            IbOption::EOT => 0x4,
324            IbOption::PPC => 0x5,
325            IbOption::READDR => 0x6,
326            IbOption::AUTOPOLL => 0x7,
327            IbOption::CICPROT => 0x8,
328            IbOption::SC => 0xa,
329            IbOption::SRE => 0xb,
330            IbOption::EOSrd => 0xc,
331            IbOption::EOSwrt => 0xd,
332            IbOption::EOScmp => 0xe,
333            IbOption::EOSchar => 0xf,
334            IbOption::PP2 => 0x10,
335            IbOption::TIMING => 0x11,
336            IbOption::ReadAdjust => 0x13,
337            IbOption::WriteAdjust => 0x14,
338            IbOption::EventQueue => 0x15,
339            IbOption::SPollBit => 0x16,
340            IbOption::SendLLO => 0x17,
341            IbOption::SPollTime => 0x18,
342            IbOption::PPollTime => 0x19,
343            IbOption::EndBitIsNormal => 0x1a,
344            IbOption::UnAddr => 0x1b,
345            IbOption::HSCableLength => 0x1f,
346            IbOption::Ist => 0x20,
347            IbOption::Rsv => 0x21,
348            IbOption::BNA => 0x200,
349            IbOption::SevenBitEOS => 0x1000,
350        }
351    }
352}
353
354#[derive(Clone, Copy)]
355pub enum IbTimeout {
356    TNone,
357    T10us,
358    T30us,
359    T100us,
360    T300us,
361    T1ms,
362    T3ms,
363    T10ms,
364    T30ms,
365    T100ms,
366    T300ms,
367    T1s,
368    T3s,
369    T10s,
370    T30s,
371    T100s,
372    T300s,
373    T1000s,
374}
375
376impl fmt::Display for IbTimeout {
377    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
378        match self {
379            IbTimeout::TNone => {
380                write!(f, "Never timeout")
381            }
382            IbTimeout::T10us => {
383                write!(f, "10 microseconds")
384            }
385            IbTimeout::T30us => {
386                write!(f, "30 microseconds")
387            }
388            IbTimeout::T100us => {
389                write!(f, "100 microseconds")
390            }
391            IbTimeout::T300us => {
392                write!(f, "300 microseconds")
393            }
394            IbTimeout::T1ms => {
395                write!(f, "1 millisecond")
396            }
397            IbTimeout::T3ms => {
398                write!(f, "3 milliseconds")
399            }
400            IbTimeout::T10ms => {
401                write!(f, "10 milliseconds")
402            }
403            IbTimeout::T30ms => {
404                write!(f, "30 milliseconds")
405            }
406            IbTimeout::T100ms => {
407                write!(f, "100 milliseconds")
408            }
409            IbTimeout::T300ms => {
410                write!(f, "300 milliseconds")
411            }
412            IbTimeout::T1s => {
413                write!(f, "1 second")
414            }
415            IbTimeout::T3s => {
416                write!(f, "3 seconds")
417            }
418            IbTimeout::T10s => {
419                write!(f, "10 seconds")
420            }
421            IbTimeout::T30s => {
422                write!(f, "30 seconds")
423            }
424            IbTimeout::T100s => {
425                write!(f, "100 seconds")
426            }
427            IbTimeout::T300s => {
428                write!(f, "300 seconds")
429            }
430            IbTimeout::T1000s => {
431                write!(f, "1000 seconds")
432            }
433        }
434    }
435}
436
437impl IbTimeout {
438    pub(crate) fn as_timeout(&self) -> c_int {
439        match self {
440            IbTimeout::TNone => 0,
441            IbTimeout::T10us => 1,
442            IbTimeout::T30us => 2,
443            IbTimeout::T100us => 3,
444            IbTimeout::T300us => 4,
445            IbTimeout::T1ms => 5,
446            IbTimeout::T3ms => 6,
447            IbTimeout::T10ms => 7,
448            IbTimeout::T30ms => 8,
449            IbTimeout::T100ms => 9,
450            IbTimeout::T300ms => 10,
451            IbTimeout::T1s => 11,
452            IbTimeout::T3s => 12,
453            IbTimeout::T10s => 13,
454            IbTimeout::T30s => 14,
455            IbTimeout::T100s => 15,
456            IbTimeout::T300s => 16,
457            IbTimeout::T1000s => 17,
458        }
459    }
460
461    pub(crate) fn as_duration(&self) -> Duration {
462        match self {
463            IbTimeout::TNone => Duration::MAX,
464            IbTimeout::T10us => Duration::from_micros(10),
465            IbTimeout::T30us => Duration::from_micros(30),
466            IbTimeout::T100us => Duration::from_micros(100),
467            IbTimeout::T300us => Duration::from_micros(300),
468            IbTimeout::T1ms => Duration::from_millis(1),
469            IbTimeout::T3ms => Duration::from_millis(3),
470            IbTimeout::T10ms => Duration::from_millis(10),
471            IbTimeout::T30ms => Duration::from_millis(30),
472            IbTimeout::T100ms => Duration::from_millis(100),
473            IbTimeout::T300ms => Duration::from_millis(300),
474            IbTimeout::T1s => Duration::from_secs(1),
475            IbTimeout::T3s => Duration::from_secs(3),
476            IbTimeout::T10s => Duration::from_secs(10),
477            IbTimeout::T30s => Duration::from_secs(30),
478            IbTimeout::T100s => Duration::from_secs(100),
479            IbTimeout::T300s => Duration::from_secs(300),
480            IbTimeout::T1000s => Duration::from_secs(1000),
481        }
482    }
483
484    /// Returns the smallest timeout value larger or equal to provided value
485    pub fn closest_from(timeout: Duration) -> Self {
486        for tmo in [
487            IbTimeout::T10us,
488            IbTimeout::T30us,
489            IbTimeout::T100us,
490            IbTimeout::T300us,
491            IbTimeout::T1ms,
492            IbTimeout::T3ms,
493            IbTimeout::T10ms,
494            IbTimeout::T30ms,
495            IbTimeout::T100ms,
496            IbTimeout::T300ms,
497            IbTimeout::T1s,
498            IbTimeout::T3s,
499            IbTimeout::T10s,
500            IbTimeout::T30s,
501            IbTimeout::T100s,
502            IbTimeout::T300s,
503            IbTimeout::T1000s,
504        ] {
505            if tmo.as_duration() >= timeout {
506                return tmo;
507            }
508        }
509        log::warn!(
510            "It is not possible to set a timeout larger than 1000s. There will be no timeout."
511        );
512        IbTimeout::TNone
513    }
514}
515
516#[derive(Copy, Clone)]
517pub struct PrimaryAddress {
518    pad: c_int,
519}
520
521impl PrimaryAddress {
522    pub fn new(pad: c_int) -> Result<PrimaryAddress, GpibError> {
523        if pad >= 0 && pad <= 30 {
524            Ok(PrimaryAddress { pad })
525        } else {
526            Err(GpibError::ValueError(format!(
527                "Primary address must be between 0 and 30. Got: {}.",
528                pad
529            )))
530        }
531    }
532
533    pub(crate) fn as_pad(&self) -> c_int {
534        self.pad
535    }
536}
537
538impl fmt::Display for PrimaryAddress {
539    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
540        write!(f, "{}", self.pad)
541    }
542}
543
544#[derive(Copy, Clone)]
545pub struct SecondaryAddress {
546    sad: c_int,
547}
548
549impl SecondaryAddress {
550    pub fn new(sad: c_int) -> Result<SecondaryAddress, GpibError> {
551        let desc = "Secondary address must be between 0 and 30 (without the 0x60 prefix), or equivalently between 0x60 and 0x7e (with the 0x60 addition). sad = 0 disables secondary address.";
552        let sad = if sad < 0 {
553            return Err(GpibError::ValueError(desc.to_owned()));
554        } else if sad == 0 {
555            // disable secondary address
556            sad
557        } else if sad <= 30 {
558            // sad are between 0 and 30 but
559            // NI convention adds 0x60 to the secondary address
560            sad + 0x60
561        } else if sad >= 0x60 && sad <= 0x7e {
562            sad
563        } else {
564            return Err(GpibError::ValueError(desc.to_owned()));
565        };
566        Ok(SecondaryAddress { sad })
567    }
568
569    pub(crate) fn as_sad(&self) -> c_int {
570        self.sad
571    }
572}
573
574impl Default for SecondaryAddress {
575    fn default() -> SecondaryAddress {
576        SecondaryAddress { sad: 0 }
577    }
578}
579
580impl fmt::Display for SecondaryAddress {
581    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
582        write!(f, "{}", self.sad)
583    }
584}
585
586#[derive(Copy, Clone)]
587pub enum IbSendEOI {
588    Disabled,
589    Enabled(c_int),
590}
591
592impl IbSendEOI {
593    pub(crate) fn as_eot(&self) -> c_int {
594        match self {
595            IbSendEOI::Disabled => 0,
596            IbSendEOI::Enabled(val) => *val,
597        }
598    }
599}
600
601impl Default for IbSendEOI {
602    fn default() -> IbSendEOI {
603        IbSendEOI::Disabled
604    }
605}
606
607impl fmt::Display for IbSendEOI {
608    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
609        match self {
610            IbSendEOI::Disabled => {
611                write!(f, "IbSendEOI::Disabled")
612            }
613            IbSendEOI::Enabled(value) => {
614                write!(f, "IbSendEOI::Enabled({})", value)
615            }
616        }
617    }
618}
619
620#[derive(Copy, Clone)]
621pub struct IbEosMode {
622    pub reos: bool,
623    pub xeos: bool,
624    pub bin: bool,
625    pub eos_char: u8,
626}
627
628impl fmt::Display for IbEosMode {
629    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
630        let mut description = String::new();
631        if self.reos {
632            description.push_str("REOS ");
633        }
634        if self.xeos {
635            description.push_str("XEOS ");
636        }
637        if self.bin {
638            description.push_str("BIN");
639        }
640        if description.len() > 0 {
641            description.push_str(&format!("{}", self.eos_char));
642            write!(f, "EosMod({description})")
643        } else {
644            write!(f, "EosMod(No flag set)")
645        }
646    }
647}
648
649impl fmt::Debug for IbEosMode {
650    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
651        let mut description = String::new();
652        if self.reos {
653            description.push_str(
654                "REOS (0x400) Enable termination of reads when eos character is received. ",
655            );
656        }
657        if self.xeos {
658            description.push_str("XEOS (0x800) Assert the EOI line whenever the eos character is sent during writes. ");
659        }
660        if self.bin {
661            description.push_str("BIN (0x1000) Match eos character using all 8 bits (instead of only looking at the 7 least significant bits). ");
662        }
663        if description.len() > 0 {
664            description.push_str("End-of-char = {self.eos_char}");
665            write!(f, "EosMod({description})")
666        } else {
667            write!(f, "EosMod(No flag set)")
668        }
669    }
670}
671
672impl IbEosMode {
673    pub fn as_mode(&self) -> c_int {
674        let mut mode: c_int = 0;
675        if self.reos {
676            mode = mode | 0x400;
677        }
678        if self.xeos {
679            mode = mode | 0x800;
680        }
681        if self.bin {
682            mode = mode | 0x1000;
683        }
684        mode | (self.eos_char as c_int)
685    }
686}
687
688impl Default for IbEosMode {
689    fn default() -> IbEosMode {
690        IbEosMode {
691            reos: true,
692            xeos: false,
693            bin: false,
694            eos_char: b'\n',
695        }
696    }
697}
698
699pub enum IbEvent {
700    None,
701    DevTrg,
702    DevClr,
703    IFC,
704}
705
706impl fmt::Display for IbEvent {
707    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
708        match self {
709            IbEvent::None => {
710                write!(f, "None")
711            }
712            IbEvent::DevTrg => {
713                write!(f, "DevTrg")
714            }
715            IbEvent::DevClr => {
716                write!(f, "DevClr")
717            }
718            IbEvent::IFC => {
719                write!(f, "IFC")
720            }
721        }
722    }
723}
724
725impl fmt::Debug for IbEvent {
726    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
727        match self {
728            IbEvent::None => {
729                write!(f, "None (The board's event queue is empty)")
730            }
731            IbEvent::DevTrg => {
732                write!(
733                    f,
734                    "DevTrg (The board has received a trigger command from the controller-in-charge)"
735                )
736            }
737            IbEvent::DevClr => {
738                write!(
739                    f,
740                    "DevClr (The board has received a clear command from the controller-in-charge)"
741                )
742            }
743            IbEvent::IFC => {
744                write!(
745                    f,
746                    "IFC (The board has received an interface clear from the system controller. Note, some models of GPIB interface board lack the ability to report interface clear events)"
747                )
748            }
749        }
750    }
751}
752
753impl IbEvent {
754    pub(crate) fn from_value(value: c_short) -> Result<IbEvent, GpibError> {
755        match value {
756            0 => Ok(IbEvent::None),
757            1 => Ok(IbEvent::DevTrg),
758            2 => Ok(IbEvent::DevClr),
759            3 => Ok(IbEvent::IFC),
760            other => Err(GpibError::ValueError(format!(
761                "Unexpected value ({}) for event.",
762                other,
763            ))),
764        }
765    }
766}
767
768pub struct IbLineStatus {
769    pub valid_dav: bool,
770    pub valid_ndac: bool,
771    pub valid_nrfd: bool,
772    pub valid_ifc: bool,
773    pub valid_ren: bool,
774    pub valid_srq: bool,
775    pub valid_atn: bool,
776    pub valid_eoi: bool,
777    pub bus_dav: bool,
778    pub bus_ndac: bool,
779    pub bus_nrfd: bool,
780    pub bus_ifc: bool,
781    pub bus_ren: bool,
782    pub bus_srq: bool,
783    pub bus_atn: bool,
784    pub bus_eoi: bool,
785}
786
787impl IbLineStatus {
788    pub(crate) fn from_line_status(line_status: c_short) -> IbLineStatus {
789        let valid_dav = (line_status & 0x1) != 0;
790        let valid_ndac = (line_status & 0x2) != 0;
791        let valid_nrfd = (line_status & 0x4) != 0;
792        let valid_ifc = (line_status & 0x8) != 0;
793        let valid_ren = (line_status & 0x10) != 0;
794        let valid_srq = (line_status & 0x20) != 0;
795        let valid_atn = (line_status & 0x40) != 0;
796        let valid_eoi = (line_status & 0x80) != 0;
797        let bus_dav = (line_status & 0x100) != 0;
798        let bus_ndac = (line_status & 0x200) != 0;
799        let bus_nrfd = (line_status & 0x400) != 0;
800        let bus_ifc = (line_status & 0x800) != 0;
801        let bus_ren = (line_status & 0x1000) != 0;
802        let bus_srq = (line_status & 0x2000) != 0;
803        let bus_atn = (line_status & 0x4000) != 0;
804        let bus_eoi = (line_status & 0x8000u16 as i16) != 0;
805        Self {
806            valid_dav,
807            valid_ndac,
808            valid_nrfd,
809            valid_ifc,
810            valid_ren,
811            valid_srq,
812            valid_atn,
813            valid_eoi,
814            bus_dav,
815            bus_ndac,
816            bus_nrfd,
817            bus_ifc,
818            bus_ren,
819            bus_srq,
820            bus_atn,
821            bus_eoi,
822        }
823    }
824}
825
826pub enum IbOnline {
827    Close,
828    Reset(c_int),
829}
830
831impl IbOnline {
832    pub(crate) fn as_online(&self) -> c_int {
833        match self {
834            IbOnline::Close => 0,
835            IbOnline::Reset(val) => *val,
836        }
837    }
838}
839
840impl fmt::Display for IbOnline {
841    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
842        match self {
843            IbOnline::Close => {
844                write!(f, "IbOnline::Close")
845            }
846            IbOnline::Reset(val) => {
847                write!(f, "IbOnline::Reset({})", val)
848            }
849        }
850    }
851}