X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=decoders%2Flin%2Fpd.py;h=11495d1177e5896012ba60c23a992ee755bd3c26;hb=826981ac5a2105c7231aeb5e5e523cd37ce72edd;hp=e0340fc4f9945a805ecad816b1721a0485be9907;hpb=546733a262c826ee5bc9ee74eaec330d2e3c088b;p=libsigrokdecode.git diff --git a/decoders/lin/pd.py b/decoders/lin/pd.py index e0340fc..11495d1 100644 --- a/decoders/lin/pd.py +++ b/decoders/lin/pd.py @@ -41,6 +41,7 @@ class LinFsm: def reset(self): self.state = LinFsm.State.WaitForBreak + self.uart_idle_count = 0 def __init__(self): a = dict() @@ -53,6 +54,7 @@ class LinFsm: self.allowed_state = a self.state = None + self.uart_idle_count = 0 self.reset() class Decoder(srd.Decoder): @@ -63,19 +65,20 @@ class Decoder(srd.Decoder): desc = 'Local Interconnect Network (LIN) protocol.' license = 'gplv2+' inputs = ['uart'] - outputs = ['lin'] + outputs = [] + tags = ['Automotive'] options = ( {'id': 'version', 'desc': 'Protocol version', 'default': 2, 'values': (1, 2)}, ) annotations = ( ('data', 'LIN data'), ('control', 'Protocol info'), - ('error', 'Error descriptions'), - ('inline_error', 'Protocol violations and errors'), + ('error', 'Error description'), + ('inline_error', 'Protocol violation or error'), ) annotation_rows = ( - ('data', 'Data', (0, 1, 3)), - ('error', 'Error', (2,)), + ('data_vals', 'Data', (0, 1, 3)), + ('errors', 'Errors', (2,)), ) def __init__(self): @@ -86,7 +89,6 @@ class Decoder(srd.Decoder): self.lin_header = [] self.lin_rsp = [] self.lin_version = None - self.out_ann = None self.ss_block = None self.es_block = None @@ -112,6 +114,15 @@ class Decoder(srd.Decoder): return True + def handle_uart_idle(self): + if self.fsm.state not in (LinFsm.State.WaitForBreak, LinFsm.State.Error): + self.fsm.uart_idle_count += 1 + + if self.fsm.uart_idle_count == 2: + self.fsm.transit(LinFsm.State.Checksum) + self.handle_checksum() + self.fsm.reset() + def handle_wait_for_break(self, value): self.wipe_break_null_byte(value) @@ -150,7 +161,7 @@ class Decoder(srd.Decoder): checksum = self.lin_rsp.pop() if len(self.lin_rsp) else None if pid: - id = pid[2] & 0x3F + id_ = pid[2] & 0x3F parity = pid[2] >> 6 expected_parity = self.calc_parity(pid[2]) @@ -161,8 +172,8 @@ class Decoder(srd.Decoder): ann_class = 0 if parity_valid else 3 self.put(pid[0], pid[1], self.out_ann, [ann_class, [ - 'ID: %02X Parity: %d (%s)' % (id, parity, 'ok' if parity_valid else 'bad'), - 'ID: 0x%02X' % id, 'I: %d' % id + 'ID: %02X Parity: %d (%s)' % (id_, parity, 'ok' if parity_valid else 'bad'), + 'ID: 0x%02X' % id_, 'I: %d' % id_ ]]) if len(self.lin_rsp): @@ -188,9 +199,9 @@ class Decoder(srd.Decoder): def checksum_is_valid(self, pid, data, checksum): if self.lin_version == 2: - id = pid & 0x3F + id_ = pid & 0x3F - if id != 60 and id != 61: + if id_ != 60 and id_ != 61: checksum += pid for d in data: @@ -203,10 +214,10 @@ class Decoder(srd.Decoder): @staticmethod def calc_parity(pid): - id = [((pid & 0x3F) >> i) & 1 for i in range(8)] + id_ = [((pid & 0x3F) >> i) & 1 for i in range(8)] - p0 = id[0] ^ id[1] ^ id[2] ^ id[4] - p1 = not (id[1] ^ id[3] ^ id[4] ^ id[5]) + p0 = id_[0] ^ id_[1] ^ id_[2] ^ id_[4] + p1 = not (id_[1] ^ id_[3] ^ id_[4] ^ id_[5]) return (p0 << 0) | (p1 << 1) @@ -216,6 +227,8 @@ class Decoder(srd.Decoder): self.ss_block, self.es_block = ss, es # Ignore all UART packets except the actual data packets or BREAK. + if ptype == 'IDLE': + self.handle_uart_idle() if ptype == 'BREAK': self.handle_break(pdata) if ptype != 'DATA':