diff 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
line wrap: on
line diff
--- a/rsib.py	Thu Aug 24 16:52:10 2023 +0930
+++ b/rsib.py	Wed Sep 25 20:56:39 2024 +0930
@@ -65,15 +65,14 @@
 #
 # Offs	Value	Meaning
 # 00	00	Length 31..24
-# 01	00	       23..16
-# 02	00	       15..8
+# 01	00	of     23..16
+# 02	00	block  15..8
 # 03	23	        7..0
-# 04	80	MsgID
+# 04	00/80	Is 0x80 if this is the last block in a sequence
 # 05	00	?
 # 06	01	Seq number
 
 MSG_HELLO = 0x40   # We send this on connect
-MSG_CMDREP = 0x80  # Reply from the instrument to us
 MSG_CMD = 0x90     # Command to the instrument
 MSG_SRQ = 0x91	   # Query SRQ
 
@@ -107,55 +106,65 @@
         self.s1 = s1
         self.s2 = s2
         self.tag = 0
-        
+
     def write(self, cmd, timeout = 0.5):
         """Send data (string) to the instrument"""
         self.s1.settimeout(timeout)
 
         if len(cmd) > 0x99:
             raise ValueError("Command too long")
-        
+
         # Pre-increment for easy comparison in read
         self.tag = (self.tag + 1) & 0xff
         msg = b'\x00\x00\x00' + bytes([len(cmd)]) + b'\x90\x00' + bytes([self.tag]) + cmd.encode('ascii')
         self.s1.send(msg)
-        
+
     def read(self, timeout = 0.5):
         """Read data from the device, waits for up to timeout seconds for each TCP read"""
 
         self.s1.settimeout(timeout)
-        
-        # Fetch the header
-        rx = b''
-        while len(rx) < 7:
-            rx = self.s1.recv(7)
-            if rx == b'':
-                raise IOError("EOF from device")
-        
-        if self.tag != rx[6]:
-            raise IOError("Reply out of order, got 0x%02x expected 0x%02x" % (ord(rx[6]), self.tag))
 
-        rxlen = rx[0] << 24 | rx[1] << 16 | rx[2] << 8 | rx[3]
-        #print "Msg ID 0x%02x" % (rx[4])
-        if False and rx[4] != MSG_CMDREP:
-            raise IOError("Unexpected Msg ID 0x%02x" % (rx[4]))
-        
-        if rx[5] != 0:
-            print("Mystery byte %d != 0" % (rx[5]))
-        # Fetch the actual reply now we know the length
         reply = b''
-        while len(reply) < rxlen:
-            rx = self.s1.recv(rxlen)
-            if rx == b'':
-                raise IOError("EOF from device")
-            reply += rx
-            
+        last = False
+        while not last:
+            # Fetch the header
+            rx = b''
+            remain = 7
+            while len(rx) < 7:
+                rx = self.s1.recv(remain)
+                if rx == b'':
+                    raise IOError("EOF from device")
+                remain -= len(rx)
+                rxlen = rx[0] << 24 | rx[1] << 16 | rx[2] << 8 | rx[3]
+                #print(rx, rxlen)
+                if self.tag != rx[6]:
+                    raise IOError("Reply out of order, got 0x%02x expected 0x%02x" % (rx[6], self.tag))
+                if rx[4] == 0x80:
+                    #print('EOM')
+                    last = True
+                if rx[5] != 0:
+                    print("Mystery byte %d != 0" % (rx[5]))
+
+                # Fetch the actual data block now we know the length
+                remain = rxlen
+                while remain > 0:
+                    rx = self.s1.recv(remain)
+                    if rx == b'':
+                        raise IOError("EOF from device")
+                    reply += rx
+                    remain -= len(rx)
+
         return(reply)
 
+    def ask(self, s, timeout = None):
+        '''Wrapper to send a command and wait for a reply'''
+        self.write(s)
+        return self.read(timeout = timeout)
+
     def queryrsb(self):
         msg = b'\x00\x00\x00\x00\xd1\x18\x00'
         self.s2.send(msg)
-        
+
         reply = b''
         while len(reply) < 7:
             rx = self.s2.recv(7)
@@ -166,12 +175,12 @@
         # '\x00\x00\x00\x00\x80\x04\x01' => STB = 4
         if rx[4] != b'\x80':
             raise IOError("Incorrect Msg ID in response to STB query")
-        
+
         return rx[5]
 
     def waitsrq(self):
         msg = b'\x00\x00\x00\x00\xb1\x00\x00'
-        
+
     def testsrq(self):
         msg = b'\x00\x00\x00\x00\x91\x00\x00'
         self.s2.send(msg)
@@ -181,7 +190,7 @@
             if rx == b'':
                 raise IOError("EOF from device")
             reply += rx
-            
+
         # 00 00 00 00 80 14 08 - SRQ = 0
         # 00 00 00 00 a0 64 07 - SRQ = 1
         if rx == b'\x00\x00\x00\x00\x80\x14\x08':