summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerhard Sittig <gerhard.sittig@gmx.net>2023-07-17 18:37:37 +0200
committerGerhard Sittig <gerhard.sittig@gmx.net>2023-07-18 21:09:40 +0200
commit5eb664089f9123a91841f66535ffb1689d9ddd98 (patch)
treea938733e6519822dc661851c87f41138988c755b
parent01416b9810ceb759e3088bad174d89621704a210 (diff)
downloadlibsigrokdecode-5eb664089f9123a91841f66535ffb1689d9ddd98.tar.gz
libsigrokdecode-5eb664089f9123a91841f66535ffb1689d9ddd98.zip
i2c: improve reliability of bitrate estimation (throughput, meta)
The I2C decoder used to track the bitrate of the observed traffic (number of address and data bits in a transfer). It's uncertain where this output went (is meta still supported, are applications using it?), and it appears to not be covered in tests. Improve the logic still. Adjust the location of the emitted annotation. It used to start at the most recently observed data byte, which looks suspicious. Output was attempted when STOP was seen, even if the start was not observed. The calculation dropped data before a repeated start. The implementation kept data around after it became obsolete. Break a long formula across several text lines. Use the fact that Python division yields floating point results. Add a comment in the ACK/NAK bit handler. It references data which was gathered when accumulating data bits. Could be acceptable but must be remained aware of.
-rw-r--r--decoders/i2c/pd.py22
1 files changed, 16 insertions, 6 deletions
diff --git a/decoders/i2c/pd.py b/decoders/i2c/pd.py
index 70795c0..850b204 100644
--- a/decoders/i2c/pd.py
+++ b/decoders/i2c/pd.py
@@ -142,9 +142,12 @@ class Decoder(srd.Decoder):
def handle_start(self, pins):
self.ss, self.es = self.samplenum, self.samplenum
- self.pdu_start = self.samplenum
- self.pdu_bits = 0
- cmd = 'START REPEAT' if self.is_repeat_start else 'START'
+ if self.is_repeat_start:
+ cmd = 'START REPEAT'
+ else:
+ cmd = 'START'
+ self.pdu_start = self.samplenum
+ self.pdu_bits = 0
self.putp([cmd, None])
cls, texts = proto[cmd][0], proto[cmd][1:]
self.putx([cls, texts])
@@ -254,6 +257,9 @@ class Decoder(srd.Decoder):
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.
self.ss, self.es = self.samplenum, self.samplenum + self.bitwidth
cmd = 'NACK' if (sda == 1) else 'ACK'
self.putp([cmd, None])
@@ -272,10 +278,14 @@ class Decoder(srd.Decoder):
def handle_stop(self, pins):
# Meta bitrate
- if self.samplerate:
- elapsed = 1 / float(self.samplerate) * (self.samplenum - self.pdu_start + 1)
+ if self.samplerate and self.pdu_start:
+ elapsed = self.samplenum - self.pdu_start + 1
+ elapsed /= self.samplerate
bitrate = int(1 / elapsed * self.pdu_bits)
- self.put(self.ss_byte, self.samplenum, self.out_bitrate, bitrate)
+ ss, es = self.pdu_start, self.samplenum
+ self.put(ss, es, self.out_bitrate, bitrate)
+ self.pdu_start = None
+ self.pdu_bits = 0
cmd = 'STOP'
self.ss, self.es = self.samplenum, self.samplenum