|
27 | 27 | from . import rpc |
28 | 28 | import random |
29 | 29 | import re |
| 30 | +import struct |
30 | 31 |
|
31 | 32 | # VXI-11 RPC constants |
32 | 33 |
|
|
85 | 86 | RX_CHR = 2 |
86 | 87 | RX_END = 4 |
87 | 88 |
|
| 89 | +# IEEE 488.1 interface device commands |
| 90 | +CMD_SEND_COMMAND = 0x020000 |
| 91 | +CMD_BUS_STATUS = 0x020001 |
| 92 | +CMD_ATN_CTRL = 0x020002 |
| 93 | +CMD_REN_CTRL = 0x020003 |
| 94 | +CMD_PASS_CTRL = 0x020004 |
| 95 | +CMD_BUS_ADDRESS = 0x02000A |
| 96 | +CMD_IFC_CTRL = 0x020010 |
| 97 | + |
| 98 | +CMD_BUS_STATUS_REMOTE = 1 |
| 99 | +CMD_BUS_STATUS_SRQ = 2 |
| 100 | +CMD_BUS_STATUS_NDAC = 3 |
| 101 | +CMD_BUS_STATUS_SYSTEM_CONTROLLER = 4 |
| 102 | +CMD_BUS_STATUS_CONTROLLER_IN_CHARGE = 5 |
| 103 | +CMD_BUS_STATUS_TALKER = 6 |
| 104 | +CMD_BUS_STATUS_LISTENER = 7 |
| 105 | +CMD_BUS_STATUS_BUS_ADDRESS = 8 |
| 106 | + |
88 | 107 | def parse_visa_resource_string(resource_string): |
89 | 108 | # valid resource strings: |
90 | 109 | # TCPIP::10.0.0.1::INSTR |
@@ -776,6 +795,211 @@ def unlock(self): |
776 | 795 | raise Vxi11Exception(error, 'unlock') |
777 | 796 |
|
778 | 797 |
|
| 798 | +class InterfaceDevice(Device): |
| 799 | + "VXI-11 IEEE 488.1 interface device interface client" |
| 800 | + |
| 801 | + def open(self): |
| 802 | + "Open connection to VXI-11 device" |
| 803 | + if self.link is not None: |
| 804 | + return |
| 805 | + |
| 806 | + if ',' in self.name: |
| 807 | + raise Vxi11Exception("Cannot specify address for InterfaceDevice") |
| 808 | + |
| 809 | + super(InterfaceDevice, self).open() |
| 810 | + |
| 811 | + def send_command(self, data): |
| 812 | + "Send command" |
| 813 | + if self.link is None: |
| 814 | + self.open() |
| 815 | + |
| 816 | + flags = 0 |
| 817 | + |
| 818 | + error, data_out = self.client.device_docmd( |
| 819 | + self.link, |
| 820 | + flags, |
| 821 | + self._timeout_ms, |
| 822 | + self._lock_timeout_ms, |
| 823 | + CMD_SEND_COMMAND, |
| 824 | + True, |
| 825 | + 1, |
| 826 | + data |
| 827 | + ) |
| 828 | + |
| 829 | + if error: |
| 830 | + raise Vxi11Exception(error, 'send_command') |
| 831 | + |
| 832 | + return data_out |
| 833 | + |
| 834 | + def _bus_status(self, val): |
| 835 | + "Bus status" |
| 836 | + if self.link is None: |
| 837 | + self.open() |
| 838 | + |
| 839 | + flags = 0 |
| 840 | + |
| 841 | + error, data_out = self.client.device_docmd( |
| 842 | + self.link, |
| 843 | + flags, |
| 844 | + self._timeout_ms, |
| 845 | + self._lock_timeout_ms, |
| 846 | + CMD_BUS_STATUS, |
| 847 | + True, |
| 848 | + 1, |
| 849 | + struct.pack('!H', val) |
| 850 | + ) |
| 851 | + |
| 852 | + if error: |
| 853 | + raise Vxi11Exception(error, 'bus_status') |
| 854 | + |
| 855 | + return struct.unpack('!H', data_out)[0] |
| 856 | + |
| 857 | + def test_ren(self): |
| 858 | + "Read REN line" |
| 859 | + return self._bus_status(CMD_BUS_STATUS_REMOTE) |
| 860 | + |
| 861 | + def test_srq(self): |
| 862 | + "Read SRQ line" |
| 863 | + return self._bus_status(CMD_BUS_STATUS_SRQ) |
| 864 | + |
| 865 | + def test_ndac(self): |
| 866 | + "Read NDAC line" |
| 867 | + return self._bus_status(CMD_BUS_STATUS_NDAC) |
| 868 | + |
| 869 | + def is_system_controller(self): |
| 870 | + "Check if interface device is a system controller" |
| 871 | + return self._bus_status(CMD_BUS_STATUS_SYSTEM_CONTROLLER) |
| 872 | + |
| 873 | + def is_controller_in_charge(self): |
| 874 | + "Check if interface device is the controller-in-charge" |
| 875 | + return self._bus_status(CMD_BUS_STATUS_CONTROLLER_IN_CHARGE) |
| 876 | + |
| 877 | + def is_talker(self): |
| 878 | + "Check if interface device is addressed as a talker" |
| 879 | + return self._bus_status(CMD_BUS_STATUS_TALKER) |
| 880 | + |
| 881 | + def is_listener(self): |
| 882 | + "Check if interface device is addressed as a listener" |
| 883 | + return self._bus_status(CMD_BUS_STATUS_LISTENER) |
| 884 | + |
| 885 | + def get_bus_address(self): |
| 886 | + "Get interface device bus address" |
| 887 | + return self._bus_status(CMD_BUS_STATUS_BUS_ADDRESS) |
| 888 | + |
| 889 | + def set_atn(self, val): |
| 890 | + "Set ATN line" |
| 891 | + if self.link is None: |
| 892 | + self.open() |
| 893 | + |
| 894 | + flags = 0 |
| 895 | + |
| 896 | + error, data_out = self.client.device_docmd( |
| 897 | + self.link, |
| 898 | + flags, |
| 899 | + self._timeout_ms, |
| 900 | + self._lock_timeout_ms, |
| 901 | + CMD_ATN_CTRL, |
| 902 | + True, |
| 903 | + 1, |
| 904 | + struct.pack('!H', val) |
| 905 | + ) |
| 906 | + |
| 907 | + if error: |
| 908 | + raise Vxi11Exception(error, 'set_atn') |
| 909 | + |
| 910 | + return struct.unpack('!H', data_out)[0] |
| 911 | + |
| 912 | + def set_ren(self, val): |
| 913 | + "Set REN line" |
| 914 | + if self.link is None: |
| 915 | + self.open() |
| 916 | + |
| 917 | + flags = 0 |
| 918 | + |
| 919 | + error, data_out = self.client.device_docmd( |
| 920 | + self.link, |
| 921 | + flags, |
| 922 | + self._timeout_ms, |
| 923 | + self._lock_timeout_ms, |
| 924 | + CMD_REN_CTRL, |
| 925 | + True, |
| 926 | + 1, |
| 927 | + struct.pack('!H', val) |
| 928 | + ) |
| 929 | + |
| 930 | + if error: |
| 931 | + raise Vxi11Exception(error, 'set_ren') |
| 932 | + |
| 933 | + return struct.unpack('!H', data_out)[0] |
| 934 | + |
| 935 | + def pass_control(self, val): |
| 936 | + "Pass control to another controller" |
| 937 | + if self.link is None: |
| 938 | + self.open() |
| 939 | + |
| 940 | + flags = 0 |
| 941 | + |
| 942 | + error, data_out = self.client.device_docmd( |
| 943 | + self.link, |
| 944 | + flags, |
| 945 | + self._timeout_ms, |
| 946 | + self._lock_timeout_ms, |
| 947 | + CMD_PASS_CTRL, |
| 948 | + True, |
| 949 | + 1, |
| 950 | + struct.pack('!L', val) |
| 951 | + ) |
| 952 | + |
| 953 | + if error: |
| 954 | + raise Vxi11Exception(error, 'pass_control') |
| 955 | + |
| 956 | + return struct.unpack('!L', data_out)[0] |
| 957 | + |
| 958 | + def set_bus_address(self, val): |
| 959 | + "Set interface device bus address" |
| 960 | + if self.link is None: |
| 961 | + self.open() |
| 962 | + |
| 963 | + flags = 0 |
| 964 | + |
| 965 | + error, data_out = self.client.device_docmd( |
| 966 | + self.link, |
| 967 | + flags, |
| 968 | + self._timeout_ms, |
| 969 | + self._lock_timeout_ms, |
| 970 | + CMD_BUS_ADDRESS, |
| 971 | + True, |
| 972 | + 1, |
| 973 | + struct.pack('!L', val) |
| 974 | + ) |
| 975 | + |
| 976 | + if error: |
| 977 | + raise Vxi11Exception(error, 'set_bus_address') |
| 978 | + |
| 979 | + return struct.unpack('!L', data_out)[0] |
| 980 | + |
| 981 | + def send_ifc(self): |
| 982 | + "Send IFC" |
| 983 | + if self.link is None: |
| 984 | + self.open() |
| 985 | + |
| 986 | + flags = 0 |
| 987 | + |
| 988 | + error, data_out = self.client.device_docmd( |
| 989 | + self.link, |
| 990 | + flags, |
| 991 | + self._timeout_ms, |
| 992 | + self._lock_timeout_ms, |
| 993 | + CMD_IFC_CTRL, |
| 994 | + True, |
| 995 | + 1, |
| 996 | + b'' |
| 997 | + ) |
| 998 | + |
| 999 | + if error: |
| 1000 | + raise Vxi11Exception(error, 'send_ifc') |
| 1001 | + |
| 1002 | + |
779 | 1003 | class Instrument(Device): |
780 | 1004 | "VXI-11 instrument interface client" |
781 | 1005 |
|
|
0 commit comments