added initial support for calibrating 64xx series cards. Added support
authorFrank Mori Hess <fmhess@speakeasy.net>
Mon, 20 May 2002 02:23:38 +0000 (02:23 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Mon, 20 May 2002 02:23:38 +0000 (02:23 +0000)
for reading calibration source voltages from eeprom.  Got rid of a couple
more global variables just for kicks.

comedi_calibrate/calib.h
comedi_calibrate/cb.c
comedi_calibrate/comedi_calibrate.c
comedi_calibrate/ni.c

index 766925888c84157eab5f8a017bcdd3570e512414..768ff5047600edc4472f477ef7a1f8560a5e2cc2 100644 (file)
@@ -49,6 +49,10 @@ typedef struct{
 typedef struct calibration_setup_struct calibration_setup_t;
 struct calibration_setup_struct {
        comedi_t *dev;
+       int ad_subdev;
+       int da_subdev;
+       int eeprom_subdev;
+       int caldac_subdev;
        int status;
        observable observables[ N_OBSERVABLES ];
        unsigned int n_observables;
@@ -57,11 +61,6 @@ struct calibration_setup_struct {
        int (*do_cal) ( calibration_setup_t *setup );
 };
 
-extern int ad_subdev;
-extern int da_subdev;
-extern int eeprom_subdev;
-extern int caldac_subdev;
-
 extern char *devicename;
 extern char *drivername;
 
index 0607631baee87b95dc7db9b180c342cae7f8067a..44f296af6b16dab42f000e3e6e0bfaaf350f4141 100644 (file)
@@ -35,6 +35,7 @@
 #include <math.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdint.h>
 
 #include "calib.h"
 
@@ -62,6 +63,8 @@ int init_observables_64xx( calibration_setup_t *setup );
 int init_observables_60xx( calibration_setup_t *setup );
 int init_observables_4020( calibration_setup_t *setup );
 
+int actual_source_voltage( comedi_t *dev, unsigned int subdevice, unsigned int eeprom_channel, float *voltage);
+
 static struct board_struct boards[]={
        { "pci-das6402/16",     STATUS_DONE,    setup_cb_pci_64xx },
        { "pci-das6402/12",     STATUS_GUESS,   setup_cb_pci_64xx },
@@ -76,15 +79,14 @@ static struct board_struct boards[]={
 
 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,
+enum observables_60xx {
+       OBS_0V_RANGE_10V_BIP_60XX = 0,
+       OBS_5V_RANGE_10V_BIP_60XX,
+};
+
+enum observables_64xx {
+       OBS_0V_RANGE_10V_BIP_64XX = 0,
+       OBS_7V_RANGE_10V_BIP_64XX,
 };
 
 int cb_setup( calibration_setup_t *setup, const char *device_name )
@@ -138,6 +140,55 @@ int setup_cb_pci_4020( calibration_setup_t *setup )
 
 int init_observables_64xx( calibration_setup_t *setup )
 {
+       comedi_insn tmpl, po_tmpl;
+       observable *o;
+       static const int ai_subdev = 0;
+       int retval;
+       float target;
+       enum source_eeprom_addr
+       {
+               EEPROM_7V_CHAN = 0x30,
+               EEPROM_3500mV_CHAN = 0x32,
+               EEPROM_1750mV_CHAN = 0x34,
+               EEPROM_875mV_CHAN = 0x36,
+               EEPROM_8600uV_CHAN = 0x38,
+       };
+
+       memset( &po_tmpl, 0, sizeof(po_tmpl) );
+       po_tmpl.insn = INSN_CONFIG;
+       po_tmpl.n = 2;
+       po_tmpl.subdev = ai_subdev;
+
+       memset( &tmpl, 0, sizeof(tmpl) );
+       tmpl.insn = INSN_READ;
+       tmpl.n = 1;
+       tmpl.subdev = ai_subdev;
+
+       o = setup->observables + OBS_0V_RANGE_10V_BIP_64XX;
+       o->name = "ground calibration source, 10V bipolar range, ground referenced";
+       o->preobserve_insn = po_tmpl;
+       o->preobserve_insn.data = o->preobserve_data;
+       o->preobserve_insn.data[0] = INSN_CONFIG_ALT_SOURCE;
+       o->preobserve_insn.data[1] = 0;
+       o->observe_insn = tmpl;
+       o->observe_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER;
+       o->target = 0.0;
+
+       o = setup->observables + OBS_7V_RANGE_10V_BIP_64XX;
+       o->name = "7V calibration source, 10V bipolar range, ground referenced";
+       o->preobserve_insn = po_tmpl;
+       o->preobserve_insn.data = o->preobserve_data;
+       o->preobserve_insn.data[0] = INSN_CONFIG_ALT_SOURCE;
+       o->preobserve_insn.data[1] = 1;
+       o->observe_insn = tmpl;
+       o->observe_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER;
+       o->target = 7.0;
+       retval = actual_source_voltage( setup->dev, setup->eeprom_subdev, EEPROM_7V_CHAN, &target );
+       if( retval == 0 )
+               o->target = target;
+
+       setup->n_observables = 2;
+
        return 0;
 }
 
@@ -146,6 +197,16 @@ int init_observables_60xx( calibration_setup_t *setup )
        comedi_insn tmpl, po_tmpl;
        observable *o;
        static const int ai_subdev = 0;
+       int retval;
+       float target;
+       enum source_eeprom_addr
+       {
+               EEPROM_10V_CHAN = 0x30,
+               EEPROM_5V_CHAN = 0x32,
+               EEPROM_500mV_CHAN = 0x38,
+               EEPROM_50mV_CHAN = 0x3e,
+               EEPROM_8mV_CHAN = 0x40,
+       };
 
        memset( &po_tmpl, 0, sizeof(po_tmpl) );
        po_tmpl.insn = INSN_CONFIG;
@@ -157,7 +218,7 @@ int init_observables_60xx( calibration_setup_t *setup )
        tmpl.n = 1;
        tmpl.subdev = ai_subdev;
 
-       o = setup->observables + 0;
+       o = setup->observables + OBS_0V_RANGE_10V_BIP_60XX;
        o->name = "ground calibration source, 10V bipolar range, ground referenced";
        o->preobserve_insn = po_tmpl;
        o->preobserve_insn.data = o->preobserve_data;
@@ -167,7 +228,7 @@ int init_observables_60xx( calibration_setup_t *setup )
        o->observe_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER;
        o->target = 0.0;
 
-       o = setup->observables + 1;
+       o = setup->observables + OBS_5V_RANGE_10V_BIP_60XX;
        o->name = "5V calibration source, 10V bipolar range, ground referenced";
        o->preobserve_insn = po_tmpl;
        o->preobserve_insn.data = o->preobserve_data;
@@ -176,6 +237,9 @@ int init_observables_60xx( calibration_setup_t *setup )
        o->observe_insn = tmpl;
        o->observe_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER;
        o->target = 5.0;
+       retval = actual_source_voltage( setup->dev, setup->eeprom_subdev, EEPROM_5V_CHAN, &target );
+       if( retval == 0 )
+               o->target = target;
 
        setup->n_observables = 2;
 
@@ -187,6 +251,13 @@ int init_observables_4020( calibration_setup_t *setup )
        comedi_insn tmpl, po_tmpl;
        observable *o;
        static const int ai_subdev = 0;
+       float target;
+       int retval;
+       enum source_eeprom_addr
+       {
+               EEPROM_4375mV_CHAN = 0x30,
+               EEPROM_625mV_CHAN = 0x32,
+       };
 
        memset( &po_tmpl, 0, sizeof(po_tmpl) );
        po_tmpl.insn = INSN_CONFIG;
@@ -208,6 +279,7 @@ int init_observables_4020( calibration_setup_t *setup )
        o->observe_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER;
        o->target = 0.0;
 
+
        o = setup->observables + 1;
        o->name = "ground calibration source, ch 1, 5V bipolar range, ground referenced";
        o->preobserve_insn = po_tmpl;
@@ -247,6 +319,9 @@ int init_observables_4020( calibration_setup_t *setup )
        o->observe_insn = tmpl;
        o->observe_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER;
        o->target = 4.375;
+       retval = actual_source_voltage( setup->dev, setup->eeprom_subdev, EEPROM_4375mV_CHAN, &target );
+       if( retval == 0 )
+               o->target = target;
 
        o = setup->observables + 5;
        o->name = "4.375V calibration source, ch 1, 5V bipolar range, ground referenced";
@@ -257,6 +332,9 @@ int init_observables_4020( calibration_setup_t *setup )
        o->observe_insn = tmpl;
        o->observe_insn.chanspec = CR_PACK( 1, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER;
        o->target = 4.375;
+       retval = actual_source_voltage( setup->dev, setup->eeprom_subdev, EEPROM_4375mV_CHAN, &target );
+       if( retval == 0 )
+               o->target = target;
 
        o = setup->observables + 6;
        o->name = "4.375V calibration source, ch 2, 5V bipolar range, ground referenced";
@@ -267,6 +345,9 @@ int init_observables_4020( calibration_setup_t *setup )
        o->observe_insn = tmpl;
        o->observe_insn.chanspec = CR_PACK( 2, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER;
        o->target = 4.375;
+       retval = actual_source_voltage( setup->dev, setup->eeprom_subdev, EEPROM_4375mV_CHAN, &target );
+       if( retval == 0 )
+               o->target = target;
 
        o = setup->observables + 7;
        o->name = "4.375V calibration source, ch 3, 5V bipolar range, ground referenced";
@@ -277,6 +358,9 @@ int init_observables_4020( calibration_setup_t *setup )
        o->observe_insn = tmpl;
        o->observe_insn.chanspec = CR_PACK( 3, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER;
        o->target = 4.375;
+       retval = actual_source_voltage( setup->dev, setup->eeprom_subdev, EEPROM_4375mV_CHAN, &target );
+       if( retval == 0 )
+               o->target = target;
 
        setup->n_observables = 8;
 
@@ -285,6 +369,26 @@ int init_observables_4020( calibration_setup_t *setup )
 
 int cal_cb_pci_64xx( calibration_setup_t *setup )
 {
+       enum caldacs_64xx
+       {
+               DAC0_GAIN_FINE = 0,
+               DAC0_GAIN_COARSE,
+               DAC0_OFFSET_COARSE,
+               DAC1_OFFSET_COARSE,
+               DAC1_GAIN_FINE,
+               DAC1_GAIN_COARSE,
+               DAC0_OFFSET_FINE,
+               DAC1_OFFSET_FINE,
+               ADC_GAIN,
+               ADC_OFFSET,
+       };
+
+       cal1( setup, OBS_0V_RANGE_10V_BIP_64XX, ADC_OFFSET );
+       cal1_fine( setup, OBS_0V_RANGE_10V_BIP_64XX, ADC_OFFSET );
+
+       cal1( setup, OBS_7V_RANGE_10V_BIP_64XX, ADC_GAIN );
+       cal1_fine( setup, OBS_7V_RANGE_10V_BIP_64XX, ADC_GAIN );
+
        return 0;
 }
 
@@ -302,17 +406,17 @@ int cal_cb_pci_60xx( calibration_setup_t *setup )
                ADC_GAIN_FINE,
        };
 
-       cal1( setup, 0, ADC_OFFSET_COARSE );
-       cal1_fine( setup, 0, ADC_OFFSET_COARSE );
+       cal1( setup, OBS_0V_RANGE_10V_BIP_60XX, ADC_OFFSET_COARSE );
+       cal1_fine( setup, OBS_0V_RANGE_10V_BIP_60XX, ADC_OFFSET_COARSE );
 
-       cal1( setup, 0, ADC_OFFSET_FINE );
-       cal1_fine( setup, 0, ADC_OFFSET_FINE );
+       cal1( setup, OBS_0V_RANGE_10V_BIP_60XX, ADC_OFFSET_FINE );
+       cal1_fine( setup, OBS_0V_RANGE_10V_BIP_60XX, ADC_OFFSET_FINE );
 
-       cal1( setup, 1, ADC_GAIN_COARSE );
-       cal1_fine( setup, 1, ADC_GAIN_COARSE );
+       cal1( setup, OBS_5V_RANGE_10V_BIP_60XX, ADC_GAIN_COARSE );
+       cal1_fine( setup, OBS_5V_RANGE_10V_BIP_60XX, ADC_GAIN_COARSE );
 
-       cal1( setup, 1, ADC_GAIN_FINE );
-       cal1_fine( setup, 1, ADC_GAIN_FINE );
+       cal1( setup, OBS_5V_RANGE_10V_BIP_60XX, ADC_GAIN_FINE );
+       cal1_fine( setup, OBS_5V_RANGE_10V_BIP_60XX, ADC_GAIN_FINE );
 
        return 0;
 }
@@ -358,3 +462,41 @@ int cal_cb_pci_4020( calibration_setup_t *setup )
        return 0;
 }
 
+// converts calibration source voltages from two 16 bit eeprom values to a floating point value
+float eeprom_to_source(uint16_t ls_word, uint16_t ms_word)
+{
+       union translator
+       {
+               uint32_t bits;
+               float   value;
+       };
+
+       union translator my_translator;
+
+       my_translator.bits = ( ls_word & 0xffff ) | ( ( ms_word << 16 ) & 0xffff0000 );
+
+       return my_translator.value;
+}
+
+int actual_source_voltage( comedi_t *dev, unsigned int subdevice, unsigned int eeprom_channel, float *voltage)
+{
+       int retval;
+       uint16_t word[2];
+       unsigned int i;
+       lsampl_t data;
+
+       for( i = 0; i < 2; i++ )
+       {
+               retval = comedi_data_read( dev, subdevice, eeprom_channel + i, 0, 0, &data );
+               if( retval < 0 )
+               {
+                       perror( "actual_source_voltage()" );
+                       return retval;
+               }
+               word[ i ] = data;
+       }
+
+       *voltage = eeprom_to_source( word[0], word[1] );
+       DPRINT(0, "eeprom ch %i,%i give calibration source of %gV\n", eeprom_channel, eeprom_channel + 1, *voltage);
+       return 0;
+}
index d1f6dd6cc111c5e795c87b54d1dc0e3fe71ac519..712894b55c85773a5a426c8679deba664844f2da 100644 (file)
 
 /* global variables */
 
-int ad_subdev;
-int da_subdev;
-int eeprom_subdev;
-int caldac_subdev;
-
 char *drivername = NULL;
 char *devicename = NULL;
 
@@ -99,6 +94,10 @@ int main(int argc, char *argv[])
        int device_status = STATUS_UNKNOWN;
        calibration_setup_t setup;
        comedi_t *dev;
+       int ad_subdev;
+       int da_subdev;
+       int eeprom_subdev;
+       int caldac_subdev;
 
        fn = "/dev/comedi0";
        while (1) {
@@ -155,7 +154,13 @@ int main(int argc, char *argv[])
 
 ok:
        memset( &setup, 0, sizeof( setup ) );
+
        setup.dev = dev;
+       setup.ad_subdev = ad_subdev;
+       setup.da_subdev = da_subdev;
+       setup.eeprom_subdev = eeprom_subdev;
+       setup.caldac_subdev = caldac_subdev;
+
        this_board->init_setup( &setup, devicename );
        device_status = setup.status;
 
@@ -725,9 +730,15 @@ int get_unipolar_lowgain(comedi_t *dev,int subdev)
 
 int read_eeprom( calibration_setup_t *setup, int addr)
 {
-       unsigned int data=0;
+       lsampl_t data = 0;
+       int retval;
 
-       comedi_data_read( setup->dev, eeprom_subdev, addr,0,0,&data);
+       retval = comedi_data_read( setup->dev, setup->eeprom_subdev, addr,0,0,&data);
+       if( retval < 0 )
+       {
+               perror( "read_eeprom()" );
+               return retval;
+       }
 
        return data;
 }
index 5707e4c6c56121ac7f3934fe6ccb80281735f81d..404e5f3325987a092eb2a5f6a70292853a605454 100644 (file)
@@ -121,7 +121,7 @@ int ni_setup( calibration_setup_t *setup , const char *device_name )
 {
        ni_setup_board( setup, device_name );
        ni_setup_observables( setup );
-       setup_caldacs( setup, caldac_subdev );
+       setup_caldacs( setup, setup->caldac_subdev );
 
        return 0;
 }
@@ -150,21 +150,21 @@ void ni_setup_observables( calibration_setup_t *setup )
        double voltage_reference;
        observable *o;
 
-       bipolar_lowgain = get_bipolar_lowgain( setup->dev, ad_subdev);
-       bipolar_highgain = get_bipolar_highgain( setup->dev, ad_subdev);
-       unipolar_lowgain = get_unipolar_lowgain( setup->dev, ad_subdev);
+       bipolar_lowgain = get_bipolar_lowgain( setup->dev, setup->ad_subdev);
+       bipolar_highgain = get_bipolar_highgain( setup->dev, setup->ad_subdev);
+       unipolar_lowgain = get_unipolar_lowgain( setup->dev, setup->ad_subdev);
 
        voltage_reference = 5.000;
 
        memset(&tmpl,0,sizeof(tmpl));
        tmpl.insn = INSN_READ;
        tmpl.n = 1;
-       tmpl.subdev = ad_subdev;
+       tmpl.subdev = setup->ad_subdev;
 
        memset(&po_tmpl2,0,sizeof(tmpl));
        po_tmpl2.insn = INSN_CONFIG;
        po_tmpl2.n = 2;
-       po_tmpl2.subdev = ad_subdev;
+       po_tmpl2.subdev = setup->ad_subdev;
 
        /* 0 offset, low gain */
        o = setup->observables + ni_zero_offset_low;
@@ -215,13 +215,13 @@ void ni_setup_observables( calibration_setup_t *setup )
                setup->n_observables = ni_unip_offset_low + 1;
        }
 
-       if(da_subdev>=0){
+       if(setup->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;
+               po_tmpl.subdev = setup->da_subdev;
 
                /* ao 0, zero offset */
                o = setup->observables + ni_ao0_zero_offset;
@@ -589,24 +589,24 @@ void cal_ni_results(void)
        //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);
+       bipolar_lowgain = get_bipolar_lowgain(dev,setup->ad_subdev);
+       bipolar_highgain = get_bipolar_highgain(dev,setup->ad_subdev);
+       unipolar_lowgain = get_unipolar_lowgain(dev,setup->ad_subdev);
 
        /* 0 offset, low gain */
-       range = comedi_get_range(dev,ad_subdev,0,bipolar_lowgain);
+       range = comedi_get_range(dev,setup->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);
+       range = comedi_get_range(dev,setup->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);
+       range = comedi_get_range(dev,setup->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);