summaryrefslogtreecommitdiff
path: root/decoders
diff options
context:
space:
mode:
authorGerhard Sittig <gerhard.sittig@gmx.net>2020-07-27 21:58:55 +0200
committerGerhard Sittig <gerhard.sittig@gmx.net>2020-08-30 07:23:58 +0200
commit80c76d2092814d2cd7d0f9fc6ddd6c0c937106dc (patch)
tree45f3c1da04177c95f237a642a7727fcb7b19328c /decoders
parentc328c18123c83e0f1e54181b9634bec76a2e3c43 (diff)
downloadlibsigrokdecode-80c76d2092814d2cd7d0f9fc6ddd6c0c937106dc.tar.gz
libsigrokdecode-80c76d2092814d2cd7d0f9fc6ddd6c0c937106dc.zip
sle44xx: rework data bits accumulation, and byte presentation
The 'databyte' is strictly local to the routine when 8 bits were seen. The 'bitcount' is redundant and becomes obsolete when bits[] is a Python list. The comment and the code disagreed, the wire is said to communicate bits in LSB first order, the implemenation kept accumulating bits in the reverse order (the annotation part, not the data byte math). Prefer the common helper to convert bits to bytes. There is uncertainty about the bit width "estimation" logic. The main loop's .wait() conditions suggest that data bit values are valid for the period of high CLK, which provides an easier and more robust condition for annotation boundaries. Add a comment for now. The order of bit and byte values' annotation emission is unfortunate, too.
Diffstat (limited to 'decoders')
-rw-r--r--decoders/sle44xx/pd.py53
1 files changed, 27 insertions, 26 deletions
diff --git a/decoders/sle44xx/pd.py b/decoders/sle44xx/pd.py
index 02bea42..a53a1ea 100644
--- a/decoders/sle44xx/pd.py
+++ b/decoders/sle44xx/pd.py
@@ -17,6 +17,7 @@
## along with this program; if not, see <http://www.gnu.org/licenses/>.
##
+from common.srdhelper import bitpack_lsb
import sigrokdecode as srd
class Pin:
@@ -81,8 +82,6 @@ class Decoder(srd.Decoder):
def reset(self):
self.ss = self.es = self.ss_byte = -1
- self.bitcount = 0
- self.databyte = 0
self.bits = []
self.cmd = 'RESET'
@@ -105,7 +104,6 @@ class Decoder(srd.Decoder):
self.cmd = 'RESET'
cls, texts = lookup_proto_ann_txt(self.cmd, {})
self.putx([cls, texts])
- self.bitcount = self.databyte = 0
self.bits = []
self.cmd = 'ATR' # Next data bytes will be ATR
@@ -115,47 +113,49 @@ class Decoder(srd.Decoder):
# If I/O is rising -> command START
# if I/O is falling -> command STOP and response data incoming
self.cmd = 'CMD' if (io == 0) else 'DATA'
- self.bitcount = self.databyte = 0
self.bits = []
# Gather 8 bits of data
def handle_data(self, pins):
rst, clk, io = pins
- # Data is transmitted LSB-first.
- self.databyte |= (io << self.bitcount)
-
- # Remember the start of the first data/address bit.
- if self.bitcount == 0:
+ # Remember the start of the first data/address bit. Collect
+ # bits in LSB first order. "Estimate" the bit's width at first,
+ # update end times as better data becomes available.
+ # TODO This estimation logic is imprecise and fragile. A single
+ # slightly stretched clock period throws off the following bit
+ # annotation. Better look for more reliable conditions. Available
+ # documentation suggests bit values are valid during high CLK.
+ if not self.bits:
self.ss_byte = self.samplenum
-
- # Store individual bits and their start/end samplenumbers.
- # In the list, index 0 represents the LSB (SLE44xx transmits LSB-first).
- self.bits.insert(0, [io, self.samplenum, self.samplenum])
- if self.bitcount > 0:
- self.bits[1][2] = self.samplenum
- if self.bitcount == 7:
- self.bitwidth = self.bits[1][2] - self.bits[2][2]
- self.bits[0][2] += self.bitwidth
-
- # Return if we haven't collected all 8 bits, yet.
- if self.bitcount < 7:
- self.bitcount += 1
+ bit_val = io
+ bit_ss = self.samplenum
+ bit_es = bit_ss # self.bitwidth is not known yet.
+ if self.bits:
+ self.bits[-1][2] = bit_ss
+ self.bits.append([bit_val, bit_ss, bit_es])
+ if len(self.bits) < 8:
return
+ bitwidth = self.bits[-1][1] - self.bits[-2][1]
+ self.bits[-1][2] += bitwidth
- self.ss, self.es = self.ss_byte, self.samplenum + self.bitwidth
+ # Get the data byte value, and byte's ss/es.
+ databyte = bitpack_lsb(self.bits, 0)
+ self.ss_byte = self.bits[0][1]
+ self.es_byte = self.bits[-1][2]
- self.putb([Bin.SEND_DATA, bytes([self.databyte])])
+ self.ss, self.es = self.ss_byte, self.es_byte
+ self.putb([Bin.SEND_DATA, bytes([databyte])])
+ # TODO Present bit values earlier. As soon as their es is known.
for bit_val, bit_ss, bit_es in self.bits:
cls, texts = lookup_proto_ann_txt('BIT', {'bit': bit_val})
self.put(bit_ss, bit_es, self.out_ann, [cls, texts])
- cls, texts = lookup_proto_ann_txt(self.cmd, {'data': self.databyte})
+ cls, texts = lookup_proto_ann_txt(self.cmd, {'data': databyte})
self.putx([cls, texts])
# Done with this packet.
- self.bitcount = self.databyte = 0
self.bits = []
def decode(self):
@@ -163,6 +163,7 @@ class Decoder(srd.Decoder):
# Signal conditions tracked by the protocol decoder:
# - RESET condition (R): RST = rising
# - Incoming data (D): RST = low, CLK = rising.
+ # TODO Add "RST low, CLK fall" for "end of DATA" here?
# - Command mode START: CLK = high, I/O = falling.
# - Command mode STOP: CLK = high, I/O = rising.
(COND_RESET, COND_DATA, COND_CMD_START, COND_CMD_STOP,) = range(4)