comparison rsib.py @ 72:da3558dec4e3

Fetch large data blocks correctly. Add ask function.
author Daniel O'Connor <doconnor@gsoft.com.au>
date Wed, 25 Sep 2024 20:56:39 +0930
parents 00800345fbae
children b6ebe05f250f
comparison
equal deleted inserted replaced
71:00800345fbae 72:da3558dec4e3
63 # Reply to command: 63 # Reply to command:
64 # <- 00 00 00 23 80 00 01 52 6f 68 ... 64 # <- 00 00 00 23 80 00 01 52 6f 68 ...
65 # 65 #
66 # Offs Value Meaning 66 # Offs Value Meaning
67 # 00 00 Length 31..24 67 # 00 00 Length 31..24
68 # 01 00 23..16 68 # 01 00 of 23..16
69 # 02 00 15..8 69 # 02 00 block 15..8
70 # 03 23 7..0 70 # 03 23 7..0
71 # 04 80 MsgID 71 # 04 00/80 Is 0x80 if this is the last block in a sequence
72 # 05 00 ? 72 # 05 00 ?
73 # 06 01 Seq number 73 # 06 01 Seq number
74 74
75 MSG_HELLO = 0x40 # We send this on connect 75 MSG_HELLO = 0x40 # We send this on connect
76 MSG_CMDREP = 0x80 # Reply from the instrument to us
77 MSG_CMD = 0x90 # Command to the instrument 76 MSG_CMD = 0x90 # Command to the instrument
78 MSG_SRQ = 0x91 # Query SRQ 77 MSG_SRQ = 0x91 # Query SRQ
79 78
80 import socket 79 import socket
81 80
105 s2.send(rx[4:]) 104 s2.send(rx[4:])
106 105
107 self.s1 = s1 106 self.s1 = s1
108 self.s2 = s2 107 self.s2 = s2
109 self.tag = 0 108 self.tag = 0
110 109
111 def write(self, cmd, timeout = 0.5): 110 def write(self, cmd, timeout = 0.5):
112 """Send data (string) to the instrument""" 111 """Send data (string) to the instrument"""
113 self.s1.settimeout(timeout) 112 self.s1.settimeout(timeout)
114 113
115 if len(cmd) > 0x99: 114 if len(cmd) > 0x99:
116 raise ValueError("Command too long") 115 raise ValueError("Command too long")
117 116
118 # Pre-increment for easy comparison in read 117 # Pre-increment for easy comparison in read
119 self.tag = (self.tag + 1) & 0xff 118 self.tag = (self.tag + 1) & 0xff
120 msg = b'\x00\x00\x00' + bytes([len(cmd)]) + b'\x90\x00' + bytes([self.tag]) + cmd.encode('ascii') 119 msg = b'\x00\x00\x00' + bytes([len(cmd)]) + b'\x90\x00' + bytes([self.tag]) + cmd.encode('ascii')
121 self.s1.send(msg) 120 self.s1.send(msg)
122 121
123 def read(self, timeout = 0.5): 122 def read(self, timeout = 0.5):
124 """Read data from the device, waits for up to timeout seconds for each TCP read""" 123 """Read data from the device, waits for up to timeout seconds for each TCP read"""
125 124
126 self.s1.settimeout(timeout) 125 self.s1.settimeout(timeout)
127 126
128 # Fetch the header
129 rx = b''
130 while len(rx) < 7:
131 rx = self.s1.recv(7)
132 if rx == b'':
133 raise IOError("EOF from device")
134
135 if self.tag != rx[6]:
136 raise IOError("Reply out of order, got 0x%02x expected 0x%02x" % (ord(rx[6]), self.tag))
137
138 rxlen = rx[0] << 24 | rx[1] << 16 | rx[2] << 8 | rx[3]
139 #print "Msg ID 0x%02x" % (rx[4])
140 if False and rx[4] != MSG_CMDREP:
141 raise IOError("Unexpected Msg ID 0x%02x" % (rx[4]))
142
143 if rx[5] != 0:
144 print("Mystery byte %d != 0" % (rx[5]))
145 # Fetch the actual reply now we know the length
146 reply = b'' 127 reply = b''
147 while len(reply) < rxlen: 128 last = False
148 rx = self.s1.recv(rxlen) 129 while not last:
149 if rx == b'': 130 # Fetch the header
150 raise IOError("EOF from device") 131 rx = b''
151 reply += rx 132 remain = 7
152 133 while len(rx) < 7:
134 rx = self.s1.recv(remain)
135 if rx == b'':
136 raise IOError("EOF from device")
137 remain -= len(rx)
138 rxlen = rx[0] << 24 | rx[1] << 16 | rx[2] << 8 | rx[3]
139 #print(rx, rxlen)
140 if self.tag != rx[6]:
141 raise IOError("Reply out of order, got 0x%02x expected 0x%02x" % (rx[6], self.tag))
142 if rx[4] == 0x80:
143 #print('EOM')
144 last = True
145 if rx[5] != 0:
146 print("Mystery byte %d != 0" % (rx[5]))
147
148 # Fetch the actual data block now we know the length
149 remain = rxlen
150 while remain > 0:
151 rx = self.s1.recv(remain)
152 if rx == b'':
153 raise IOError("EOF from device")
154 reply += rx
155 remain -= len(rx)
156
153 return(reply) 157 return(reply)
158
159 def ask(self, s, timeout = None):
160 '''Wrapper to send a command and wait for a reply'''
161 self.write(s)
162 return self.read(timeout = timeout)
154 163
155 def queryrsb(self): 164 def queryrsb(self):
156 msg = b'\x00\x00\x00\x00\xd1\x18\x00' 165 msg = b'\x00\x00\x00\x00\xd1\x18\x00'
157 self.s2.send(msg) 166 self.s2.send(msg)
158 167
159 reply = b'' 168 reply = b''
160 while len(reply) < 7: 169 while len(reply) < 7:
161 rx = self.s2.recv(7) 170 rx = self.s2.recv(7)
162 if rx == b'': 171 if rx == b'':
163 raise IOError("EOF from device") 172 raise IOError("EOF from device")
164 reply += rx 173 reply += rx
165 174
166 # '\x00\x00\x00\x00\x80\x04\x01' => STB = 4 175 # '\x00\x00\x00\x00\x80\x04\x01' => STB = 4
167 if rx[4] != b'\x80': 176 if rx[4] != b'\x80':
168 raise IOError("Incorrect Msg ID in response to STB query") 177 raise IOError("Incorrect Msg ID in response to STB query")
169 178
170 return rx[5] 179 return rx[5]
171 180
172 def waitsrq(self): 181 def waitsrq(self):
173 msg = b'\x00\x00\x00\x00\xb1\x00\x00' 182 msg = b'\x00\x00\x00\x00\xb1\x00\x00'
174 183
175 def testsrq(self): 184 def testsrq(self):
176 msg = b'\x00\x00\x00\x00\x91\x00\x00' 185 msg = b'\x00\x00\x00\x00\x91\x00\x00'
177 self.s2.send(msg) 186 self.s2.send(msg)
178 reply = b'' 187 reply = b''
179 while len(reply) < 7: 188 while len(reply) < 7:
180 rx = self.s2.recv(7) 189 rx = self.s2.recv(7)
181 if rx == b'': 190 if rx == b'':
182 raise IOError("EOF from device") 191 raise IOError("EOF from device")
183 reply += rx 192 reply += rx
184 193
185 # 00 00 00 00 80 14 08 - SRQ = 0 194 # 00 00 00 00 80 14 08 - SRQ = 0
186 # 00 00 00 00 a0 64 07 - SRQ = 1 195 # 00 00 00 00 a0 64 07 - SRQ = 1
187 if rx == b'\x00\x00\x00\x00\x80\x14\x08': 196 if rx == b'\x00\x00\x00\x00\x80\x14\x08':
188 return False 197 return False
189 elif rx == b'\x00\x00\x00\x00\xa0\x64\x07': 198 elif rx == b'\x00\x00\x00\x00\xa0\x64\x07':