Created
April 4, 2025 22:22
-
-
Save andyboeh/b04ff053e42b21cc9af5db20bcf6c554 to your computer and use it in GitHub Desktop.
Sigrok protocol decoder for elero unidirectional protocol
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## | |
## This file is part of the libsigrokdecode project. | |
## | |
## Copyright (C) 2013 Uwe Hermann <[email protected]> | |
## | |
## This program is free software; you can redistribute it and/or modify | |
## it under the terms of the GNU General Public License as published by | |
## the Free Software Foundation; either version 2 of the License, or | |
## (at your option) any later version. | |
## | |
## This program is distributed in the hope that it will be useful, | |
## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
## GNU General Public License for more details. | |
## | |
## You should have received a copy of the GNU General Public License | |
## along with this program; if not, see <http://www.gnu.org/licenses/>. | |
## | |
''' | |
Simple Elero unidirectional decoder | |
''' | |
from .pd import Decoder |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sigrokdecode as srd | |
from common.srdhelper import bitpack | |
''' | |
OUTPUT_PYTHON format: | |
Packet: | |
[<ptype>, <pdata>] | |
<ptype>, <pdata> | |
- 'ITEM', [<item>, <itembitsize>] | |
- 'WORD', [<word>, <wordbitsize>, <worditemcount>] | |
<item>: | |
- A single item (a number). It can be of arbitrary size. The max. number | |
of bits in this item is specified in <itembitsize>. | |
<itembitsize>: | |
- The size of an item (in bits). For a 4-bit parallel bus this is 4, | |
for a 16-bit parallel bus this is 16, and so on. | |
<word>: | |
- A single word (a number). It can be of arbitrary size. The max. number | |
of bits in this word is specified in <wordbitsize>. The (exact) number | |
of items in this word is specified in <worditemcount>. | |
<wordbitsize>: | |
- The size of a word (in bits). For a 2-item word with 8-bit items | |
<wordbitsize> is 16, for a 3-item word with 4-bit items <wordbitsize> | |
is 12, and so on. | |
<worditemcount>: | |
- The size of a word (in number of items). For a 4-item word (no matter | |
how many bits each item consists of) <worditemcount> is 4, for a 7-item | |
word <worditemcount> is 7, and so on. | |
''' | |
class Ann: | |
ITEM, NIBBLE, WARN = range(3) | |
class ChannelError(Exception): | |
pass | |
class Decoder(srd.Decoder): | |
api_version = 3 | |
id = 'elerouni' | |
name = 'EleroUni' | |
longname = 'Elero unidirectional protocol' | |
desc = 'Basic Elero unidirectional decoder' | |
license = 'gplv2+' | |
inputs = ['logic'] | |
outputs = ['elero'] | |
tags = ['Util'] | |
started = False | |
tik = True | |
channels = ( | |
{'id': 'data', 'name': 'Data', 'desc': 'Data line'}, | |
{'id': 'clk', 'name': 'Clock', 'desc': 'Clock line'}, | |
) | |
annotations = ( | |
('item', 'Item'), | |
('nibble', 'Nibble'), | |
('warning', 'Warning'), | |
) | |
annotation_rows = ( | |
('items', 'Items', (Ann.ITEM,)), | |
('nibbles', 'Nibbles', (Ann.NIBBLE,)), | |
('warnings', 'Warnings', (Ann.WARN,)), | |
) | |
def __init__(self): | |
self.reset() | |
print('init') | |
def reset(self): | |
self.pend_item = None | |
self.word_items = [] | |
self.started = False | |
def start(self): | |
self.out_python = self.register(srd.OUTPUT_PYTHON) | |
self.out_ann = self.register(srd.OUTPUT_ANN) | |
def putg(self, ss, es, ann, txts): | |
self.put(ss, es, self.out_ann, [ann, txts]) | |
def putpy(self, ss, es, ann, data): | |
self.put(ss, es, self.out_python, [ann, data]) | |
def detect_idle1(self, window): | |
idle1 = [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1] | |
return window == idle1 | |
def detect_idle2(self, window): | |
idle2 = [0, 0, 0, 0, 1, 1, 1, 1] | |
return window[4:] == idle2 | |
def decode(self): | |
print('decode') | |
# Determine which (optional) channels have input data. Insist in | |
# a non-empty input data set. Cope with sparse connection maps. | |
# Store enough state to later "compress" sampled input data. | |
if not self.has_channel(0) or not self.has_channel(1): | |
raise ChannelError('Need clock and data channels.') | |
conds = [{1 : 'r'}] | |
window = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] | |
ds = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] | |
bits = [0, 0] | |
nibble = [0, 0, 0, 0] | |
npos = [0, 0, 0, 0] | |
data_index = 0 | |
while True: | |
pins = self.wait(conds) | |
clock_edge = self.matched[0] | |
data_state = pins[0] | |
window.pop(0) | |
window.append(data_state) | |
ds.pop(0) | |
ds.append(self.samplenum) | |
if self.started: | |
if self.tik: | |
bits[0] = data_state | |
self.tik = False | |
else: | |
bits[1] = data_state | |
self.tik = True | |
db = -1 | |
if bits[0] == 0 and bits[1] == 1: | |
self.putg(self.samplenum, self.samplenum, Ann.ITEM, ['0']) | |
db = 0 | |
elif bits[0] == 1 and bits[1] == 0: | |
self.putg(self.samplenum, self.samplenum, Ann.ITEM, ['1']) | |
db = 1 | |
nibble.pop(0) | |
nibble.append(db) | |
npos.pop(0) | |
npos.append(self.samplenum) | |
if data_index % 4 == 0 and data_index > 0: | |
if not -1 in nibble: | |
nibble_string = hex(int("".join(str(x) for x in nibble), 2)) | |
else: | |
nibble_string = "error" | |
self.putg(npos[0], self.samplenum, Ann.NIBBLE, [nibble_string]) | |
data_index += 1 | |
if data_index == 65: | |
data_index = 0 | |
self.started = False | |
if self.detect_idle1(window): | |
es = self.samplenum | |
ss = ds[0] | |
self.putg(ss, es, Ann.ITEM, ['IDLE1']) | |
self.started = True | |
if self.detect_idle2(window): | |
es = self.samplenum | |
ss = ds[4] | |
self.putg(ss, es, Ann.ITEM, ['IDLE2']) | |
self.started = True |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment