diff -r aa3d55f78563 -r 3b50c46fca56 gpib.py --- a/gpib.py Tue Dec 11 00:07:54 2007 +0100 +++ b/gpib.py Fri Dec 14 00:21:47 2007 +0100 @@ -9,15 +9,138 @@ class ConnectionError(Exception): pass +GPIB_CONTROLLER = 1 +GPIB_DEVICE = 0 + +# IEEE 488.2 Status Byte constants +MAV = 0x10 # Message AVailable: bit 4 of the Status Byte +ESB = 0x20 # Event Status Bit: bit 5 of the Status Byte +MSS = 0x40 # Master Summary Status bit: bit 6 of the Status Byte (NOT + # sent in response to a serial poll) +RQS = 0x40 # Request Service: bit 6 of the Status Byte (when sent in + # response to a serial poll) + +# SESR constants (Standard Event Status Register) +PON = 0x80 # Power On: Power has been turned On since last register + # read access +URQ = 0x40 # User Request: the user has activated some device control + # (whatever the Remote Local state is) +CME = 0x20 # Command Error +EXE = 0x10 # Execution Error +DDE = 0x08 # Device Dependant Error +QYE = 0x04 # QuerY Error (attempt to read data while Output Queue is + # empty, or data in the OQ was lost) +RQC = 0x02 # Request Control: tell the CiC that the device wants to + # become the CiC +OPC = 0x01 # Operation Complete: device has completed any pending + # operation (ready to accept new commands). This bit is + # generated in response to a OPC command. + +##################### +# HP3562A constants + +# GPIB buffer size is 3x80 characters lines + +# HP3562A Status Byte +RQS = 0x40 # Request Service: when sent in response to a serial poll +ERR = 0x20 # ERRor: GPIB error +RDY = 0x10 #ReaDY: ready to accept GPIB commands + + class GPIB(object): _retries = 15 def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1, address=0, mode=1): + """ + Create a new GPIB controller for the Prologix USB-GPIB device + located on serial device 'device'. + """ self._cnx = serial.Serial(port=device, baudrate=baudrate, timeout=timeout) self._timeout = timeout self.set_mode(mode) self.set_address(address) + + def set_address(self, address): + """ + Set the address of the GPIB device: + + - if the device is the Controller In Charge, this is the + address of the device commands are sent to, + + - if the device is in GPIB_DEVICE mode, this is its address. + """ + self._set_cmd('addr', address) + self._adress = address + + def set_mode(self, mode): + """ + Set GPIB device mode to 'mode': + + - GPIB_CONTROLLER: set the device as the Controller In Charge + on the GPIB bus + + - GPIB_DEVICE: set the device as a standard GPIB device on the + bus. + """ + self._set_cmd('mode', mode) + self._mode = mode + + def set_controler(self): + """ + Set GPIB device the Controller In Charge on the GPIB bus. + """ + self.set_mode(1) + + def set_device(self): + """ + Set the GPIB device as a simple device on the GPIB bus. + """ + self.set_mode(0) + + def send_command(self, cmd): + """ + Send the specified GPIB command on the bus (must be the CIC), + and read the answer. + """ + assert self._mode == 1 + self._cnx.write(cmd+'\r') + time.sleep(self._timeout) # required? + ret = self._cnx.readlines() + return ''.join(ret) + + def check_srq(self): + """ + Check the SRQ line + """ + assert self._mode == 1, "must be the Controller In Charge" + self._cnx.write('++srq\r') + ret = self._cnx.readline().strip() + if ret: + return bool(int(ret)) + return None + + def poll(self): + """ + Poll every address, and return a dictionnary + {add: status, ...} + """ + assert self._mode == 1, "must be the Controller In Charge" + dico = {} + for add in range(31): + self._cnx.write('++spoll %d\r'%i) + ret = self._cnx.readline().strip() + if ret: + dico[i] = int(ret) + return dico + + def _read(self): + for i in range(self._retries): + rdata = self._cnx.readline() + if rdata.strip() != "": + break + time.sleep(self._timeout) + return rdata def _set_cmd(self, cmd, value): self._cnx.write('++%s %d\r'%(cmd, value)) @@ -25,19 +148,4 @@ rval = self._read().strip() if not rval.isdigit() or int(rval) != value: raise ConnectionError("Can't set GPIB %s to %s [ret=%s]"%(cmd, value, repr(rval))) - - def set_address(self, address): - self._set_cmd('addr', address) - self._adress = address - - def set_mode(self, mode): - self._set_cmd('mode', mode) - self._mode = mode - - def _read(self): - for i in range(self._retries): - rdata = self._cnx.readline() - if rdata.strip() != "": - break - time.sleep(self._timeout) - return rdata +