Index: trunk/software/tty/readtty_power.c
===================================================================
--- trunk/software/tty/readtty_power.c	(revision 8)
+++ trunk/software/tty/readtty_power.c	(revision 12)
@@ -2,9 +2,12 @@
 #include <stdlib.h>
 #include <unistd.h>
+#include <string.h>
 #include <errno.h>
+#include <err.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <termios.h>
 #include <sys/ioctl.h>
+#include <sys/select.h>
 
 struct scale {
@@ -13,16 +16,9 @@
 };
 
-const struct scale *current_scale = NULL;
-const struct scale *voltage_scale = NULL;
+struct scale current_scale;
+struct scale voltage_scale;
 float current_r = 0;
 
-const struct scale current_scale_1 = {3851, 0.5367};
-const float current_r_1 = 0.2;
-const struct scale current_scale_2 = {3651, 0.9761};
-const float current_r_2 = 0.1;
-// const float current_r_3 = 0.05;
-const struct scale voltage_scale_1 = {4041.5, 5.996};
-const struct scale voltage_scale_2 = {4063.5, 13.547};
-const struct scale voltage_scale_3 = {4038, 23.672};
+const float current_ra[] = {0.2, 0.1, 0.05, 0.02};
 
 volatile int quit;
@@ -38,6 +34,58 @@
 usage()
 {
-	errx(1, "usage: %s -c [1|2] -v [1|2|3] <device>", prog);
-}
+	errx(1, "usage: %s -c[1|2|3|4] -v[1|2|3] [-n] <device>", prog);
+}
+
+static void
+get_cal_data(const char *b, int ci, int vi)
+{
+	int cr[4], vr[3];
+	float ca[4], vv[3];
+	int ret;
+
+	ret = sscanf(b, "cal_data %d %f %d %f %d %f %d %f %d %f %d %f %d %f",
+	    &cr[0], &ca[0], &cr[1], &ca[1], &cr[2], &ca[2], &cr[3], &ca[3],
+	    &vr[0], &vv[0], &vr[1], &vv[1], &vr[2], &vv[2]);
+	if (ret != 14) {
+		errx(1, "cal_data: converted only %d\n", ret);
+	}
+	for (int i = 0; i < 4; i++) {
+		printf("cr %d ca %f\n", cr[i], ca[i]);
+	}
+	for (int i = 0; i < 3; i++) {
+		printf("vr %d vv %f\n", vr[i], vv[i]);
+	}
+	current_scale.read = cr[ci - 1];
+	current_scale.result = ca[ci - 1];
+	voltage_scale.read = vr[vi - 1];
+	voltage_scale.result = vv[vi - 1];
+}
+
+static void
+readline(int d, char *buf, int l)
+{
+	int i;
+	int bytes;
+	do {
+		for (i = 0; i < l; i++) {
+			do {
+				bytes = read(d, &buf[i], 1);
+				if (quit)
+					return;
+			} while ((bytes < 0 && errno == EAGAIN) || buf[i] == '\r');
+			if (bytes != 1) {
+				fprintf(stderr, "readline: read %d\n", bytes);
+				err(1, "read line");
+			}
+			if (buf[i] == '\n')
+				break;
+		}
+	} while (i == 0);
+	if (buf[i] != '\n') {
+		warnx("realine: end of line not found");
+	}
+	buf[i] = '\0';
+}
+
 int
 main(int argc, char * const argv[])
@@ -46,12 +94,15 @@
 	int bytes;
 	int nfds;
+	int lineno = 0;
+	int nopt = 0;
 	char buf[256];
 	int i;
 	fd_set rfds;
-	char gpio[2], current[4], tension[4];
+	char gpio[3], current[4], tension[4];
 	char *endp;
-	int currenti, tensioni;
+	int gpioi, currenti, tensioni;
 	float current_a, tension_v;
-	int val;
+	int val, gpio_val;
+	int c_opt = 0, v_opt = 0;
         extern char *optarg;
 	extern int optind;
@@ -69,27 +120,21 @@
 	prog = argv[0];
 	state = INIT;
-	currenti = tensioni = 0;
-
-	while ((ch = getopt(argc, argv, "c:v:")) != -1) {
+	gpioi = currenti = tensioni = 0;
+
+	while ((ch = getopt(argc, argv, "np:c:v:")) != -1) {
 		switch (ch) {
+		case 'n':
+			nopt = 1;
+			break;
 		case 'c':
-			val = atoi(optarg);
-			if (val == 1) {	
-				current_scale = &current_scale_1;
-				current_r = current_r_1;
-			} else if (val == 2) {
-				current_scale = &current_scale_2;
-				current_r = current_r_2;
-			}
+			c_opt = atoi(optarg);
+			if (c_opt < 1 || c_opt > 4)
+				usage();
+			current_r = current_ra[c_opt  -1];
 			break;
 		case 'v':
-			val = atoi(optarg);
-			if (val == 1) {	
-				voltage_scale = &voltage_scale_1;
-			} else if (val == 2) {
-				voltage_scale = &voltage_scale_2;
-			} else if (val == 3) {
-				voltage_scale = &voltage_scale_3;
-			}
+			v_opt = atoi(optarg);
+			if (v_opt < 1 || v_opt > 3)
+				usage();
 			break;
 		default: 
@@ -100,5 +145,5 @@
 	argv += optind;
 
-	if (argc != 1 || current_scale == NULL || voltage_scale == NULL) 
+	if (argc != 1 || c_opt == 0 || v_opt == 0) 
 		usage();
 
@@ -139,4 +184,22 @@
 	}
 	fprintf(stderr, "tty ready\n");
+	do {
+		write(d, "M0\n", 3);
+		readline(d, buf, sizeof(buf));
+		if (quit)
+			goto quit;
+	} while (memcmp(buf, "OK", 2) != 0);
+	write(d, "C\n", 2);
+	readline(d, buf, sizeof(buf));
+	if (quit)
+		goto quit;
+	printf("cal_data: %s\n", buf);
+	get_cal_data(buf, c_opt, v_opt);
+	printf("cal_data selected: %f %f, %f %f\n",
+	    current_scale.read, current_scale.result,
+	    voltage_scale.read, voltage_scale.result);
+
+	/* start measures */
+	write(d, "M1\n", 3);
 	FD_ZERO(&rfds);
 	while (quit == 0) {
@@ -152,11 +215,16 @@
 				case INIT:
 					/* look for an X mark */
-					if (buf[i] == 'X')
+					if (buf[i] == 'X') {
 						state = GPIO;
+						gpioi = 0;
+					}
 					break;
 				case GPIO:
-					gpio[0] = buf[i];
-					gpio[1] = '\0';
-					val = strtol(gpio, &endp, 16);
+					gpio[gpioi] = buf[i];
+					gpioi++;
+					if (gpioi < 2)
+						break;
+					gpio[gpioi] = '\0';
+					gpio_val = strtol(gpio, &endp, 16);
 					if (*endp != '\0') {
 						fprintf(stderr,
@@ -167,5 +235,4 @@
 						state = TENSION;
 						tensioni = 0;
-						printf("%2d ", val);
 					}
 					break;
@@ -189,10 +256,16 @@
 						}
 						state = MARK;
-						current_a = val / current_scale->read * current_scale->result;
-						printf("%8f ", current_a);
+						current_a = val / current_scale.read * current_scale.result;
 						/* correct for in our resistor */
 						tension_v -= current_a * current_r;
-						printf("%8f ", tension_v);
-						printf("%8f\n", current_a * tension_v);
+						if (nopt) {
+							printf("%8f ", (float)lineno / 5000);
+							lineno++;
+						}
+						printf("%3d %8f %8f %8f\n",
+						    gpio_val,
+						    current_a,
+						    tension_v,
+						    current_a * tension_v);
 					}
 					break;
@@ -217,5 +290,5 @@
 						state = CURRENT;
 						currenti = 0;
-						tension_v = val / voltage_scale->read * voltage_scale->result;
+						tension_v = val / voltage_scale.read * voltage_scale.result;
 					}
 					break;
@@ -228,4 +301,5 @@
 					} else {
 						state = GPIO;
+						gpioi = 0;
 					}
 					break;
@@ -236,4 +310,10 @@
 		}
 	}
+quit:
+	/* stop measures */
+	write(d, "M0\n", 3);
+	if (fflush(stdout) == EOF) {
+		warn("fflush");
+	}
 	if (tcsetattr(d, TCSANOW, &ot) < 0) {
 		err(1, "restore tcsetattr");
@@ -241,4 +321,2 @@
 	exit(0);
 }
-
-
