Split up comedi_calibrate.c, additional hacking
This commit is contained in:
parent
909b845030
commit
f3681b41fa
4 changed files with 717 additions and 578 deletions
|
@ -7,11 +7,12 @@ LDFLAGS += -L../lib/ -lcomedi -lm
|
|||
|
||||
|
||||
BINS=comedi_calibrate
|
||||
objs = comedi_calibrate.o ni.o
|
||||
|
||||
all: $(BINS)
|
||||
|
||||
comedi_calibrate: comedi_calibrate.o
|
||||
$(CC) -o comedi_calibrate comedi_calibrate.o $(LDFLAGS)
|
||||
comedi_calibrate: $(objs)
|
||||
$(CC) -o $@ $(objs) $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
-rm -f *.o $(BINS)
|
||||
|
|
181
comedi_calibrate/calib.h
Normal file
181
comedi_calibrate/calib.h
Normal file
|
@ -0,0 +1,181 @@
|
|||
|
||||
#ifndef __CALIB_H_
|
||||
#define __CALIB_H_
|
||||
|
||||
#include <comedilib.h>
|
||||
#if 0
|
||||
#include <stdio.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>
|
||||
#endif
|
||||
|
||||
#define DPRINT(level,fmt,args...) do{if(verbose>=level)printf(fmt, ## args);}while(0)
|
||||
|
||||
#define N_CALDACS 32
|
||||
#define N_OBSERVABLES 32
|
||||
|
||||
typedef struct{
|
||||
int subdev;
|
||||
int chan;
|
||||
|
||||
int maxdata;
|
||||
int current;
|
||||
|
||||
int type;
|
||||
double gain;
|
||||
}caldac;
|
||||
|
||||
typedef struct{
|
||||
char *name;
|
||||
|
||||
comedi_insn preobserve_insn;
|
||||
lsampl_t preobserve_data;
|
||||
|
||||
comedi_insn observe_insn;
|
||||
|
||||
//comedi_range *range;
|
||||
//int maxdata;
|
||||
|
||||
double target;
|
||||
}observable;
|
||||
|
||||
extern caldac caldacs[N_CALDACS];
|
||||
extern int n_caldacs;
|
||||
|
||||
extern observable observables[N_OBSERVABLES];
|
||||
extern int n_observables;
|
||||
|
||||
extern comedi_t *dev;
|
||||
|
||||
extern int ad_subdev;
|
||||
extern int da_subdev;
|
||||
extern int eeprom_subdev;
|
||||
extern int caldac_subdev;
|
||||
|
||||
extern char *devicename;
|
||||
extern char *drivername;
|
||||
|
||||
extern int verbose;
|
||||
|
||||
enum {
|
||||
STATUS_UNKNOWN = 0,
|
||||
STATUS_GUESS,
|
||||
STATUS_SOME,
|
||||
STATUS_DONE
|
||||
};
|
||||
extern int device_status;
|
||||
|
||||
extern int do_output;
|
||||
|
||||
/* high level */
|
||||
|
||||
void observe(void);
|
||||
void preobserve(int obs);
|
||||
void observable_dependence(int obs);
|
||||
void measure_observable(int obs);
|
||||
void reset_caldacs(void);
|
||||
|
||||
/* drivers */
|
||||
|
||||
void ni_setup(void);
|
||||
|
||||
/* low level */
|
||||
|
||||
void set_target(int obs,double target);
|
||||
void update_caldac(int i);
|
||||
void setup_caldacs(void);
|
||||
void postgain_cal(int obs1, int obs2, int dac);
|
||||
void cal1(int obs, int dac);
|
||||
|
||||
/* misc and temp */
|
||||
|
||||
void channel_dependence(int adc,int range);
|
||||
void caldac_dependence(int caldac);
|
||||
void dump_curve(int adc,int caldac);
|
||||
void chan_cal(int adc,int caldac,int range,double target);
|
||||
int read_eeprom(int addr);
|
||||
|
||||
double read_chan(int adc,int range);
|
||||
int read_chan2(char *s,int adc,int range);
|
||||
void set_ao(comedi_t *dev,int subdev,int chan,int range,double value);
|
||||
void check_gain(int ad_chan,int range);
|
||||
double check_gain_chan(int ad_chan,int range,int cdac);
|
||||
|
||||
void (*do_cal)(void);
|
||||
void cal_ni_results(void);
|
||||
|
||||
/* helper functions */
|
||||
|
||||
int get_bipolar_lowgain(comedi_t *dev,int subdev);
|
||||
int get_bipolar_highgain(comedi_t *dev,int subdev);
|
||||
int get_unipolar_lowgain(comedi_t *dev,int subdev);
|
||||
|
||||
/* printing scientific numbers */
|
||||
|
||||
int sci_sprint(char *s,double x,double y);
|
||||
int sci_sprint_alt(char *s,double x,double y);
|
||||
|
||||
/* linear fitting */
|
||||
|
||||
typedef struct {
|
||||
int n;
|
||||
|
||||
double *y_data;
|
||||
double *yerr_data;
|
||||
double *x_data;
|
||||
|
||||
double x0;
|
||||
double dx;
|
||||
double yerr;
|
||||
|
||||
/* stats */
|
||||
double s1,sx,sy,sxy,sxx;
|
||||
|
||||
double min,max;
|
||||
|
||||
/* results */
|
||||
double ave_x;
|
||||
double ave_y;
|
||||
double slope;
|
||||
double err_slope;
|
||||
double err_ave_y;
|
||||
double S_min;
|
||||
double dof;
|
||||
|
||||
}linear_fit_t;
|
||||
int linear_fit_monotonic(linear_fit_t *l);
|
||||
double linear_fit_func_y(linear_fit_t *l,double x);
|
||||
double check_gain_chan_x(linear_fit_t *l,unsigned int ad_chanspec,int cdac);
|
||||
|
||||
/* slowly varying measurements */
|
||||
|
||||
typedef struct{
|
||||
comedi_t *dev;
|
||||
|
||||
int maxdata;
|
||||
int order;
|
||||
int aref;
|
||||
int range;
|
||||
int subd;
|
||||
int chan;
|
||||
|
||||
comedi_range *rng;
|
||||
|
||||
int n;
|
||||
double average;
|
||||
double stddev;
|
||||
double error;
|
||||
}new_sv_t;
|
||||
|
||||
int new_sv_measure(new_sv_t *sv);
|
||||
int new_sv_init(new_sv_t *sv,comedi_t *dev,int subdev,int chan,int range,int aref);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -33,203 +33,38 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DPRINT(level,fmt,args...) do{if(verbose>=level)printf(fmt, ## args);}while(0)
|
||||
#include "calib.h"
|
||||
|
||||
#define N_CALDACS 32
|
||||
#define N_OBSERVABLES 32
|
||||
/* global variables */
|
||||
|
||||
typedef struct{
|
||||
int subdev;
|
||||
int chan;
|
||||
caldac caldacs[N_CALDACS];
|
||||
int n_caldacs;
|
||||
|
||||
int maxdata;
|
||||
int current;
|
||||
observable observables[N_OBSERVABLES];
|
||||
int n_observables;
|
||||
|
||||
int type;
|
||||
double gain;
|
||||
}caldac;
|
||||
comedi_t *dev;
|
||||
|
||||
typedef struct{
|
||||
char *name;
|
||||
int ad_subdev;
|
||||
int da_subdev;
|
||||
int eeprom_subdev;
|
||||
int caldac_subdev;
|
||||
|
||||
comedi_insn preobserve_insn;
|
||||
lsampl_t preobserve_data;
|
||||
|
||||
comedi_insn observe_insn;
|
||||
|
||||
//comedi_range *range;
|
||||
//int maxdata;
|
||||
|
||||
double target;
|
||||
}observable;
|
||||
|
||||
static caldac caldacs[N_CALDACS];
|
||||
static observable observables[N_OBSERVABLES];
|
||||
|
||||
static int n_caldacs;
|
||||
static int n_observables;
|
||||
|
||||
static comedi_t *dev;
|
||||
|
||||
static int ad_subdev;
|
||||
static int da_subdev;
|
||||
static int eeprom_subdev;
|
||||
static int caldac_subdev;
|
||||
|
||||
double read_chan(int adc,int range);
|
||||
int read_chan2(char *s,int adc,int range);
|
||||
void set_ao(comedi_t *dev,int subdev,int chan,int range,double value);
|
||||
void check_gain(int ad_chan,int range);
|
||||
double check_gain_chan(int ad_chan,int range,int cdac);
|
||||
char *drivername = NULL;
|
||||
char *devicename = NULL;
|
||||
|
||||
int verbose = 0;
|
||||
|
||||
enum {
|
||||
STATUS_UNKNOWN = 0,
|
||||
STATUS_SOME,
|
||||
STATUS_DONE
|
||||
};
|
||||
int device_status = STATUS_UNKNOWN;
|
||||
|
||||
/* tmep */
|
||||
void do_cal(void);
|
||||
/* */
|
||||
|
||||
void observe(void);
|
||||
void preobserve(int obs);
|
||||
void observable_dependence(int obs);
|
||||
void measure_observable(int obs);
|
||||
void ni_setup(void);
|
||||
void set_target(int obs,double target);
|
||||
|
||||
void cal_ni_results(void);
|
||||
|
||||
void update_caldac(int i);
|
||||
void reset_caldacs(void);
|
||||
void setup_caldacs(void);
|
||||
void cal_ni_mio_E(void);
|
||||
void ni_mio_ai_postgain_cal(void);
|
||||
void ni_mio_ai_postgain_cal_2(int chan,int dac,int range_lo,int range_hi,double gain);
|
||||
void channel_dependence(int adc,int range);
|
||||
void caldac_dependence(int caldac);
|
||||
void dump_curve(int adc,int caldac);
|
||||
void chan_cal(int adc,int caldac,int range,double target);
|
||||
int read_eeprom(int addr);
|
||||
|
||||
int get_bipolar_lowgain(comedi_t *dev,int subdev);
|
||||
int get_bipolar_highgain(comedi_t *dev,int subdev);
|
||||
int get_unipolar_lowgain(comedi_t *dev,int subdev);
|
||||
|
||||
int sci_sprint(char *s,double x,double y);
|
||||
int sci_sprint_alt(char *s,double x,double y);
|
||||
|
||||
|
||||
typedef struct {
|
||||
int n;
|
||||
|
||||
double *y_data;
|
||||
double *yerr_data;
|
||||
double *x_data;
|
||||
|
||||
double x0;
|
||||
double dx;
|
||||
double yerr;
|
||||
|
||||
/* stats */
|
||||
double s1,sx,sy,sxy,sxx;
|
||||
|
||||
double min,max;
|
||||
|
||||
/* results */
|
||||
double ave_x;
|
||||
double ave_y;
|
||||
double slope;
|
||||
double err_slope;
|
||||
double err_ave_y;
|
||||
double S_min;
|
||||
double dof;
|
||||
|
||||
}linear_fit_t;
|
||||
int linear_fit_monotonic(linear_fit_t *l);
|
||||
double linear_fit_func_y(linear_fit_t *l,double x);
|
||||
double check_gain_chan_x(linear_fit_t *l,unsigned int ad_chanspec,int cdac);
|
||||
|
||||
typedef struct{
|
||||
comedi_t *dev;
|
||||
|
||||
int maxdata;
|
||||
int order;
|
||||
int aref;
|
||||
int range;
|
||||
int subd;
|
||||
int chan;
|
||||
|
||||
comedi_range *rng;
|
||||
|
||||
int n;
|
||||
double average;
|
||||
double stddev;
|
||||
double error;
|
||||
}new_sv_t;
|
||||
|
||||
int new_sv_measure(new_sv_t *sv);
|
||||
int new_sv_init(new_sv_t *sv,comedi_t *dev,int subdev,int chan,int range,int aref);
|
||||
|
||||
struct board_struct{
|
||||
char *name;
|
||||
void (*setup)(void);
|
||||
};
|
||||
|
||||
#if 0
|
||||
void cal_ni_16e_1(void);
|
||||
void cal_ni_16e_10(void);
|
||||
void cal_ni_16xe_50(void);
|
||||
void cal_ni_16xe_10(void);
|
||||
void cal_ni_6023e(void);
|
||||
void cal_ni_6071e(void);
|
||||
void cal_ni_daqcard_ai_16xe_50(void);
|
||||
void cal_ni_unknown(void);
|
||||
|
||||
struct board_struct boards[]={
|
||||
{ "at-mio-16e-1", cal_ni_16e_1 },
|
||||
{ "at-mio-16e-2", cal_ni_16e_1 },
|
||||
{ "at-mio-16e-10", cal_ni_16e_10 },
|
||||
// { "at-mio-16de-10", cal_ni_unknown },
|
||||
{ "at-mio-64e-3", cal_ni_16e_1 },
|
||||
// { "at-mio-16xe-50", cal_ni_unknown },
|
||||
// { "at-mio-16xe-10", cal_ni_unknown },
|
||||
// { "at-ai-16xe-10", cal_ni_unknown },
|
||||
{ "pci-mio-16xe-50", cal_ni_16xe_50 },
|
||||
{ "pci-mio-16xe-10", cal_ni_16xe_10 },
|
||||
// { "pxi-6030e", cal_ni_unknown },
|
||||
{ "pci-mio-16e-1", cal_ni_16e_1 },
|
||||
// { "pci-mio-16e-4", cal_ni_unknown },
|
||||
// { "pxi-6040e", cal_ni_unknown },
|
||||
// { "pci-6031e", cal_ni_unknown },
|
||||
// { "pci-6032e", cal_ni_unknown },
|
||||
// { "pci-6033e", cal_ni_unknown },
|
||||
// { "pci-6071e", cal_ni_unknown },
|
||||
{ "pci-6023e", cal_ni_6023e },
|
||||
{ "pci-6024e", cal_ni_6023e }, // guess
|
||||
{ "pci-6025e", cal_ni_6023e }, // guess
|
||||
{ "pxi-6025e", cal_ni_6023e }, // guess
|
||||
{ "pci-6034e", cal_ni_6023e }, // guess
|
||||
{ "pci-6035e", cal_ni_6023e },
|
||||
// { "pci-6052e", cal_ni_unknown },
|
||||
// { "pci-6110e", cal_ni_unknown },
|
||||
// { "pci-6111e", cal_ni_unknown },
|
||||
// { "pci-6711", cal_ni_unknown },
|
||||
// { "pci-6713", cal_ni_unknown },
|
||||
{ "pxi-6071e", cal_ni_6071e },
|
||||
// { "pxi-6070e", cal_ni_unknown },
|
||||
// { "pxi-6052e", cal_ni_unknown },
|
||||
{ "DAQCard-ai-16xe-50", cal_ni_daqcard_ai_16xe_50 },
|
||||
// { "DAQCard-ai-16e-4", cal_ni_unknown },
|
||||
// { "DAQCard-6062e", cal_ni_unknown },
|
||||
// { "DAQCard-6024e", cal_ni_unknown },
|
||||
};
|
||||
#define n_boards (sizeof(boards)/sizeof(boards[0]))
|
||||
#endif
|
||||
|
||||
struct board_struct drivers[] = {
|
||||
{ "ni_pcimio", ni_setup },
|
||||
{ "ni_atmio", ni_setup },
|
||||
|
@ -240,7 +75,7 @@ struct board_struct drivers[] = {
|
|||
int do_dump = 0;
|
||||
int do_reset = 1;
|
||||
int do_calibrate = 1;
|
||||
int do_results = 1;
|
||||
int do_results = 0;
|
||||
int do_output = 1;
|
||||
|
||||
struct option options[] = {
|
||||
|
@ -257,6 +92,8 @@ struct option options[] = {
|
|||
{ "no-dump", 0, &do_dump, 0 },
|
||||
{ "results", 0, &do_results, 1 },
|
||||
{ "no-results", 0, &do_results, 0 },
|
||||
{ "output", 0, &do_output, 1 },
|
||||
{ "no-output", 0, &do_output, 0 },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
|
@ -264,8 +101,6 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
char *fn = NULL;
|
||||
int c;
|
||||
char *drivername = NULL;
|
||||
char *devicename = NULL;
|
||||
int i;
|
||||
struct board_struct *this_board;
|
||||
int index;
|
||||
|
@ -353,147 +188,12 @@ ok:
|
|||
|
||||
if(do_reset)reset_caldacs();
|
||||
if(do_dump)observe();
|
||||
if(do_calibrate)do_cal();
|
||||
if(do_calibrate && do_cal)do_cal();
|
||||
if(do_results)observe();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum {
|
||||
ni_zero_offset_low = 0,
|
||||
ni_zero_offset_high,
|
||||
ni_reference_low,
|
||||
ni_unip_offset_low,
|
||||
ni_ao0_zero_offset,
|
||||
ni_ao0_reference,
|
||||
ni_ao1_zero_offset,
|
||||
ni_ao1_reference,
|
||||
};
|
||||
|
||||
void ni_setup(void)
|
||||
{
|
||||
comedi_insn tmpl;
|
||||
int bipolar_lowgain;
|
||||
int bipolar_highgain;
|
||||
int unipolar_lowgain;
|
||||
double voltage_reference;
|
||||
observable *o;
|
||||
|
||||
bipolar_lowgain = get_bipolar_lowgain(dev,ad_subdev);
|
||||
bipolar_highgain = get_bipolar_highgain(dev,ad_subdev);
|
||||
unipolar_lowgain = get_unipolar_lowgain(dev,ad_subdev);
|
||||
|
||||
voltage_reference = 5.000;
|
||||
|
||||
memset(&tmpl,0,sizeof(tmpl));
|
||||
tmpl.insn = INSN_READ;
|
||||
tmpl.n = 1;
|
||||
tmpl.subdev = ad_subdev;
|
||||
|
||||
/* 0 offset, low gain */
|
||||
o = observables + ni_zero_offset_low;
|
||||
o->name = "ai, bipolar zero offset, low gain";
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec = CR_PACK(0,bipolar_lowgain,AREF_OTHER);
|
||||
o->target = 0;
|
||||
|
||||
/* 0 offset, high gain */
|
||||
o = observables + ni_zero_offset_high;
|
||||
o->name = "ai, bipolar zero offset, high gain";
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec = CR_PACK(0,bipolar_highgain,AREF_OTHER);
|
||||
o->target = 0;
|
||||
|
||||
/* voltage reference */
|
||||
o = observables + ni_reference_low;
|
||||
o->name = "ai, bipolar voltage reference, low gain";
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec = CR_PACK(5,bipolar_lowgain,AREF_OTHER);
|
||||
o->target = voltage_reference;
|
||||
|
||||
if(unipolar_lowgain>=0){
|
||||
/* unip/bip offset */
|
||||
o = observables + ni_unip_offset_low;
|
||||
o->name = "ai, unipolar zero offset, low gain";
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec =
|
||||
CR_PACK(0,unipolar_lowgain,AREF_OTHER);
|
||||
o->target = 0;
|
||||
|
||||
#if 0
|
||||
/* unip gain */
|
||||
o = observables + ni_unip_reference_low;
|
||||
o->name = "ai, unipolar voltage reference, low gain";
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec =
|
||||
CR_PACK(5,unipolar_lowgain,AREF_OTHER);
|
||||
o->target = voltage_reference;
|
||||
i++;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(da_subdev>=0){
|
||||
comedi_insn po_tmpl;
|
||||
|
||||
memset(&po_tmpl,0,sizeof(po_tmpl));
|
||||
po_tmpl.insn = INSN_WRITE;
|
||||
po_tmpl.n = 1;
|
||||
po_tmpl.subdev = da_subdev;
|
||||
|
||||
/* ao 0, zero offset */
|
||||
o = observables + ni_ao0_zero_offset;
|
||||
o->name = "ao 0, zero offset, low gain";
|
||||
o->preobserve_insn = po_tmpl;
|
||||
o->preobserve_insn.chanspec = CR_PACK(0,0,0);
|
||||
o->preobserve_insn.data = &o->preobserve_data;
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec =
|
||||
CR_PACK(2,bipolar_lowgain,AREF_OTHER);
|
||||
set_target(ni_ao0_zero_offset,0.0);
|
||||
|
||||
/* ao 0, gain */
|
||||
o = observables + ni_ao0_reference;
|
||||
o->name = "ao 0, reference voltage, low gain";
|
||||
o->preobserve_insn = po_tmpl;
|
||||
o->preobserve_insn.chanspec = CR_PACK(0,0,0);
|
||||
o->preobserve_insn.data = &o->preobserve_data;
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec =
|
||||
CR_PACK(6,bipolar_lowgain,AREF_OTHER);
|
||||
set_target(ni_ao0_reference,5.0);
|
||||
o->target -= voltage_reference;
|
||||
|
||||
/* ao 1, zero offset */
|
||||
o = observables + ni_ao1_zero_offset;
|
||||
o->name = "ao 1, zero offset, low gain";
|
||||
o->preobserve_insn = po_tmpl;
|
||||
o->preobserve_insn.chanspec = CR_PACK(1,0,0);
|
||||
o->preobserve_insn.data = &o->preobserve_data;
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec =
|
||||
CR_PACK(3,bipolar_lowgain,AREF_OTHER);
|
||||
set_target(ni_ao1_zero_offset,0.0);
|
||||
|
||||
/* ao 1, gain */
|
||||
o = observables + ni_ao1_reference;
|
||||
o->name = "ao 1, reference voltage, low gain";
|
||||
o->preobserve_insn = po_tmpl;
|
||||
o->preobserve_insn.chanspec = CR_PACK(1,0,0);
|
||||
o->preobserve_insn.data = &o->preobserve_data;
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec =
|
||||
CR_PACK(7,bipolar_lowgain,AREF_OTHER);
|
||||
set_target(ni_ao1_reference,5.0);
|
||||
o->target -= voltage_reference;
|
||||
|
||||
}
|
||||
n_observables = ni_ao1_reference + 1;
|
||||
|
||||
setup_caldacs();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void set_target(int obs,double target)
|
||||
{
|
||||
comedi_range *range;
|
||||
|
@ -641,264 +341,6 @@ void cal1(int obs, int dac)
|
|||
}
|
||||
}
|
||||
|
||||
void do_cal(void)
|
||||
{
|
||||
#if 0
|
||||
// daqcard
|
||||
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,2);
|
||||
cal1(ni_zero_offset_high,8);
|
||||
cal1(ni_reference_low,0);
|
||||
#endif
|
||||
|
||||
// 16e-2
|
||||
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
|
||||
cal1(ni_zero_offset_high,0);
|
||||
cal1(ni_reference_low,3);
|
||||
cal1(ni_unip_offset_low,2);
|
||||
if(do_output){
|
||||
cal1(ni_ao0_zero_offset,5);
|
||||
cal1(ni_ao0_reference,6);
|
||||
cal1(ni_ao1_zero_offset,8);
|
||||
cal1(ni_ao1_reference,9);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// 16e-10 (old)
|
||||
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
|
||||
cal1(ni_zero_offset_high,10);
|
||||
cal1(ni_zero_offset_high,0);
|
||||
cal1(ni_reference_low,3);
|
||||
cal1(ni_unip_offset_low,2);
|
||||
if(do_output){
|
||||
cal1(ni_ao0_zero_offset,5); // guess
|
||||
cal1(ni_ao0_reference,6); // guess
|
||||
cal1(ni_ao0_zero_offset,8); // guess
|
||||
cal1(ni_ao0_reference,9); // guess
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// 16xe-50 (old) (same as daqcard?)
|
||||
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,2);
|
||||
cal1(ni_zero_offset_high,8);
|
||||
cal1(ni_reference_low,0);
|
||||
if(do_output){
|
||||
// unknown
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// 6035e (old)
|
||||
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
|
||||
cal1(ni_zero_offset_high,0);
|
||||
cal1(ni_reference_low,3);
|
||||
if(do_output){
|
||||
// unknown
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// 6071e (old)
|
||||
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
|
||||
cal1(ni_zero_offset_high,0);
|
||||
cal1(ni_reference_low,3);
|
||||
if(do_output){
|
||||
// unknown
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double ni_get_reference(int lsb_loc,int msb_loc)
|
||||
{
|
||||
int lsb,msb;
|
||||
int uv;
|
||||
double ref;
|
||||
|
||||
lsb=read_eeprom(lsb_loc);
|
||||
msb=read_eeprom(msb_loc);
|
||||
printf("lsb=%d msb=%d\n",read_eeprom(425),read_eeprom(426));
|
||||
|
||||
uv=lsb | (msb<<8);
|
||||
if(uv>=0x8000)uv-=0x10000;
|
||||
ref=5.000+1.0e-6*uv;
|
||||
printf("ref=%g\n",ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
void cal_ni_unknown(void)
|
||||
{
|
||||
comedi_range *range;
|
||||
int bipolar_lowgain;
|
||||
int bipolar_highgain;
|
||||
int unipolar_lowgain;
|
||||
int have_ao = 1;
|
||||
|
||||
reset_caldacs();
|
||||
printf("Warning: device not calibrated due to insufficient information\n");
|
||||
printf("Please send this output to <ds@schleef.org>\n");
|
||||
printf("$Id$\n");
|
||||
printf("Device name: %s\n",comedi_get_board_name(dev));
|
||||
printf("Comedi version: %d.%d.%d\n",
|
||||
(comedi_get_version_code(dev)>>16)&0xff,
|
||||
(comedi_get_version_code(dev)>>8)&0xff,
|
||||
(comedi_get_version_code(dev))&0xff);
|
||||
|
||||
bipolar_lowgain = get_bipolar_lowgain(dev,ad_subdev);
|
||||
bipolar_highgain = get_bipolar_highgain(dev,ad_subdev);
|
||||
unipolar_lowgain = get_unipolar_lowgain(dev,ad_subdev);
|
||||
|
||||
/* 0 offset, low gain */
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
DPRINT(0,"bipolar zero offset, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(0,bipolar_lowgain);
|
||||
|
||||
/* 0 offset, high gain */
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_highgain);
|
||||
DPRINT(0,"bipolar zero offset, high gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(0,bipolar_highgain);
|
||||
|
||||
/* unip/bip offset */
|
||||
range = comedi_get_range(dev,ad_subdev,0,unipolar_lowgain);
|
||||
DPRINT(0,"unipolar zero offset, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(0,unipolar_lowgain);
|
||||
|
||||
/* voltage reference */
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
DPRINT(0,"bipolar voltage reference, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(5,bipolar_lowgain);
|
||||
|
||||
have_ao = (comedi_get_subdevice_type(dev,da_subdev)==COMEDI_SUBD_AO);
|
||||
if(have_ao){
|
||||
int ao_chan;
|
||||
|
||||
/* ao 0, zero offset */
|
||||
ao_chan = 0;
|
||||
set_ao(dev,da_subdev,ao_chan,0,0.0);
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
DPRINT(0,"ao 0, zero offset, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(2,bipolar_lowgain);
|
||||
|
||||
/* ao 0, gain */
|
||||
ao_chan = 0;
|
||||
set_ao(dev,da_subdev,ao_chan,0,5.0);
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
DPRINT(0,"ao 0, gain, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(6,bipolar_lowgain);
|
||||
|
||||
/* ao 1, zero offset */
|
||||
ao_chan = 1;
|
||||
set_ao(dev,da_subdev,ao_chan,0,0.0);
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
DPRINT(0,"ao 1, zero offset, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(3,bipolar_lowgain);
|
||||
|
||||
/* ao 1, gain */
|
||||
ao_chan = 1;
|
||||
set_ao(dev,da_subdev,ao_chan,0,5.0);
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
DPRINT(0,"ao 1, gain, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(7,bipolar_lowgain);
|
||||
}
|
||||
|
||||
cal_ni_results();
|
||||
}
|
||||
|
||||
void cal_ni_results(void)
|
||||
{
|
||||
comedi_range *range;
|
||||
int bipolar_lowgain;
|
||||
int bipolar_highgain;
|
||||
int unipolar_lowgain;
|
||||
//int have_ao;
|
||||
char s[32];
|
||||
|
||||
bipolar_lowgain = get_bipolar_lowgain(dev,ad_subdev);
|
||||
bipolar_highgain = get_bipolar_highgain(dev,ad_subdev);
|
||||
unipolar_lowgain = get_unipolar_lowgain(dev,ad_subdev);
|
||||
|
||||
/* 0 offset, low gain */
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
read_chan2(s,0,bipolar_lowgain);
|
||||
DPRINT(0,"bipolar zero offset, low gain [%g,%g]: %s\n",
|
||||
range->min,range->max,s);
|
||||
|
||||
/* 0 offset, high gain */
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_highgain);
|
||||
read_chan2(s,0,bipolar_highgain);
|
||||
DPRINT(0,"bipolar zero offset, high gain [%g,%g]: %s\n",
|
||||
range->min,range->max,s);
|
||||
|
||||
/* unip/bip offset */
|
||||
range = comedi_get_range(dev,ad_subdev,0,unipolar_lowgain);
|
||||
read_chan2(s,0,unipolar_lowgain);
|
||||
DPRINT(0,"unipolar zero offset, low gain [%g,%g]: %s\n",
|
||||
range->min,range->max,s);
|
||||
|
||||
}
|
||||
|
||||
void ni_mio_ai_postgain_cal(void)
|
||||
{
|
||||
linear_fit_t l;
|
||||
double offset_r0;
|
||||
double offset_r7;
|
||||
double gain;
|
||||
double a;
|
||||
|
||||
check_gain_chan_x(&l,CR_PACK(0,0,AREF_OTHER),1);
|
||||
offset_r0=linear_fit_func_y(&l,caldacs[1].current);
|
||||
printf("offset r0 %g\n",offset_r0);
|
||||
|
||||
check_gain_chan_x(&l,CR_PACK(0,7,AREF_OTHER),1);
|
||||
offset_r7=linear_fit_func_y(&l,caldacs[1].current);
|
||||
printf("offset r7 %g\n",offset_r7);
|
||||
|
||||
gain=l.slope;
|
||||
|
||||
a=(offset_r0-offset_r7)/(200.0-1.0);
|
||||
a=caldacs[1].current-a/gain;
|
||||
|
||||
printf("%g\n",a);
|
||||
|
||||
caldacs[1].current=rint(a);
|
||||
update_caldac(1);
|
||||
}
|
||||
|
||||
void ni_mio_ai_postgain_cal_2(int chan,int dac,int range_lo,int range_hi,double gain)
|
||||
{
|
||||
double offset_lo,offset_hi;
|
||||
linear_fit_t l;
|
||||
double slope;
|
||||
double a;
|
||||
|
||||
check_gain_chan_x(&l,CR_PACK(chan,range_lo,AREF_OTHER),dac);
|
||||
offset_lo=linear_fit_func_y(&l,caldacs[dac].current);
|
||||
printf("offset lo %g\n",offset_lo);
|
||||
|
||||
check_gain_chan_x(&l,CR_PACK(chan,range_hi,AREF_OTHER),dac);
|
||||
offset_hi=linear_fit_func_y(&l,caldacs[dac].current);
|
||||
printf("offset hi %g\n",offset_hi);
|
||||
|
||||
slope=l.slope;
|
||||
|
||||
a=(offset_lo-offset_hi)/(gain-1.0);
|
||||
a=caldacs[dac].current-a/slope;
|
||||
|
||||
printf("%g\n",a);
|
||||
|
||||
caldacs[dac].current=rint(a);
|
||||
update_caldac(dac);
|
||||
}
|
||||
|
||||
void chan_cal(int adc,int cdac,int range,double target)
|
||||
{
|
||||
linear_fit_t l;
|
||||
|
|
515
comedi_calibrate/ni.c
Normal file
515
comedi_calibrate/ni.c
Normal file
|
@ -0,0 +1,515 @@
|
|||
/*
|
||||
A little auto-calibration utility, for boards
|
||||
that support it.
|
||||
|
||||
Right now, it only supports NI E series boards,
|
||||
but it should be easily portable.
|
||||
|
||||
A few things need improvement here:
|
||||
- current system gets "close", but doesn't
|
||||
do any fine-tuning
|
||||
- no pre/post gain discrimination for the
|
||||
A/D zero offset.
|
||||
- should read (and use) the actual reference
|
||||
voltage value from eeprom
|
||||
- statistics would be nice, to show how good
|
||||
the calibration is.
|
||||
- doesn't check unipolar ranges
|
||||
- "alternate calibrations" would be cool--to
|
||||
accurately measure 0 in a unipolar range
|
||||
- more portable
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
struct board_struct{
|
||||
char *name;
|
||||
int status;
|
||||
void (*cal)(void);
|
||||
};
|
||||
|
||||
void ni_setup_board(void);
|
||||
void ni_setup_observables(void);
|
||||
|
||||
void cal_ni_16e_1(void);
|
||||
void cal_ni_daqcard_ai_16xe_50(void);
|
||||
void cal_ni_6035e(void);
|
||||
void cal_ni_6071e(void);
|
||||
void cal_ni_16e_10(void);
|
||||
void cal_ni_16xe_50(void);
|
||||
|
||||
struct board_struct boards[]={
|
||||
{ "at-mio-16e-2", STATUS_DONE, cal_ni_16e_1 },
|
||||
{ "DAQCard-ai-16xe-50", STATUS_DONE, cal_ni_daqcard_ai_16xe_50 },
|
||||
{ "at-mio-16e-1", STATUS_SOME, cal_ni_16e_1 },
|
||||
{ "pci-mio-16e-1", STATUS_SOME, cal_ni_16e_1 },
|
||||
{ "pci-6035e", STATUS_GUESS, cal_ni_6035e },
|
||||
{ "pci-6071e", STATUS_GUESS, cal_ni_6071e },
|
||||
{ "pxi-6071e", STATUS_GUESS, cal_ni_6071e },
|
||||
{ "at-mio-16e-10", STATUS_GUESS, cal_ni_16e_10 },
|
||||
{ "pci-mio-16xe-50", STATUS_GUESS, cal_ni_16xe_50 },
|
||||
{ "pci-6023e", STATUS_GUESS, cal_ni_6035e },
|
||||
#if 0
|
||||
// { "at-mio-16de-10", cal_ni_unknown },
|
||||
{ "at-mio-64e-3", cal_ni_16e_1 },
|
||||
// { "at-mio-16xe-50", cal_ni_unknown },
|
||||
// { "at-mio-16xe-10", cal_ni_unknown },
|
||||
// { "at-ai-16xe-10", cal_ni_unknown },
|
||||
{ "pci-mio-16xe-10", cal_ni_16xe_10 },
|
||||
// { "pxi-6030e", cal_ni_unknown },
|
||||
// { "pci-mio-16e-4", cal_ni_unknown },
|
||||
// { "pxi-6040e", cal_ni_unknown },
|
||||
// { "pci-6031e", cal_ni_unknown },
|
||||
// { "pci-6032e", cal_ni_unknown },
|
||||
// { "pci-6033e", cal_ni_unknown },
|
||||
// { "pci-6071e", cal_ni_unknown },
|
||||
{ "pci-6024e", cal_ni_6023e }, // guess
|
||||
{ "pci-6025e", cal_ni_6023e }, // guess
|
||||
{ "pxi-6025e", cal_ni_6023e }, // guess
|
||||
{ "pci-6034e", cal_ni_6023e }, // guess
|
||||
{ "pci-6035e", cal_ni_6023e },
|
||||
// { "pci-6052e", cal_ni_unknown },
|
||||
// { "pci-6110e", cal_ni_unknown },
|
||||
// { "pci-6111e", cal_ni_unknown },
|
||||
// { "pci-6711", cal_ni_unknown },
|
||||
// { "pci-6713", cal_ni_unknown },
|
||||
// { "pxi-6070e", cal_ni_unknown },
|
||||
// { "pxi-6052e", cal_ni_unknown },
|
||||
// { "DAQCard-ai-16e-4", cal_ni_unknown },
|
||||
// { "DAQCard-6062e", cal_ni_unknown },
|
||||
// { "DAQCard-6024e", cal_ni_unknown },
|
||||
#endif
|
||||
};
|
||||
#define n_boards (sizeof(boards)/sizeof(boards[0]))
|
||||
|
||||
enum {
|
||||
ni_zero_offset_low = 0,
|
||||
ni_zero_offset_high,
|
||||
ni_reference_low,
|
||||
ni_unip_offset_low,
|
||||
ni_ao0_zero_offset,
|
||||
ni_ao0_reference,
|
||||
ni_ao1_zero_offset,
|
||||
ni_ao1_reference,
|
||||
};
|
||||
|
||||
void ni_setup(void)
|
||||
{
|
||||
ni_setup_board();
|
||||
ni_setup_observables();
|
||||
setup_caldacs();
|
||||
}
|
||||
|
||||
void ni_setup_board(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<n_boards;i++){
|
||||
if(!strcmp(devicename,boards[i].name)){
|
||||
device_status = boards[i].status;
|
||||
do_cal = boards[i].cal;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ni_setup_observables(void)
|
||||
{
|
||||
comedi_insn tmpl;
|
||||
int bipolar_lowgain;
|
||||
int bipolar_highgain;
|
||||
int unipolar_lowgain;
|
||||
double voltage_reference;
|
||||
observable *o;
|
||||
|
||||
bipolar_lowgain = get_bipolar_lowgain(dev,ad_subdev);
|
||||
bipolar_highgain = get_bipolar_highgain(dev,ad_subdev);
|
||||
unipolar_lowgain = get_unipolar_lowgain(dev,ad_subdev);
|
||||
|
||||
voltage_reference = 5.000;
|
||||
|
||||
memset(&tmpl,0,sizeof(tmpl));
|
||||
tmpl.insn = INSN_READ;
|
||||
tmpl.n = 1;
|
||||
tmpl.subdev = ad_subdev;
|
||||
|
||||
/* 0 offset, low gain */
|
||||
o = observables + ni_zero_offset_low;
|
||||
o->name = "ai, bipolar zero offset, low gain";
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec = CR_PACK(0,bipolar_lowgain,AREF_OTHER);
|
||||
o->target = 0;
|
||||
|
||||
/* 0 offset, high gain */
|
||||
o = observables + ni_zero_offset_high;
|
||||
o->name = "ai, bipolar zero offset, high gain";
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec = CR_PACK(0,bipolar_highgain,AREF_OTHER);
|
||||
o->target = 0;
|
||||
|
||||
/* voltage reference */
|
||||
o = observables + ni_reference_low;
|
||||
o->name = "ai, bipolar voltage reference, low gain";
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec = CR_PACK(5,bipolar_lowgain,AREF_OTHER);
|
||||
o->target = voltage_reference;
|
||||
|
||||
if(unipolar_lowgain>=0){
|
||||
/* unip/bip offset */
|
||||
o = observables + ni_unip_offset_low;
|
||||
o->name = "ai, unipolar zero offset, low gain";
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec =
|
||||
CR_PACK(0,unipolar_lowgain,AREF_OTHER);
|
||||
o->target = 0;
|
||||
|
||||
#if 0
|
||||
/* unip gain */
|
||||
o = observables + ni_unip_reference_low;
|
||||
o->name = "ai, unipolar voltage reference, low gain";
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec =
|
||||
CR_PACK(5,unipolar_lowgain,AREF_OTHER);
|
||||
o->target = voltage_reference;
|
||||
i++;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(da_subdev>=0){
|
||||
comedi_insn po_tmpl;
|
||||
|
||||
memset(&po_tmpl,0,sizeof(po_tmpl));
|
||||
po_tmpl.insn = INSN_WRITE;
|
||||
po_tmpl.n = 1;
|
||||
po_tmpl.subdev = da_subdev;
|
||||
|
||||
/* ao 0, zero offset */
|
||||
o = observables + ni_ao0_zero_offset;
|
||||
o->name = "ao 0, zero offset, low gain";
|
||||
o->preobserve_insn = po_tmpl;
|
||||
o->preobserve_insn.chanspec = CR_PACK(0,0,0);
|
||||
o->preobserve_insn.data = &o->preobserve_data;
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec =
|
||||
CR_PACK(2,bipolar_lowgain,AREF_OTHER);
|
||||
set_target(ni_ao0_zero_offset,0.0);
|
||||
|
||||
/* ao 0, gain */
|
||||
o = observables + ni_ao0_reference;
|
||||
o->name = "ao 0, reference voltage, low gain";
|
||||
o->preobserve_insn = po_tmpl;
|
||||
o->preobserve_insn.chanspec = CR_PACK(0,0,0);
|
||||
o->preobserve_insn.data = &o->preobserve_data;
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec =
|
||||
CR_PACK(6,bipolar_lowgain,AREF_OTHER);
|
||||
set_target(ni_ao0_reference,5.0);
|
||||
o->target -= voltage_reference;
|
||||
|
||||
/* ao 1, zero offset */
|
||||
o = observables + ni_ao1_zero_offset;
|
||||
o->name = "ao 1, zero offset, low gain";
|
||||
o->preobserve_insn = po_tmpl;
|
||||
o->preobserve_insn.chanspec = CR_PACK(1,0,0);
|
||||
o->preobserve_insn.data = &o->preobserve_data;
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec =
|
||||
CR_PACK(3,bipolar_lowgain,AREF_OTHER);
|
||||
set_target(ni_ao1_zero_offset,0.0);
|
||||
|
||||
/* ao 1, gain */
|
||||
o = observables + ni_ao1_reference;
|
||||
o->name = "ao 1, reference voltage, low gain";
|
||||
o->preobserve_insn = po_tmpl;
|
||||
o->preobserve_insn.chanspec = CR_PACK(1,0,0);
|
||||
o->preobserve_insn.data = &o->preobserve_data;
|
||||
o->observe_insn = tmpl;
|
||||
o->observe_insn.chanspec =
|
||||
CR_PACK(7,bipolar_lowgain,AREF_OTHER);
|
||||
set_target(ni_ao1_reference,5.0);
|
||||
o->target -= voltage_reference;
|
||||
|
||||
}
|
||||
n_observables = ni_ao1_reference + 1;
|
||||
}
|
||||
|
||||
void cal_ni_daqcard_ai_16xe_50(void)
|
||||
{
|
||||
// daqcard
|
||||
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,2);
|
||||
cal1(ni_zero_offset_high,8);
|
||||
cal1(ni_reference_low,0);
|
||||
}
|
||||
|
||||
void cal_ni_16e_1(void)
|
||||
{
|
||||
// 16e-2
|
||||
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
|
||||
cal1(ni_zero_offset_high,0);
|
||||
cal1(ni_reference_low,3);
|
||||
cal1(ni_unip_offset_low,2);
|
||||
if(do_output){
|
||||
cal1(ni_ao0_zero_offset,5);
|
||||
cal1(ni_ao0_reference,6);
|
||||
cal1(ni_ao1_zero_offset,8);
|
||||
cal1(ni_ao1_reference,9);
|
||||
}
|
||||
}
|
||||
|
||||
void cal_ni_16e_10(void)
|
||||
{
|
||||
// 16e-10 (old)
|
||||
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
|
||||
cal1(ni_zero_offset_high,10);
|
||||
cal1(ni_zero_offset_high,0);
|
||||
cal1(ni_reference_low,3);
|
||||
cal1(ni_unip_offset_low,2);
|
||||
if(do_output){
|
||||
cal1(ni_ao0_zero_offset,5); // guess
|
||||
cal1(ni_ao0_reference,6); // guess
|
||||
cal1(ni_ao0_zero_offset,8); // guess
|
||||
cal1(ni_ao0_reference,9); // guess
|
||||
}
|
||||
}
|
||||
|
||||
void cal_ni_16xe_50(void)
|
||||
{
|
||||
// 16xe-50 (old) (same as daqcard?)
|
||||
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,2);
|
||||
cal1(ni_zero_offset_high,8);
|
||||
cal1(ni_reference_low,0);
|
||||
if(do_output){
|
||||
// unknown
|
||||
}
|
||||
}
|
||||
|
||||
void cal_ni_6035e(void)
|
||||
{
|
||||
// 6035e (old)
|
||||
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
|
||||
cal1(ni_zero_offset_high,0);
|
||||
cal1(ni_reference_low,3);
|
||||
if(do_output){
|
||||
// unknown
|
||||
}
|
||||
}
|
||||
|
||||
void cal_ni_6071e(void)
|
||||
{
|
||||
// 6071e (old)
|
||||
postgain_cal(ni_zero_offset_low,ni_zero_offset_high,1);
|
||||
cal1(ni_zero_offset_high,0);
|
||||
cal1(ni_reference_low,3);
|
||||
if(do_output){
|
||||
// unknown
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double ni_get_reference(int lsb_loc,int msb_loc)
|
||||
{
|
||||
int lsb,msb;
|
||||
int uv;
|
||||
double ref;
|
||||
|
||||
lsb=read_eeprom(lsb_loc);
|
||||
msb=read_eeprom(msb_loc);
|
||||
printf("lsb=%d msb=%d\n",read_eeprom(425),read_eeprom(426));
|
||||
|
||||
uv=lsb | (msb<<8);
|
||||
if(uv>=0x8000)uv-=0x10000;
|
||||
ref=5.000+1.0e-6*uv;
|
||||
printf("ref=%g\n",ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
void cal_ni_unknown(void)
|
||||
{
|
||||
comedi_range *range;
|
||||
int bipolar_lowgain;
|
||||
int bipolar_highgain;
|
||||
int unipolar_lowgain;
|
||||
int have_ao = 1;
|
||||
|
||||
reset_caldacs();
|
||||
printf("Warning: device not calibrated due to insufficient information\n");
|
||||
printf("Please send this output to <ds@schleef.org>\n");
|
||||
printf("$Id$\n");
|
||||
printf("Device name: %s\n",comedi_get_board_name(dev));
|
||||
printf("Comedi version: %d.%d.%d\n",
|
||||
(comedi_get_version_code(dev)>>16)&0xff,
|
||||
(comedi_get_version_code(dev)>>8)&0xff,
|
||||
(comedi_get_version_code(dev))&0xff);
|
||||
|
||||
bipolar_lowgain = get_bipolar_lowgain(dev,ad_subdev);
|
||||
bipolar_highgain = get_bipolar_highgain(dev,ad_subdev);
|
||||
unipolar_lowgain = get_unipolar_lowgain(dev,ad_subdev);
|
||||
|
||||
/* 0 offset, low gain */
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
DPRINT(0,"bipolar zero offset, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(0,bipolar_lowgain);
|
||||
|
||||
/* 0 offset, high gain */
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_highgain);
|
||||
DPRINT(0,"bipolar zero offset, high gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(0,bipolar_highgain);
|
||||
|
||||
/* unip/bip offset */
|
||||
range = comedi_get_range(dev,ad_subdev,0,unipolar_lowgain);
|
||||
DPRINT(0,"unipolar zero offset, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(0,unipolar_lowgain);
|
||||
|
||||
/* voltage reference */
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
DPRINT(0,"bipolar voltage reference, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(5,bipolar_lowgain);
|
||||
|
||||
have_ao = (comedi_get_subdevice_type(dev,da_subdev)==COMEDI_SUBD_AO);
|
||||
if(have_ao){
|
||||
int ao_chan;
|
||||
|
||||
/* ao 0, zero offset */
|
||||
ao_chan = 0;
|
||||
set_ao(dev,da_subdev,ao_chan,0,0.0);
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
DPRINT(0,"ao 0, zero offset, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(2,bipolar_lowgain);
|
||||
|
||||
/* ao 0, gain */
|
||||
ao_chan = 0;
|
||||
set_ao(dev,da_subdev,ao_chan,0,5.0);
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
DPRINT(0,"ao 0, gain, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(6,bipolar_lowgain);
|
||||
|
||||
/* ao 1, zero offset */
|
||||
ao_chan = 1;
|
||||
set_ao(dev,da_subdev,ao_chan,0,0.0);
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
DPRINT(0,"ao 1, zero offset, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(3,bipolar_lowgain);
|
||||
|
||||
/* ao 1, gain */
|
||||
ao_chan = 1;
|
||||
set_ao(dev,da_subdev,ao_chan,0,5.0);
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
DPRINT(0,"ao 1, gain, low gain [%g,%g]\n",
|
||||
range->min,range->max);
|
||||
channel_dependence(7,bipolar_lowgain);
|
||||
}
|
||||
|
||||
cal_ni_results();
|
||||
}
|
||||
|
||||
void cal_ni_results(void)
|
||||
{
|
||||
comedi_range *range;
|
||||
int bipolar_lowgain;
|
||||
int bipolar_highgain;
|
||||
int unipolar_lowgain;
|
||||
//int have_ao;
|
||||
char s[32];
|
||||
|
||||
bipolar_lowgain = get_bipolar_lowgain(dev,ad_subdev);
|
||||
bipolar_highgain = get_bipolar_highgain(dev,ad_subdev);
|
||||
unipolar_lowgain = get_unipolar_lowgain(dev,ad_subdev);
|
||||
|
||||
/* 0 offset, low gain */
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
|
||||
read_chan2(s,0,bipolar_lowgain);
|
||||
DPRINT(0,"bipolar zero offset, low gain [%g,%g]: %s\n",
|
||||
range->min,range->max,s);
|
||||
|
||||
/* 0 offset, high gain */
|
||||
range = comedi_get_range(dev,ad_subdev,0,bipolar_highgain);
|
||||
read_chan2(s,0,bipolar_highgain);
|
||||
DPRINT(0,"bipolar zero offset, high gain [%g,%g]: %s\n",
|
||||
range->min,range->max,s);
|
||||
|
||||
/* unip/bip offset */
|
||||
range = comedi_get_range(dev,ad_subdev,0,unipolar_lowgain);
|
||||
read_chan2(s,0,unipolar_lowgain);
|
||||
DPRINT(0,"unipolar zero offset, low gain [%g,%g]: %s\n",
|
||||
range->min,range->max,s);
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
void ni_mio_ai_postgain_cal(void)
|
||||
{
|
||||
linear_fit_t l;
|
||||
double offset_r0;
|
||||
double offset_r7;
|
||||
double gain;
|
||||
double a;
|
||||
|
||||
check_gain_chan_x(&l,CR_PACK(0,0,AREF_OTHER),1);
|
||||
offset_r0=linear_fit_func_y(&l,caldacs[1].current);
|
||||
printf("offset r0 %g\n",offset_r0);
|
||||
|
||||
check_gain_chan_x(&l,CR_PACK(0,7,AREF_OTHER),1);
|
||||
offset_r7=linear_fit_func_y(&l,caldacs[1].current);
|
||||
printf("offset r7 %g\n",offset_r7);
|
||||
|
||||
gain=l.slope;
|
||||
|
||||
a=(offset_r0-offset_r7)/(200.0-1.0);
|
||||
a=caldacs[1].current-a/gain;
|
||||
|
||||
printf("%g\n",a);
|
||||
|
||||
caldacs[1].current=rint(a);
|
||||
update_caldac(1);
|
||||
}
|
||||
|
||||
void ni_mio_ai_postgain_cal_2(int chan,int dac,int range_lo,int range_hi,double gain)
|
||||
{
|
||||
double offset_lo,offset_hi;
|
||||
linear_fit_t l;
|
||||
double slope;
|
||||
double a;
|
||||
|
||||
check_gain_chan_x(&l,CR_PACK(chan,range_lo,AREF_OTHER),dac);
|
||||
offset_lo=linear_fit_func_y(&l,caldacs[dac].current);
|
||||
printf("offset lo %g\n",offset_lo);
|
||||
|
||||
check_gain_chan_x(&l,CR_PACK(chan,range_hi,AREF_OTHER),dac);
|
||||
offset_hi=linear_fit_func_y(&l,caldacs[dac].current);
|
||||
printf("offset hi %g\n",offset_hi);
|
||||
|
||||
slope=l.slope;
|
||||
|
||||
a=(offset_lo-offset_hi)/(gain-1.0);
|
||||
a=caldacs[dac].current-a/slope;
|
||||
|
||||
printf("%g\n",a);
|
||||
|
||||
caldacs[dac].current=rint(a);
|
||||
update_caldac(dac);
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Add table
Reference in a new issue