linux_gpib_rs/
types.rs

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