linux_gpib_rs/lowlevel/
utility.rs

1#![allow(non_snake_case)]
2
3use crate::error::GpibError;
4use crate::types::{PrimaryAddress, SecondaryAddress};
5use linux_gpib_sys::{Addr4882_t, NOADDR};
6use std::default::Default;
7use std::fmt;
8use std::os::raw::{c_int, c_long};
9
10/// pack primary and secondary address into an Addr4882_t value
11pub fn MakeAddr(pad: u16, sad: u16) -> Addr4882_t {
12    let first_part: Addr4882_t = pad & 0xff;
13    let second_part: u16 = (sad << 8) & 0xff00;
14    first_part | second_part
15}
16
17/// extract primary address from an Addr4882_t value
18pub fn GetPAD(address: Addr4882_t) -> u16 {
19    address & 0xff
20}
21
22/// extract secondary address from an Addr4882_t value
23pub fn GetSAD(address: Addr4882_t) -> u16 {
24    (address >> 8) & 0xff
25}
26
27/// ibcnt value for the last asynchronous I/O operation resynchronized to the current thread is returned.
28pub fn AsyncIbcnt() -> c_int {
29    unsafe { linux_gpib_sys::AsyncIbcnt() }
30}
31
32/// ibcntl value for the last asynchronous I/O operation resynchronized to the current thread is returned.
33pub fn AsyncIbcntl() -> c_long {
34    unsafe { linux_gpib_sys::AsyncIbcntl() }
35}
36
37/// thread-specific ibcnt value
38pub fn ThreadIbcnt() -> c_int {
39    unsafe { linux_gpib_sys::ThreadIbcnt() }
40}
41
42/// thread-specific ibcntl value
43pub fn ThreadIbcntl() -> c_long {
44    unsafe { linux_gpib_sys::ThreadIbcntl() }
45}
46
47/// thread-specific iberr value
48pub fn ThreadIberr() -> c_int {
49    unsafe { linux_gpib_sys::ThreadIberr() }
50}
51
52/// thread-specific ibsta value
53pub fn ThreadIbsta() -> c_int {
54    unsafe { linux_gpib_sys::ThreadIbsta() }
55}
56
57/// iberr value for last asynchronous I/O operation
58///
59/// AsyncIberr() returns a thread-local error number related to the global variable iberr. Its value corresponds to the result of the last asynchronous I/O operation resynchronized to the current thread by an ibwait or ibstop call. This function only reflects the result of the asynchronous I/O operation itself and not, for example, the ibwait which resynchronized the asynchronous result to the current thread. Thus the result from AsyncIberr() is easier to interpret than ThreadIberr(), since it is unambiguous whether the value is associated with the asynchronous I/O result, or with the function call used to resynchronize (ibwait or ibstop).
60///
61/// See: [Linux GPIB Reference](https://linux-gpib.sourceforge.io/doc_html/reference-function-async-iberr.html)
62pub fn AsyncIberr() -> c_int {
63    unsafe { linux_gpib_sys::AsyncIberr() }
64}
65
66/// ibsta value for last asynchronous I/O operation
67///
68/// AsyncIbsta() returns a thread-local status value related to the global variable ibsta. Its value corresponds to the result of the last asynchronous I/O operation resynchronized to the current thread by an ibwait or ibstop call. This function only reflects the result of the asynchronous I/O operation itself and not, for example, the ibwait which resynchronized the asynchronous result to the current thread. Thus the result from AsyncIbsta() is easier to interpret than ThreadIbsta(), since it is unambiguous whether the value is associated with the asynchronous I/O result, or with the function call used to resynchronize (ibwait or ibstop).
69///
70/// Only the status bits END | ERR | TIMO | CMPL are valid in the returned status byte. The rest of the bits should be ignored and will be set to zero.
71///
72/// See: [Linux GPIB Reference](https://linux-gpib.sourceforge.io/doc_html/reference-function-async-ibsta.html)
73pub fn AsyncIbsta() -> c_int {
74    unsafe { linux_gpib_sys::AsyncIbsta() }
75}
76
77#[derive(Clone, Copy)]
78pub struct Addr4882 {
79    pub addr: linux_gpib_sys::Addr4882_t,
80}
81
82impl Addr4882 {
83    pub fn new(
84        primary_address: PrimaryAddress,
85        secondary_address: SecondaryAddress,
86    ) -> Result<Self, GpibError> {
87        let addr = MakeAddr(
88            primary_address.as_pad().try_into()?,
89            secondary_address.as_sad().try_into()?,
90        );
91        Ok(Self { addr })
92    }
93
94    pub fn no_addr() -> Self {
95        Self { addr: NOADDR }
96    }
97
98    pub fn pad(&self) -> u16 {
99        GetPAD(self.addr)
100    }
101
102    pub fn sad(&self) -> u16 {
103        GetSAD(self.addr)
104    }
105
106    pub fn primary_address(&self) -> Result<PrimaryAddress, GpibError> {
107        PrimaryAddress::new(self.pad().into())
108    }
109
110    pub fn secondary_address(&self) -> Result<SecondaryAddress, GpibError> {
111        SecondaryAddress::new(self.sad().into())
112    }
113}
114
115impl Default for Addr4882 {
116    fn default() -> Self {
117        Addr4882::no_addr()
118    }
119}
120
121impl fmt::Debug for Addr4882 {
122    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
123        write!(f, "Addr4882({},{})", self.pad(), self.sad())
124    }
125}
126
127impl fmt::Display for Addr4882 {
128    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
129        write!(f, "{}:{}", self.pad(), self.sad())
130    }
131}