]> sigrok.org Git - libsigrokdecode.git/blobdiff - decoders/i2c/pd.py
Use new binary class definition format.
[libsigrokdecode.git] / decoders / i2c / pd.py
index da8056702b0f0d5ef766e7e569629a818e6fe7b3..ff769737e49c7ca2fed4804aff734e7739ec07f5 100644 (file)
@@ -81,19 +81,26 @@ class Decoder(srd.Decoder):
         'address_format': ['Displayed slave address format', 'shifted'],
     }
     annotations = [
-        ['Start', 'Start condition'],
-        ['Repeat start', 'Repeat start condition'],
-        ['Stop', 'Stop condition'],
-        ['ACK', 'ACK'],
-        ['NACK', 'NACK'],
-        ['Address read', 'Address read'],
-        ['Address write', 'Address write'],
-        ['Data read', 'Data read'],
-        ['Data write', 'Data write'],
-        ['Warnings', 'Human-readable warnings'],
+        ['start', 'Start condition'],
+        ['repeat-start', 'Repeat start condition'],
+        ['stop', 'Stop condition'],
+        ['ack', 'ACK'],
+        ['nack', 'NACK'],
+        ['address-read', 'Address read'],
+        ['address-write', 'Address write'],
+        ['data-read', 'Data read'],
+        ['data-write', 'Data write'],
+        ['warnings', 'Human-readable warnings'],
     ]
+    binary = (
+        ('address-read', 'Address read'),
+        ('address-write', 'Address write'),
+        ('data-read', 'Data read'),
+        ('data-write', 'Data write'),
+    )
 
     def __init__(self, **kwargs):
+        self.samplerate = None
         self.startsample = -1
         self.samplenum = None
         self.bitcount = 0
@@ -104,13 +111,19 @@ class Decoder(srd.Decoder):
         self.oldscl = 1
         self.oldsda = 1
         self.oldpins = [1, 1]
+        self.pdu_start = None
+        self.pdu_bits = 0
 
-    def start(self):
-        self.out_proto = self.add(srd.OUTPUT_PYTHON, 'i2c')
-        self.out_ann = self.add(srd.OUTPUT_ANN, 'i2c')
+    def metadata(self, key, value):
+        if key == srd.SRD_CONF_SAMPLERATE:
+            self.samplerate = value
 
-    def report(self):
-        pass
+    def start(self):
+        self.out_proto = self.register(srd.OUTPUT_PYTHON)
+        self.out_ann = self.register(srd.OUTPUT_ANN)
+        self.out_binary = self.add(srd.OUTPUT_BINARY)
+        self.out_bitrate = self.register(srd.OUTPUT_META,
+                meta=(int, 'Bitrate', 'Bitrate from Start bit to Stop bit'))
 
     def putx(self, data):
         self.put(self.startsample, self.samplenum, self.out_ann, data)
@@ -118,6 +131,9 @@ class Decoder(srd.Decoder):
     def putp(self, data):
         self.put(self.startsample, self.samplenum, self.out_proto, data)
 
+    def putb(self, data):
+        self.put(self.startsample, self.samplenum, self.out_binary, data)
+
     def is_start_condition(self, scl, sda):
         # START condition (S): SDA = falling, SCL = high
         if (self.oldsda == 1 and sda == 0) and scl == 1:
@@ -138,6 +154,8 @@ class Decoder(srd.Decoder):
 
     def found_start(self, scl, sda):
         self.startsample = self.samplenum
+        self.pdu_start = self.samplenum
+        self.pdu_bits = 0
         cmd = 'START REPEAT' if (self.is_repeat_start == 1) else 'START'
         self.putp([cmd, None])
         self.putx([proto[cmd][0], proto[cmd][1:]])
@@ -170,18 +188,24 @@ class Decoder(srd.Decoder):
             if self.options['address_format'] == 'shifted':
                 d = d >> 1
 
+        bin_class = -1
         if self.state == 'FIND ADDRESS' and self.wr == 1:
             cmd = 'ADDRESS WRITE'
+            bin_class = 1
         elif self.state == 'FIND ADDRESS' and self.wr == 0:
             cmd = 'ADDRESS READ'
+            bin_class = 0
         elif self.state == 'FIND DATA' and self.wr == 1:
             cmd = 'DATA WRITE'
+            bin_class = 3
         elif self.state == 'FIND DATA' and self.wr == 0:
             cmd = 'DATA READ'
+            bin_class = 2
 
         self.putp([cmd, d])
         self.putx([proto[cmd][0], ['%s: %02X' % (proto[cmd][1], d),
                   '%s: %02X' % (proto[cmd][2], d), '%02X' % d]])
+        self.putb((bin_class, bytes([d])))
 
         # Done with this packet.
         self.startsample = -1
@@ -198,6 +222,11 @@ class Decoder(srd.Decoder):
         self.state = 'FIND DATA'
 
     def found_stop(self, scl, sda):
+        # Meta bitrate
+        elapsed = 1 / float(self.samplerate) * (self.samplenum - self.pdu_start + 1)
+        bitrate = int(1 / elapsed * self.pdu_bits)
+        self.put(self.startsample, self.samplenum, self.out_bitrate, bitrate)
+
         self.startsample = self.samplenum
         cmd = 'STOP'
         self.putp([cmd, None])
@@ -207,6 +236,8 @@ class Decoder(srd.Decoder):
         self.wr = -1
 
     def decode(self, ss, es, data):
+        if self.samplerate is None:
+            raise Exception("Cannot decode without samplerate.")
         for (self.samplenum, pins) in data:
 
             # Ignore identical samples early on (for performance reasons).
@@ -214,6 +245,8 @@ class Decoder(srd.Decoder):
                 continue
             self.oldpins, (scl, sda) = pins, pins
 
+            self.pdu_bits += 1
+
             # TODO: Wait until the bus is idle (SDA = SCL = 1) first?
 
             # State machine.