mirror of
git://projects.qi-hardware.com/ben-wpan.git
synced 2024-11-29 11:47:11 +02:00
atusb/fw3/an/: USB debugging scripts
This commit is contained in:
parent
c1dc00ee44
commit
f4d299d22b
25
atusb/fw3/an/README
Normal file
25
atusb/fw3/an/README
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
workflow:
|
||||||
|
|
||||||
|
- connect zprobe (note: it currently inverts because it didn't have any
|
||||||
|
other chips around. this may change later.)
|
||||||
|
|
||||||
|
- capture the USB signals at an interesting moment with a sample rate of
|
||||||
|
50 MSa/s
|
||||||
|
|
||||||
|
- zoom into the frame(s) of interest
|
||||||
|
|
||||||
|
- download the data with
|
||||||
|
./get.py
|
||||||
|
|
||||||
|
- decode with
|
||||||
|
./dec.py
|
||||||
|
|
||||||
|
For manual decoding, set the coders to D+ and D- (we need D- for SE0
|
||||||
|
and SE1 detection), then click on a rising clock edge left of the
|
||||||
|
packet and move the cursor to the right.
|
||||||
|
|
||||||
|
- if there are problems with the clock, the analog signal and digital
|
||||||
|
signals derived from it can be examined after running dec.py with
|
||||||
|
./plot
|
||||||
|
|
||||||
|
(Note that the digital zprobe hides any analog anomalies.)
|
127
atusb/fw3/an/dec.py
Executable file
127
atusb/fw3/an/dec.py
Executable file
@ -0,0 +1,127 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from tmc.wave import *
|
||||||
|
from tmc.dxplore import dxplore
|
||||||
|
from tmc.decode import d_usb_stream
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Clock recovery: we assume that each change in the wave is triggered by a
|
||||||
|
# clock edge. We know the clock's nominal period and resynchronize on each
|
||||||
|
# edge. Additionally, we can obtain a list of times when a timing violation
|
||||||
|
# has occurred.
|
||||||
|
#
|
||||||
|
# Note that the timing violations logic doesn't make much sense in its present
|
||||||
|
# form, since it mainly measures noise (particularly if we're digitizing slow
|
||||||
|
# edges) and not clock drift.
|
||||||
|
#
|
||||||
|
# A more useful metric would be accumulated error from some point of reference
|
||||||
|
# or at least the timing of same edges, to eliminate (generally harmless) time
|
||||||
|
# offsets introduced by digitizing.
|
||||||
|
#
|
||||||
|
# So it would probably make more sense for "recover" not to check for timing
|
||||||
|
# violations at all, and leave this to more specialized functions.
|
||||||
|
#
|
||||||
|
def recover(self, period, min = None, max = None, t0 = None):
|
||||||
|
if t0 is None:
|
||||||
|
t0 = self.data[0]
|
||||||
|
v = not self.initial
|
||||||
|
res = []
|
||||||
|
violations = []
|
||||||
|
for t in self.data:
|
||||||
|
v = not v
|
||||||
|
if t <= t0:
|
||||||
|
continue
|
||||||
|
n = 0
|
||||||
|
while t0 < t-period/2:
|
||||||
|
res.append(t0)
|
||||||
|
t0 += period
|
||||||
|
n += 1
|
||||||
|
if min is not None:
|
||||||
|
if t0-t > n*min:
|
||||||
|
violations.append(t)
|
||||||
|
if max is not None:
|
||||||
|
if t-t0 > n*max:
|
||||||
|
violations.append(t)
|
||||||
|
t0 = t
|
||||||
|
return res, violations
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Load the analog waves saved by get.py
|
||||||
|
#
|
||||||
|
wv = waves()
|
||||||
|
wv.load("_wv")
|
||||||
|
|
||||||
|
#
|
||||||
|
# Digitize the waves and save the result.
|
||||||
|
#
|
||||||
|
dp = wv[0].digitize(1.5, 1.8)
|
||||||
|
dm = wv[1].digitize(1.5, 1.8)
|
||||||
|
wv = waves(dp, dm, dp-dm)
|
||||||
|
wv.save("_dig")
|
||||||
|
|
||||||
|
#
|
||||||
|
# Also record the differential signal.
|
||||||
|
#
|
||||||
|
wd = wv[1]-wv[0]
|
||||||
|
dd = wd.digitize(-0.5, 0.5)
|
||||||
|
wd.save("_diff")
|
||||||
|
|
||||||
|
#
|
||||||
|
# Run clock recovery on D+/D-. We only need one, but check both to be sure.
|
||||||
|
#
|
||||||
|
#p = 1/1.5e6
|
||||||
|
p = 1/12e6
|
||||||
|
dp_t, viol = recover(dp, p, p*0.9, p*1.1)
|
||||||
|
print viol
|
||||||
|
dm_t, viol = recover(dm, p, p*.9, p*1.1, t0 = dp.data[0])
|
||||||
|
print viol
|
||||||
|
|
||||||
|
#
|
||||||
|
# Shift the clock by half a period, add a few periods to get steady state and
|
||||||
|
# SE0s (if any), and then sample the data lines.
|
||||||
|
#
|
||||||
|
clk = map(lambda t: t+p/2, dp_t)
|
||||||
|
clk.extend((clk[-1]+p, clk[-1]+2*p, clk[-1]+3*p))
|
||||||
|
dp_bv = dp.get(clk)
|
||||||
|
dm_bv = dm.get(clk)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Save a wave with the recovered clock to make it easier to find the bits in
|
||||||
|
# analog graphs.
|
||||||
|
#
|
||||||
|
dd.data = dp_t;
|
||||||
|
dd.save("_clk")
|
||||||
|
|
||||||
|
#
|
||||||
|
# For decoding, we need a fake bit clock. We generate it by doubling each data
|
||||||
|
# bit and generating a L->H transition during this bit.
|
||||||
|
#
|
||||||
|
dpd = []
|
||||||
|
dmd = []
|
||||||
|
dck = []
|
||||||
|
|
||||||
|
# err, silly, seems that we've mixed up D+ and D- all over the place :-)
|
||||||
|
print d_usb_stream(dm_bv[:], dp_bv[:])
|
||||||
|
|
||||||
|
for v in dp_bv:
|
||||||
|
dpd.append(v)
|
||||||
|
dpd.append(v)
|
||||||
|
dck.append(0)
|
||||||
|
dck.append(1)
|
||||||
|
|
||||||
|
for v in dm_bv:
|
||||||
|
dmd.append(v)
|
||||||
|
dmd.append(v)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Display the reconstructed digital signal. Note that the absolute time is only
|
||||||
|
# correct at the beginning and that relative time is only accurate over
|
||||||
|
# intervals in which no significant clock resynchronization has occurred.
|
||||||
|
#
|
||||||
|
# In fact, dxplore should probably have an option to either turn off time
|
||||||
|
# entirely or to display a user-provided time axis. The latter may be a bit
|
||||||
|
# tricky to implement.
|
||||||
|
#
|
||||||
|
dxplore((dmd, dpd, dck), 0, p/2, labels = ("D+", "D-", "CLK"))
|
31
atusb/fw3/an/get.py
Executable file
31
atusb/fw3/an/get.py
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from tmc.scope import rigol_ds1000c
|
||||||
|
|
||||||
|
#-800, +1600
|
||||||
|
s = rigol_ds1000c()
|
||||||
|
#s.debug = False
|
||||||
|
|
||||||
|
pos = s.hor.pos
|
||||||
|
scale = s.hor.scale
|
||||||
|
t0 = pos-scale*s.div_hor/2
|
||||||
|
t1 = pos+scale*s.div_hor/2
|
||||||
|
print t0, t1
|
||||||
|
|
||||||
|
#zoom = 10
|
||||||
|
#step = scale/s.samples_per_div/zoom
|
||||||
|
#print step
|
||||||
|
step = 4e-9
|
||||||
|
step = 2e-9
|
||||||
|
|
||||||
|
w = s.wave((s.ch[0], s.ch[1]), start = t0, end = t1, step = step)
|
||||||
|
w[0] = 3.3-w[0]
|
||||||
|
w[1] = 3.3-w[1]
|
||||||
|
|
||||||
|
s.hor.pos = pos
|
||||||
|
s.hor.scale = scale
|
||||||
|
|
||||||
|
w[0].label = "D+";
|
||||||
|
w[1].label = "D-";
|
||||||
|
|
||||||
|
w.save("_wv")
|
12
atusb/fw3/an/plot
Executable file
12
atusb/fw3/an/plot
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Plot output of "dec"
|
||||||
|
#
|
||||||
|
gnuplot -persist <<EOF
|
||||||
|
set style data lines
|
||||||
|
plot "_wv" using 1:(\$2-4), \
|
||||||
|
"_dig" using 1:(\$2*3.3-4) lw 2, \
|
||||||
|
"_wv" using 1:3, \
|
||||||
|
"_dig" using 1:(\$3*3.3) lw 2, \
|
||||||
|
"_clk" using 1:(\$2+1) lt 7
|
||||||
|
EOF
|
Loading…
Reference in New Issue
Block a user