summaryrefslogtreecommitdiff
path: root/decoders/parallel
diff options
context:
space:
mode:
authorGerhard Sittig <gerhard.sittig@gmx.net>2017-12-22 14:48:37 +0100
committerUwe Hermann <uwe@hermann-uwe.de>2018-01-01 22:15:51 +0100
commita0b7e07f5576605141e543f9d81a220a920edc27 (patch)
treea1a73576180cd3398ca886645819030834f145cd /decoders/parallel
parent6f7dd46d60a7ca2f1893f5a7d5fd7e87212743f7 (diff)
downloadlibsigrokdecode-a0b7e07f5576605141e543f9d81a220a920edc27.tar.gz
libsigrokdecode-a0b7e07f5576605141e543f9d81a220a920edc27.zip
parallel: cope with sparse input mappings, assume zero for not-connected pins
Cope when users only provide e.g. input lines D0 and D2 to the parallel decoder. Assume that not-connected pins are "always zero". Rephrase the .decode() logic which determines .wait() conditions while we are here, to slightly unobfuscate the implementation. This fixes bug #1088.
Diffstat (limited to 'decoders/parallel')
-rw-r--r--decoders/parallel/pd.py53
1 files changed, 29 insertions, 24 deletions
diff --git a/decoders/parallel/pd.py b/decoders/parallel/pd.py
index 593b39b..1c3435c 100644
--- a/decoders/parallel/pd.py
+++ b/decoders/parallel/pd.py
@@ -18,6 +18,7 @@
##
import sigrokdecode as srd
+from common.srdhelper import bitpack
'''
OUTPUT_PYTHON format:
@@ -95,7 +96,6 @@ class Decoder(srd.Decoder):
self.saved_item = None
self.ss_item = self.es_item = None
self.first = True
- self.num_channels = 0
def start(self):
self.out_python = self.register(srd.OUTPUT_PYTHON)
@@ -113,12 +113,7 @@ class Decoder(srd.Decoder):
def putw(self, data):
self.put(self.ss_word, self.es_word, self.out_ann, data)
- def handle_bits(self, datapins):
- # Get the bits for this item.
- item, used_pins = 0, datapins.count(1) + datapins.count(0)
- for i in range(used_pins):
- item |= datapins[i] << i
-
+ def handle_bits(self, item, used_pins):
# Save the item, and its sample number if it's the first part of a word.
if not self.items:
self.ss_word = self.samplenum
@@ -160,25 +155,35 @@ class Decoder(srd.Decoder):
self.items = []
def decode(self):
- for i in range(len(self.optional_channels)):
- if self.has_channel(i):
- self.num_channels += 1
-
- if self.num_channels == 0:
+ # 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.
+ max_possible = len(self.optional_channels)
+ idx_channels = [
+ idx if self.has_channel(idx) else None
+ for idx in range(max_possible)
+ ]
+ has_channels = [idx for idx in idx_channels if idx is not None]
+ if not has_channels:
raise ChannelError('At least one channel has to be supplied.')
-
- if not self.has_channel(0):
- # CLK was not supplied, sample on ANY edge of ANY of the pins
- # (but only of those pins that were actually supplied).
- conds = []
- for i in range(1, len(self.optional_channels)):
- if self.has_channel(i):
- conds.append({i: 'e'})
- else:
- # Sample on the rising or falling CLK edge (depends on config).
+ max_connected = max(has_channels)
+ idx_strip = max_connected + 1
+
+ # Determine .wait() conditions, depending on the presence of a
+ # clock signal. Either inspect samples on the configured edge of
+ # the clock, or inspect samples upon ANY edge of ANY of the pins
+ # which provide input data.
+ if self.has_channel(0):
edge = self.options['clock_edge'][0]
- conds = [{0: edge}]
+ conds = {0: edge}
+ else:
+ conds = [{idx: 'e'} for idx in has_channels]
+ # Keep processing the input stream. Assume "always zero" for
+ # not-connected input lines. Pass data bits (all inputs except
+ # clock) to the handle_bits() method.
while True:
pins = self.wait(conds)
- self.handle_bits(pins[1:])
+ bits = [0 if idx is None else pins[idx] for idx in idx_channels]
+ bits = bits[1:idx_strip]
+ self.handle_bits(bitpack(bits), len(bits))