Files
templates/tools/dsview/decoders/set_can/pd.py

67 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import sigrokdecode as srd
from common.setgui_decoders.set_can import Reassembler, legacy
class Decoder(srd.Decoder):
api_version = 3
id = 'set_can'
name = 'SET CAN'
longname = 'SET v2 CAN / ProtoCAN / Balsam'
desc = 'Application fields and segmented SET packets over classic CAN.'
license = 'gplv2+'
inputs = ['can']
outputs = ['set']
tags = ['Embedded/industrial']
options = ({'id': 'protocol', 'desc': 'CAN protocol (select explicitly)',
'default': 'protocan', 'values': ('protocan', 'set-v2', 'balsam')},)
annotations = (('frame', 'Frame'), ('payload', 'Payload'), ('error', 'Error'))
annotation_rows = (('frames', 'Frames', (0,)), ('payload', 'Payload', (1,)), ('errors', 'Errors', (2,)))
def __init__(self):
self.reset()
# Состояние принадлежит одному запуску декодера. Сброс не должен
# переносить незавершённый кадр или частоту из предыдущей записи.
def reset(self):
self.reassembler = Reassembler()
self.samplerate = None
# DSView передаёт время в номерах отсчётов. Частота нужна общему ядру
# для перевода тайм-аутов и измерений в физические единицы.
def metadata(self, key, value):
if key == srd.SRD_CONF_SAMPLERATE:
self.samplerate = value
# Выходы регистрируются в жизненном цикле sigrok, а не в конструкторе.
# Аннотации предназначены для дорожек, структурированные события — для стека.
def start(self):
self.out_ann = self.register(srd.OUTPUT_ANN)
self.out_python = self.register(srd.OUTPUT_PYTHON)
def decode(self, ss, es, data):
frame_type, ident, rtr, dlc, payload = data
if frame_type != 'extended' or rtr == 'remote':
return
mode = self.options['protocol']
if not 0 <= dlc <= 8 or len(payload) != dlc:
events = [(ss, es, None, 'Invalid classic CAN DLC')]
# Сегментированный SET v2 требует времени для тайм-аута сборки.
# Идентификатор, порядок сегментов и CRC проверяет общее ядро.
elif mode == 'set-v2':
if not self.samplerate:
raise ValueError('SET CAN requires samplerate for reassembly timeout')
events = self.reassembler.feed(ident, payload, ss, es, es * 1000.0 / self.samplerate)
else:
try:
result = legacy(ident, payload, mode)
events = [(ss, es, result, None)] if result else []
except ValueError as exc:
events = [(ss, es, None, str(exc))]
for start, end, result, error in events:
self.put(start, end, self.out_ann, [2 if error else 0, [error or result['summary']]])
if result:
result['can_id'] = ident
self.put(start, end, self.out_python, ['FRAME', result])
if events and payload:
self.put(ss, es, self.out_ann, [1, [' '.join('%02X' % b for b in payload)]])