# Werner's Miscellanea Git Source Tree

## Root/m1/usb/dec.py

 1 #!/usr/bin/python 2 3 from tmc.wave import * 4 from tmc.dxplore import dxplore 5 from tmc.decode import d_usb_stream 6 7 8 # 9 # Clock recovery: we assume that each change in the wave is triggered by a 10 # clock edge. We know the clock's nominal period and resynchronize on each 11 # edge. Additionally, we can obtain a list of times when a timing violation 12 # has occurred. 13 # 14 # Note that the timing violations logic doesn't make much sense in its present 15 # form, since it mainly measures noise (particularly if we're digitizing slow 16 # edges) and not clock drift. 17 # 18 # A more useful metric would be accumulated error from some point of reference 19 # or at least the timing of same edges, to eliminate (generally harmless) time 20 # offsets introduced by digitizing. 21 # 22 # So it would probably make more sense for "recover" not to check for timing 23 # violations at all, and leave this to more specialized functions. 24 # 25 def recover(self, period, min = None, max = None, t0 = None): 26 if t0 is None: 27 t0 = self.data[0] 28 v = not self.initial 29 res = [] 30 violations = [] 31 for t in self.data: 32 v = not v 33 if t <= t0: 34 continue 35 n = 0 36 while t0 < t-period/2: 37 res.append(t0) 38 t0 += period 39 n += 1 40 if min is not None: 41 if t0-t > n*min: 42 violations.append(t) 43 if max is not None: 44 if t-t0 > n*max: 45 violations.append(t) 46 t0 = t 47 return res, violations 48 49 50 # 51 # Load the analog waves saved by get.py 52 # 53 wv = waves() 54 wv.load("_wv") 55 56 # 57 # Digitize the waves and save the result. 58 # 59 dm = wv[0].digitize(1.5, 1.8) 60 dp = wv[1].digitize(1.5, 1.8) 61 wv = waves(dp, dm, dp-dm) 62 wv.save("_dig") 63 64 # 65 # Also record the differential signal. 66 # 67 wd = wv[1]-wv[0] 68 dd = wd.digitize(-0.5, 0.5) 69 wd.save("_diff") 70 71 # 72 # Run clock recovery on D+/D-. We only need one, but check both to be sure. 73 # 74 #p = 1/1.5e6 75 p = 1/12e6 76 dp_t, viol = recover(dp, p, p*0.9, p*1.1) 77 print viol 78 dm_t, viol = recover(dm, p, p*.9, p*1.1, t0 = dp.data[0]) 79 print viol 80 81 # 82 # Shift the clock by half a period, add a few periods to get steady state and 83 # SE0s (if any), and then sample the data lines. 84 # 85 clk = map(lambda t: t+p/2, dp_t) 86 clk.extend((clk[-1]+p, clk[-1]+2*p, clk[-1]+3*p)) 87 dp_bv = dp.get(clk) 88 dm_bv = dm.get(clk) 89 90 # 91 # Save a wave with the recovered clock to make it easier to find the bits in 92 # analog graphs. 93 # 94 dd.data = dp_t; 95 dd.save("_clk") 96 97 # 98 # For decoding, we need a fake bit clock. We generate it by doubling each data 99 # bit and generating a L->H transition during this bit. 100 # 101 dpd = [] 102 dmd = [] 103 dck = [] 104 105 # err, silly, seems that we've mixed up D+ and D- all over the place :-) 106 print d_usb_stream(dm_bv[:], dp_bv[:]) 107 108 for v in dp_bv: 109 dpd.append(v) 110 dpd.append(v) 111 dck.append(0) 112 dck.append(1) 113 114 for v in dm_bv: 115 dmd.append(v) 116 dmd.append(v) 117 118 # 119 # Display the reconstructed digital signal. Note that the absolute time is only 120 # correct at the beginning and that relative time is only accurate over 121 # intervals in which no significant clock resynchronization has occurred. 122 # 123 # In fact, dxplore should probably have an option to either turn off time 124 # entirely or to display a user-provided time axis. The latter may be a bit 125 # tricky to implement. 126 # 127 dxplore((dmd, dpd, dck), 0, p/2, labels = ("D+", "D-", "CLK")) 128

Branches:
master