summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--decoders/i2c/pd.py59
1 files changed, 34 insertions, 25 deletions
diff --git a/decoders/i2c/pd.py b/decoders/i2c/pd.py
index a6c7437..1f53e87 100644
--- a/decoders/i2c/pd.py
+++ b/decoders/i2c/pd.py
@@ -120,6 +120,7 @@ class Decoder(srd.Decoder):
self.pdu_start = None
self.pdu_bits = 0
self.data_bits = []
+ self.bitwidth = 0
def metadata(self, key, value):
if key == srd.SRD_CONF_SAMPLERATE:
@@ -141,13 +142,12 @@ class Decoder(srd.Decoder):
def putb(self, ss, es, data):
self.put(ss, es, self.out_binary, data)
- def handle_start(self, pins):
- ss, es = self.samplenum, self.samplenum
+ def handle_start(self, ss, es):
if self.is_repeat_start:
cmd = 'START REPEAT'
else:
cmd = 'START'
- self.pdu_start = self.samplenum
+ self.pdu_start = ss
self.pdu_bits = 0
self.putp(ss, es, [cmd, None])
cls, texts = proto[cmd][0], proto[cmd][1:]
@@ -157,10 +157,10 @@ class Decoder(srd.Decoder):
self.is_write = None
self.rem_addr_bytes = None
self.data_bits.clear()
+ self.bitwidth = 0
# Gather 8 bits of data plus the ACK/NACK bit.
- def handle_address_or_data(self, pins):
- scl, sda = pins
+ def handle_address_or_data(self, ss, es, value):
self.pdu_bits += 1
# Accumulate a byte's bits, including its start position.
@@ -172,12 +172,12 @@ class Decoder(srd.Decoder):
# (gsi: Shouldn't falling SCL be the end of the bit value?)
# Keep the bits in receive order (MSB first) during accumulation.
if self.data_bits:
- self.data_bits[-1][2] = self.samplenum
- self.data_bits.append([sda, self.samplenum, self.samplenum])
+ self.data_bits[-1][2] = ss
+ self.data_bits.append([value, ss, es])
if len(self.data_bits) < 8:
return
self.bitwidth = self.data_bits[-2][2] - self.data_bits[-3][2]
- self.data_bits[-1][2] += self.bitwidth
+ self.data_bits[-1][2] = self.data_bits[-1][1] + self.bitwidth
# Get the byte value. Address and data are transmitted MSB-first.
d = bitpack_msb(self.data_bits, 0)
@@ -256,13 +256,9 @@ class Decoder(srd.Decoder):
self.data_bits.clear()
self.state = 'FIND ACK'
- def get_ack(self, pins):
- scl, sda = pins
- # NOTE! Re-uses the last data bit's width for ACK/NAK as well.
- # Which might be acceptable because this decoder implementation
- # only gets to handle ACK/NAK after all DATA BITS were seen.
- ss_bit, es_bit = self.samplenum, self.samplenum + self.bitwidth
- cmd = 'NACK' if (sda == 1) else 'ACK'
+ def get_ack(self, ss, es, value):
+ ss_bit, es_bit = ss, es
+ cmd = 'NACK' if value == 1 else 'ACK'
self.putp(ss_bit, es_bit, [cmd, None])
cls, texts = proto[cmd][0], proto[cmd][1:]
self.putg(ss_bit, es_bit, cls, texts)
@@ -277,19 +273,18 @@ class Decoder(srd.Decoder):
else:
self.state = 'FIND DATA'
- def handle_stop(self, pins):
+ def handle_stop(self, ss, es):
# Meta bitrate
if self.samplerate and self.pdu_start:
- elapsed = self.samplenum - self.pdu_start + 1
+ elapsed = es - self.pdu_start + 1
elapsed /= self.samplerate
bitrate = int(1 / elapsed * self.pdu_bits)
- ss_meta, es_meta = self.pdu_start, self.samplenum
+ ss_meta, es_meta = self.pdu_start, es
self.put(ss_meta, es_meta, self.out_bitrate, bitrate)
self.pdu_start = None
self.pdu_bits = 0
cmd = 'STOP'
- ss, es = self.samplenum, self.samplenum
self.putp(ss, es, [cmd, None])
cls, texts = proto[cmd][0], proto[cmd][1:]
self.putg(ss, es, cls, texts)
@@ -299,14 +294,21 @@ class Decoder(srd.Decoder):
self.data_bits.clear()
def decode(self):
+ # Check for several bus conditions. Determine sample numbers
+ # here and pass ss, es, and bit values to handling routines.
while True:
# State machine.
if self.state == 'FIND START':
# Wait for a START condition (S): SCL = high, SDA = falling.
- self.handle_start(self.wait({0: 'h', 1: 'f'}))
+ pins = self.wait({0: 'h', 1: 'f'})
+ ss, es = self.samplenum, self.samplenum
+ self.handle_start(ss, es)
elif self.state == 'FIND ADDRESS':
# Wait for a data bit: SCL = rising.
- self.handle_address_or_data(self.wait({0: 'r'}))
+ pins = self.wait({0: 'r'})
+ _, sda = pins
+ ss, es = self.samplenum, self.samplenum # TODO plus bitwidth
+ self.handle_address_or_data(ss, es, sda)
elif self.state == 'FIND DATA':
# Wait for any of the following conditions (or combinations):
# a) Data sampling of receiver: SCL = rising, and/or
@@ -316,11 +318,18 @@ class Decoder(srd.Decoder):
# Check which of the condition(s) matched and handle them.
if self.matched[0]:
- self.handle_address_or_data(pins)
+ _, sda = pins
+ ss, es = self.samplenum, self.samplenum # TODO plus bitwidth
+ self.handle_address_or_data(ss, es, sda)
elif self.matched[1]:
- self.handle_start(pins)
+ ss, es = self.samplenum, self.samplenum
+ self.handle_start(ss, es)
elif self.matched[2]:
- self.handle_stop(pins)
+ ss, es = self.samplenum, self.samplenum
+ self.handle_stop(ss, es)
elif self.state == 'FIND ACK':
# Wait for a data/ack bit: SCL = rising.
- self.get_ack(self.wait({0: 'r'}))
+ pins = self.wait({0: 'r'})
+ _, sda = pins
+ ss, es = self.samplenum, self.samplenum + self.bitwidth
+ self.get_ack(ss, es, sda)