def reset(self):
self.state = LinFsm.State.WaitForBreak
+ self.uart_idle_count = 0
def __init__(self):
a = dict()
self.allowed_state = a
self.state = None
+ self.uart_idle_count = 0
self.reset()
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):
self.lin_header = []
self.lin_rsp = []
self.lin_version = None
- self.out_ann = None
self.ss_block = None
self.es_block = None
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)
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])
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):
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:
@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)
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':