|
|
@@ -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); |
|
|
|