rid of global variables as I go.
LDFLAGS += -L../lib/ -lcomedi -lm
-BINS=comedi_calibrate
-objs = comedi_calibrate.o ni.o
+BINS = comedi_calibrate
+objs = comedi_calibrate.o ni.o cb.o
all: $(BINS)
double target;
}observable;
+typedef struct calibration_setup_struct calibration_setup;
+struct calibration_setup_struct {
+ int status;
+ observable *observables;
+ unsigned int n_observables;
+ caldac *caldacs;
+ unsigned int n_caldacs;
+ int (*do_cal) ( calibration_setup *setup );
+};
+
extern caldac caldacs[N_CALDACS];
extern int n_caldacs;
void preobserve(int obs);
void observable_dependence(int obs);
void measure_observable(int obs);
-void reset_caldacs(void);
+void reset_caldacs( const calibration_setup *setup);
/* drivers */
extern char ni_id[];
+extern char cb_id[];
-int ni_setup(void);
+int ni_setup( calibration_setup*, const char *device_name );
+int cb_setup( calibration_setup*, const char *device_name );
/* low level */
void set_target(int obs,double target);
-void update_caldac(int i);
+void update_caldac( caldac );
void setup_caldacs(void);
void postgain_cal(int obs1, int obs2, int dac);
void cal1(int obs, int dac);
--- /dev/null
+/***************************************************************************
+ cb.c - calibration support for some Measurement computing boards.
+ Based on ni.c by David Schleef.
+ -------------------
+
+ begin : Sat Apr 27 2002
+ copyright : (C) 2002 by Frank Mori Hess
+ email : fmhess@users.sourceforge.net
+
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <comedilib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "calib.h"
+
+
+char cb_id[] = "$Id$";
+
+struct board_struct{
+ char *name;
+ int status;
+ int (*setup)( calibration_setup *setup );
+};
+
+int cb_setup_board(void);
+void cb_setup_observables(void);
+
+int setup_cb_pci_64xx( calibration_setup *setup );
+int setup_cb_pci_60xx( calibration_setup *setup );
+int setup_cb_pci_4020( calibration_setup *setup );
+
+int cal_cb_pci_64xx( calibration_setup *setup );
+int cal_cb_pci_60xx( calibration_setup *setup );
+int cal_cb_pci_4020( calibration_setup *setup );
+
+int init_observables_64xx( calibration_setup *setup );
+int init_observables_60xx( calibration_setup *setup );
+int init_observables_4020( calibration_setup *setup );
+
+static struct board_struct boards[]={
+ { "pci-das6402/16", STATUS_DONE, setup_cb_pci_64xx },
+ { "pci-das6402/12", STATUS_GUESS, setup_cb_pci_64xx },
+ { "pci-das64/m1/16", STATUS_GUESS, setup_cb_pci_64xx },
+ { "pci-das64/m2/16", STATUS_GUESS, setup_cb_pci_64xx },
+ { "pci-das64/m3/16", STATUS_GUESS, setup_cb_pci_64xx },
+ { "pci-das6025", STATUS_DONE, setup_cb_pci_60xx },
+ { "pci-das6034", STATUS_GUESS, setup_cb_pci_60xx },
+ { "pci-das6035", STATUS_GUESS, setup_cb_pci_60xx },
+ { "pci-das4020/12", STATUS_DONE, setup_cb_pci_4020 },
+};
+
+static const int num_boards = ( sizeof(boards) / sizeof(boards[0]) );
+
+enum {
+ cb_zero_offset_low = 0,
+ cb_zero_offset_high,
+ cb_reference_low,
+ cb_unip_offset_low,
+ cb_ao0_zero_offset,
+ cb_ao0_reference,
+ cb_ao1_zero_offset,
+ cb_ao1_reference,
+};
+
+int cb_setup( calibration_setup *setup, const char *device_name )
+{
+ unsigned int i;
+
+ for( i = 0; i < num_boards; i++ )
+ {
+ if( !strcmp( devicename, boards[i].name ) )
+ {
+ return boards[i].setup( setup );
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int setup_cb_pci_64xx( calibration_setup *setup )
+{
+ init_observables_64xx( setup );
+ setup->do_cal = cal_cb_pci_64xx;
+ return 0;
+}
+
+int setup_cb_pci_60xx( calibration_setup *setup )
+{
+ init_observables_60xx( setup );
+ setup->do_cal = cal_cb_pci_60xx;
+ return 0;
+}
+
+int setup_cb_pci_4020( calibration_setup *setup )
+{
+ init_observables_4020( setup );
+ setup->do_cal = cal_cb_pci_60xx;
+ return 0;
+}
+
+int init_observables_64xx( calibration_setup *setup )
+{
+ return 0;
+}
+
+int init_observables_60xx( calibration_setup *setup )
+{
+ return 0;
+}
+
+int init_observables_4020( calibration_setup *setup )
+{
+ return 0;
+}
+
+int cal_cb_pci_64xx( calibration_setup *setup )
+{
+ return 0;
+}
+
+int cal_cb_pci_60xx( calibration_setup *setup )
+{
+ return 0;
+}
+
+int cal_cb_pci_4020( calibration_setup *setup )
+{
+ return 0;
+}
+
struct board_struct{
char *name;
char *id;
- int (*setup)(void);
+ int (*setup)( calibration_setup *setup, const char *device_name );
};
struct board_struct drivers[] = {
{ "ni_pcimio", ni_id, ni_setup },
{ "ni_atmio", ni_id, ni_setup },
{ "ni_mio_cs", ni_id, ni_setup },
+ { "cb_pcidas64", cb_id, cb_setup },
};
#define n_drivers (sizeof(drivers)/sizeof(drivers[0]))
struct board_struct *this_board;
int index;
int device_status = STATUS_UNKNOWN;
-
+ calibration_setup setup;
fn = "/dev/comedi0";
while (1) {
return 1;
ok:
- device_status = this_board->setup();
+ memset( &setup, 0, sizeof( setup ) );
+ this_board->setup( &setup, devicename );
+ device_status = setup.status;
if(device_status<STATUS_DONE){
printf("Warning: device not fully calibrated due to insufficient information\n");
(comedi_get_version_code(dev))&0xff);
}
- if(do_reset)reset_caldacs();
- if(do_dump)observe();
- if(do_calibrate && do_cal)do_cal();
- if(do_results)observe();
+ if(do_reset)reset_caldacs( &setup );
+ if(do_dump) observe();
+ if(do_calibrate && do_cal) setup.do_cal( &setup );
+ if(do_results) observe();
return 0;
}
a=caldacs[dac].current-a;
caldacs[dac].current=rint(a);
- update_caldac(dac);
+ update_caldac( caldacs[dac] );
usleep(100000);
DPRINT(0,"caldac[%d] set to %g (%g)\n",dac,rint(a),a);
a=linear_fit_func_x(&l,observables[obs].target);
caldacs[dac].current=rint(a);
- update_caldac(dac);
+ update_caldac( caldacs[dac] );
usleep(100000);
DPRINT(0,"caldac[%d] set to %g (%g)\n",dac,rint(a),a);
a=linear_fit_func_x(&l,observables[obs].target);
caldacs[dac].current=rint(a);
- update_caldac(dac);
+ update_caldac( caldacs[dac] );
usleep(100000);
DPRINT(0,"caldac[%d] set to %g (%g)\n",dac,rint(a),a);
n_caldacs=n_chan;
}
-void reset_caldacs(void)
+void reset_caldacs( const calibration_setup *setup )
{
int i;
- for(i=0;i<n_caldacs;i++){
- caldacs[i].current=caldacs[i].maxdata/2;
- update_caldac(i);
+ for( i = 0; i < setup->n_caldacs; i++){
+ setup->caldacs[i].current = setup->caldacs[i].maxdata / 2;
+ update_caldac( setup->caldacs[i] );
}
}
-void update_caldac(int i)
+void update_caldac( caldac dac )
{
int ret;
-
- DPRINT(4,"update %d %d %d\n",caldacs[i].subdev,caldacs[i].chan,caldacs[i].current);
- if(caldacs[i].current<0){
- DPRINT(1,"caldac set out of range (%d<0)\n",caldacs[i].current);
- caldacs[i].current=0;
+
+ DPRINT(4,"update %d %d %d\n", dac.subdev, dac.chan, dac.current);
+ if( dac.current < 0 ){
+ DPRINT(1,"caldac set out of range (%d<0)\n", dac.current);
+ dac.current = 0;
}
- if(caldacs[i].current>caldacs[i].maxdata){
+ if( dac.current > dac.maxdata ){
DPRINT(1,"caldac set out of range (%d>%d)\n",
- caldacs[i].current,caldacs[i].maxdata);
- caldacs[i].current=caldacs[i].maxdata;
+ dac.current, dac.maxdata);
+ dac.current = dac.maxdata;
}
- ret = comedi_data_write(dev,caldacs[i].subdev,caldacs[i].chan,0,0,
- caldacs[i].current);
- if(ret<0)perror("update_caldac()");
+ ret = comedi_data_write(dev, dac.subdev, dac.chan, 0, 0,
+ dac.current);
+ if(ret < 0) perror("update_caldac()");
}
#if 0
sv.cr_flags = CR_ALT_FILTER | CR_ALT_SOURCE;
caldacs[cdac].current=0;
- update_caldac(cdac);
+ update_caldac( caldacs[cdac] );
usleep(100000);
new_sv_measure(&sv);
sum_err=0;
for(i=0;i*step<n;i++){
caldacs[cdac].current=i*step;
- update_caldac(cdac);
+ update_caldac( caldacs[cdac] );
//usleep(100000);
new_sv_measure(&sv);
}
caldacs[cdac].current=orig;
- update_caldac(cdac);
+ update_caldac( caldacs[cdac] );
l->yerr=sum_err/sum_err_count;
l->dx=step;
sv.cr_flags = CR_ALT_FILTER | CR_ALT_SOURCE;
caldacs[cdac].current=0;
- update_caldac(cdac);
+ update_caldac( caldacs[cdac] );
usleep(100000);
new_sv_measure(&sv);
sum_err=0;
for(i=0;i<n;i++){
caldacs[cdac].current=i+orig-fine_size;
- update_caldac(cdac);
+ update_caldac( caldacs[cdac] );
usleep(100000);
new_sv_measure(&sv);
}
caldacs[cdac].current=orig;
- update_caldac(cdac);
+ update_caldac( caldacs[cdac] );
l->yerr=sum_err/sum_err_count;
l->dx=1;
struct board_struct{
char *name;
int status;
- void (*cal)(void);
+ int (*cal)( calibration_setup *setup);
};
-int ni_setup_board(void);
+int ni_setup_board( calibration_setup *setup , const char *device_name );
void ni_setup_observables(void);
-void cal_ni_at_mio_16e_2(void);
-void cal_ni_daqcard_ai_16xe_50(void);
-void cal_ni_at_mio_16e_1(void);
-void cal_ni_pci_mio_16e_1(void);
-void cal_ni_pci_6025e(void);
-void cal_ni_pci_6035e(void);
-void cal_ni_pci_6071e(void);
-void cal_ni_pxi_6071e(void);
-void cal_ni_at_mio_16e_10(void);
-void cal_ni_pci_mio_16xe_50(void);
-void cal_ni_pci_6023e(void);
-void cal_ni_pci_6024e(void);
-void cal_ni_at_mio_16xe_50(void);
-void cal_ni_pci_mio_16xe_10(void);
-void cal_ni_pci_6052e(void);
-
-struct board_struct boards[]={
+int cal_ni_at_mio_16e_2(calibration_setup *setup);
+int cal_ni_daqcard_ai_16xe_50(calibration_setup *setup);
+int cal_ni_at_mio_16e_1(calibration_setup *setup);
+int cal_ni_pci_mio_16e_1(calibration_setup *setup);
+int cal_ni_pci_6025e(calibration_setup *setup);
+int cal_ni_pci_6035e(calibration_setup *setup);
+int cal_ni_pci_6071e(calibration_setup *setup);
+int cal_ni_pxi_6071e(calibration_setup *setup);
+int cal_ni_at_mio_16e_10(calibration_setup *setup);
+int cal_ni_pci_mio_16xe_50(calibration_setup *setup);
+int cal_ni_pci_6023e(calibration_setup *setup);
+int cal_ni_pci_6024e(calibration_setup *setup);
+int cal_ni_at_mio_16xe_50(calibration_setup *setup);
+int cal_ni_pci_mio_16xe_10(calibration_setup *setup);
+int cal_ni_pci_6052e(calibration_setup *setup);
+
+static struct board_struct boards[]={
{ "at-mio-16e-2", STATUS_DONE, cal_ni_at_mio_16e_2 },
{ "DAQCard-ai-16xe-50", STATUS_DONE, cal_ni_daqcard_ai_16xe_50 },
{ "at-mio-16xe-50", STATUS_SOME, cal_ni_at_mio_16xe_50 },
ni_ao1_reference,
};
-int ni_setup(void)
+int ni_setup( calibration_setup *setup , const char *device_name )
{
- int status;
-
- status = ni_setup_board();
+ ni_setup_board( setup, device_name );
+ setup->observables = observables;
+ setup->n_observables = n_observables;
+ setup->caldacs = caldacs;
+ setup->n_caldacs = n_caldacs;
ni_setup_observables();
setup_caldacs();
- return status;
+ return 0;
}
-int ni_setup_board(void)
+int ni_setup_board( calibration_setup *setup, const char *device_name )
{
int i;
- int device_status = STATUS_UNKNOWN;
- for(i=0;i<n_boards;i++){
- if(!strcmp(devicename,boards[i].name)){
- device_status = boards[i].status;
- do_cal = boards[i].cal;
+ for(i = 0; i < n_boards; i++ ){
+ if(!strcmp( device_name, boards[i].name )){
+ setup->status = boards[i].status;
+ setup->do_cal = boards[i].cal;
break;
}
}
- //do_cal = cal_ni_unknown;
- return device_status;
+ return 0;
}
void ni_setup_observables(void)
}
}
-void cal_ni_at_mio_16e_2(void)
+int cal_ni_at_mio_16e_2(calibration_setup *setup)
{
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
cal1(ni_zero_offset_high,0);
cal1(ni_ao1_zero_offset,8);
cal1(ni_ao1_reference,9);
}
+ return 0;
}
/*
* caldac[2] gain=7.8670(11)e-5 V/bit S_min=903.291 dof=254
* caldac[8] gain=2.7732(74)e-7 V/bit S_min=415.399 dof=254
*/
-void cal_ni_daqcard_ai_16xe_50(void)
+int cal_ni_daqcard_ai_16xe_50(calibration_setup *setup)
{
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,2);
cal1(ni_zero_offset_high,8);
cal1(ni_reference_low,0);
cal1_fine(ni_reference_low,0);
cal1(ni_reference_low,1);
+ return 0;
}
-void cal_ni_at_mio_16xe_50(void)
+int cal_ni_at_mio_16xe_50(calibration_setup *setup)
{
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,2);
cal1(ni_zero_offset_high,8);
cal1(ni_reference_low,0);
cal1_fine(ni_reference_low,0);
cal1(ni_reference_low,1);
-
+
if(do_output){
cal1(ni_ao0_zero_offset,6);
cal1(ni_ao0_reference,4);
cal1(ni_ao1_zero_offset,7);
cal1(ni_ao1_reference,5);
}
+ return 0;
}
-void cal_ni_pci_mio_16xe_10(void)
+int cal_ni_pci_mio_16xe_10(calibration_setup *setup)
{
postgain_cal(ni_zero_offset_low, ni_zero_offset_high, 2);
postgain_cal(ni_zero_offset_low, ni_zero_offset_high, 3);
cal1(ni_ao1_zero_offset,7);
cal1(ni_ao1_reference,5);
}
+ return 0;
}
-void cal_ni_at_mio_16e_1(void)
+int cal_ni_at_mio_16e_1(calibration_setup *setup)
{
- cal_ni_at_mio_16e_2();
+ return cal_ni_at_mio_16e_2( setup );
}
-void cal_ni_pci_mio_16e_1(void)
+int cal_ni_pci_mio_16e_1(calibration_setup *setup)
{
//cal_ni_at_mio_16e_2();
//cal1(ni_ao1_zero_offset,7); /* linearity? */
cal1(ni_ao1_reference,9);
}
+ return 0;
}
-void cal_ni_pci_6035e(void)
+int cal_ni_pci_6035e(calibration_setup *setup)
{
// 6035e (old)
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
if(do_output){
// unknown
}
+ return 0;
}
-void cal_ni_pci_6071e(void)
+int cal_ni_pci_6071e(calibration_setup *setup)
{
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
cal1(ni_zero_offset_high,0);
//cal1(ni_ao1_zero_offset,7); /* linearity? */
cal1(ni_ao1_reference,9);
}
+ return 0;
}
-void cal_ni_pxi_6071e(void)
+int cal_ni_pxi_6071e(calibration_setup *setup)
{
// 6071e (old)
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
if(do_output){
// unknown
}
+ return 0;
}
-void cal_ni_at_mio_16e_10(void)
+int cal_ni_at_mio_16e_10(calibration_setup *setup)
{
// 16e-10 (old)
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
cal1(ni_ao1_zero_offset,8); // guess
cal1(ni_ao1_reference,9); // guess
}
+ return 0;
}
-void cal_ni_pci_mio_16xe_50(void)
+int cal_ni_pci_mio_16xe_50(calibration_setup *setup)
{
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,2);
cal1(ni_zero_offset_high,8);
cal1(ni_reference_low,0);
cal1_fine(ni_reference_low,0);
cal1(ni_reference_low,1);
-
+
if(do_output){
cal1(ni_ao0_zero_offset,6);
cal1(ni_ao0_reference,4);
cal1(ni_ao1_zero_offset,7);
cal1(ni_ao1_reference,5);
}
+ return 0;
}
-void cal_ni_pci_6023e(void)
+int cal_ni_pci_6023e(calibration_setup *setup)
{
/* There seems to be a bug in the driver that doesn't allow
* access to caldac 10, and possibly others. */
//cal1(ni_zero_offset_high,10);
//cal1(ni_zero_offset_high,0);
cal1(ni_reference_low,3);
+ return 0;
}
-void cal_ni_pci_6024e(void)
+int cal_ni_pci_6024e(calibration_setup *setup)
{
/* There seems to be a bug in the driver that doesn't allow
* access to caldac 10, and possibly others. */
//cal1(ni_ao1_zero_offset,7); // nonlinearity?
//cal1(ni_ao1_reference,9);
}
+ return 0;
}
-void cal_ni_pci_6025e(void)
+int cal_ni_pci_6025e(calibration_setup *setup)
{
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,4); // was 1
//cal1(ni_zero_offset_high,XXX); // was 10
//cal1(ni_ao1_zero_offset,1); // nonlinearity was 7
cal1(ni_ao1_reference,5); // was 9
}
+ return 0;
}
-void cal_ni_pci_6052e(void)
+int cal_ni_pci_6052e(calibration_setup *setup)
{
/*
* This board has noisy caldacs
cal1(ni_ao1_reference,12+9);
cal1(ni_ao1_reference,12+5);
}
+ return 0;
}
double ni_get_reference(int lsb_loc,int msb_loc)