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 );
{ "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 },
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;
}
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 );
+}
+