diff options
author | Soeren Apel <soeren@apelpie.net> | 2020-07-29 23:44:56 +0200 |
---|---|---|
committer | Soeren Apel <soeren@apelpie.net> | 2020-07-29 23:50:53 +0200 |
commit | c9d548c7bcbd6db5d689143955dfde405138ea5d (patch) | |
tree | de3ad1b88f81cb93e961e813f711761f89aad02c | |
parent | 4d8b4da74356e2cdd8da75b4ce80c4a17e81b335 (diff) | |
download | libsigrokdecode-c9d548c7bcbd6db5d689143955dfde405138ea5d.tar.gz libsigrokdecode-c9d548c7bcbd6db5d689143955dfde405138ea5d.zip |
lfast: More bug fixes and enhancements
-rw-r--r-- | decoders/lfast/pd.py | 103 |
1 files changed, 63 insertions, 40 deletions
diff --git a/decoders/lfast/pd.py b/decoders/lfast/pd.py index 5cf99b6..7476e59 100644 --- a/decoders/lfast/pd.py +++ b/decoders/lfast/pd.py @@ -24,20 +24,20 @@ import decimal ''' OUTPUT_PYTHON format: -[<data>] where <data> is the payload contained between the LFAST header and -the LFAST stop bit. It's an array of bytes. +[ss, es, data] where data is a data byte of the LFAST payload. All bytes of +the payload are sent at once, each with its start and end sample. ''' # See tc27xD_um_v2.2.pdf, Table 20-10 payload_sizes = { 0b000: '8 bit', - 0b001: '32 bit', - 0b010: '64 bit', - 0b011: '96 bit', - 0b100: '128 bit', - 0b101: '256 bit', - 0b110: '512 bit', - 0b111: '288 bit' + 0b001: '32 bit / 4 byte', + 0b010: '64 bit / 8 byte', + 0b011: '96 bit / 12 byte', + 0b100: '128 bit / 16 byte', + 0b101: '256 bit / 32 byte', + 0b110: '512 bit / 64 byte', + 0b111: '288 bit / 36 byte' } # See tc27xD_um_v2.2.pdf, Table 20-10 @@ -54,7 +54,7 @@ payload_byte_sizes = { # See tc27xD_um_v2.2.pdf, Table 20-11 channel_types = { - 0b0000: 'Interface Control / PING (32 bit)', + 0b0000: 'Interface Control / PING', 0b0001: 'Unsolicited Status (32 bit)', 0b0010: 'Slave Interface Control / Read', 0b0011: 'CTS Transfer', @@ -128,16 +128,19 @@ class Decoder(srd.Decoder): def __init__(self): decimal.getcontext().rounding = decimal.ROUND_HALF_UP + self.bit_len = 0xFFFFFFFF self.reset() def reset(self): + self.prev_bit_len = self.bit_len self.ss = self.es = 0 self.ss_payload = self.es_payload = 0 + self.ss_byte = 0 self.bits = [] self.payload = [] self.payload_size = 0 # Expected number of bytes, as read from header self.bit_len = 0 # Length of one bit time, in samples - self.timeout = 0 # desired timeout for next edge, in samples + self.timeout = 0 # Desired timeout for next edge, in samples self.ch_type_id = 0 # ID of channel type self.state = state_sync @@ -164,9 +167,13 @@ class Decoder(srd.Decoder): self.put_ann(self.ss_sync, self.es_bit, ann_sync, ['Sync OK']) else: self.put_ann(self.ss_sync, self.es_bit, ann_warning, ['Wrong Sync Value: {:02X}'.format(value)]) + self.reset() - self.bits = [] - self.state = state_header + # Only continue if we didn't just reset + if self.ss > 0: + self.bits = [] + self.state = state_header + self.timeout = int(9.4 * self.bit_len) def handle_header(self): if len(self.bits) == 1: @@ -178,27 +185,30 @@ class Decoder(srd.Decoder): value = bitpack(self.bits) ss = self.ss_header - es = ss + 3 * bit_len + es = ss + 3 * bit_len size_id = (value & 0xE0) >> 5 size = payload_sizes.get(size_id) - self.payload_size = payload_byte_sizes.get(size_id) + self.payload_size = payload_byte_sizes.get(size_id) self.put_ann(int(ss), int(es), ann_header_pl_size, [size]) ss = es - es = ss + 4 * bit_len + es = ss + 4 * bit_len self.ch_type_id = (value & 0x1E) >> 1 ch_type = channel_types.get(self.ch_type_id) self.put_ann(int(ss), int(es), ann_header_ch_type, [ch_type]) ss = es - es = ss + bit_len - cts = value & 0x01 + es = ss + bit_len + cts = value & 0x01 self.put_ann(int(ss), int(es), ann_header_cts, ['{}'.format(cts)]) self.bits = [] self.state = state_payload + self.timeout = int(9.4 * self.bit_len) def handle_payload(self): + self.timeout = int((self.payload_size - len(self.payload)) * 8 * self.bit_len) + if len(self.bits) == 1: self.ss_byte = self.ss_bit if self.ss_payload == 0: @@ -207,9 +217,9 @@ class Decoder(srd.Decoder): if len(self.bits) == 8: value = bitpack(self.bits) value_hex = '{:02X}'.format(value) - + # Control transfers have no SIPI payload, show them as control transfers - # Check the channel_types list for the meaning of the magic values + # Check the channel_types list for the meaning of the magic values if (self.ch_type_id >= 0b0100) and (self.ch_type_id <= 0b1011): self.put_ann(self.ss_byte, self.es_bit, ann_payload, [value_hex]) else: @@ -221,15 +231,12 @@ class Decoder(srd.Decoder): self.put_ann(self.ss_byte, self.es_bit, ann_control_data, [value_hex]) self.bits = [] - self.payload.append(value) self.es_payload = self.es_bit - - self.timeout = int((self.payload_size - len(self.payload)) * 8 * self.bit_len) - - if (len(self.payload) == self.payload_size): - self.timeout = int(1.4 * self.bit_len) - self.bits = [] - self.state = state_sleepbit + self.payload.append((self.ss_byte, self.es_payload, value)) + + if (len(self.payload) == self.payload_size): + self.timeout = int(1.4 * self.bit_len) + self.state = state_sleepbit def handle_sleepbit(self): if len(self.bits) == 0: @@ -243,13 +250,11 @@ class Decoder(srd.Decoder): self.put_ann(self.ss_bit, self.es_bit, ann_sleepbit, ['No LVDS sleep mode request', 'No sleep', 'N']) # We only send the payload out if this is an actual data transfer; - # check the channel_types list for the meaning of the magic values + # check the channel_types list for the meaning of the magic values if (self.ch_type_id >= 0b0100) and (self.ch_type_id <= 0b1011): if len(self.payload) > 0: self.put_payload() - self.reset() - def decode(self): while True: if self.timeout == 0: @@ -260,18 +265,28 @@ class Decoder(srd.Decoder): # If this is the first edge, we only update ss if self.ss == 0: self.ss = self.samplenum + # Let's set the timeout for the sync pattern as well + self.timeout = int(16.2 * self.prev_bit_len) continue - + self.es = self.samplenum - if int(self.es - self.ss) == 0: - continue - # Check for the sleep bit if this is a timeout condition - if (self.timeout > 0) and (self.es - self.ss == self.timeout): + if (len(self.matched) == 2) and self.matched[1]: rising_edge = ~rising_edge - if self.state == state_sleepbit: + if self.state == state_sync: + self.reset() + continue + elif self.state == state_sleepbit: + self.ss_bit += self.bit_len + self.es_bit = self.ss_bit + self.bit_len self.handle_sleepbit() + self.reset() + continue + + # Shouldn't happen but we check just in case + if int(self.es - self.ss) == 0: + continue # We use the first bit to deduce the bit length if self.bit_len == 0: @@ -280,12 +295,12 @@ class Decoder(srd.Decoder): # Determine number of bits covered by this edge bit_count = (self.es - self.ss) / self.bit_len bit_count = int(decimal.Decimal(bit_count).to_integral_value()) - + if bit_count == 0: self.put_ann(self.ss, self.es, ann_warning, ['Bit time too short']) self.reset() continue - + bit_value = '0' if rising_edge else '1' divided_len = (self.es - self.ss) / bit_count @@ -305,8 +320,16 @@ class Decoder(srd.Decoder): self.handle_payload() elif self.state == state_sleepbit: self.handle_sleepbit() - break + self.reset() + + if self.ss == 0: + break # Because reset() was called, invalidating everything # Only update ss if we didn't just perform a reset if self.ss > 0: self.ss = self.samplenum + + # If we got here when a timeout occurred, we have processed all null + # bits that we could and should reset now to find the next packet + if (len(self.matched) == 2) and self.matched[1]: + self.reset() |