r4610 - developers/werner/ahrt/host/tmc/lib
werner at docs.openmoko.org
werner at docs.openmoko.org
Tue Aug 26 04:54:55 CEST 2008
Author: werner
Date: 2008-08-26 04:54:54 +0200 (Tue, 26 Aug 2008)
New Revision: 4610
Modified:
developers/werner/ahrt/host/tmc/lib/scope.py
Log:
Support for full waveform retrieval with DS1000CD. This allows decoding of
SPI (and SD) sequences of up to about 50kbits.
- lib/scope.py (scale_125): improved tolerance against rounding errors
- lib/scope.py: added full-depth retrieval for analog and digital waves
- lib/scope.py: give credit to rew's Rigol interface program
- lib/scope.py: send parameters of horizontal system only in non-exponential
format (exponents confuse the Rigol)
Modified: developers/werner/ahrt/host/tmc/lib/scope.py
===================================================================
--- developers/werner/ahrt/host/tmc/lib/scope.py 2008-08-26 01:48:14 UTC (rev 4609)
+++ developers/werner/ahrt/host/tmc/lib/scope.py 2008-08-26 02:54:54 UTC (rev 4610)
@@ -3,8 +3,12 @@
# scope.py - Oscilloscope control
#
-# Found screen dump algorithm here:
+# Found Rigol screen dump algorithm here:
# http://www.circuitsonline.net/forum/view/message/652573#652573
+#
+# Rigol data retrieval is heavily based on
+# http://prive.bitwizard.nl/rigol/rigol-0.1rew3.tgz
+#
#
# Our oscilloscope model consists of three elements:
@@ -23,6 +27,7 @@
# TODO: make range configurable
def scale_125(n = None, fuzz = None, min = None, max = None):
+ epsilon = 1e-15
res = None
for e in range(-9, 1+1):
for m in [1, 2, 5]:
@@ -33,9 +38,9 @@
r = float(s)
if n is not None and r >= n*(1-fuzz) and r <= n*(1+fuzz):
return s
- if min is not None and r >= min:
+ if min is not None and r >= min-epsilon:
return s
- if max is not None and r <= max:
+ if max is not None and r <= max+epsilon:
res = s
if res is not None:
return res
@@ -107,38 +112,8 @@
def wave(self, start = None, end = None, step = None):
- width = self.scope.div_hor*self.scope.hor.scale
- if start is None and end is None:
- start = self.scope.hor.pos
- if start is not None and end is None:
- end = start+width
- elif start is None and end is not None:
- start = end-width
- if step is None:
- return self.scope.download_wave(self, start, end, None)
- else:
- # @@@ put setting the horizontal system into download_wave
- if step*self.scope.sampling_rate() < 1:
- raise hell
- span = step*self.scope.samples_per_div*self.scope.div_hor
- if False and span >= start-end:
- return self.scope.download_wave(self, start, end, None)
- else:
- scale = float(scale_125(max = step*self.scope.samples_per_div))
- orig_pos = self.scope.hor.pos
- orig_scale = self.scope.hor.scale
- self.scope.hor.scale = scale
- span = self.scope.div_hor*self.scope.hor.scale
- wave = analog_wave()
- pos = start
- while pos < end:
- self.scope.hor.pos = pos
- wave.extend(self.scope.download_wave(self, pos, pos+span,
- None))
- pos += span
- self.scope.hor.pos = orig_pos
- self.scope.hor.scale = orig_scale
- return wave
+ # @@@ move start and end adjustment here !
+ return self.scope.download_wave(self, start, end, step)
# === horizontal ==============================================================
@@ -149,9 +124,11 @@
def __init__(self, scope):
self.scope = scope
self.pos = setting(scope, ":TIM:OFFS",
- lambda x: float(x))
+ lambda x: float(x),
+ lambda x: "%.9f" % x)
self.scale = setting(scope, ":TIM:SCAL",
- lambda x: float(x))
+ lambda x: float(x),
+ lambda x: "%.9f" % x)
self.forget()
def forget(self):
@@ -264,6 +241,42 @@
return res
+def rigol_wave(scope, start, end, step, query, merge, fn, *args):
+ wave = None
+ orig_pos = scope.hor.pos
+ orig_scale = scope.hor.scale
+
+ width = scope.div_hor*orig_scale
+ if start is None:
+ start = orig_pos-width/2
+ if end is None:
+ end = orig_pos+width/2
+ if step is None:
+ step = 1/scope.sampling_rate()
+
+ scope.hor.scale = float(scale_125(max = step*scope.samples_per_div))
+ while start < end:
+ scope.hor.pos = start+6*scope.hor.scale
+ data = scope.query(query)
+ data = fn(data, scope.hor.pos, scope.hor.scale, *args)
+ if wave is None:
+ wave = data
+ else:
+ merge(wave, data)
+ start += 12*scope.hor.scale
+
+ scope.hor.pos = orig_pos
+ scope.hor.scale = orig_scale
+ return wave
+
+
+def rigol_extend_la(a, b):
+ i = 0
+ while i != 16:
+ a[i].extend(b[i])
+ i += 1
+
+
def rigol_to_ppm(s):
lut = []
i = 0
@@ -282,7 +295,7 @@
channels = 2
div_hor = 12
div_vert = 10
- samples_per_div = 600 #@@@ not exactly true. needs more investigation
+ samples_per_div = 50
def __init__(self):
scope.__init__(self, "usbtmc", "rigol", "timeout=2", "retry",
@@ -321,15 +334,17 @@
for n in range(0, len(self.ch)):
if self.ch[n] == channel:
c_num = n+1
- data = self.query(":WAV:DATA? CHAN"+str(c_num))
- return rigol_channel_data(data, self.hor.pos, self.hor.scale,
- channel.pos, channel.scale)
+ return rigol_wave(self, start, end, step,
+ ":WAV:DATA? CHAN"+str(c_num),
+ lambda a, b: a.extend(b),
+ rigol_channel_data, channel.pos, channel.scale)
# experimental
- def download_la(self):
- data = self.query(":WAV:DATA? DIG")
- return rigol_la_data(data, self.hor.pos, self.hor.scale)
+ def download_la(self, start = None, end = None, step = None):
+ return rigol_wave(self, start, end, step,
+ ":WAV:DATA? DIG",
+ rigol_extend_la, rigol_la_data)
def sampling_rate(self):
return float(self.query(":ACQ:SAMP? CH1"))
More information about the commitlog
mailing list