r4526 - developers/werner/ahrt/host/tmc

werner at docs.openmoko.org werner at docs.openmoko.org
Tue Jul 15 13:09:05 CEST 2008


Author: werner
Date: 2008-07-15 13:09:04 +0200 (Tue, 15 Jul 2008)
New Revision: 4526

Modified:
   developers/werner/ahrt/host/tmc/python.c
   developers/werner/ahrt/host/tmc/tmc.c
   developers/werner/ahrt/host/tmc/usbtmc.c
Log:
- usbtmc.c: added support for Rigol-specific protocol variations
- usbtmc.c (bulk_write): combined "dump", "usb_bulk_write", and error handling
  into a single function
- python.c (tmc_py_read): return string such that it can also contain NUL
  characters
- tmc.c (tmc_stop): pthread_join so that we race less when sending new
  commands
- tmc.c (launch): allow cancellation just before reading
- tmc.c (tmc_start): check if pthread_create fails



Modified: developers/werner/ahrt/host/tmc/python.c
===================================================================
--- developers/werner/ahrt/host/tmc/python.c	2008-07-14 12:10:43 UTC (rev 4525)
+++ developers/werner/ahrt/host/tmc/python.c	2008-07-15 11:09:04 UTC (rev 4526)
@@ -139,7 +139,7 @@
 static PyObject *tmc_py_read(PyObject *self, PyObject *noarg)
 {
 	struct py_instr *s = (struct py_instr *) self;
-	static char buf[BUF_SIZE+1];
+	static char buf[BUF_SIZE];
 	int len;
 
 //fprintf(stderr, "tmc_py_read\n");
@@ -152,8 +152,7 @@
 		ERROR;
 		return NULL;
 	}
-	buf[len] = 0;
-	return Py_BuildValue("s", buf);
+	return Py_BuildValue("s#", buf, len);
 }
 
 

Modified: developers/werner/ahrt/host/tmc/tmc.c
===================================================================
--- developers/werner/ahrt/host/tmc/tmc.c	2008-07-14 12:10:43 UTC (rev 4525)
+++ developers/werner/ahrt/host/tmc/tmc.c	2008-07-15 11:09:04 UTC (rev 4526)
@@ -96,6 +96,7 @@
 	struct tmc_dsc *dsc = arg;
 
 	while (1) {
+		pthread_testcancel();
 		if (dsc->ops->read(dsc->proto_dsc, io_push_async, dsc->io_dsc)
 		    < 0)
 			return NULL;
@@ -111,6 +112,8 @@
 
 int tmc_start(struct tmc_dsc *dsc, const char *file, const char *repeat)
 {
+	int err;
+
 	if (dsc->running) {
 		fprintf(stderr, "tmc_start: already running\n");
 		return -1;
@@ -128,7 +131,11 @@
 		}
 	}
 	dsc->running = 1;
-	pthread_create(&dsc->thread, NULL, launch, dsc);
+	err = pthread_create(&dsc->thread, NULL, launch, dsc);
+	if (err) {
+		fprintf(stderr, "pthread_create: %s\n", strerror(err));
+		return -1;
+	}
 	return 0;
 }
 
@@ -145,6 +152,10 @@
 	if (err) {
 		fprintf(stderr, "pthread_cancel: %s\n", strerror(err));
 	}
+	err = pthread_join(dsc->thread, NULL);
+	if (err) {
+		fprintf(stderr, "pthread_join: %s\n", strerror(err));
+	}
 	dsc->running = 0;
 	io_end_async(dsc->io_dsc);
 	free(dsc->repeat);

Modified: developers/werner/ahrt/host/tmc/usbtmc.c
===================================================================
--- developers/werner/ahrt/host/tmc/usbtmc.c	2008-07-14 12:10:43 UTC (rev 4525)
+++ developers/werner/ahrt/host/tmc/usbtmc.c	2008-07-15 11:09:04 UTC (rev 4526)
@@ -66,6 +66,7 @@
 	uint16_t max_packet;		/* maximum ep_bulk_in packet size */
 	unsigned long timeout;		/* timeout in milliseconds */
 	int retry;			/* retry after timeouts */
+	int rigol;			/* enable Rigol-specific hacks */
 	void *last_buf;			/* last buffer sent */
 	int last_len;
 };
@@ -103,7 +104,7 @@
 static void multiple_dev(void)
 {
 	fprintf(stderr,
-	    "multiple devices found. Please add more qualifiers\n");
+	    "multiple devices found. Please add more qualifiers.\n");
 }
 
 
@@ -213,11 +214,21 @@
 	const struct usb_config_descriptor *cfg;
 	const struct usb_interface *itf;
 	struct usb_interface_descriptor *alt;
+	int valid;
 
-	if (dev->descriptor.bDeviceClass ||
-	    dev->descriptor.bDeviceSubClass ||
-	    dev->descriptor.bDeviceProtocol)
-		return 0;
+	/* According to USB TMC spec */
+	valid = dev->descriptor.bDeviceClass == USB_CLASS_PER_INTERFACE &&
+	    !dev->descriptor.bDeviceSubClass &&
+	    !dev->descriptor.bDeviceProtocol;
+
+	/* According to Rigol Corp. */
+	valid |= dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
+	    dev->descriptor.bDeviceSubClass == 0xff &&
+	    dev->descriptor.bDeviceProtocol == 0xff;
+
+	if (!valid)
+	    return 0;
+
 	/* seems that libusb doesn't provide the Device_Qualifier
 	   descriptor, so we can't sanity-check that one */
 
@@ -402,7 +413,7 @@
 static void usage(void)
 {
 	fprintf(stderr,
-            "usage: \"usbtmc\" [, retry] [, timeout=N]\n"
+            "usage: \"usbtmc\" [, retry] [, rigol] [, timeout=N]\n"
             "       [, bus=N] [, device=N] [, vendor=N] [, product=N]\n");
 }
 
@@ -450,6 +461,8 @@
 			if (*end || !product || product > 0xffff)
 				goto usage;
 		}
+		else if (!strcmp(argv[i], "rigol"))
+			d->rigol = 1;
 		else goto usage;
 	}
 	if (open_usbtmc(d, vendor, product, bus, device) < 0)
@@ -481,13 +494,31 @@
 }
 
 
+static int bulk_write(void *dsc, const char *label, void *buf, int size)
+{
+	struct usbtmc_dsc *d = dsc;
+	int sent;
+
+	dump(label, buf, size);
+	sent = usb_bulk_write(d->handle, d->ep_bulk_out, buf, size, d->timeout);
+	if (sent < 0) {
+		fprintf(stderr, "write error %d\n", sent);
+		return -1;
+	}
+	if (sent != size) {
+		fprintf(stderr, "sent %d instead of %d bytes\n", sent,  size);
+		return -1;
+	}
+	return sent;
+}
+
+
 static int usbtmc_write(void *dsc, const void *buf, size_t len)
 {
 	struct usbtmc_dsc *d = dsc;
 	uint8_t tmp[SIZE_IOBUFFER];
 	char *msg;
 	size_t left, size, send_size;
-	ssize_t sent;
 
 	msg = malloc(len);
 	if (!msg) {
@@ -511,28 +542,28 @@
 		tmp[0] = DEV_DEP_MSG_OUT;
 		tmp[1] = d->bTag;
 		tmp[2] = ~d->bTag;
+		tmp[3] = 0;
 		tmp[4] = size;
 		tmp[5] = size >> 8;
 		tmp[6] = size >> 16;
 		tmp[7] = size >> 24;
 		tmp[9] = tmp[10] = tmp[11] = 0;
 
-		memcpy(tmp+12, msg, size);
-		msg += size;
+		if (!d->rigol) {
+			memcpy(tmp+12, msg, size);
+			msg += size;
 
-		send_size = 12+((size+3) & ~3);
+			send_size = 12+((size+3) & ~3);
 
-		dump("SEND: DEV_DEP_MSG_OUT", tmp, send_size);
-		sent = usb_bulk_write(d->handle, d->ep_bulk_out, (void *) tmp,
-		    send_size, d->timeout);
-		if (sent < 0) {
-			fprintf(stderr, "write error %d\n", (int) sent);
-			return -1;
+			if (bulk_write(d, "DEV_DEP_MSG_OUT", tmp, send_size)
+			    < 0)
+				return -1;
 		}
-		if (sent != send_size) {
-			fprintf(stderr, "sent %d instead of %d bytes\n",
-			    (int) sent, (int) send_size);
-			return -1;
+		else {
+			if (bulk_write(d, "SEND: DEV_DEP_MSG_OUT", tmp, 12) < 0)
+				return -1;
+			if (bulk_write(d, "SEND", msg, size) < 0)
+				return -1;
 		}
 	}
 	return 0;
@@ -544,7 +575,7 @@
 	struct usbtmc_dsc *d = dsc;
 	uint8_t tmp[SIZE_IOBUFFER];
 	size_t size;
-	ssize_t sent, got;
+	ssize_t got;
 	uint32_t payload;
 	struct timeval tv;
 	int end = 0;
@@ -557,28 +588,18 @@
 		tmp[0] = DEV_DEP_MSG_IN;
 		tmp[1] = d->bTag;
 		tmp[2] = ~d->bTag;
+		tmp[3] = 0;
 		tmp[4] = size;
 		tmp[5] = size >> 8;
 		tmp[6] = size >> 16;
 		tmp[7] = size >> 24;
 		tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0;
 
-		dump("SEND: DEV_DEP_MSG_IN", tmp, 12);
-		sent =
-		    usb_bulk_write(d->handle, d->ep_bulk_out, (void *) tmp, 12,
-		    d->timeout);
-		if (sent < 0) {
-			fprintf(stderr, "write error %d\n", (int) sent);
+		if (bulk_write(d, "SEND: DEV_DEP_MSG_IN", tmp, 12) < 0)
 			return -1;
-		}
-		if (sent != 12) {
-			fprintf(stderr, "sent %d instead of 12 bytes\n",
-			    (int) sent);
-			return -1;
-		}
 
 		got = usb_bulk_read(d->handle, d->ep_bulk_in, (void *) tmp,
-		    size, d->timeout);
+		    d->rigol ? 64 : size, d->timeout);
 		if (got < 0) {
 			usbtmc_abort_in(d);
 			fprintf(stderr, "read error %d\n", (int) got);
@@ -645,6 +666,12 @@
 			return -1;
 		}
 
+		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);
+		}
+
 		end = tmp[8] & 1;
 		push(push_dsc, &tv, tmp+12, payload, end);
 	}
@@ -665,7 +692,10 @@
 	if (debug)
 		fprintf(stderr, "DCI\n");
 	//usbtmc_clear(d);
-	usbtmc_abort_in(d);
+	if (d->rigol)
+		usb_reset(d->handle);
+	else
+		usbtmc_abort_in(d);
 	//usbtmc_abort_out(d);
 	return 0;
 }





More information about the commitlog mailing list