summaryrefslogtreecommitdiff
path: root/decoders/can
diff options
context:
space:
mode:
authorGerhard Sittig <gerhard.sittig@gmx.net>2017-07-02 12:39:08 +0200
committerUwe Hermann <uwe@hermann-uwe.de>2017-07-04 12:01:04 +0200
commit45a5088085c07c862549ad820d752a46ef0e0c76 (patch)
tree6ff69adb5c9bf370fe8baa07a05e2697f1bf1525 /decoders/can
parent300f9194250913babbd57d5eccc2ceccf9010785 (diff)
downloadlibsigrokdecode-45a5088085c07c862549ad820d752a46ef0e0c76.tar.gz
libsigrokdecode-45a5088085c07c862549ad820d752a46ef0e0c76.zip
can: introduce clock synchronization (simple implementation)
Check for falling edges (i.e. changes to dominant state) between bits of a CAN frame, and adjust subsequent bit slots' sample points accordingly. This is a simple implementation which could get improved later. But it improves the decoder's reliability when the input signal's rate differs from the nominal rate. This fixes bug #990. Reported-By: PeterMortensen via IRC
Diffstat (limited to 'decoders/can')
-rw-r--r--decoders/can/pd.py26
1 files changed, 23 insertions, 3 deletions
diff --git a/decoders/can/pd.py b/decoders/can/pd.py
index 6904ed9..5be3e99 100644
--- a/decoders/can/pd.py
+++ b/decoders/can/pd.py
@@ -105,9 +105,24 @@ class Decoder(srd.Decoder):
self.ss_bit12 = None
self.ss_databytebits = []
+ # Poor man's clock synchronization. Use signal edges which change to
+ # dominant state in rather simple ways. This naive approach is neither
+ # aware of the SYNC phase's width nor the specific location of the edge,
+ # but improves the decoder's reliability when the input signal's bitrate
+ # does not exactly match the nominal rate.
+ def dom_edge_seen(self, force = False):
+ self.dom_edge_snum = self.samplenum
+ self.dom_edge_bcount = self.curbit
+
+ def bit_sampled(self):
+ # EMPTY
+ pass
+
# Determine the position of the next desired bit's sample point.
def get_sample_point(self, bitnum):
- samplenum = int(self.sof + (self.bit_width * bitnum) + self.sample_point)
+ samplenum = self.dom_edge_snum
+ samplenum += int(self.bit_width * (bitnum - self.dom_edge_bcount))
+ samplenum += int(self.sample_point)
return samplenum
def is_stuff_bit(self):
@@ -382,9 +397,14 @@ class Decoder(srd.Decoder):
# Wait for a dominant state (logic 0) on the bus.
(can_rx,) = self.wait({0: 'l'})
self.sof = self.samplenum
+ self.dom_edge_seen(force = True)
self.state = 'GET BITS'
elif self.state == 'GET BITS':
# Wait until we're in the correct bit/sampling position.
pos = self.get_sample_point(self.curbit)
- (can_rx,) = self.wait({'skip': pos - self.samplenum})
- self.handle_bit(can_rx)
+ (can_rx,) = self.wait([{'skip': pos - self.samplenum}, {0: 'f'}])
+ if self.matched[1]:
+ self.dom_edge_seen()
+ if self.matched[0]:
+ self.handle_bit(can_rx)
+ self.bit_sampled()