summaryrefslogtreecommitdiff
path: root/decoders/usb_signalling
diff options
context:
space:
mode:
authorStefan BrĂ¼ns <stefan.bruens@rwth-aachen.de>2015-09-30 00:24:24 +0200
committerUwe Hermann <uwe@hermann-uwe.de>2015-10-06 17:41:21 +0200
commita241cfb6e1fbf1f7c85109a54e914672b633f5f3 (patch)
tree564d9e52394b0315df99fbb50c14121c7bce0992 /decoders/usb_signalling
parent0e3cb15e814f20b201709688ab4eaa6eee54dc40 (diff)
downloadlibsigrokdecode-a241cfb6e1fbf1f7c85109a54e914672b633f5f3.tar.gz
libsigrokdecode-a241cfb6e1fbf1f7c85109a54e914672b633f5f3.zip
usb_signalling: Track USB symbol width to compensate frequency errors
USB low/full speed allows for frequency tolerance of 1.5%/0.25%. At maximum packet size (sync + PID + data + CRC16) of 12 bytes/1027 bytes this amounts to 1.4 bits/20 bits, so the decoder has to lock to the actual symbol frequency to avoid any symbol misdetections. The signal is sampled twice, once at the symbol center and once at the expected edge position. Comparing the symbol at both positions gives an indication if the current bit width is too low or too high. Adjust accordingly.
Diffstat (limited to 'decoders/usb_signalling')
-rw-r--r--decoders/usb_signalling/pd.py33
1 files changed, 24 insertions, 9 deletions
diff --git a/decoders/usb_signalling/pd.py b/decoders/usb_signalling/pd.py
index 8ba55d9..6b4c028 100644
--- a/decoders/usb_signalling/pd.py
+++ b/decoders/usb_signalling/pd.py
@@ -117,9 +117,11 @@ class Decoder(srd.Decoder):
self.syms = []
self.bitrate = None
self.bitwidth = None
- self.bitnum = 0
+ self.samplepos = None
self.samplenum_target = None
+ self.samplenum_edge = None
self.oldpins = None
+ self.edgepins = None
self.consecutive_ones = 0
self.state = 'IDLE'
@@ -150,16 +152,16 @@ class Decoder(srd.Decoder):
def putpb(self, data):
s, h = self.samplenum, self.halfbit
- self.put(s - h, s + h, self.out_python, data)
+ self.put(self.samplenum_edge, s + h, self.out_python, data)
def putb(self, data):
s, h = self.samplenum, self.halfbit
- self.put(s - h, s + h, self.out_ann, data)
+ self.put(self.samplenum_edge, s + h, self.out_ann, data)
def set_new_target_samplenum(self):
- bitpos = self.ss_sop + (self.bitwidth / 2)
- bitpos += self.bitnum * self.bitwidth
- self.samplenum_target = int(bitpos)
+ self.samplepos += self.bitwidth;
+ self.samplenum_target = int(self.samplepos)
+ self.samplenum_edge = int(self.samplepos - (self.bitwidth / 2))
def wait_for_sop(self, sym):
# Wait for a Start of Packet (SOP), i.e. a J->K symbol change.
@@ -167,6 +169,7 @@ class Decoder(srd.Decoder):
self.oldsym = sym
return
self.ss_sop = self.samplenum
+ self.samplepos = self.ss_sop - (self.bitwidth / 2) + 0.5
self.set_new_target_samplenum()
self.putpx(['SOP', None])
self.putx([4, ['SOP', 'S']])
@@ -194,15 +197,15 @@ class Decoder(srd.Decoder):
self.syms.append(sym)
self.putpb(['SYM', sym])
self.putb([sym_idx[sym], ['%s' % sym, '%s' % sym[0]]])
- self.bitnum += 1
self.set_new_target_samplenum()
self.oldsym = sym
if self.syms[-2:] == ['SE0', 'J']:
# Got an EOP.
self.putpm(['EOP', None])
self.putm([5, ['EOP', 'E']])
- self.bitnum, self.syms, self.state = 0, [], 'IDLE'
+ self.syms, self.state = [], 'IDLE'
self.consecutive_ones = 0
+ self.bitwidth = float(self.samplerate) / float(self.bitrate)
def get_bit(self, sym):
if sym == 'SE0':
@@ -214,8 +217,17 @@ class Decoder(srd.Decoder):
self.syms.append(sym)
self.putpb(['SYM', sym])
b = '0' if self.oldsym != sym else '1'
+ if (self.oldsym != sym):
+ # edge
+ edgesym = symbols[self.options['signalling']][tuple(self.edgepins)]
+ if (edgesym not in ('SE0', 'SE1')):
+ if (edgesym == sym):
+ self.bitwidth = self.bitwidth - (0.001 * self.bitwidth)
+ self.samplepos = self.samplepos - (0.01 * self.bitwidth)
+ else:
+ self.bitwidth = self.bitwidth + (0.001 * self.bitwidth)
+ self.samplepos = self.samplepos + (0.01 * self.bitwidth)
self.handle_bit(sym, b)
- self.bitnum += 1
self.set_new_target_samplenum()
self.oldsym = sym
@@ -231,8 +243,11 @@ class Decoder(srd.Decoder):
self.oldpins = pins
sym = symbols[self.options['signalling']][tuple(pins)]
self.wait_for_sop(sym)
+ self.edgepins = pins
elif self.state in ('GET BIT', 'GET EOP'):
# Wait until we're in the middle of the desired bit.
+ if self.samplenum == self.samplenum_edge:
+ self.edgepins = pins
if self.samplenum < self.samplenum_target:
continue
sym = symbols[self.options['signalling']][tuple(pins)]