diff options
author | Gerhard Sittig <gerhard.sittig@gmx.net> | 2020-07-27 21:58:55 +0200 |
---|---|---|
committer | Gerhard Sittig <gerhard.sittig@gmx.net> | 2020-08-30 07:23:58 +0200 |
commit | 80c76d2092814d2cd7d0f9fc6ddd6c0c937106dc (patch) | |
tree | 45f3c1da04177c95f237a642a7727fcb7b19328c /decoders | |
parent | c328c18123c83e0f1e54181b9634bec76a2e3c43 (diff) | |
download | libsigrokdecode-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.py | 53 |
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) |