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_uint, 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: u16 = pad & 0xff;
13    let second_part: u16 = (sad << 8) & 0xff00;
14
15    #[cfg(feature = "linuxgpib")]
16    let res = first_part | second_part;
17    #[cfg(feature = "nigpib")]
18    let res = (first_part | second_part).try_into().unwrap();
19
20    res
21}
22
23/// extract primary address from an Addr4882_t value
24pub fn GetPAD(address: Addr4882_t) -> u16 {
25    #[cfg(feature = "nigpib")]
26    let address: u16 = address.try_into().unwrap();
27
28    address & 0xff
29}
30
31/// extract secondary address from an Addr4882_t value
32pub fn GetSAD(address: Addr4882_t) -> u16 {
33    #[cfg(feature = "nigpib")]
34    let address: u16 = address.try_into().unwrap();
35
36    (address >> 8) & 0xff
37}
38
39#[cfg(feature = "linuxgpib")]
40/// ibcnt value for the last asynchronous I/O operation resynchronized to the current thread is returned.
41pub fn AsyncIbcnt() -> c_int {
42    unsafe { linux_gpib_sys::AsyncIbcnt() }
43}
44
45#[cfg(feature = "linuxgpib")]
46/// ibcntl value for the last asynchronous I/O operation resynchronized to the current thread is returned.
47pub fn AsyncIbcntl() -> c_long {
48    unsafe { linux_gpib_sys::AsyncIbcntl() }
49}
50
51#[cfg(feature = "linuxgpib")]
52/// thread-specific ibcnt value
53pub fn ThreadIbcnt() -> c_int {
54    unsafe { linux_gpib_sys::ThreadIbcnt() }
55}
56
57#[cfg(feature = "linuxgpib")]
58/// thread-specific ibcntl value
59pub fn ThreadIbcntl() -> c_long {
60    unsafe { linux_gpib_sys::ThreadIbcntl() }
61}
62
63#[cfg(feature = "nigpib")]
64pub fn Ibcnt() -> c_uint {
65    unsafe { linux_gpib_sys::Ibcnt() }
66}
67
68#[cfg(feature = "linuxgpib")]
69/// thread-specific iberr value
70pub fn ThreadIberr() -> c_int {
71    unsafe { linux_gpib_sys::ThreadIberr() }
72}
73
74#[cfg(feature = "linuxgpib")]
75/// thread-specific ibsta value
76pub fn ThreadIbsta() -> c_int {
77    unsafe { linux_gpib_sys::ThreadIbsta() }
78}
79
80#[cfg(feature = "linuxgpib")]
81/// iberr value for last asynchronous I/O operation
82///
83/// 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).
84///
85/// See: [Linux GPIB Reference](https://linux-gpib.sourceforge.io/doc_html/reference-function-async-iberr.html)
86pub fn AsyncIberr() -> c_int {
87    unsafe { linux_gpib_sys::AsyncIberr() }
88}
89
90#[cfg(feature = "linuxgpib")]
91/// ibsta value for last asynchronous I/O operation
92///
93/// 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).
94///
95/// 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.
96///
97/// See: [Linux GPIB Reference](https://linux-gpib.sourceforge.io/doc_html/reference-function-async-ibsta.html)
98pub fn AsyncIbsta() -> c_int {
99    unsafe { linux_gpib_sys::AsyncIbsta() }
100}
101
102#[derive(Clone, Copy)]
103pub struct Addr4882 {
104    pub addr: linux_gpib_sys::Addr4882_t,
105}
106
107impl Addr4882 {
108    pub fn new(
109        primary_address: PrimaryAddress,
110        secondary_address: SecondaryAddress,
111    ) -> Result<Self, GpibError> {
112        let addr = MakeAddr(
113            primary_address.as_pad().try_into()?,
114            secondary_address.as_sad().try_into()?,
115        );
116        Ok(Self { addr })
117    }
118
119    pub fn no_addr() -> Self {
120        Self { addr: NOADDR }
121    }
122
123    pub fn pad(&self) -> u16 {
124        GetPAD(self.addr)
125    }
126
127    pub fn sad(&self) -> u16 {
128        GetSAD(self.addr)
129    }
130
131    pub fn primary_address(&self) -> Result<PrimaryAddress, GpibError> {
132        PrimaryAddress::new(self.pad().into())
133    }
134
135    pub fn secondary_address(&self) -> Result<SecondaryAddress, GpibError> {
136        SecondaryAddress::new(self.sad().into())
137    }
138}
139
140impl Default for Addr4882 {
141    fn default() -> Self {
142        Addr4882::no_addr()
143    }
144}
145
146impl fmt::Debug for Addr4882 {
147    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
148        write!(f, "Addr4882({},{})", self.pad(), self.sad())
149    }
150}
151
152impl fmt::Display for Addr4882 {
153    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154        write!(f, "{}:{}", self.pad(), self.sad())
155    }
156}