]> sigrok.org Git - libsigrokdecode.git/commitdiff
adf435x: factor out inspection of 32bit words
authorGerhard Sittig <redacted>
Fri, 30 Dec 2022 10:57:04 +0000 (11:57 +0100)
committerGerhard Sittig <redacted>
Mon, 9 Jan 2023 19:13:35 +0000 (20:13 +0100)
Move the inspection of a completed 32bit word into the .decode_word()
routine. This simplifies checks for fatal constraints, as well as
optional inspection of deeper detail levels when extra parsers are
available.

Rename variables in the code path which accumulate bits. Add comments
to helper routines and to essential steps in complex interpretation
code paths. Eliminate the unused return value of the .decode_field()
method. Results in a lean and readable .decode() body.

decoders/adf435x/pd.py

index d234a815f4f2e7fb299130cf5809e2351b91d09b..15ec2e5d51d391293409715e01d6ffecaa950c6e 100644 (file)
@@ -122,50 +122,60 @@ class Decoder(srd.Decoder):
         self.put(ss, es, self.out_ann, [ cls, data, ])
 
     def decode_bits(self, offset, width):
+        '''Extract a bit field. Expects LSB input data.'''
         bits = self.bits[offset:][:width]
         ss, es = bits[-1][1], bits[0][2]
         value = bitpack_lsb(bits, 0)
         return ( value, ( ss, es, ))
 
     def decode_field(self, name, offset, width, parser):
+        '''Interpret a bit field. Emits an annotation.'''
         val, ( ss, es, ) = self.decode_bits(offset, width)
         val = parser(val) if parser else str(val)
         text = ['%s: %s' % (name, val)]
         self.putg(ss, es, ANN_REG, text)
-        return val
+
+    def decode_word(self, ss, es, bits):
+        '''Interpret a 32bit word after accumulation completes.'''
+        # SPI transfer content must be exactly one 32bit word.
+        if len(self.bits) != 32:
+            text = [
+                'Frame error: Bit count: want 32, got %d' % len(self.bits),
+                'Frame error: Bit count',
+                'Frame error',
+            ]
+            self.putg(ss, es, ANN_WARN, text)
+            return
+        # Holding bits in LSB order during interpretation simplifies
+        # bit field extraction. And annotation emitting routines expect
+        # this reverse order of bits' timestamps.
+        self.bits.reverse()
+        # Determine which register was accessed.
+        reg_addr, ( reg_ss, reg_es, ) = self.decode_bits(0, 3)
+        text = [
+            'Register: %d' % reg_addr,
+            'Reg: %d' % reg_addr,
+            '[%d]' % reg_addr,
+        ]
+        self.putg(reg_ss, reg_es, ANN_REG, text)
+        # Interpret the register's content (when parsers are available).
+        field_descs = regs.get(reg_addr, None)
+        if not field_descs:
+            return
+        for field_desc in field_descs:
+            self.decode_field(*field_desc)
 
     def decode(self, ss, es, data):
         ptype, _, _ = data
 
         if ptype == 'TRANSFER':
-            if len(self.bits) == 32:
-                self.bits.reverse()
-                reg_value, ( reg_ss, reg_es, ) = self.decode_bits(0, 3)
-                text = [
-                    'Register: %d' % reg_value,
-                    'Reg: %d' % reg_value,
-                    '[%d]' % reg_value,
-                ]
-                self.putg(reg_ss, reg_es, ANN_REG, text)
-                if reg_value < len(regs):
-                    field_descs = regs[reg_value]
-                    for field_desc in field_descs:
-                        field = self.decode_field(*field_desc)
-            else:
-                text = [
-                    'Frame error: Bit count: want 32, got %d' % len(self.bits),
-                    'Frame error: Bit count',
-                    'Frame error',
-                ]
-                self.putg(ss, es, ANN_WARN, text)
+            # Process accumulated bits after completion of a transfer.
+            self.decode_word(ss, es, self.bits)
             self.bits.clear()
 
         if ptype == 'BITS':
             _, mosi_bits, miso_bits = data
-            # Cope with the lower layer SPI decoder's output convention:
-            # Regardless of wire transfer's frame format, .decode() input
-            # provides BITS in the LE order. Accumulate in MSB order here,
-            # and reverse before data processing when 'TRANSFER' is seen.
-            mosi_bits = mosi_bits.copy()
-            mosi_bits.reverse()
-            self.bits.extend(mosi_bits)
+            # Accumulate bits in MSB order as they are seen in SPI frames.
+            msb_bits = mosi_bits.copy()
+            msb_bits.reverse()
+            self.bits.extend(msb_bits)