analog output calibration for cb_pcidas boards, plus reading of calibration
authorFrank Mori Hess <fmhess@speakeasy.net>
Wed, 1 Jan 2003 22:47:07 +0000 (22:47 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Wed, 1 Jan 2003 22:47:07 +0000 (22:47 +0000)
voltages from eeprom.

comedi_calibrate/cb.c

index b81f6a907528a406b0efb578cf6312f472c0690a..cbfafbac57b22c6d5123e6fb7b487fa502054d93 100644 (file)
@@ -52,18 +52,21 @@ int setup_cb_pci_64xx( calibration_setup_t *setup );
 int setup_cb_pci_60xx( calibration_setup_t *setup );
 int setup_cb_pci_4020( calibration_setup_t *setup );
 int setup_cb_pci_1xxx( calibration_setup_t *setup );
+int setup_cb_pci_1001( calibration_setup_t *setup );
 int setup_cb_pci_1602_16( calibration_setup_t *setup );
 
 int cal_cb_pci_64xx( calibration_setup_t *setup );
 int cal_cb_pci_60xx( calibration_setup_t *setup );
 int cal_cb_pci_4020( calibration_setup_t *setup );
 int cal_cb_pci_1xxx( calibration_setup_t *setup );
+int cal_cb_pci_1001( calibration_setup_t *setup );
 int cal_cb_pci_1602_16( calibration_setup_t *setup );
 
 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 init_observables_1xxx( calibration_setup_t *setup );
+int init_observables_1001( calibration_setup_t *setup );
 int init_observables_1602_16( calibration_setup_t *setup );
 
 int actual_source_voltage( comedi_t *dev, unsigned int subdevice, unsigned int eeprom_channel, float *voltage);
@@ -80,7 +83,7 @@ static struct board_struct boards[]={
        { "pci-das6035",        STATUS_GUESS,   setup_cb_pci_60xx },
        { "pci-das4020/12",     STATUS_DONE,    setup_cb_pci_4020 },
        { "pci-das1000",        STATUS_GUESS,   setup_cb_pci_1xxx },
-       { "pci-das1001",        STATUS_GUESS,   setup_cb_pci_1xxx },
+       { "pci-das1001",        STATUS_GUESS,   setup_cb_pci_1001 },
        { "pci-das1002",        STATUS_GUESS,   setup_cb_pci_1xxx },
        { "pci-das1200",        STATUS_DONE,    setup_cb_pci_1xxx },
        { "pci-das1200/jr",     STATUS_GUESS,   setup_cb_pci_1xxx },
@@ -104,6 +107,10 @@ enum observables_64xx {
 enum observables_1xxx {
        OBS_0V_RANGE_10V_BIP_1XXX = 0,
        OBS_7V_RANGE_10V_BIP_1XXX,
+       OBS_DAC0_GROUND_1XXX,
+       OBS_DAC0_HIGH_1XXX,
+       OBS_DAC1_GROUND_1XXX,
+       OBS_DAC1_HIGH_1XXX,
 };
 
 enum observables_1602_16 {
@@ -173,6 +180,18 @@ int setup_cb_pci_1xxx( calibration_setup_t *setup )
        return 0;
 }
 
+int setup_cb_pci_1001( calibration_setup_t *setup )
+{
+       static const int caldac_subdev = 4;
+       static const int calpot_subdev = 5;
+
+       init_observables_1001( setup );
+       setup_caldacs( setup, caldac_subdev );
+       setup_caldacs( setup, calpot_subdev );
+       setup->do_cal = cal_cb_pci_1001;
+       return 0;
+}
+
 int setup_cb_pci_1602_16( calibration_setup_t *setup )
 {
        static const int caldac_subdev = 4;
@@ -409,21 +428,18 @@ int init_observables_4020( calibration_setup_t *setup )
 
 int init_observables_1xxx( calibration_setup_t *setup )
 {
-       comedi_insn tmpl;//, po_tmpl;
+       comedi_insn tmpl, po_tmpl;
        observable *o;
-#if 0
-// XXX need to figure out eeprom map
        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,
+               EEPROM_7V_CHAN = 0x80,
+               EEPROM_3500mV_CHAN = 0x84,
+               EEPROM_1750mV_CHAN = 0x88,
+               EEPROM_875mV_CHAN = 0x8c,
+               EEPROM_8600uV_CHAN = 0x90,
        };
-#endif
        enum calibration_source
        {
                CAL_SRC_GROUND = 0,
@@ -435,12 +451,17 @@ int init_observables_1xxx( calibration_setup_t *setup )
                CAL_SRC_DAC0 = 6,
                CAL_SRC_DAC1 = 7,
        };
-#if 0
-       memset( &po_tmpl, 0, sizeof(po_tmpl) );
-       po_tmpl.insn = INSN_CONFIG;
-       po_tmpl.n = 2;
-       po_tmpl.subdev = setup->ad_subdev;
-#endif
+       enum ai_ranges
+       {
+               AI_RNG_BIP_10V = 0
+       };
+       enum ao_ranges
+       {
+               AO_RNG_BIP_10V = 1,
+       };
+
+       setup->n_observables = 0;
+
        memset( &tmpl, 0, sizeof(tmpl) );
        tmpl.insn = INSN_READ;
        tmpl.n = 1;
@@ -450,21 +471,197 @@ int init_observables_1xxx( calibration_setup_t *setup )
        o->name = "ground calibration source, 10V bipolar range, ground referenced";
        o->reference_source = CAL_SRC_GROUND;
        o->observe_insn = tmpl;
-       o->observe_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER;
+       o->observe_insn.chanspec = CR_PACK( 0, AI_RNG_BIP_10V, AREF_GROUND) |
+               CR_ALT_SOURCE | CR_ALT_FILTER;
        o->target = 0.0;
+       setup->n_observables++;
 
        o = setup->observables + OBS_7V_RANGE_10V_BIP_1XXX;
        o->name = "7V calibration source, 10V bipolar range, ground referenced";
        o->reference_source = CAL_SRC_7V;
        o->observe_insn = tmpl;
-       o->observe_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER;
+       o->observe_insn.chanspec = CR_PACK( 0, AI_RNG_BIP_10V, AREF_GROUND) |
+               CR_ALT_SOURCE | CR_ALT_FILTER;
        o->target = 7.0;
-#if 0
        retval = actual_source_voltage( setup->dev, setup->eeprom_subdev, EEPROM_7V_CHAN, &target );
        if( retval == 0 )
                o->target = target;
-#endif
-       setup->n_observables = 2;
+       setup->n_observables++;
+
+       if( setup->da_subdev >= 0 )
+       {
+               memset( &po_tmpl, 0, sizeof(po_tmpl) );
+               po_tmpl.insn = INSN_WRITE;
+               po_tmpl.n = 1;
+               po_tmpl.subdev = setup->da_subdev;
+
+               o = setup->observables + OBS_DAC0_GROUND_1XXX;
+               o->name = "DAC0 ground calibration source, 10V bipolar input range";
+               o->reference_source = CAL_SRC_DAC0;
+               o->preobserve_insn = po_tmpl;
+               o->preobserve_insn.chanspec = CR_PACK( 0, AO_RNG_BIP_10V, AREF_GROUND );
+               o->preobserve_insn.data = o->preobserve_data;
+               o->observe_insn = tmpl;
+               o->observe_insn.chanspec = CR_PACK( 0, AI_RNG_BIP_10V, AREF_GROUND) |
+                       CR_ALT_SOURCE | CR_ALT_FILTER;
+               set_target( setup, OBS_DAC0_GROUND_1XXX, 0.0 );
+               setup->n_observables++;
+
+               o = setup->observables + OBS_DAC0_HIGH_1XXX;
+               o->name = "DAC0 high calibration source, 10V bipolar input range";
+               o->reference_source = CAL_SRC_DAC0;
+               o->preobserve_insn = po_tmpl;
+               o->preobserve_insn.chanspec = CR_PACK( 0 , AO_RNG_BIP_10V, AREF_GROUND );
+               o->preobserve_insn.data = o->preobserve_data;
+               o->observe_insn = tmpl;
+               o->observe_insn.chanspec = CR_PACK( 0, AI_RNG_BIP_10V, AREF_GROUND) |
+                       CR_ALT_SOURCE | CR_ALT_FILTER;
+               set_target( setup, OBS_DAC0_HIGH_1XXX, 8.0 );
+               setup->n_observables++;
+
+               o = setup->observables + OBS_DAC1_GROUND_1XXX;
+               o->name = "DAC1 ground calibration source, 10V bipolar input range";
+               o->reference_source = CAL_SRC_DAC1;
+               o->preobserve_insn = po_tmpl;
+               o->preobserve_insn.chanspec = CR_PACK( 1, AO_RNG_BIP_10V, AREF_GROUND );
+               o->preobserve_insn.data = o->preobserve_data;
+               o->observe_insn = tmpl;
+               o->observe_insn.chanspec = CR_PACK( 0, AI_RNG_BIP_10V, AREF_GROUND) |
+                       CR_ALT_SOURCE | CR_ALT_FILTER;
+               set_target( setup, OBS_DAC1_GROUND_1XXX, 0.0 );
+               setup->n_observables++;
+
+               o = setup->observables + OBS_DAC1_HIGH_1XXX;
+               o->name = "DAC1 high calibration source, 10V bipolar input range";
+               o->reference_source = CAL_SRC_DAC1;
+               o->preobserve_insn = po_tmpl;
+               o->preobserve_insn.chanspec = CR_PACK( 1 , AO_RNG_BIP_10V, AREF_GROUND );
+               o->preobserve_insn.data = o->preobserve_data;
+               o->observe_insn = tmpl;
+               o->observe_insn.chanspec = CR_PACK( 0, AI_RNG_BIP_10V, AREF_GROUND) |
+                       CR_ALT_SOURCE | CR_ALT_FILTER;
+               set_target( setup, OBS_DAC1_HIGH_1XXX, 8.0 );
+               setup->n_observables++;
+       }
+
+       return 0;
+}
+
+int init_observables_1001( calibration_setup_t *setup )
+{
+       comedi_insn tmpl, po_tmpl;
+       observable *o;
+       int retval;
+       float target;
+       enum source_eeprom_addr
+       {
+               EEPROM_7V_CHAN = 0x80,
+               EEPROM_88600uV_CHAN = 0x88,
+               EEPROM_875mV_CHAN = 0x8c,
+               EEPROM_8600uV_CHAN = 0x90,
+       };
+       enum calibration_source
+       {
+               CAL_SRC_GROUND = 0,
+               CAL_SRC_7V = 1,
+               CAL_SRC_88600uV = 3,
+               CAL_SRC_875mV = 4,
+               CAL_SRC_8600uV = 5,
+               CAL_SRC_DAC0 = 6,
+               CAL_SRC_DAC1 = 7,
+       };
+       enum ai_ranges
+       {
+               AI_RNG_BIP_10V = 0
+       };
+       enum ao_ranges
+       {
+               AO_RNG_BIP_10V = 1,
+       };
+
+       setup->n_observables = 0;
+
+       memset( &tmpl, 0, sizeof(tmpl) );
+       tmpl.insn = INSN_READ;
+       tmpl.n = 1;
+       tmpl.subdev = setup->ad_subdev;
+
+       o = setup->observables + OBS_0V_RANGE_10V_BIP_1XXX;
+       o->name = "ground calibration source, 10V bipolar range, ground referenced";
+       o->reference_source = CAL_SRC_GROUND;
+       o->observe_insn = tmpl;
+       o->observe_insn.chanspec = CR_PACK( 0, AI_RNG_BIP_10V, AREF_GROUND) |
+               CR_ALT_SOURCE | CR_ALT_FILTER;
+       o->target = 0.0;
+       setup->n_observables++;
+
+       o = setup->observables + OBS_7V_RANGE_10V_BIP_1XXX;
+       o->name = "7V calibration source, 10V bipolar range, ground referenced";
+       o->reference_source = CAL_SRC_7V;
+       o->observe_insn = tmpl;
+       o->observe_insn.chanspec = CR_PACK( 0, AI_RNG_BIP_10V, 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++;
+
+       if( setup->da_subdev >= 0 )
+       {
+               memset( &po_tmpl, 0, sizeof(po_tmpl) );
+               po_tmpl.insn = INSN_WRITE;
+               po_tmpl.n = 1;
+               po_tmpl.subdev = setup->da_subdev;
+
+               o = setup->observables + OBS_DAC0_GROUND_1XXX;
+               o->name = "DAC0 ground calibration source, 10V bipolar input range";
+               o->reference_source = CAL_SRC_DAC0;
+               o->preobserve_insn = po_tmpl;
+               o->preobserve_insn.chanspec = CR_PACK( 0, AO_RNG_BIP_10V, AREF_GROUND );
+               o->preobserve_insn.data = o->preobserve_data;
+               o->observe_insn = tmpl;
+               o->observe_insn.chanspec = CR_PACK( 0, AI_RNG_BIP_10V, AREF_GROUND) |
+                       CR_ALT_SOURCE | CR_ALT_FILTER;
+               set_target( setup, OBS_DAC0_GROUND_1XXX, 0.0 );
+               setup->n_observables++;
+
+               o = setup->observables + OBS_DAC0_HIGH_1XXX;
+               o->name = "DAC0 high calibration source, 10V bipolar input range";
+               o->reference_source = CAL_SRC_DAC0;
+               o->preobserve_insn = po_tmpl;
+               o->preobserve_insn.chanspec = CR_PACK( 0 , AO_RNG_BIP_10V, AREF_GROUND );
+               o->preobserve_insn.data = o->preobserve_data;
+               o->observe_insn = tmpl;
+               o->observe_insn.chanspec = CR_PACK( 0, AI_RNG_BIP_10V, AREF_GROUND) |
+                       CR_ALT_SOURCE | CR_ALT_FILTER;
+               set_target( setup, OBS_DAC0_HIGH_1XXX, 8.0 );
+               setup->n_observables++;
+
+               o = setup->observables + OBS_DAC1_GROUND_1XXX;
+               o->name = "DAC1 ground calibration source, 10V bipolar input range";
+               o->reference_source = CAL_SRC_DAC1;
+               o->preobserve_insn = po_tmpl;
+               o->preobserve_insn.chanspec = CR_PACK( 1, AO_RNG_BIP_10V, AREF_GROUND );
+               o->preobserve_insn.data = o->preobserve_data;
+               o->observe_insn = tmpl;
+               o->observe_insn.chanspec = CR_PACK( 0, AI_RNG_BIP_10V, AREF_GROUND) |
+                       CR_ALT_SOURCE | CR_ALT_FILTER;
+               set_target( setup, OBS_DAC1_GROUND_1XXX, 0.0 );
+               setup->n_observables++;
+
+               o = setup->observables + OBS_DAC1_HIGH_1XXX;
+               o->name = "DAC1 high calibration source, 10V bipolar input range";
+               o->reference_source = CAL_SRC_DAC1;
+               o->preobserve_insn = po_tmpl;
+               o->preobserve_insn.chanspec = CR_PACK( 1 , AO_RNG_BIP_10V, AREF_GROUND );
+               o->preobserve_insn.data = o->preobserve_data;
+               o->observe_insn = tmpl;
+               o->observe_insn.chanspec = CR_PACK( 0, AI_RNG_BIP_10V, AREF_GROUND) |
+                       CR_ALT_SOURCE | CR_ALT_FILTER;
+               set_target( setup, OBS_DAC1_HIGH_1XXX, 8.0 );
+               setup->n_observables++;
+       }
 
        return 0;
 }
@@ -493,7 +690,7 @@ int init_observables_1602_16( calibration_setup_t *setup )
                CAL_SRC_3500mV = 2,
                CAL_SRC_1750mV = 3,
                CAL_SRC_875mV = 4,
-               CAL_SRC_8600uV = 5,
+               CAL_SRC_minus_10V = 5,
                CAL_SRC_DAC0 = 6,
                CAL_SRC_DAC1 = 7,
        };
@@ -650,6 +847,55 @@ int cal_cb_pci_1xxx( calibration_setup_t *setup )
        cal1( setup, OBS_7V_RANGE_10V_BIP_1XXX, ADC_GAIN );
        cal1_fine( setup, OBS_7V_RANGE_10V_BIP_1XXX, ADC_GAIN );
 
+       if( setup->da_subdev >= 0 )
+       {
+               cal1( setup, OBS_DAC0_GROUND_1XXX, DAC0_OFFSET );
+               cal1( setup, OBS_DAC0_HIGH_1XXX, DAC0_GAIN_COARSE );
+               cal1( setup, OBS_DAC0_HIGH_1XXX, DAC0_GAIN_FINE );
+
+               cal1( setup, OBS_DAC1_GROUND_1XXX, DAC1_OFFSET );
+               cal1( setup, OBS_DAC1_HIGH_1XXX, DAC1_GAIN_COARSE );
+               cal1( setup, OBS_DAC1_HIGH_1XXX, DAC1_GAIN_FINE );
+       }
+
+       return 0;
+}
+
+int cal_cb_pci_1001( calibration_setup_t *setup )
+{
+       enum cal_knobs_1xxx
+       {
+               DAC0_GAIN_FINE = 0,
+               DAC0_GAIN_COARSE,
+               DAC0_OFFSET,
+               DAC1_OFFSET,
+               DAC1_GAIN_FINE,
+               DAC1_GAIN_COARSE,
+               ADC_OFFSET_COARSE,
+               ADC_OFFSET_FINE,
+               ADC_GAIN,
+       };
+
+       cal1( setup, OBS_0V_RANGE_10V_BIP_1XXX, ADC_OFFSET_COARSE );
+       cal1_fine( setup, OBS_0V_RANGE_10V_BIP_1XXX, ADC_OFFSET_COARSE );
+
+       cal1( setup, OBS_0V_RANGE_10V_BIP_1XXX, ADC_OFFSET_FINE );
+       cal1_fine( setup, OBS_0V_RANGE_10V_BIP_1XXX, ADC_OFFSET_FINE );
+
+       cal1( setup, OBS_7V_RANGE_10V_BIP_1XXX, ADC_GAIN );
+       cal1_fine( setup, OBS_7V_RANGE_10V_BIP_1XXX, ADC_GAIN );
+
+       if( setup->da_subdev >= 0 )
+       {
+               cal1( setup, OBS_DAC0_GROUND_1XXX, DAC0_OFFSET );
+               cal1( setup, OBS_DAC0_HIGH_1XXX, DAC0_GAIN_COARSE );
+               cal1( setup, OBS_DAC0_HIGH_1XXX, DAC0_GAIN_FINE );
+
+               cal1( setup, OBS_DAC1_GROUND_1XXX, DAC1_OFFSET );
+               cal1( setup, OBS_DAC1_HIGH_1XXX, DAC1_GAIN_COARSE );
+               cal1( setup, OBS_DAC1_HIGH_1XXX, DAC1_GAIN_FINE );
+       }
+
        return 0;
 }
 
@@ -683,7 +929,7 @@ int cal_cb_pci_1602_16( calibration_setup_t *setup )
 }
 
 // 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)
+float eeprom16_to_source( uint16_t *data )
 {
        union translator
        {
@@ -693,7 +939,26 @@ float eeprom_to_source(uint16_t ls_word, uint16_t ms_word)
 
        union translator my_translator;
 
-       my_translator.bits = ( ls_word & 0xffff ) | ( ( ms_word << 16 ) & 0xffff0000 );
+       my_translator.bits = ( data[ 0 ] & 0xffff ) | ( ( data[ 1 ] << 16 ) & 0xffff0000 );
+
+       return my_translator.value;
+}
+
+float eeprom8_to_source( uint8_t *data )
+{
+       union translator
+       {
+               uint32_t bits;
+               float   value;
+       };
+       union translator my_translator;
+       int i;
+
+       my_translator.bits = 0;
+       for( i = 0; i < 4; i++ )
+       {
+               my_translator.bits |= ( data[ i ] & 0xffff ) << ( 8 * i );
+       }
 
        return my_translator.value;
 }
@@ -701,22 +966,48 @@ float eeprom_to_source(uint16_t ls_word, uint16_t ms_word)
 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;
+       int max_data;
+
+       max_data = comedi_get_maxdata( dev, subdevice, eeprom_channel );
+
+       if( max_data == 0xffff )
+       {
+               uint16_t word[ 2 ];
 
-       for( i = 0; i < 2; i++ )
+               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 = eeprom16_to_source( word );
+       }else if( max_data == 0xff )
        {
-               retval = comedi_data_read( dev, subdevice, eeprom_channel + i, 0, 0, &data );
-               if( retval < 0 )
+               uint8_t byte[ 4 ];
+
+               for( i = 0; i < 4; i++ )
                {
-                       perror( "actual_source_voltage()" );
-                       return retval;
+                       retval = comedi_data_read( dev, subdevice, eeprom_channel + i, 0, 0, &data );
+                       if( retval < 0 )
+                       {
+                               perror( "actual_source_voltage()" );
+                               return retval;
+                       }
+                       byte[ i ] = data;
                }
-               word[ i ] = data;
+               *voltage = eeprom8_to_source( byte );
+       }else
+       {
+               perror( "actual_source_voltage(), maxdata invalid" );
+               return -1;
        }
 
-       *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);
+       DPRINT(0, "eeprom ch %i gives calibration source of %gV\n", eeprom_channel, *voltage);
        return 0;
 }