linux_gpib_rs/
status.rs

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