Source code for qblox_instruments.ieee488_2.ieee488_2

# ----------------------------------------------------------------------------
# Description    : IEEE488.2 interface
# Git repository : https://gitlab.com/qblox/packages/software/qblox_instruments.git
# Copyright (C) Qblox BV (2020)
# ----------------------------------------------------------------------------


# -- include -----------------------------------------------------------------

from qblox_instruments.ieee488_2 import Transport


# -- class -------------------------------------------------------------------


[docs] class Ieee488_2: """ Class that implements the IEEE488.2 interface. """ # ------------------------------------------------------------------------
[docs] def __init__(self, transport: Transport): """ Creates IEEE488.2 interface object. Parameters ---------- transport : Transport Transport class responsible for the lowest level of communication (e.g. ethernet). Returns ---------- Raises ---------- """ self._transport = transport
# ------------------------------------------------------------------------ def _write(self, cmd_str: str) -> None: """ Write command to instrument Parameters ---------- cmd_str : str Command string. Returns ---------- Raises ---------- """ self._transport.write(cmd_str + " ") # ------------------------------------------------------------------------ def _write_bin(self, cmd_str: str, bin_block: bytes) -> None: """ Write command and binary data block to instrument Parameters ---------- cmd_str : str Command string. bin_block : bytes Binary data array to send. Returns ---------- Raises ---------- """ self._bin_block_write(cmd_str + " ", bin_block) # ------------------------------------------------------------------------ def _read(self, cmd_str: str) -> str: """ Write command to instrument and read response. Using an empty command string will skip the write and only read. Parameters ---------- cmd_str : str Command string. Returns ---------- str Command response string. Raises ---------- """ self._transport.write(cmd_str) return ( self._transport.readline().rstrip() ) # Remove trailing white space, CR, LF # ------------------------------------------------------------------------ def _read_bin(self, cmd_str: str, flush_line_end: bool = True) -> bytes: """ Write command to instrument and read binary data block. Using an empty command string will skip the write and only read to allow reading concatinated binary blocks. Parameters ---------- cmd_str : str Command string. flush_line_end : bool Flush end of line characters. Returns ---------- bytes Binary data array received. Raises ---------- """ if cmd_str != "": self._transport.write(cmd_str) return self._bin_block_read(flush_line_end) # ------------------------------------------------------------------------ def _bin_block_write(self, cmd_str: str, bin_block: bytes) -> None: """ Write IEEE488.2 binary data block to instrument. Parameters ---------- cmd_str : str Command string. bin_block : bytes Binary data array to send. Returns ---------- Raises ---------- """ header = cmd_str + Ieee488_2._build_header_string(len(bin_block)) bin_msg = header.encode() + bin_block self._transport.write_binary(bin_msg) self._transport.write("") # Add a Line Terminator # ------------------------------------------------------------------------ def _bin_block_read(self, flush_line_end: bool = True) -> bytes: """ Read IEEE488.2 binary data block from instrument. Parameters ---------- flush_line_end : bool Flush end of line characters. Returns ---------- bytes Binary data array received. Raises ---------- RunTimeError Header error. """ header_a = self._transport.read_binary(2) # Read '#N' header_a_str = header_a.decode() if header_a_str[0] != "#": s = "Header error: received {}".format(header_a) raise RuntimeError(s) digit_cnt = int(header_a_str[1]) header_b = self._transport.read_binary(digit_cnt) byte_cnt = int(header_b.decode()) bin_block = self._transport.read_binary(byte_cnt) if flush_line_end: self._flush_line_end() return bin_block # ------------------------------------------------------------------------ @staticmethod def _build_header_string(byte_cnt: int) -> str: """ Generate IEEE488.2 binary data block header. Parameters ---------- byte_cnt : int Size of the binary data block in bytes. Returns ---------- str Header string. Raises ---------- """ byte_cnt_str = str(byte_cnt) digit_cnt_str = str(len(byte_cnt_str)) bin_header_str = "#" + digit_cnt_str + byte_cnt_str return bin_header_str # ------------------------------------------------------------------------ def _flush_line_end(self) -> None: """ Flush end of line <CR><LF> characters. Parameters ---------- Returns ---------- Raises ---------- """ self._transport.read_binary(2) # Consume <CR><LF> # ------------------------------------------------------------------------ # IEEE488.2 constants # ------------------------------------------------------------------------ # *ESR and *ESE bits _ESR_OPERATION_COMPLETE = 0x01 _ESR_REQUEST_CONTROL = 0x02 _ESR_QUERY_ERROR = 0x04 _ESR_DEVICE_DEPENDENT_ERROR = 0x08 _ESR_EXECUTION_ERROR = 0x10 _ESR_COMMAND_ERROR = 0x20 _ESR_USER_REQUEST = 0x40 _ESR_POWER_ON = 0x80 # STATus:OPERation bits _STAT_OPER_CALIBRATING = ( 0x0001 # The instrument is currently performing a calibration ) _STAT_OPER_SETTLING = 0x0002 # The instrument is waiting for signals it controls to stabilize enough to begin measurements _STAT_OPER_RANGING = 0x0004 # The instrument is currently changing its range _STAT_OPER_SWEEPING = 0x0008 # A sweep is in progress _STAT_OPER_MEASURING = 0x0010 # The instrument is actively measuring _STAT_OPER_WAIT_TRIG = ( 0x0020 # The instrument is in a “wait for trigger” state of the trigger model ) _STAT_OPER_WAIT_ARM = ( 0x0040 # The instrument is in a “wait for arm” state of the trigger model ) _STAT_OPER_CORRECTING = ( 0x0080 # The instrument is currently performing a correction ) _STAT_OPER_INST_SUMMARY = ( 0x2000 # One of n multiple logical instruments is reporting OPERational status ) _STAT_OPER_PROG_RUNNING = ( 0x4000 # A user-defined program is currently in the run state ) # STATus:QUEStionable bits _STAT_QUES_VOLTAGE = 0x0001 _STAT_QUES_CURRENT = 0x0002 _STAT_QUES_TIME = 0x0004 _STAT_QUES_POWER = 0x0008 _STAT_QUES_TEMPERATURE = 0x0010 _STAT_QUES_FREQUENCY = 0x0020 _STAT_QUES_PHASE = 0x0040 _STAT_QUES_MODULATION = 0x0080 _STAT_QUES_CALIBRATION = 0x0100 _STAT_QUES_INST_SUMMARY = 0x2000 _STAT_QUES_COMMAND_WARNING = 0x4000