]> sigrok.org Git - libsigrokdecode.git/blobdiff - scripts/i2c.py
Various small decoder script fixes.
[libsigrokdecode.git] / scripts / i2c.py
index 973751b466be40181be530cee0b4634f8505b23e..5a41a58018841abd2eb0f5a91c300c58f2118a76 100644 (file)
 # Repeated START condition (Sr): same as S
 # STOP condition (P): SDA = rising, SCL = high
 #
-# All data bytes on SDA are extactly 8 bits long (transmitted MSB-first).
+# All data bytes on SDA are exactly 8 bits long (transmitted MSB-first).
 # Each byte has to be followed by a 9th ACK/NACK bit. If that bit is low,
 # that indicates an ACK, if it's high that indicates a NACK.
 #
 # After the first START condition, a master sends the device address of the
 # slave it wants to talk to. Slave addresses are 7 bits long (MSB-first).
-# After those 7 bits a data direction bit is sent. If the bit is low that
+# After those 7 bits, a data direction bit is sent. If the bit is low that
 # indicates a WRITE operation, if it's high that indicates a READ operation.
 #
 # Later an optional 10bit slave addressing scheme was added.
 # TODO: Implement support for inverting SDA/SCL levels (0->1 and 1->0).
 # TODO: Implement support for detecting various bus errors.
 
-# TODO: Return two buffers, one with structured data for the GUI to parse
-#       and display, and one with human-readable ASCII output.
-
-def sigrokdecode_i2c(inbuf):
+def decode(inbuf):
        """I2C protocol decoder"""
 
+       # FIXME: Get the data in the correct format in the first place.
+       inbuf = [ord(x) for x in inbuf]
+
        # FIXME: This should be passed in as metadata, not hardcoded here.
        signals = (2, 5)
        channels = 8
 
        o = wr = ack = d = ''
        bitcount = data = 0
-       state = 'IDLE'
+       IDLE, START, ADDRESS, DATA = range(4)
+       state = IDLE
 
        # Get the bit number (and thus probe index) of the SCL/SDA signals.
        scl_bit, sda_bit = signals
 
        # Get SCL/SDA bit values (0/1 for low/high) of the first sample.
-       s = ord(inbuf[0])
+       s = inbuf[0]
        oldscl = (s & (1 << scl_bit)) >> scl_bit
        oldsda = (s & (1 << sda_bit)) >> sda_bit
 
        # Loop over all samples.
        # TODO: Handle LAs with more/less than 8 channels.
        for samplenum, s in enumerate(inbuf[1:]): # We skip the first byte...
-               s = ord(s) # FIXME
-
                # Get SCL/SDA bit values (0/1 for low/high).
                scl = (s & (1 << scl_bit)) >> scl_bit
                sda = (s & (1 << sda_bit)) >> sda_bit
@@ -102,7 +100,7 @@ def sigrokdecode_i2c(inbuf):
                # START condition (S): SDA = falling, SCL = high
                if (oldsda == 1 and sda == 0) and scl == 1:
                        o += "%d\t\tSTART\n" % samplenum
-                       state = 'ADDRESS'
+                       state = ADDRESS
                        bitcount = data = 0
 
                # Data latching by transmitter: SCL = low
@@ -125,20 +123,21 @@ def sigrokdecode_i2c(inbuf):
 
                        # We received 8 address/data bits and the ACK/NACK bit.
                        data >>= 1 # Shift out unwanted ACK/NACK bit here.
-                       o += "%d\t\t%s: " % (samplenum, state)
+                       # o += "%d\t\t%s: " % (samplenum, state)
+                       o += "%d\t\tTODO:STATE: " % samplenum
                        ack = (sda == 1) and 'NACK' or 'ACK'
-                       d = (state == 'ADDRESS') and (data & 0xfe) or data
+                       d = (state == ADDRESS) and (data & 0xfe) or data
                        wr = ''
-                       if state == 'ADDRESS':
+                       if state == ADDRESS:
                                wr = (data & 1) and ' (W)' or ' (R)'
-                               state = 'DATA'
+                               state = DATA
                        o += "0x%02x%s (%s)\n" % (d, wr, ack)
                        bitcount = data = 0
 
                # STOP condition (P): SDA = rising, SCL = high
                elif (oldsda == 0 and sda == 1) and scl == 1:
                        o += "%d\t\tSTOP\n" % samplenum
-                       state = 'IDLE'
+                       state = IDLE
 
                # Save current SDA/SCL values for the next round.
                oldscl = scl
@@ -146,26 +145,23 @@ def sigrokdecode_i2c(inbuf):
 
        return o
 
-# This is just a draft.
-def sigrokdecode_register_i2c():
-       metadata = {
+def register():
+       return {
                'id': 'i2c',
                'name': 'I2C',
-               'description': 'Inter-Integrated Circuit (I2C) bus',
-               'function': 'sigrokdecode_i2c',
+               'desc': 'Inter-Integrated Circuit (I2C) bus',
                'inputformats': ['raw'],
                'signalnames':  {
                                'SCL': 'Serial clock line',
                                'SDA': 'Serial data line',
                                },
-               'ouputformats': ['i2c', 'ascii'],
+               'outputformats': ['i2c'],
        }
-       return metadata
 
 # Use psyco (if available) as it results in huge performance improvements.
 try:
        import psyco
-       psyco.bind(sigrokdecode_i2c)
+       psyco.bind(decode)
 except ImportError:
        pass