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}
626
627impl fmt::Display for IbEosMode {
628    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
629        let mut description = String::new();
630        if self.reos {
631            description.push_str("REOS ");
632        }
633        if self.xeos {
634            description.push_str("XEOS ");
635        }
636        if self.bin {
637            description.push_str("BIN");
638        }
639        if description.len() > 0 {
640            write!(f, "EosMod({description})")
641        } else {
642            write!(f, "EosMod(No flag set)")
643        }
644    }
645}
646
647impl fmt::Debug for IbEosMode {
648    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
649        let mut description = String::new();
650        if self.reos {
651            description.push_str(
652                "REOS (0x400) Enable termination of reads when eos character is received.",
653            );
654        }
655        if self.xeos {
656            description.push_str("XEOS (0x800) Assert the EOI line whenever the eos character is sent during writes.");
657        }
658        if self.bin {
659            description.push_str("BIN (0x1000) Match eos character using all 8 bits (instead of only looking at the 7 least significant bits).");
660        }
661        if description.len() > 0 {
662            write!(f, "EosMod({description})")
663        } else {
664            write!(f, "EosMod(No flag set)")
665        }
666    }
667}
668
669impl IbEosMode {
670    pub fn as_mode(&self) -> c_int {
671        let mut mode = 0;
672        if self.reos {
673            mode = mode | 0x400;
674        }
675        if self.xeos {
676            mode = mode | 0x800;
677        }
678        if self.bin {
679            mode = mode | 0x1000;
680        }
681        mode
682    }
683}
684
685impl Default for IbEosMode {
686    fn default() -> IbEosMode {
687        IbEosMode {
688            reos: true,
689            xeos: false,
690            bin: false,
691        }
692    }
693}
694
695pub enum IbEvent {
696    None,
697    DevTrg,
698    DevClr,
699    IFC,
700}
701
702impl fmt::Display for IbEvent {
703    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
704        match self {
705            IbEvent::None => {
706                write!(f, "None")
707            }
708            IbEvent::DevTrg => {
709                write!(f, "DevTrg")
710            }
711            IbEvent::DevClr => {
712                write!(f, "DevClr")
713            }
714            IbEvent::IFC => {
715                write!(f, "IFC")
716            }
717        }
718    }
719}
720
721impl fmt::Debug for IbEvent {
722    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
723        match self {
724            IbEvent::None => {
725                write!(f, "None (The board's event queue is empty)")
726            }
727            IbEvent::DevTrg => {
728                write!(
729                    f,
730                    "DevTrg (The board has received a trigger command from the controller-in-charge)"
731                )
732            }
733            IbEvent::DevClr => {
734                write!(
735                    f,
736                    "DevClr (The board has received a clear command from the controller-in-charge)"
737                )
738            }
739            IbEvent::IFC => {
740                write!(
741                    f,
742                    "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)"
743                )
744            }
745        }
746    }
747}
748
749impl IbEvent {
750    pub(crate) fn from_value(value: c_short) -> Result<IbEvent, GpibError> {
751        match value {
752            0 => Ok(IbEvent::None),
753            1 => Ok(IbEvent::DevTrg),
754            2 => Ok(IbEvent::DevClr),
755            3 => Ok(IbEvent::IFC),
756            other => Err(GpibError::ValueError(format!(
757                "Unexpected value ({}) for event.",
758                other,
759            ))),
760        }
761    }
762}
763
764pub struct IbLineStatus {
765    pub valid_dav: bool,
766    pub valid_ndac: bool,
767    pub valid_nrfd: bool,
768    pub valid_ifc: bool,
769    pub valid_ren: bool,
770    pub valid_srq: bool,
771    pub valid_atn: bool,
772    pub valid_eoi: bool,
773    pub bus_dav: bool,
774    pub bus_ndac: bool,
775    pub bus_nrfd: bool,
776    pub bus_ifc: bool,
777    pub bus_ren: bool,
778    pub bus_srq: bool,
779    pub bus_atn: bool,
780    pub bus_eoi: bool,
781}
782
783impl IbLineStatus {
784    pub(crate) fn from_line_status(line_status: c_short) -> IbLineStatus {
785        let valid_dav = (line_status & 0x1) != 0;
786        let valid_ndac = (line_status & 0x2) != 0;
787        let valid_nrfd = (line_status & 0x4) != 0;
788        let valid_ifc = (line_status & 0x8) != 0;
789        let valid_ren = (line_status & 0x10) != 0;
790        let valid_srq = (line_status & 0x20) != 0;
791        let valid_atn = (line_status & 0x40) != 0;
792        let valid_eoi = (line_status & 0x80) != 0;
793        let bus_dav = (line_status & 0x100) != 0;
794        let bus_ndac = (line_status & 0x200) != 0;
795        let bus_nrfd = (line_status & 0x400) != 0;
796        let bus_ifc = (line_status & 0x800) != 0;
797        let bus_ren = (line_status & 0x1000) != 0;
798        let bus_srq = (line_status & 0x2000) != 0;
799        let bus_atn = (line_status & 0x4000) != 0;
800        let bus_eoi = (line_status & 0x8000u16 as i16) != 0;
801        Self {
802            valid_dav,
803            valid_ndac,
804            valid_nrfd,
805            valid_ifc,
806            valid_ren,
807            valid_srq,
808            valid_atn,
809            valid_eoi,
810            bus_dav,
811            bus_ndac,
812            bus_nrfd,
813            bus_ifc,
814            bus_ren,
815            bus_srq,
816            bus_atn,
817            bus_eoi,
818        }
819    }
820}
821
822pub enum IbOnline {
823    Close,
824    Reset(c_int),
825}
826
827impl IbOnline {
828    pub(crate) fn as_online(&self) -> c_int {
829        match self {
830            IbOnline::Close => 0,
831            IbOnline::Reset(val) => *val,
832        }
833    }
834}
835
836impl fmt::Display for IbOnline {
837    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
838        match self {
839            IbOnline::Close => {
840                write!(f, "IbOnline::Close")
841            }
842            IbOnline::Reset(val) => {
843                write!(f, "IbOnline::Reset({})", val)
844            }
845        }
846    }
847}