7 import time |
7 import time |
8 |
8 |
9 class ConnectionError(Exception): |
9 class ConnectionError(Exception): |
10 pass |
10 pass |
11 |
11 |
|
12 GPIB_CONTROLLER = 1 |
|
13 GPIB_DEVICE = 0 |
|
14 |
|
15 # IEEE 488.2 Status Byte constants |
|
16 MAV = 0x10 # Message AVailable: bit 4 of the Status Byte |
|
17 ESB = 0x20 # Event Status Bit: bit 5 of the Status Byte |
|
18 MSS = 0x40 # Master Summary Status bit: bit 6 of the Status Byte (NOT |
|
19 # sent in response to a serial poll) |
|
20 RQS = 0x40 # Request Service: bit 6 of the Status Byte (when sent in |
|
21 # response to a serial poll) |
|
22 |
|
23 # SESR constants (Standard Event Status Register) |
|
24 PON = 0x80 # Power On: Power has been turned On since last register |
|
25 # read access |
|
26 URQ = 0x40 # User Request: the user has activated some device control |
|
27 # (whatever the Remote Local state is) |
|
28 CME = 0x20 # Command Error |
|
29 EXE = 0x10 # Execution Error |
|
30 DDE = 0x08 # Device Dependant Error |
|
31 QYE = 0x04 # QuerY Error (attempt to read data while Output Queue is |
|
32 # empty, or data in the OQ was lost) |
|
33 RQC = 0x02 # Request Control: tell the CiC that the device wants to |
|
34 # become the CiC |
|
35 OPC = 0x01 # Operation Complete: device has completed any pending |
|
36 # operation (ready to accept new commands). This bit is |
|
37 # generated in response to a OPC command. |
|
38 |
|
39 ##################### |
|
40 # HP3562A constants |
|
41 |
|
42 # GPIB buffer size is 3x80 characters lines |
|
43 |
|
44 # HP3562A Status Byte |
|
45 RQS = 0x40 # Request Service: when sent in response to a serial poll |
|
46 ERR = 0x20 # ERRor: GPIB error |
|
47 RDY = 0x10 #ReaDY: ready to accept GPIB commands |
|
48 |
|
49 |
12 class GPIB(object): |
50 class GPIB(object): |
13 _retries = 15 |
51 _retries = 15 |
14 def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1, |
52 def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1, |
15 address=0, mode=1): |
53 address=0, mode=1): |
|
54 """ |
|
55 Create a new GPIB controller for the Prologix USB-GPIB device |
|
56 located on serial device 'device'. |
|
57 """ |
16 self._cnx = serial.Serial(port=device, baudrate=baudrate, timeout=timeout) |
58 self._cnx = serial.Serial(port=device, baudrate=baudrate, timeout=timeout) |
17 self._timeout = timeout |
59 self._timeout = timeout |
18 |
60 |
19 self.set_mode(mode) |
61 self.set_mode(mode) |
20 self.set_address(address) |
62 self.set_address(address) |
|
63 |
|
64 def set_address(self, address): |
|
65 """ |
|
66 Set the address of the GPIB device: |
|
67 |
|
68 - if the device is the Controller In Charge, this is the |
|
69 address of the device commands are sent to, |
|
70 |
|
71 - if the device is in GPIB_DEVICE mode, this is its address. |
|
72 """ |
|
73 self._set_cmd('addr', address) |
|
74 self._adress = address |
|
75 |
|
76 def set_mode(self, mode): |
|
77 """ |
|
78 Set GPIB device mode to 'mode': |
|
79 |
|
80 - GPIB_CONTROLLER: set the device as the Controller In Charge |
|
81 on the GPIB bus |
|
82 |
|
83 - GPIB_DEVICE: set the device as a standard GPIB device on the |
|
84 bus. |
|
85 """ |
|
86 self._set_cmd('mode', mode) |
|
87 self._mode = mode |
|
88 |
|
89 def set_controler(self): |
|
90 """ |
|
91 Set GPIB device the Controller In Charge on the GPIB bus. |
|
92 """ |
|
93 self.set_mode(1) |
|
94 |
|
95 def set_device(self): |
|
96 """ |
|
97 Set the GPIB device as a simple device on the GPIB bus. |
|
98 """ |
|
99 self.set_mode(0) |
|
100 |
|
101 def send_command(self, cmd): |
|
102 """ |
|
103 Send the specified GPIB command on the bus (must be the CIC), |
|
104 and read the answer. |
|
105 """ |
|
106 assert self._mode == 1 |
|
107 self._cnx.write(cmd+'\r') |
|
108 time.sleep(self._timeout) # required? |
|
109 ret = self._cnx.readlines() |
|
110 return ''.join(ret) |
|
111 |
|
112 def check_srq(self): |
|
113 """ |
|
114 Check the SRQ line |
|
115 """ |
|
116 assert self._mode == 1, "must be the Controller In Charge" |
|
117 self._cnx.write('++srq\r') |
|
118 ret = self._cnx.readline().strip() |
|
119 if ret: |
|
120 return bool(int(ret)) |
|
121 return None |
|
122 |
|
123 def poll(self): |
|
124 """ |
|
125 Poll every address, and return a dictionnary |
|
126 {add: status, ...} |
|
127 """ |
|
128 assert self._mode == 1, "must be the Controller In Charge" |
|
129 dico = {} |
|
130 for add in range(31): |
|
131 self._cnx.write('++spoll %d\r'%i) |
|
132 ret = self._cnx.readline().strip() |
|
133 if ret: |
|
134 dico[i] = int(ret) |
|
135 return dico |
|
136 |
|
137 def _read(self): |
|
138 for i in range(self._retries): |
|
139 rdata = self._cnx.readline() |
|
140 if rdata.strip() != "": |
|
141 break |
|
142 time.sleep(self._timeout) |
|
143 return rdata |
21 |
144 |
22 def _set_cmd(self, cmd, value): |
145 def _set_cmd(self, cmd, value): |
23 self._cnx.write('++%s %d\r'%(cmd, value)) |
146 self._cnx.write('++%s %d\r'%(cmd, value)) |
24 self._cnx.write('++%s\r'%(cmd)) |
147 self._cnx.write('++%s\r'%(cmd)) |
25 rval = self._read().strip() |
148 rval = self._read().strip() |
26 if not rval.isdigit() or int(rval) != value: |
149 if not rval.isdigit() or int(rval) != value: |
27 raise ConnectionError("Can't set GPIB %s to %s [ret=%s]"%(cmd, value, repr(rval))) |
150 raise ConnectionError("Can't set GPIB %s to %s [ret=%s]"%(cmd, value, repr(rval))) |
28 |
151 |
29 def set_address(self, address): |
|
30 self._set_cmd('addr', address) |
|
31 self._adress = address |
|
32 |
|
33 def set_mode(self, mode): |
|
34 self._set_cmd('mode', mode) |
|
35 self._mode = mode |
|
36 |
|
37 def _read(self): |
|
38 for i in range(self._retries): |
|
39 rdata = self._cnx.readline() |
|
40 if rdata.strip() != "": |
|
41 break |
|
42 time.sleep(self._timeout) |
|
43 return rdata |
|