r4608 - in developers/werner/ahrt/host/tmc: . lib

werner at docs.openmoko.org werner at docs.openmoko.org
Mon Aug 25 20:51:26 CEST 2008


Author: werner
Date: 2008-08-25 20:51:26 +0200 (Mon, 25 Aug 2008)
New Revision: 4608

Modified:
   developers/werner/ahrt/host/tmc/lib/instrument.py
   developers/werner/ahrt/host/tmc/lib/scope.py
   developers/werner/ahrt/host/tmc/lib/wave.py
   developers/werner/ahrt/host/tmc/python.c
   developers/werner/ahrt/host/tmc/usbtmc.c
Log:
This mainly adds the long-awaited screendump functionality. Also fixes
two serious bugs, namely an off-by-twelve error in Rigol USB TMC read
function and caching converted instead of unconverted values in
settings, which broke larger scripts.

- lib/wave.py: added "extend" method for all waves
- lib/scope.py: started support for piecewise wave retrieval (doesn't work yet)
- lib/instrument.py (setting.set): store the value being set, not the one
  converted for the instrument
- usbtmc.c, python.c: increased SIZE_IOBUFFER from 4kB to 1MB and BUF_SIZE
  from 8kB to 1MB, to accommodate Rigol screen dumps
- usbtmc.c: added pointer to rew's Rigol driver
- lib/scope.py: new method "screendump"
- usbtmc.c (usbtmc_read): Rigol buffer reads were off by 12 bytes
- lib/scope.py (rigol_channel_data, rigol_la_data): added 12 to offsets and
  corrected off-by-two error in analog wave offset



Modified: developers/werner/ahrt/host/tmc/lib/instrument.py
===================================================================
--- developers/werner/ahrt/host/tmc/lib/instrument.py	2008-08-25 18:40:25 UTC (rev 4607)
+++ developers/werner/ahrt/host/tmc/lib/instrument.py	2008-08-25 18:51:26 UTC (rev 4608)
@@ -38,13 +38,13 @@
 	if value is None:
 	    self.value = None
 	elif value != self.value:
+	    self.value = value
 	    if self.out_convert:
 		value = self.out_convert(value)
 		if value is None:
 		    raise hell
 	    self.instr.send((self.set_cmd, self.path)[self.set_cmd is None]+
 	      " "+self.args+str(value))
-	    self.value = value
 
 
 class settable(object):

Modified: developers/werner/ahrt/host/tmc/lib/scope.py
===================================================================
--- developers/werner/ahrt/host/tmc/lib/scope.py	2008-08-25 18:40:25 UTC (rev 4607)
+++ developers/werner/ahrt/host/tmc/lib/scope.py	2008-08-25 18:51:26 UTC (rev 4608)
@@ -3,6 +3,9 @@
 # scope.py - Oscilloscope control
 # 
 
+# Found screen dump algorithm here:
+# http://www.circuitsonline.net/forum/view/message/652573#652573
+
 #
 # Our oscilloscope model consists of three elements:
 #
@@ -19,7 +22,8 @@
 # horizontal system only accepts some frequencies
 # TODO: make range configurable
 
-def scale_125(n, fuzz):
+def scale_125(n = None, fuzz = None, min = None, max = None):
+    res = None
     for e in range(-9, 1+1):
 	for m in [1, 2, 5]:
 	    if e < 0:
@@ -27,8 +31,15 @@
 	    else:
 		s = str(m)+"0"*e
 	    r = float(s)
-	    if r >= n*(1-fuzz) and r <= n*(1+fuzz):
+	    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:
+		return s
+	    if max is not None and r <= max:
+		res = s
+    if res is not None:
+	return res
+    raise hell
 
 
 # TODO: figure out what to do with signals. should they be objects in their
@@ -96,7 +107,38 @@
 
 
     def wave(self, start = None, end = None, step = None):
-	return self.scope.download_wave(self, start, end, step)
+	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
 
 
 # === horizontal ==============================================================
@@ -196,9 +238,9 @@
 
 def rigol_channel_data(s, t0, td, v0, vd):
     res = analog_wave()
-    i = 202
-    while i != 800:
-	div = (i-502)/50.0
+    i = 212
+    while i != 812:
+	div = (i-512)/50.0
 	t = t0+div*td
 	div = (125-ord(s[i]))/25.0
 	v = v0+div*vd
@@ -211,9 +253,9 @@
     res = []
     for b in range(0, 16):
 	res.append(digital_wave())
-    i = 412 
-    while i != 1612:
-	div = (i-1012)/100.0
+    i = 424
+    while i != 1624:
+	div = (i-1024)/100.0
 	t = t0+div*td
 	for b in range(0, 8):
 	    res[b].append(t, (ord(s[i]) & (1 << b)) != 0)
@@ -222,10 +264,25 @@
     return res
 
 
+def rigol_to_ppm(s):
+    lut = []
+    i = 0
+    while i != 256:
+	lut.append(chr(i & 0xc0)+chr((i & 0x38) << 2)+chr((i & 3) << 5))
+	i += 1
+    res = "P6 320 234 255\n"
+    i = 0
+    while i != 320*234:
+	res += lut[ord(s[i])]
+	i += 1
+    return res
+
+
 class rigol_ds1000c(scope):
     channels = 2
     div_hor = 12
     div_vert = 10
+    samples_per_div = 600	#@@@ not exactly true. needs more investigation
 
     def __init__(self):
 	scope.__init__(self, "usbtmc", "rigol", "timeout=2", "retry",
@@ -273,3 +330,10 @@
     def download_la(self):
 	data = self.query(":WAV:DATA? DIG")
 	return rigol_la_data(data, self.hor.pos, self.hor.scale)
+
+    def sampling_rate(self):
+	return float(self.query(":ACQ:SAMP? CH1"))
+
+    def screendump(self):
+	self.send(":HARDCOPY")
+	return rigol_to_ppm(self.query(":LCD:DATA?"))

Modified: developers/werner/ahrt/host/tmc/lib/wave.py
===================================================================
--- developers/werner/ahrt/host/tmc/lib/wave.py	2008-08-25 18:40:25 UTC (rev 4607)
+++ developers/werner/ahrt/host/tmc/lib/wave.py	2008-08-25 18:51:26 UTC (rev 4608)
@@ -111,6 +111,12 @@
 	    raise hell
 	self.data.append((t, y))
 
+    def extend(self, wave):
+	if len(self.data) and len(wave.data) and \
+	  wave.data[0][0] < self.data[-1][0]:
+	    raise hell
+	self.data.extend(wave.data)
+
     def get_one(self, t):
 	if len(self.data) == 0 or t < self.data[0][0] or t > self.data[-1][0]:
 	    raise hell
@@ -153,7 +159,6 @@
     def __init__(self):
 	self.initial = None
 	self.data = []
-	self.cursor = None
 	self.t_end = None
 
     def start(self):
@@ -173,6 +178,22 @@
 	    self.data.append(t)
 	self.t_end = t
 
+    def extend(self, wave):
+	if wave.t_end is None:
+	    return
+	if self.t_end is None:
+	    self.t_end = wave.t_end
+	    self.data = wave.data
+	    self.initial = wave.initial
+	    return
+	if wave.data[0] < self.t_end:
+	    raise hell
+	if self.initial ^ (len(self.data) & 1) == wave.initial:
+	    self.data.extend(wave.data)
+	else:
+	    self.data.extend(wave.data[1:])
+	self.t_end = wave.t_end
+
     def get_one(self, t):
 	if len(self.data) == 0 or t < self.data[0] or t > self.t_end:
 	    raise hell

Modified: developers/werner/ahrt/host/tmc/python.c
===================================================================
--- developers/werner/ahrt/host/tmc/python.c	2008-08-25 18:40:25 UTC (rev 4607)
+++ developers/werner/ahrt/host/tmc/python.c	2008-08-25 18:51:26 UTC (rev 4608)
@@ -17,7 +17,7 @@
 #include "tmc.h"
 
 
-#define BUF_SIZE 8192
+#define BUF_SIZE (1024*1024)
 #define ERROR fprintf(stderr, "ERROR %d\n", __LINE__)
 	/* @@@FIXME: raise exceptions */
 

Modified: developers/werner/ahrt/host/tmc/usbtmc.c
===================================================================
--- developers/werner/ahrt/host/tmc/usbtmc.c	2008-08-25 18:40:25 UTC (rev 4607)
+++ developers/werner/ahrt/host/tmc/usbtmc.c	2008-08-25 18:51:26 UTC (rev 4608)
@@ -14,6 +14,9 @@
  * Based on the Agilent USBTMC kernel driver by Stefan Kopp:
  * http://www.home.agilent.com/upload/cmc_upload/All/usbtmc.html
  * http://www.home.agilent.com/upload/cmc_upload/All/usbtmc.tar
+ *
+ * The Rigol protocol variant is based on this driver:
+ * http://www.circuitsonline.net/forum/view/message/652371#652371
  */
 
 
@@ -42,7 +45,7 @@
 #define USB_PROTOCOL_USB488 1
 #endif
 
-#define SIZE_IOBUFFER 4096
+#define SIZE_IOBUFFER (1024*1024)	/* memory is cheap ;-) */
 
 #define DEV_DEP_MSG_OUT			1
 #define DEV_DEP_MSG_IN			2
@@ -668,8 +671,8 @@
 
 		if (d->rigol && payload > 64-12) {
 			got = usb_bulk_read(d->handle, d->ep_bulk_in,
-			    (void *) tmp+64-12, payload-12, d->timeout);
-			dump("RECV", tmp+64-12, got);
+			    (void *) tmp+64, payload-(64-12), d->timeout);
+			dump("RECV", tmp+64, got);
 		}
 
 		end = tmp[8] & 1;




More information about the commitlog mailing list