X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=decoders%2Fi2c%2Fi2c.py;h=b1c4a8acaf3080258cdbd186a5d5769cd641f2ee;hb=156509ca42f0df2380c9f205f9aad337e1a07802;hp=f0a95b79fd334b1dc6d9e2ca875b0dee988694fe;hpb=64c29e28e0efa184319f7831b3eca18c7f73f7d0;p=libsigrokdecode.git diff --git a/decoders/i2c/i2c.py b/decoders/i2c/i2c.py index f0a95b7..b1c4a8a 100644 --- a/decoders/i2c/i2c.py +++ b/decoders/i2c/i2c.py @@ -18,46 +18,7 @@ ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ## -# # I2C protocol decoder -# - -# -# The Inter-Integrated Circuit (I2C) bus is a bidirectional, multi-master -# bus using two signals (SCL = serial clock line, SDA = serial data line). -# -# There can be many devices on the same bus. Each device can potentially be -# master or slave (and that can change during runtime). Both slave and master -# can potentially play the transmitter or receiver role (this can also -# change at runtime). -# -# Possible maximum data rates: -# - Standard mode: 100 kbit/s -# - Fast mode: 400 kbit/s -# - Fast-mode Plus: 1 Mbit/s -# - High-speed mode: 3.4 Mbit/s -# -# START condition (S): SDA = falling, SCL = high -# Repeated START condition (Sr): same as S -# Data bit sampling: SCL = rising -# STOP condition (P): SDA = rising, SCL = high -# -# 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 -# indicates a WRITE operation, if it's high that indicates a READ operation. -# -# Later an optional 10bit slave addressing scheme was added. -# -# Documentation: -# http://www.nxp.com/acrobat/literature/9398/39340011.pdf (v2.1 spec) -# http://www.nxp.com/acrobat/usermanuals/UM10204_3.pdf (v3 spec) -# http://en.wikipedia.org/wiki/I2C -# # TODO: Look into arbitration, collision detection, clock synchronisation, etc. # TODO: Handle clock stretching. @@ -69,27 +30,6 @@ # TODO: Handle multiple different I2C devices on same bus # -> we need to decode multiple protocols at the same time. -''' -Protocol output format: - -I2C packet: -[, , ] - - is one of: - - 'START' (START condition) - - 'START REPEAT' (Repeated START) - - 'ADDRESS READ' (Address, read) - - 'ADDRESS WRITE' (Address, write) - - 'DATA READ' (Data, read) - - 'DATA WRITE' (Data, write) - - 'STOP' (STOP condition) - - is the data or address byte associated with the 'ADDRESS*' and 'DATA*' -command. For 'START', 'START REPEAT' and 'STOP', this is None. - - is either 'ACK' or 'NACK', but may also be None. -''' - import sigrokdecode as srd # Annotation feed formats @@ -116,6 +56,7 @@ FIND_ADDRESS = 1 FIND_DATA = 2 class Decoder(srd.Decoder): + api_version = 1 id = 'i2c' name = 'I2C' longname = 'Inter-Integrated Circuit' @@ -128,6 +69,7 @@ class Decoder(srd.Decoder): {'id': 'scl', 'name': 'SCL', 'desc': 'Serial clock line'}, {'id': 'sda', 'name': 'SDA', 'desc': 'Serial data line'}, ] + optional_probes = [] options = { 'addressing': ['Slave addressing (in bits)', 7], # 7 or 10 } @@ -143,19 +85,16 @@ class Decoder(srd.Decoder): ] def __init__(self, **kwargs): - self.samplecnt = 0 + self.startsample = -1 + self.samplenum = None self.bitcount = 0 self.databyte = 0 self.wr = -1 - self.startsample = -1 self.is_repeat_start = 0 self.state = FIND_START self.oldscl = None self.oldsda = None - # Set protocol decoder option defaults. - self.addressing = Decoder.options['addressing'][1] - def start(self, metadata): self.out_proto = self.add(srd.OUTPUT_PROTO, 'i2c') self.out_ann = self.add(srd.OUTPUT_ANN, 'i2c') @@ -182,8 +121,9 @@ class Decoder(srd.Decoder): return False def found_start(self, scl, sda): - cmd = 'START REPEAT' if (self.is_repeat_start == 1) else 'START' + self.startsample = self.samplenum + cmd = 'START REPEAT' if (self.is_repeat_start == 1) else 'START' self.put(self.out_proto, [cmd, None, None]) self.put(self.out_ann, [ANN_SHIFTED, [protocol[cmd][0]]]) self.put(self.out_ann, [ANN_SHIFTED_SHORT, [protocol[cmd][1]]]) @@ -193,19 +133,17 @@ class Decoder(srd.Decoder): self.is_repeat_start = 1 self.wr = -1 + # Gather 8 bits of data plus the ACK/NACK bit. def found_address_or_data(self, scl, sda): - # Gather 8 bits of data plus the ACK/NACK bit. - - if self.startsample == -1: - # TODO: Should be samplenum, as received from the feed. - self.startsample = self.samplecnt - self.bitcount += 1 - # Address and data are transmitted MSB-first. self.databyte <<= 1 self.databyte |= sda + if self.bitcount == 0: + self.startsample = self.samplenum + # Return if we haven't collected all 8 + 1 bits, yet. + self.bitcount += 1 if self.bitcount != 9: return @@ -255,6 +193,8 @@ class Decoder(srd.Decoder): pass def found_stop(self, scl, sda): + self.startsample = self.samplenum + self.put(self.out_proto, ['STOP', None, None]) self.put(self.out_ann, [ANN_SHIFTED, [protocol['STOP'][0]]]) self.put(self.out_ann, [ANN_SHIFTED_SHORT, [protocol['STOP'][1]]]) @@ -265,12 +205,11 @@ class Decoder(srd.Decoder): def put(self, output_id, data): # Inject sample range into the call up to sigrok. - # TODO: 0-0 sample range for now. - super(Decoder, self).put(0, 0, output_id, data) + super(Decoder, self).put(self.startsample, self.samplenum, output_id, data) def decode(self, ss, es, data): for samplenum, (scl, sda) in data: - self.samplecnt += 1 + self.samplenum = samplenum # First sample: Save SCL/SDA value. if self.oldscl == None: @@ -295,8 +234,7 @@ class Decoder(srd.Decoder): elif self.is_stop_condition(scl, sda): self.found_stop(scl, sda) else: - # TODO: Error? - pass + raise Exception('Invalid state %d' % self.STATE) # Save current SDA/SCL values for the next round. self.oldscl = scl