]> sigrok.org Git - libsigrokdecode.git/blobdiff - decoders/sdq/pd.py
sdq: prefer Python's .format() method for string formatting
[libsigrokdecode.git] / decoders / sdq / pd.py
index 80b15ff5f304ca4d9676999df221edbe2182d225..66df42025f1b9343d75678ff16fa3652e03b62ab 100644 (file)
 ## along with this program; if not, see <http://www.gnu.org/licenses/>.
 ##
 
+from common.srdhelper import bitpack
 import sigrokdecode as srd
 
 class SamplerateError(Exception):
     pass
 
+class Pin:
+    SDQ, = range(1)
+
+class Ann:
+    BIT, BYTE, BREAK, = range(3)
+
 class Decoder(srd.Decoder):
     api_version = 3
     id = 'sdq'
@@ -44,9 +51,9 @@ class Decoder(srd.Decoder):
         ('break', 'Break'),
     )
     annotation_rows = (
-        ('bits', 'Bits', (0,)),
-        ('bytes', 'Bytes', (1,)),
-        ('breaks', 'Breaks', (2,)),
+        ('bits', 'Bits', (Ann.BIT,)),
+        ('bytes', 'Bytes', (Ann.BYTE,)),
+        ('breaks', 'Breaks', (Ann.BREAK,)),
     )
 
     def puts(self, data):
@@ -58,18 +65,11 @@ class Decoder(srd.Decoder):
     def putbetu(self, data):
         self.put(self.bytepos, self.startsample + int(self.bit_width), self.out_ann, data)
 
-    def bits2num(self, bitlist):
-        number = 0
-        for i in range(len(bitlist)):
-            number += bitlist[i] * 2**i
-        return number
-
     def __init__(self):
         self.reset()
 
     def reset(self):
         self.samplerate = None
-        self.state = 'INIT'
         self.startsample = 0
         self.bits = []
         self.bytepos = 0
@@ -80,22 +80,25 @@ class Decoder(srd.Decoder):
     def metadata(self, key, value):
         if key == srd.SRD_CONF_SAMPLERATE:
             self.samplerate = value
-            self.bit_width = float(self.samplerate) / float(self.options['bitrate'])
-            self.half_bit_width = self.bit_width / 2.0
-            self.break_threshold = self.bit_width * 1.2 # Break if the line is low for longer than this
 
     def handle_bit(self, bit):
         self.bits.append(bit)
-        self.putetu([0, ['Bit: %d' % bit, '%d' % bit]])
+        self.putetu([Ann.BIT, [
+            'Bit: {:d}'.format(bit),
+            '{:d}'.format(bit),
+        ]])
 
         if len(self.bits) == 8:
-            byte = self.bits2num(self.bits)
-            self.putbetu([1, ['Byte: %#04x' % byte, '%#04x' % byte]])
+            byte = bitpack(self.bits)
+            self.putbetu([Ann.BYTE, [
+                'Byte: 0x{:02x}'.format(byte),
+                '0x{:02x}'.format(byte),
+            ]])
             self.bits = []
             self.bytepos = 0
 
     def handle_break(self):
-        self.puts([2, ['Break', 'BR']])
+        self.puts([Ann.BREAK, ['Break', 'BR']])
         self.bits = []
         self.startsample = self.samplenum
         self.bytepos = 0
@@ -103,29 +106,26 @@ class Decoder(srd.Decoder):
     def decode(self):
         if not self.samplerate:
             raise SamplerateError('Cannot decode without samplerate.')
+        self.bit_width = float(self.samplerate) / float(self.options['bitrate'])
+        self.half_bit_width = self.bit_width / 2.0
+        # BREAK if the line is low for longer than this.
+        break_threshold = self.bit_width * 1.2
 
+        # Wait until the line is high before inspecting input data.
+        sdq, = self.wait({Pin.SDQ: 'h'})
         while True:
-            if self.state == 'INIT':
-                sdq, = self.wait({0: 'h'}) # Wait until the line is high before starting
-                self.state = 'DATA'
-
-            elif self.state == 'DATA':
-                sdq, = self.wait({0: 'f'}) # Falling edge
-
-                self.startsample = self.samplenum
-                if self.bytepos == 0:
-                    self.bytepos = self.samplenum
-
-                sdq, = self.wait({0: 'r'}) # Rising edge
-
-                delta = self.samplenum - self.startsample
-                if delta > self.break_threshold:
-                    self.state = 'BREAK'
-                elif delta > self.half_bit_width:
-                    self.handle_bit(0)
-                else:
-                    self.handle_bit(1)
-
-            elif self.state == 'BREAK':
+            # Get the length of a low pulse (falling to rising edge).
+            sdq, = self.wait({Pin.SDQ: 'f'})
+            self.startsample = self.samplenum
+            if self.bytepos == 0:
+                self.bytepos = self.samplenum
+            sdq, = self.wait({Pin.SDQ: 'r'})
+
+            # Check for 0 or 1 data bits, or the BREAK symbol.
+            delta = self.samplenum - self.startsample
+            if delta > break_threshold:
                 self.handle_break()
-                self.state = 'DATA'
+            elif delta > self.half_bit_width:
+                self.handle_bit(0)
+            else:
+                self.handle_bit(1)