From 9119cd5cdf61de2ac195e908a75366bdda138d80 Mon Sep 17 00:00:00 2001 From: nilm Date: Wed, 14 Oct 2009 21:35:50 +0000 Subject: [PATCH] Fix various bugs git-svn-id: https://bucket.mit.edu/svn/nilm/zoom@7988 ddd99763-3ecb-0310-9145-efcb8ce7c51f --- pc/dctest.c | 67 ++++++++++++++++++++++++++++++++---------------- pc/serial-util.c | 6 ++--- pc/serial-util.h | 7 ++++- pc/zoom.c | 2 +- 4 files changed, 55 insertions(+), 27 deletions(-) diff --git a/pc/dctest.c b/pc/dctest.c index 5fcbd7a..def8782 100644 --- a/pc/dctest.c +++ b/pc/dctest.c @@ -97,7 +97,6 @@ int main(int argc, char *argv[]) } struct keithley_t { - pthread_mutex_t mutex; double desired; double actual; int stable; @@ -106,6 +105,7 @@ struct keithley_t { struct threadinfo_t { int quit_flag; int fd; + pthread_mutex_t mutex; float calibration; struct keithley_t k; }; @@ -116,6 +116,7 @@ int process_adc_dac(const uint8_t *buf, struct threadinfo_t *ti) int16_t adc; int overflow; double idesired, iactual; + double calib; int stable; /* data OK? */ @@ -134,19 +135,20 @@ int process_adc_dac(const uint8_t *buf, struct threadinfo_t *ti) dac = (buf[2] << 8) | buf[3]; - /* get keithley data */ - pthread_mutex_lock(&ti->k.mutex); + /* get locked data */ + pthread_mutex_lock(&ti->mutex); idesired = ti->k.desired; iactual = ti->k.actual; stable = ti->k.stable; - pthread_mutex_unlock(&ti->k.mutex); + calib = ti->calibration; + pthread_mutex_unlock(&ti->mutex); /* write it out */ - printf("%d %.8f %.8f %.8f %5d %5d %d\n", + printf("%d %.15f %.15f %.8f %5d %5d %d\n", stable, idesired, iactual, - ti->calibration, + calib, dac, adc, overflow); @@ -157,8 +159,10 @@ int process_adc_dac(const uint8_t *buf, struct threadinfo_t *ti) static int process_calibration(const uint8_t *buf, struct threadinfo_t *ti) { float f = *(float *)buf; + pthread_mutex_lock(&ti->mutex); ti->calibration = f; - info("new calibration value: %.8f\n", ti->calibration); + pthread_mutex_unlock(&ti->mutex); + info("New calibration value: %.8f\n", f); return 1; } @@ -221,14 +225,14 @@ static void *read_data(void *arg) } /* change keithley and update keithley_t structure with locking */ -static int keithley_change(int gpib, double desired, struct keithley_t *k) +static int keithley_change(int gpib, double desired, struct threadinfo_t *ti) { double actual; - pthread_mutex_lock(&k->mutex); - k->stable = 0; - k->desired = desired; - pthread_mutex_unlock(&k->mutex); + pthread_mutex_lock(&ti->mutex); + ti->k.stable = 0; + ti->k.desired = desired; + pthread_mutex_unlock(&ti->mutex); if (keithley_current(gpib, desired) < 0) return -1; @@ -237,9 +241,10 @@ static int keithley_change(int gpib, double desired, struct keithley_t *k) if (isnan(actual)) return -1; - pthread_mutex_lock(&k->mutex); - k->actual = actual; - pthread_mutex_unlock(&k->mutex); + pthread_mutex_lock(&ti->mutex); + ti->k.actual = actual; + ti->k.stable = 1; + pthread_mutex_unlock(&ti->mutex); return 0; } @@ -247,11 +252,13 @@ static void dctest(int zoom, int gpib) { pthread_t thread; struct threadinfo_t ti; - + double tmp; + int i; + /* Do a calibration with Keithley off */ info("Triggering calibration\n"); zoomrun_trigger_calibrate(zoom); - usleep(1000000); + usleep(500000); /* Init Keithley */ info("Initializing GPIB\n"); @@ -265,27 +272,43 @@ static void dctest(int zoom, int gpib) /* Start the thread that reads and dumps data */ info("Spawning thread\n"); - if (pthread_mutex_init(&ti.k.mutex, NULL) != 0) { + if (pthread_mutex_init(&ti.mutex, NULL) != 0) { info("failed\n"); goto out2; } - ti.calibration = 1.0; + ti.calibration = 0.0; ti.k.desired = 0; ti.k.actual = 0; ti.k.stable = 0; ti.quit_flag = 0; ti.fd = zoom; + drain_timeout(zoom, 0); if (pthread_create(&thread, NULL, read_data, &ti) != 0) { info("failed\n"); goto out2; } - /* Do another calibration now */ + /* Do another calibration now, and verify it works */ info("Triggering calibration\n"); - if (keithley_change(gpib, 0.0, &ti.k) < 0) { info("failed\n"); goto out3; } + pthread_mutex_lock(&ti.mutex); + ti.calibration = 0.0; + pthread_mutex_unlock(&ti.mutex); + if (keithley_change(gpib, 0.0, &ti) < 0) { info("failed\n"); goto out3; } zoomrun_trigger_calibrate(zoom); - usleep(1000000); + for (i = 0; i < 100; i++) { + usleep(50000); + pthread_mutex_lock(&ti.mutex); + tmp = ti.calibration; + pthread_mutex_unlock(&ti.mutex); + if (tmp != 0.0) + break; + } + if (tmp == 0.0) { + info("Invalid calibration data: is zoom NILM working?\n"); + goto out3; + } + info("Running\n"); /* Change Keithley values */ while (!g_quit) { sleep(1); diff --git a/pc/serial-util.c b/pc/serial-util.c index 6d14ce1..60da6ae 100644 --- a/pc/serial-util.c +++ b/pc/serial-util.c @@ -135,13 +135,13 @@ ssize_t safewrite(int fd, const void *buf, size_t count) return nwritten; } -/* Read bytes until no more are available for 0.1 sec */ -int drain(int fd) +/* Read bytes until no more are available for specified time */ +int drain_timeout(int fd, int msec) { char buf[1024]; int ret; while (1) { - ret = saferead_timeout(fd, buf, sizeof(buf), 100); + ret = saferead_timeout(fd, buf, sizeof(buf), msec); if (ret <= 0) return ret; } diff --git a/pc/serial-util.h b/pc/serial-util.h index 6dafcd0..e254b24 100644 --- a/pc/serial-util.h +++ b/pc/serial-util.h @@ -23,8 +23,13 @@ static inline int saferead(int fd, void *buf, size_t count) { /* Like write(), but restarts after EINTR */ ssize_t safewrite(int fd, const void *buf, size_t count); +/* Read bytes until no more are available for specified time */ +int drain_timeout(int fd, int msec); + /* Read bytes until no more are available for 0.1 sec */ -int drain(int fd); +static inline int drain(int fd) { + return drain_timeout(fd, 100); +} /* Like fprintf, but to a fd, using safewrite */ int fdprintf(int fd, const char *fmt, ...); diff --git a/pc/zoom.c b/pc/zoom.c index c401c51..40b4c28 100644 --- a/pc/zoom.c +++ b/pc/zoom.c @@ -84,5 +84,5 @@ void zoomrun_trigger_calibrate(int fd) { char c = 'c'; write(fd, &c, 1); - drain(fd); + drain_timeout(fd, 0); }