linux_gpib_rs/
status.rs

1#[cfg(feature = "linuxgpib")]
2use crate::lowlevel::utility::{AsyncIbsta, ThreadIbsta};
3use linux_gpib_sys::{
4    ibsta_bit_numbers_ATN_NUM, ibsta_bit_numbers_CIC_NUM, ibsta_bit_numbers_CMPL_NUM,
5    ibsta_bit_numbers_DCAS_NUM, ibsta_bit_numbers_DTAS_NUM, ibsta_bit_numbers_END_NUM,
6    ibsta_bit_numbers_ERR_NUM, ibsta_bit_numbers_EVENT_NUM, ibsta_bit_numbers_LACS_NUM,
7    ibsta_bit_numbers_LOK_NUM, ibsta_bit_numbers_REM_NUM, ibsta_bit_numbers_RQS_NUM,
8    ibsta_bit_numbers_SPOLL_NUM, ibsta_bit_numbers_SRQI_NUM, ibsta_bit_numbers_TACS_NUM,
9    ibsta_bit_numbers_TIMO_NUM,
10};
11use std::default::Default;
12use std::fmt;
13
14pub struct IbStatus {
15    pub dcas: bool,
16    pub dtas: bool,
17    pub lacs: bool,
18    pub tacs: bool,
19    pub atn: bool,
20    pub cic: bool,
21    pub rem: bool,
22    pub lok: bool,
23    pub cmpl: bool,
24    pub event: bool,
25    pub spoll: bool,
26    pub rqs: bool,
27    pub srqi: bool,
28    pub end: bool,
29    pub timo: bool,
30    pub err: bool,
31}
32
33impl IbStatus {
34    /// Get current value of from Linux-GPIB ibsta global variable.
35    /// Use `current_thread_local_status` or `current_async_status` instead.
36    pub unsafe fn current_global_status() -> IbStatus {
37        #[cfg(feature = "linuxgpib")]
38        return IbStatus::from_ibsta(unsafe { linux_gpib_sys::ibsta });
39        #[cfg(feature = "nigpib")]
40        return IbStatus::from_ibsta(unsafe { linux_gpib_sys::Ibsta() });
41    }
42
43    #[cfg(feature = "linuxgpib")]
44    /// The value of ibsta corresponding to the last 'traditional' or 'multidevice' function
45    /// called by the current thread is returned.
46    pub fn current_thread_local_status() -> IbStatus {
47        IbStatus::from_ibsta(ThreadIbsta())
48    }
49
50    #[cfg(feature = "linuxgpib")]
51    /// Thread-local status value corresponding 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).
52    pub fn current_async_local_status() -> IbStatus {
53        IbStatus::from_ibsta(AsyncIbsta())
54    }
55
56    /// Convert c_int status value to IbStatus
57    pub fn from_ibsta(ibsta: linux_gpib_sys::ibsta_type) -> IbStatus {
58        let dcas = ((1 << ibsta_bit_numbers_DCAS_NUM) & ibsta) != 0;
59        let dtas = ((1 << ibsta_bit_numbers_DTAS_NUM) & ibsta) != 0;
60        let lacs = ((1 << ibsta_bit_numbers_LACS_NUM) & ibsta) != 0;
61        let tacs = ((1 << ibsta_bit_numbers_TACS_NUM) & ibsta) != 0;
62        let atn = ((1 << ibsta_bit_numbers_ATN_NUM) & ibsta) != 0;
63        let cic = ((1 << ibsta_bit_numbers_CIC_NUM) & ibsta) != 0;
64        let rem = ((1 << ibsta_bit_numbers_REM_NUM) & ibsta) != 0;
65        let lok = ((1 << ibsta_bit_numbers_LOK_NUM) & ibsta) != 0;
66        let cmpl = ((1 << ibsta_bit_numbers_CMPL_NUM) & ibsta) != 0;
67        let event = ((1 << ibsta_bit_numbers_EVENT_NUM) & ibsta) != 0;
68        let spoll = ((1 << ibsta_bit_numbers_SPOLL_NUM) & ibsta) != 0;
69        let rqs = ((1 << ibsta_bit_numbers_RQS_NUM) & ibsta) != 0;
70        let srqi = ((1 << ibsta_bit_numbers_SRQI_NUM) & ibsta) != 0;
71        let end = ((1 << ibsta_bit_numbers_END_NUM) & ibsta) != 0;
72        let timo = ((1 << ibsta_bit_numbers_TIMO_NUM) & ibsta) != 0;
73        let err = ((1 << ibsta_bit_numbers_ERR_NUM) & ibsta) != 0;
74        IbStatus {
75            dcas,
76            dtas,
77            lacs,
78            tacs,
79            atn,
80            cic,
81            rem,
82            lok,
83            cmpl,
84            event,
85            spoll,
86            rqs,
87            srqi,
88            end,
89            timo,
90            err,
91        }
92    }
93
94    pub fn as_status_mask(&self) -> linux_gpib_sys::status_mask_type {
95            #[cfg(feature = "linuxgpib")]
96            let res = self.as_ibsta();
97            #[cfg(feature = "nigpib")]
98            let res = self.as_ibsta().try_into().unwrap();
99            res
100    }
101
102    /// Convert IbStatus to Linux GPIB c_int status
103    pub fn as_ibsta(&self) -> linux_gpib_sys::ibsta_type {
104        let mut ibsta = 0;
105        if self.dcas {
106            ibsta = ibsta | (1 << ibsta_bit_numbers_DCAS_NUM);
107        }
108        if self.dtas {
109            ibsta = ibsta | (1 << ibsta_bit_numbers_DTAS_NUM);
110        }
111        if self.lacs {
112            ibsta = ibsta | (1 << ibsta_bit_numbers_LACS_NUM);
113        }
114        if self.tacs {
115            ibsta = ibsta | (1 << ibsta_bit_numbers_TACS_NUM);
116        }
117        if self.atn {
118            ibsta = ibsta | (1 << ibsta_bit_numbers_ATN_NUM);
119        }
120        if self.cic {
121            ibsta = ibsta | (1 << ibsta_bit_numbers_CIC_NUM);
122        }
123        if self.rem {
124            ibsta = ibsta | (1 << ibsta_bit_numbers_REM_NUM);
125        }
126        if self.lok {
127            ibsta = ibsta | (1 << ibsta_bit_numbers_LOK_NUM);
128        }
129        if self.cmpl {
130            ibsta = ibsta | (1 << ibsta_bit_numbers_CMPL_NUM);
131        }
132        if self.event {
133            ibsta = ibsta | (1 << ibsta_bit_numbers_EVENT_NUM);
134        }
135        if self.spoll {
136            ibsta = ibsta | (1 << ibsta_bit_numbers_SPOLL_NUM);
137        }
138        if self.rqs {
139            ibsta = ibsta | (1 << ibsta_bit_numbers_RQS_NUM);
140        }
141        if self.srqi {
142            ibsta = ibsta | (1 << ibsta_bit_numbers_SRQI_NUM);
143        }
144        if self.end {
145            ibsta = ibsta | (1 << ibsta_bit_numbers_END_NUM);
146        }
147        if self.timo {
148            ibsta = ibsta | (1 << ibsta_bit_numbers_TIMO_NUM);
149        }
150        if self.err {
151            ibsta = ibsta | (1 << ibsta_bit_numbers_ERR_NUM);
152        }
153        ibsta
154    }
155
156    pub fn with_dcas(mut self, dcas: bool) -> Self {
157        self.dcas = dcas;
158        self
159    }
160    pub fn with_dtas(mut self, dtas: bool) -> Self {
161        self.dtas = dtas;
162        self
163    }
164    pub fn with_lacs(mut self, lacs: bool) -> Self {
165        self.lacs = lacs;
166        self
167    }
168    pub fn with_tacs(mut self, tacs: bool) -> Self {
169        self.tacs = tacs;
170        self
171    }
172    pub fn with_atn(mut self, atn: bool) -> Self {
173        self.atn = atn;
174        self
175    }
176    pub fn with_cic(mut self, cic: bool) -> Self {
177        self.cic = cic;
178        self
179    }
180    pub fn with_rem(mut self, rem: bool) -> Self {
181        self.rem = rem;
182        self
183    }
184    pub fn with_lok(mut self, lok: bool) -> Self {
185        self.lok = lok;
186        self
187    }
188    pub fn with_cmpl(mut self, cmpl: bool) -> Self {
189        self.cmpl = cmpl;
190        self
191    }
192    pub fn with_event(mut self, event: bool) -> Self {
193        self.event = event;
194        self
195    }
196    pub fn with_spoll(mut self, spoll: bool) -> Self {
197        self.spoll = spoll;
198        self
199    }
200    pub fn with_rqs(mut self, rqs: bool) -> Self {
201        self.rqs = rqs;
202        self
203    }
204    pub fn with_srqi(mut self, srqi: bool) -> Self {
205        self.srqi = srqi;
206        self
207    }
208    pub fn with_end(mut self, end: bool) -> Self {
209        self.end = end;
210        self
211    }
212    pub fn with_timo(mut self, timo: bool) -> Self {
213        self.timo = timo;
214        self
215    }
216    pub fn with_err(mut self, err: bool) -> Self {
217        self.err = err;
218        self
219    }
220}
221
222impl fmt::Debug for IbStatus {
223    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
224        let mut description = String::new();
225        if self.dcas {
226            description.push_str("DCAS (device clear) ");
227        }
228        if self.dtas {
229            description.push_str("DTAS (device trigger) ");
230        }
231        if self.lacs {
232            description.push_str("LACS (board is currently addressed as a listener) ");
233        }
234        if self.tacs {
235            description.push_str("TACS (board is currently addressed as a talker) ");
236        }
237        if self.atn {
238            description.push_str("ATN (ATN line is asserted) ");
239        }
240        if self.cic {
241            description.push_str("CIC (board is controller-in-charge, able to set the ATN line) ");
242        }
243        if self.rem {
244            description.push_str("REM (board is in 'remote' state) ");
245        }
246        if self.lok {
247            description.push_str("LOK (board is in 'lockout' state) ");
248        }
249        if self.cmpl {
250            description.push_str("CMPL (I/O operation complete) ");
251        }
252        if self.event {
253            description
254                .push_str("EVENT (one or more clear, trigger, or interface clear event received) ");
255        }
256        if self.spoll {
257            description.push_str("SPOLL (board is serial polled) ");
258        }
259        if self.rqs {
260            description.push_str("RQS (device has requested service) ");
261        }
262        if self.srqi {
263            description
264                .push_str("SRQI (a device connected to the board is asserting the SRQ line) ");
265        }
266        if self.end {
267            description.push_str("END (last I/O operation ended with the EOI line asserted) ");
268        }
269        if self.timo {
270            description.push_str("TIMO (last I/O operation, or ibwait, timed out) ");
271        }
272        if self.err {
273            description.push_str("ERR (last function call failed)");
274        }
275        if description.len() > 0 {
276            write!(f, "IbStatus({})", description.trim())
277        } else {
278            write!(f, "IbStatus(No flag set)")
279        }
280    }
281}
282
283impl fmt::Display for IbStatus {
284    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
285        let mut description = String::new();
286        if self.dcas {
287            description.push_str("DCAS ");
288        }
289        if self.dtas {
290            description.push_str("DTAS ");
291        }
292        if self.lacs {
293            description.push_str("LACS ");
294        }
295        if self.tacs {
296            description.push_str("TACS ");
297        }
298        if self.atn {
299            description.push_str("ATN ");
300        }
301        if self.cic {
302            description.push_str("CIC ");
303        }
304        if self.rem {
305            description.push_str("REM ");
306        }
307        if self.lok {
308            description.push_str("LOK ");
309        }
310        if self.cmpl {
311            description.push_str("CMPL ");
312        }
313        if self.event {
314            description.push_str("EVENT ");
315        }
316        if self.spoll {
317            description.push_str("SPOLL ");
318        }
319        if self.rqs {
320            description.push_str("RQS ");
321        }
322        if self.srqi {
323            description.push_str("SRQI ");
324        }
325        if self.end {
326            description.push_str("END ");
327        }
328        if self.timo {
329            description.push_str("TIMO ");
330        }
331        if self.err {
332            description.push_str("ERR");
333        }
334        if description.len() > 0 {
335            write!(f, "IbStatus({})", description.trim())
336        } else {
337            write!(f, "IbStatus(No flag set)")
338        }
339    }
340}
341
342impl Default for IbStatus {
343    fn default() -> Self {
344        Self {
345            dcas: false,
346            dtas: false,
347            lacs: false,
348            tacs: false,
349            atn: false,
350            cic: false,
351            rem: false,
352            lok: false,
353            cmpl: false,
354            event: false,
355            spoll: false,
356            rqs: false,
357            srqi: false,
358            end: false,
359            timo: false,
360            err: false,
361        }
362    }
363}