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