X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=decoders%2Fsle44xx%2Fpd.py;h=775ee3c8a8fb78c9d29aa826a683e480e5da1885;hb=e4f70391abbb153364a534d45a59026961ce1b1f;hp=02bea428b694eec7f992fd5ad70cfb2ce9a1d004;hpb=c328c18123c83e0f1e54181b9634bec76a2e3c43;p=libsigrokdecode.git diff --git a/decoders/sle44xx/pd.py b/decoders/sle44xx/pd.py index 02bea42..775ee3c 100644 --- a/decoders/sle44xx/pd.py +++ b/decoders/sle44xx/pd.py @@ -17,6 +17,7 @@ ## along with this program; if not, see . ## +from common.srdhelper import bitpack_lsb import sigrokdecode as srd class Pin: @@ -81,10 +82,8 @@ 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' + self.cmd = None def metadata(self, key, value): if key == srd.SRD_CONF_SAMPLERATE: @@ -105,57 +104,61 @@ 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 + # Next data bytes will be Answer To Reset. + self.cmd = 'ATR' def handle_command(self, pins): rst, clk, io = pins self.ss, self.es = self.samplenum, self.samplenum + # XXX Is the comment inverted? # 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.cmd = 'CMD' if io == 0 else 'DATA' 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}) - self.putx([cls, texts]) + cls, texts = lookup_proto_ann_txt(self.cmd, {'data': databyte}) + if cls: + self.putx([cls, texts]) # Done with this packet. - self.bitcount = self.databyte = 0 self.bits = [] def decode(self): @@ -163,6 +166,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)