X-Git-Url: https://sigrok.org/gitweb/?p=libsigrokdecode.git;a=blobdiff_plain;f=scripts%2Fi2c.py;h=5a41a58018841abd2eb0f5a91c300c58f2118a76;hp=973751b466be40181be530cee0b4634f8505b23e;hb=a156f09eac00be0f6d8beaeadef77b03077ab7b1;hpb=930bd9d961b9a13259ffb4997be9fa6ebcdb9da9 diff --git a/scripts/i2c.py b/scripts/i2c.py index 973751b..5a41a58 100644 --- a/scripts/i2c.py +++ b/scripts/i2c.py @@ -41,13 +41,13 @@ # 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. @@ -65,34 +65,32 @@ # 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