File Coverage

blib/lib/Device/GPIB/Prologix.pm
Criterion Covered Total %
statement 6 190 3.1
branch 0 86 0.0
condition 0 3 0.0
subroutine 2 35 5.7
pod 28 32 87.5
total 36 346 10.4


line stmt bran cond sub pod time code
1             # Prologix.pm
2              
3             # Author: Mike McCauley (mikem@airspayce.com),
4             # Copyright (C) AirSpayce Pty Ltd
5             # $Id: $
6              
7             package Device::GPIB::Prologix;
8              
9 1     1   71414 use strict;
  1         3  
  1         32  
10 1     1   799 use Device::SerialPort;
  1         30998  
  1         2286  
11              
12             $Device::GPIB::Prologix::VERSION = '0.06';
13             $Device::GPIB::Prologix::debug = 0;
14              
15             sub new($$)
16             {
17 0     0 1   my ($class, $port) = @_;
18              
19 0           my $self = {};
20 0           bless $self, $class;
21              
22             # Defaults:
23 0           $self->{Port} = '/dev/ttyUSB0';
24 0           $self->{Baudrate} = '9600';
25 0           $self->{Databits} = '8';
26 0           $self->{Parity} = 'n';
27 0           $self->{Stopbits} = '1';
28 0           $self->{Handshake} = 'rts';
29 0           $self->{ReadCharTimeout} = 2000; # ms
30              
31 0 0         $self->{Port} = $port if defined $port;
32              
33             my ($portname, $baudrate, $databits, $parity, $stopbits, $handshake)
34 0           = split(/:/, $self->{Port});
35 0 0         $self->{Baudrate} = $baudrate if defined $baudrate;
36 0 0         $self->{Databits} = $databits if defined $databits;
37 0 0         $self->{Parity} = $parity if defined $parity;
38 0 0         $self->{Stopbits} = $stopbits if defined $stopbits;
39 0 0         $self->{Handshake} = $handshake if defined $handshake;
40              
41 0           debug("$class is connecting to $portname with $self->{Databits}:$self->{Parity}:$self->{Stopbits}:$self->{Handshake}");
42              
43 0           $self->{serialport} = new Device::SerialPort($portname);
44 0 0         if (!$self->{serialport})
45             {
46 0           warning("Could not open serial port $portname: $!");
47 0           return;
48             }
49 0           $self->{serialport}->baudrate($self->{Baudrate});
50 0           $self->{serialport}->databits($self->{Databits});
51 0           $self->{serialport}->parity($self->{Parity});
52 0           $self->{serialport}->stopbits($self->{Stopbits});
53 0           $self->{serialport}->handshake($self->{Handshake});
54 0           $self->{serialport}->read_char_time($self->{ReadCharTimeout});
55 0           $self->{serialport}->read_const_time(0);
56 0           $self->{serialport}->stty_icanon(0);
57              
58 0           $self->{CurrentAddress} = -1;
59            
60 0 0         return unless $self->initialised();
61              
62 0           return $self;
63             }
64              
65             sub initialised($)
66             {
67 0     0 0   my ($self) = @_;
68              
69 0 0         return unless $self->version() =~ /^Prologix/;
70             # Set the Prologix into a state we like
71 0           $self->auto(0);
72 0 0         return unless $self->auto() == 0;
73              
74 0           return 1; # OK
75             }
76              
77             sub send($$)
78             {
79 0     0 1   my ($self, $s) = @_;
80            
81 0           debug("Sending: '$s'");
82              
83             # TODO:
84             # Escape $s, prepend CR, LF or ESC with ESC
85 0           $self->{serialport}->write($s);
86 0           $self->{serialport}->write("\n"); # Trigger transmission
87             }
88              
89             sub sendTo($$)
90             {
91 0     0 1   my ($self, $s, $addr) = @_;
92            
93 0 0         $self->addr($addr) if defined $addr;
94 0           $self->send($s);
95             }
96              
97             sub read_to_timeout($)
98             {
99 0     0 1   my ($self) = @_;
100              
101 0           my $buf;
102 0           while (1)
103             {
104 0           my ($count, $ch) = $self->{serialport}->read(1);
105 0           my $x = unpack('H*', $ch);
106 0           debug("got $count, $ch: $x");
107 0 0         return $buf
108             unless $count; # Timeout
109 0           $buf .= $ch;
110             }
111             }
112              
113             sub read_to_eol($)
114             {
115 0     0 1   my ($self) = @_;
116              
117 0           my $buf;
118 0           while (1)
119             {
120 0           my ($count, $ch) = $self->{serialport}->read(1);
121 0 0         if ($count)
122             {
123 0           my $x = unpack('H*', $ch);
124 0           debug("got $count, $ch: $x");
125 0 0 0       if ($ch eq ';' && $self->{EOIMode}) # Experimental
    0          
    0          
126             {
127             # Not EOI/LF mode, so this is the last char
128 0           last;
129             }
130             elsif ($ch eq "\r")
131             {
132             # ignore CR
133             }
134             elsif ($ch eq "\n")
135             {
136             # NL, end of message (unless we are reading binary)
137 0           last;
138             }
139             else
140             {
141 0           $buf .= $ch;
142             }
143             }
144             else
145             {
146 0           last;
147             }
148             }
149              
150             # Got a buffer full
151 0           debug("Read: '$buf'");
152 0           return $buf;
153             }
154              
155             # REad until a char or timeout.
156             # $waitfor can be either 'eoi' or the decimal number of the char < 256
157             sub read_until_timeout_or($$)
158             {
159 0     0 0   my ($self, $waitfor) = @_;
160            
161 0           my $cmd = '++read';
162 0 0         $cmd .= " $waitfor"
163             if defined($waitfor);
164 0           $self->send($cmd);
165 0           return $self->read_to_eol();
166             }
167              
168             sub read($)
169             {
170 0     0 1   my ($self, $addr) = @_;
171              
172 0 0         $self->addr($addr) if defined $addr;
173 0           return $self->read_until_timeout_or('eoi'); # Only works if EOI is enabled
174             }
175              
176             sub read_binary($)
177             {
178 0     0 1   my ($self, $addr) = @_;
179              
180 0 0         $self->addr($addr) if defined $addr;
181 0           $self->send('++read eoi');
182 0           return $self->read_to_timeout();
183             }
184              
185             sub warning($)
186             {
187 0     0 0   my ($s) = @_;
188              
189 0           print "WARNING: $s\n";
190             }
191              
192             sub debug($)
193             {
194 0     0 0   my ($s) = @_;
195              
196 0 0         print "DEBUG: $s\n"
197             if $Device::GPIB::Prologix::debug;
198             }
199              
200             sub close($)
201             {
202 0     0 1   my ($self) = @_;
203              
204 0 0         if ($self->{serialport})
205             {
206 0           $self->{serialport}->close();
207 0           undef $self->{serialport};
208             }
209             }
210              
211             sub DESTROY($)
212             {
213 0     0     my ($self) = @_;
214              
215 0           $self->close();
216             }
217              
218             ###
219             ### Implementations of low level Prologix commands
220             ###
221              
222             sub version($)
223             {
224 0     0 1   my ($self) = @_;
225              
226             # Send the command
227 0           $self->send('++ver');
228             # Read the result
229 0           return $self->read_to_eol();
230             }
231              
232             sub auto($$)
233             {
234 0     0 1   my ($self, $value) = @_;
235            
236 0 0         if (defined($value))
237             {
238 0           $self->send("++auto $value");
239 0           return;
240             }
241             else
242             {
243 0           $self->send("++auto");
244 0           return $self->read_to_eol();
245             }
246             }
247              
248             sub addr($$$)
249             {
250 0     0 1   my ($self, $addr, $sad) = @_;
251            
252 0 0         if (defined($addr))
253             {
254 0 0         if ($addr != $self->{CurrentAddress})
255             {
256 0           my $cmd = "++addr $addr";
257 0 0         $cmd .= " $sad"
258             if defined $sad;
259 0           $self->send($cmd);
260 0           $self->{CurrentAddress} = $addr;
261 0           return;
262             }
263             }
264             else
265             {
266 0           $self->send('++addr');
267 0           return $self->read_to_eol();
268             }
269             }
270              
271             sub clr($)
272             {
273 0     0 1   my ($self, $addr) = @_;
274              
275 0 0         $self->addr($addr) if defined $addr;
276 0           $self->send('++clr');
277             }
278              
279             sub eoi($$)
280             {
281 0     0 1   my ($self, $val) = @_;
282              
283 0 0         if (defined($val))
284             {
285 0 0         $self->send('++eoi ' . $val ? '1' : '0');
286 0           return;
287             }
288             else
289             {
290 0           $self->send('++eoi');
291 0           return $self->read_to_eol();
292             }
293             }
294              
295             sub eos($$)
296             {
297 0     0 1   my ($self, $val) = @_;
298              
299 0 0         if (defined($val))
300             {
301 0           $self->send("++eos $val");
302 0           return;
303             }
304             else
305             {
306 0           $self->send('++eos');
307 0           return $self->read_to_eol();
308             }
309             }
310              
311             sub eot_enable($$)
312             {
313 0     0 1   my ($self, $val) = @_;
314              
315 0 0         if (defined($val))
316             {
317 0 0         $self->send('++eot_enable ' . $val ? '1' : '0');
318 0           return;
319             }
320             else
321             {
322 0           $self->send('++eot_enable');
323 0           return $self->read_to_eol();
324             }
325             }
326              
327             sub eot_char($$)
328             {
329 0     0 1   my ($self, $val) = @_;
330              
331 0 0         if (defined($val))
332             {
333 0           $self->send('++eot_char ' . ord($val));
334 0           return;
335             }
336             else
337             {
338 0           $self->send('++eot_char');
339 0           return $self->read_to_eol();
340             }
341             }
342              
343             sub ifc($)
344             {
345 0     0 1   my ($self) = @_;
346              
347 0           $self->send('++ifc');
348             }
349              
350             sub llo($)
351             {
352 0     0 1   my ($self, $addr) = @_;
353              
354 0 0         $self->addr($addr) if defined $addr;
355 0           $self->send('++llo');
356             }
357              
358             sub loc($)
359             {
360 0     0 1   my ($self, $addr) = @_;
361              
362 0 0         $self->addr($addr) if defined $addr;
363 0           $self->send('++loc');
364             }
365              
366             sub lon($$)
367             {
368 0     0 1   my ($self, $val) = @_;
369              
370 0 0         if (defined($val))
371             {
372 0 0         $self->send('++lon ' . $val ? '1' : '0');
373 0           return;
374             }
375             else
376             {
377 0           $self->send('++lon');
378 0           return $self->read_to_eol();
379             }
380             }
381              
382             sub mode($$)
383             {
384 0     0 1   my ($self, $val) = @_;
385              
386 0 0         if (defined($val))
387             {
388 0 0         $self->send('++mode ' . $val ? '1' : '0');
389 0           return;
390             }
391             else
392             {
393 0           $self->send('++mode');
394 0           return $self->read_to_eol();
395             }
396             }
397              
398             sub read_tmo_ms($$)
399             {
400 0     0 1   my ($self, $val) = @_;
401              
402 0           $self->send('++read_tmo_ms ' . int($val));
403             }
404              
405             sub rst($)
406             {
407 0     0 1   my ($self) = @_;
408              
409 0           $self->send('++rst');
410             }
411              
412             sub savecfg($$)
413             {
414 0     0 1   my ($self, $val) = @_;
415              
416 0 0         if (defined($val))
417             {
418 0 0         $self->send('++savecfg ' . $val ? '1' : '0');
419 0           return;
420             }
421             else
422             {
423 0           $self->send('++savecfg');
424 0           return $self->read_to_eol();
425             }
426             }
427              
428             sub spoll($$$)
429             {
430 0     0 1   my ($self, $addr, $sad) = @_;
431            
432 0           my $cmd = '++spoll';
433 0 0         $cmd .= " $addr"
434             if defined($addr);
435 0 0         $cmd .= " $sad"
436             if defined($sad);
437 0           $self->send($cmd);
438             }
439              
440             sub srq($)
441             {
442 0     0 1   my ($self) = @_;
443              
444 0           $self->send('++srq');
445 0           return $self->read_to_eol();
446             }
447              
448             sub status($$)
449             {
450 0     0 1   my ($self, $val) = @_;
451              
452 0 0         if (defined($val))
453             {
454 0           $self->send('++status ' . $val);
455 0           return;
456             }
457             else
458             {
459 0           $self->send('++status');
460 0           return $self->read_to_eol();
461             }
462             }
463              
464             sub trg($@)
465             {
466 0     0 1   my ($self, @addrs) = @_;
467              
468 0           my $cmd = '++trg';
469 0           while (@addrs)
470             {
471 0           $cmd .= ' ' . shift(@addrs);
472             }
473 0           $self->send($cmd);
474             }
475              
476             1;
477              
478             __END__