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 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 pub fn current_thread_local_status() -> IbStatus {
47 IbStatus::from_ibsta(ThreadIbsta())
48 }
49
50 #[cfg(feature = "linuxgpib")]
51 pub fn current_async_local_status() -> IbStatus {
53 IbStatus::from_ibsta(AsyncIbsta())
54 }
55
56 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 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}