Added outline of code for loading pci-6052 caldacs from eeprom
authorFrank Mori Hess <fmhess@speakeasy.net>
Sat, 10 Sep 2005 22:20:43 +0000 (22:20 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Sat, 10 Sep 2005 22:20:43 +0000 (22:20 +0000)
(doesn't work yet).

comedi_calibrate/cb64.c

index 3d2fb7c567067020a8710fd2bf599f76eb1aca2a..527637397bdcf6ae5cbbd34dc2a64e966ba8da77 100644 (file)
@@ -46,11 +46,13 @@ struct board_struct{
 static int setup_cb_pci_64xx( calibration_setup_t *setup );
 static int setup_cb_pci_60xx( calibration_setup_t *setup );
 static int setup_cb_pci_603x( calibration_setup_t *setup );
+static int setup_cb_pci_6052( calibration_setup_t *setup );
 static int setup_cb_pci_4020( calibration_setup_t *setup );
 static int setup_cb_pci_unknown( calibration_setup_t *setup );
 
 static int cal_cb_pci_64xx( calibration_setup_t *setup );
 static int cal_cb_pci_60xx( calibration_setup_t *setup );
+static int cal_cb_pci_6052( calibration_setup_t *setup );
 static int cal_cb_pci_4020( calibration_setup_t *setup );
 
 static int init_observables_64xx( calibration_setup_t *setup );
@@ -74,7 +76,7 @@ static struct board_struct boards[]={
        { "pci-das6035",        STATUS_GUESS,   setup_cb_pci_603x },
        { "pci-das6036",        STATUS_GUESS,   setup_cb_pci_603x },
        { "pci-das6040",        STATUS_GUESS,   setup_cb_pci_60xx },
-       { "pci-das6052",        STATUS_UNKNOWN, setup_cb_pci_unknown },
+       { "pci-das6052",        STATUS_GUESS,   setup_cb_pci_6052 },
        { "pci-das6070",        STATUS_GUESS,   setup_cb_pci_60xx },
        { "pci-das6071",        STATUS_GUESS,   setup_cb_pci_60xx },
        { "pci-das4020/12",     STATUS_DONE,    setup_cb_pci_4020 },
@@ -139,6 +141,20 @@ enum cal_knobs_64xx
        ADC_OFFSET_64XX = 9,
 };
 
+enum cal_knobs_6052    // FIXME these values are uneducated guesses
+{
+       DAC0_GAIN_FINE_6052 = 0,
+       DAC0_GAIN_COARSE_6052 = 1,
+       DAC0_OFFSET_COARSE_6052 = 2,
+       DAC1_OFFSET_COARSE_6052 = 3,
+       DAC1_GAIN_FINE_6052 = 4,
+       DAC1_GAIN_COARSE_6052 = 5,
+       DAC0_OFFSET_FINE_6052 = 6,
+       DAC1_OFFSET_FINE_6052 = 7,
+       ADC_GAIN_6052 = 8,
+       ADC_OFFSET_6052 = 9,
+};
+
 int cb64_setup( calibration_setup_t *setup, const char *device_name )
 {
        unsigned int i;
@@ -947,3 +963,327 @@ static int init_observables_unknown( calibration_setup_t *setup )
        }
        return 0;
 }
+
+/* We were unable to read the onboard calibration reference voltages on the 6052, so we'll just
+ * load caldac values from eeprom until the problem is resolved somehow. */
+
+static int setup_cb_pci_6052( calibration_setup_t *setup )
+{
+       if( setup->caldac_subdev < 0 )
+       {
+               fprintf( stderr, "no caldac subdevice found\n");
+               return -1;
+       }
+       setup->do_cal = &cal_cb_pci_6052;
+       setup_caldacs(setup, setup->caldac_subdev);
+
+       return 0;
+}
+
+
+/* load analog input caldacs from eeprom values (depend on range used) */
+static void grab_ai_calibration_cb_pci_6052(calibration_setup_t *setup, unsigned int range)
+{
+       comedi_calibration_setting_t *current_cal;
+       enum source_eeprom_addr
+       {
+               EEPROM_5V_CHAN = 0x30,
+               EEPROM_3500mV_CHAN = 0x32,
+               EEPROM_1750mV_CHAN = 0x34,
+               EEPROM_875mV_CHAN = 0x36,
+               EEPROM_8600uV_CHAN = 0x38,
+       };
+/*     According to Measurement Computing the adc eeprom channels are:
+ADC Calibration values
+50      BIP10V offset
+51      BIP10V gain
+52      BIP5V offset
+53      BIP5V gain
+54      BIP2.5V offset
+55      BIP2.5V gain
+56      BIP1V offset
+57      BIP1V gain
+58      BIP0.5V offset
+59      BIP0.5V gain
+5A      BIP0.25V offset
+5B      BIP0.25V gain
+5C      BIP0.1V offset
+5D      BIP0.1V gain
+5E      BIP50mV offset
+5F      BIP50mV gain
+60      UNI10V offset
+61      UNI10V gain
+62      UNI5V offset
+63      UNI5V gain
+64      UNI2.5V offset
+65      UNI2.5V gain
+66      UNI1V offset
+67      UNI1V gain
+68      UNI0.5V offset
+69      UNI0.5V gain
+6A      UNI0.25V offset
+6B      UNI0.25V gain
+6C      UNI0.1V offset
+6D      UNI0.1V gain
+*/
+       int offset_eeprom_channel;
+       int gain_eeprom_channel;
+       int value;
+       const double epsilon = 0.001;
+       comedi_range *range_ptr = comedi_get_range(setup->dev, setup->ad_subdev, 0, range);
+       if(range_ptr == NULL)
+       {
+               fprintf(stderr, "%s: comedi_get_range returned NULL\n", __FUNCTION__);
+               abort();
+       }
+       if(is_unipolar(setup->dev, setup->ad_subdev, 0, range) == 0)
+       {
+               if(fabs(10. - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x50;
+                       gain_eeprom_channel = 0x51;
+               }else if(fabs(5. - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x52;
+                       gain_eeprom_channel = 0x53;
+               }else if(fabs(2.5 - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x54;
+                       gain_eeprom_channel = 0x55;
+               }else if(fabs(1. - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x56;
+                       gain_eeprom_channel = 0x57;
+               }else if(fabs(0.5 - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x58;
+                       gain_eeprom_channel = 0x59;
+               }else if(fabs(0.25 - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x5a;
+                       gain_eeprom_channel = 0x5b;
+               }else if(fabs(0.1 - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x5c;
+                       gain_eeprom_channel = 0x5d;
+               }else if(fabs(0.5 - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x5e;
+                       gain_eeprom_channel = 0x5f;
+               }else
+               {
+                       fprintf(stderr, "%s: logic error, failed to determine eeprom channel for range min=%g, max=%g\n",
+                               __FUNCTION__, range_ptr->min, range_ptr->max);
+                       abort();
+               }
+       }else
+       {
+               if(fabs(10. - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x60;
+                       gain_eeprom_channel = 0x61;
+               }else if(fabs(5. - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x62;
+                       gain_eeprom_channel = 0x63;
+               }else if(fabs(2.5 - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x64;
+                       gain_eeprom_channel = 0x65;
+               }else if(fabs(1. - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x66;
+                       gain_eeprom_channel = 0x67;
+               }else if(fabs(0.5 - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x68;
+                       gain_eeprom_channel = 0x69;
+               }else if(fabs(0.25 - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x6a;
+                       gain_eeprom_channel = 0x6b;
+               }else if(fabs(0.1 - range_ptr->max) < epsilon)
+               {
+                       offset_eeprom_channel = 0x6c;
+                       gain_eeprom_channel = 0x6d;
+               }else
+               {
+                       fprintf(stderr, "%s: logic error, failed to determine eeprom channel for range min=%g, max=%g\n",
+                               __FUNCTION__, range_ptr->min, range_ptr->max);
+                       abort();
+               }
+       }
+       current_cal = sc_alloc_calibration_setting(setup);
+
+       /* load offset */
+       value = read_eeprom(setup, offset_eeprom_channel);
+       if(value < 0)
+       {
+               fprintf(stderr, "%s: line %i: read_eeprom() returned error\n", __FUNCTION__, __LINE__);
+               abort();
+       }
+       update_caldac(setup, ADC_OFFSET_6052, value);
+       sc_push_caldac(current_cal, setup->caldacs[ADC_OFFSET_6052]);
+
+       /* load gain */
+       value = read_eeprom(setup, gain_eeprom_channel);
+       if(value < 0)
+       {
+               fprintf(stderr, "%s: line %i: read_eeprom() returned error\n", __FUNCTION__, __LINE__);
+               abort();
+       }
+       update_caldac(setup, ADC_GAIN_6052, value);
+       sc_push_caldac(current_cal, setup->caldacs[ADC_GAIN_6052]);
+
+       current_cal->subdevice = setup->ad_subdev;
+       sc_push_channel(current_cal, SC_ALL_CHANNELS);
+       sc_push_range(current_cal, range);
+       sc_push_aref(current_cal, SC_ALL_AREFS);
+
+       DPRINT( 0, "loaded adc range %i calibration from eeprom\n", range );
+}
+
+static int dac_gain_coarse_6052( unsigned int channel )
+{
+       if( channel ) return DAC1_GAIN_COARSE_6052;
+       else return DAC0_GAIN_COARSE_6052;
+}
+static int dac_gain_fine_6052( unsigned int channel )
+{
+       if( channel ) return DAC1_GAIN_FINE_6052;
+       else return DAC0_GAIN_FINE_6052;
+}
+static int dac_offset_coarse_6052( unsigned int channel )
+{
+       if( channel ) return DAC1_OFFSET_COARSE_6052;
+       else return DAC0_OFFSET_COARSE_6052;
+}
+static int dac_offset_fine_6052( unsigned int channel )
+{
+       if( channel ) return DAC1_OFFSET_FINE_6052;
+       else return DAC0_OFFSET_FINE_6052;
+}
+
+/* load analog output caldacs from eeprom values (depend on range used) */
+static void grab_ao_calibration_cb_pci_6052(calibration_setup_t *setup,
+       unsigned int channel, unsigned int range)
+{
+       comedi_calibration_setting_t *current_cal;
+       int value;
+       int gain_eeprom_chan;
+       int offset_eeprom_chan;
+/* According to Measurement Computing the dac eeprom channels are:
+DAC Calibration values
+70      DAC0 BIP10V coarse offset       DAC0 BIP10V fine offset
+71      DAC0 BIP10V coarse gain DAC0 BIP10V fine gain
+72      DAC0 UNI10V coarse offset       DAC0 UNI10V fine offset
+73      DAC0 UNI10V coarse gain DAC0 UNI10V fine gain
+74      DAC1 BIP10V coarse offset       DAC1 BIP10V fine offset
+75      DAC1 BIP10V coarse gain DAC1 BIP10V fine gain
+76      DAC1 UNI10V coarse offset       DAC1 UNI10V fine offset
+77      DAC1 UNI10V coarse gain DAC1 UNI10V fine gain
+*/
+       current_cal = sc_alloc_calibration_setting(setup);
+
+       if(is_unipolar(setup->dev, setup->da_subdev, channel, range))
+       {
+               switch(channel)
+               {
+               case 0:
+                       offset_eeprom_chan = 0x72;
+                       gain_eeprom_chan = 0x73;
+                       break;
+               case 1:
+                       offset_eeprom_chan = 0x76;
+                       gain_eeprom_chan = 0x77;
+                       break;
+               default:
+                       fprintf(stderr, "%s: line %i: logic error\n", __FUNCTION__, __LINE__);
+                       abort();
+                       break;
+               }
+       }else
+       {
+               switch(channel)
+               {
+               case 0:
+                       offset_eeprom_chan = 0x70;
+                       gain_eeprom_chan = 0x71;
+                       break;
+               case 1:
+                       offset_eeprom_chan = 0x74;
+                       gain_eeprom_chan = 0x75;
+                       break;
+               default:
+                       fprintf(stderr, "%s: line %i: logic error\n", __FUNCTION__, __LINE__);
+                       abort();
+                       break;
+               }
+       }
+
+       /* load offset */
+       value = read_eeprom(setup, offset_eeprom_chan);
+       if(value < 0)
+       {
+               fprintf(stderr, "%s: line %i: read_eeprom() returned error\n", __FUNCTION__, __LINE__);
+               abort();
+       }
+       update_caldac(setup, dac_offset_coarse_6052(channel), (value >> 8) & 0xff);
+       sc_push_caldac(current_cal, setup->caldacs[dac_offset_coarse_6052(channel)]);
+       update_caldac(setup, dac_offset_fine_6052(channel), value & 0xff);
+       sc_push_caldac(current_cal, setup->caldacs[dac_offset_fine_6052(channel)]);
+
+       // load gain calibration
+       value = read_eeprom(setup, gain_eeprom_chan);
+       if(value < 0)
+       {
+               fprintf(stderr, "%s: line %i: read_eeprom() returned error\n", __FUNCTION__, __LINE__);
+               abort();
+       }
+       update_caldac(setup, dac_gain_coarse_6052(channel), (value >> 8) & 0xff);
+       sc_push_caldac(current_cal, setup->caldacs[dac_gain_coarse_6052(channel)]);
+       update_caldac(setup, dac_gain_fine_6052(channel), value & 0xff);
+       sc_push_caldac(current_cal, setup->caldacs[dac_gain_fine_6052(channel)]);
+
+       current_cal->subdevice = setup->da_subdev;
+       sc_push_channel(current_cal, channel);
+       sc_push_range(current_cal, range);
+       sc_push_aref(current_cal, SC_ALL_AREFS);
+
+       DPRINT( 0, "loaded dac channel %i range %i calibration from eeprom\n",
+               channel, range );
+}
+
+
+static int cal_cb_pci_6052( calibration_setup_t *setup )
+{
+       int range, channel, num_ai_ranges, num_ao_ranges;
+
+       num_ai_ranges = comedi_get_n_ranges(setup->dev, setup->ad_subdev, 0);
+       if(num_ai_ranges < 0)
+       {
+               fprintf(stderr, "%s: line %i: comedi_get_n_ranges() returned error\n", __FUNCTION__, __LINE__);
+               abort();
+       }
+       num_ao_ranges = comedi_get_n_ranges(setup->dev, setup->da_subdev, 0);
+       if(num_ao_ranges < 0)
+       {
+               fprintf(stderr, "%s: line %i: comedi_get_n_ranges() returned error\n", __FUNCTION__, __LINE__);
+               abort();
+       }
+
+       for(range = 0; range < num_ai_ranges; range++)
+               grab_ai_calibration_cb_pci_6052(setup, range);
+
+       if(setup->da_subdev >= 0 && setup->do_output)
+       {
+               for(channel = 0; channel < 2; channel++)
+               {
+                       for(range = 0; range < num_ao_ranges; range++)
+                               grab_ao_calibration_cb_pci_6052(setup, channel, range);
+               }
+       }
+
+       return write_calibration_file( setup );
+}
+