]> sigrok.org Git - libsigrokdecode.git/commitdiff
lfast: More bug fixes and enhancements
authorSoeren Apel <redacted>
Wed, 29 Jul 2020 21:44:56 +0000 (23:44 +0200)
committerSoeren Apel <redacted>
Wed, 29 Jul 2020 21:50:53 +0000 (23:50 +0200)
decoders/lfast/pd.py

index 5cf99b6ce48ab007b6ddc089c743596231447d33..7476e59a813cbe741f81ea5b3cb2fd082b5a6025 100644 (file)
@@ -24,20 +24,20 @@ import decimal
 '''
 OUTPUT_PYTHON format:
 
-[<data>] where <data> is the payload contained between the LFAST header and
-the LFAST stop bit. It's an array of bytes. 
+[ss, es, data] where data is a data byte of the LFAST payload. All bytes of
+the payload are sent at once, each with its start and end sample.
 '''
 
 # See tc27xD_um_v2.2.pdf, Table 20-10
 payload_sizes = {
     0b000: '8 bit',
-    0b001: '32 bit',
-    0b010: '64 bit',
-    0b011: '96 bit',
-    0b100: '128 bit',
-    0b101: '256 bit',
-    0b110: '512 bit',
-    0b111: '288 bit'
+    0b001: '32 bit / 4 byte',
+    0b010: '64 bit / 8 byte',
+    0b011: '96 bit / 12 byte',
+    0b100: '128 bit / 16 byte',
+    0b101: '256 bit / 32 byte',
+    0b110: '512 bit / 64 byte',
+    0b111: '288 bit / 36 byte'
 }
 
 # See tc27xD_um_v2.2.pdf, Table 20-10
@@ -54,7 +54,7 @@ payload_byte_sizes = {
 
 # See tc27xD_um_v2.2.pdf, Table 20-11
 channel_types = {
-    0b0000: 'Interface Control / PING (32 bit)',
+    0b0000: 'Interface Control / PING',
     0b0001: 'Unsolicited Status (32 bit)',
     0b0010: 'Slave Interface Control / Read',
     0b0011: 'CTS Transfer',
@@ -128,16 +128,19 @@ class Decoder(srd.Decoder):
 
     def __init__(self):
         decimal.getcontext().rounding = decimal.ROUND_HALF_UP
+        self.bit_len = 0xFFFFFFFF
         self.reset()
 
     def reset(self):
+        self.prev_bit_len = self.bit_len
         self.ss = self.es = 0
         self.ss_payload = self.es_payload = 0
+        self.ss_byte = 0
         self.bits = []
         self.payload = []
         self.payload_size = 0  # Expected number of bytes, as read from header
         self.bit_len = 0       # Length of one bit time, in samples
-        self.timeout = 0       # desired timeout for next edge, in samples
+        self.timeout = 0       # Desired timeout for next edge, in samples
         self.ch_type_id = 0    # ID of channel type
         self.state = state_sync
 
@@ -164,9 +167,13 @@ class Decoder(srd.Decoder):
                 self.put_ann(self.ss_sync, self.es_bit, ann_sync, ['Sync OK'])
             else:
                 self.put_ann(self.ss_sync, self.es_bit, ann_warning, ['Wrong Sync Value: {:02X}'.format(value)])
+                self.reset()
 
-            self.bits = []
-            self.state = state_header
+            # Only continue if we didn't just reset
+            if self.ss > 0:
+                self.bits = []
+                self.state = state_header
+                self.timeout = int(9.4 * self.bit_len)
 
     def handle_header(self):
         if len(self.bits) == 1:
@@ -178,27 +185,30 @@ class Decoder(srd.Decoder):
             value = bitpack(self.bits)
 
             ss = self.ss_header
-            es = ss + 3 * bit_len 
+            es = ss + 3 * bit_len
             size_id = (value & 0xE0) >> 5
             size = payload_sizes.get(size_id)
-            self.payload_size = payload_byte_sizes.get(size_id) 
+            self.payload_size = payload_byte_sizes.get(size_id)
             self.put_ann(int(ss), int(es), ann_header_pl_size, [size])
 
             ss = es
-            es = ss + 4 * bit_len 
+            es = ss + 4 * bit_len
             self.ch_type_id = (value & 0x1E) >> 1
             ch_type = channel_types.get(self.ch_type_id)
             self.put_ann(int(ss), int(es), ann_header_ch_type, [ch_type])
 
             ss = es
-            es = ss + bit_len 
-            cts = value & 0x01 
+            es = ss + bit_len
+            cts = value & 0x01
             self.put_ann(int(ss), int(es), ann_header_cts, ['{}'.format(cts)])
 
             self.bits = []
             self.state = state_payload
+            self.timeout = int(9.4 * self.bit_len)
 
     def handle_payload(self):
+        self.timeout = int((self.payload_size - len(self.payload)) * 8 * self.bit_len)
+
         if len(self.bits) == 1:
             self.ss_byte = self.ss_bit
             if self.ss_payload == 0:
@@ -207,9 +217,9 @@ class Decoder(srd.Decoder):
         if len(self.bits) == 8:
             value = bitpack(self.bits)
             value_hex = '{:02X}'.format(value)
-            
+
             # Control transfers have no SIPI payload, show them as control transfers
-            # Check the channel_types list for the meaning of the magic values 
+            # Check the channel_types list for the meaning of the magic values
             if (self.ch_type_id >= 0b0100) and (self.ch_type_id <= 0b1011):
                 self.put_ann(self.ss_byte, self.es_bit, ann_payload, [value_hex])
             else:
@@ -221,15 +231,12 @@ class Decoder(srd.Decoder):
                     self.put_ann(self.ss_byte, self.es_bit, ann_control_data, [value_hex])
 
             self.bits = []
-            self.payload.append(value)
             self.es_payload = self.es_bit
-            
-        self.timeout = int((self.payload_size - len(self.payload)) * 8 * self.bit_len)
-        
-        if (len(self.payload) == self.payload_size):
-            self.timeout = int(1.4 * self.bit_len)
-            self.bits = []
-            self.state = state_sleepbit
+            self.payload.append((self.ss_byte, self.es_payload, value))
+
+            if (len(self.payload) == self.payload_size):
+                self.timeout = int(1.4 * self.bit_len)
+                self.state = state_sleepbit
 
     def handle_sleepbit(self):
         if len(self.bits) == 0:
@@ -243,13 +250,11 @@ class Decoder(srd.Decoder):
                 self.put_ann(self.ss_bit, self.es_bit, ann_sleepbit, ['No LVDS sleep mode request', 'No sleep', 'N'])
 
         # We only send the payload out if this is an actual data transfer;
-        # check the channel_types list for the meaning of the magic values 
+        # check the channel_types list for the meaning of the magic values
         if (self.ch_type_id >= 0b0100) and (self.ch_type_id <= 0b1011):
             if len(self.payload) > 0:
                 self.put_payload()
 
-        self.reset()
-
     def decode(self):
         while True:
             if self.timeout == 0:
@@ -260,18 +265,28 @@ class Decoder(srd.Decoder):
             # If this is the first edge, we only update ss
             if self.ss == 0:
                 self.ss = self.samplenum
+                # Let's set the timeout for the sync pattern as well
+                self.timeout = int(16.2 * self.prev_bit_len)
                 continue
-            
+
             self.es = self.samplenum
 
-            if int(self.es - self.ss) == 0:
-                continue 
-            
             # Check for the sleep bit if this is a timeout condition
-            if (self.timeout > 0) and (self.es - self.ss == self.timeout):
+            if (len(self.matched) == 2) and self.matched[1]:
                 rising_edge = ~rising_edge
-                if self.state == state_sleepbit:
+                if self.state == state_sync:
+                    self.reset()
+                    continue
+                elif self.state == state_sleepbit:
+                    self.ss_bit += self.bit_len
+                    self.es_bit = self.ss_bit + self.bit_len
                     self.handle_sleepbit()
+                    self.reset()
+                    continue
+
+            # Shouldn't happen but we check just in case
+            if int(self.es - self.ss) == 0:
+                continue
 
             # We use the first bit to deduce the bit length
             if self.bit_len == 0:
@@ -280,12 +295,12 @@ class Decoder(srd.Decoder):
             # Determine number of bits covered by this edge
             bit_count = (self.es - self.ss) / self.bit_len
             bit_count = int(decimal.Decimal(bit_count).to_integral_value())
-            
+
             if bit_count == 0:
                 self.put_ann(self.ss, self.es, ann_warning, ['Bit time too short'])
                 self.reset()
                 continue
-            
+
             bit_value = '0' if rising_edge else '1'
 
             divided_len = (self.es - self.ss) / bit_count
@@ -305,8 +320,16 @@ class Decoder(srd.Decoder):
                     self.handle_payload()
                 elif self.state == state_sleepbit:
                     self.handle_sleepbit()
-                    break
+                    self.reset()
+
+                if self.ss == 0:
+                    break  # Because reset() was called, invalidating everything
 
             # Only update ss if we didn't just perform a reset
             if self.ss > 0:
                 self.ss = self.samplenum
+
+            # If we got here when a timeout occurred, we have processed all null
+            # bits that we could and should reset now to find the next packet
+            if (len(self.matched) == 2) and self.matched[1]:
+                self.reset()