From 43c7a043b741e0dcfac116118d40e63d3eb1e3f2 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Sat, 10 Sep 2005 22:20:43 +0000 Subject: [PATCH] Added outline of code for loading pci-6052 caldacs from eeprom (doesn't work yet). --- comedi_calibrate/cb64.c | 342 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 341 insertions(+), 1 deletion(-) diff --git a/comedi_calibrate/cb64.c b/comedi_calibrate/cb64.c index 3d2fb7c..5276373 100644 --- a/comedi_calibrate/cb64.c +++ b/comedi_calibrate/cb64.c @@ -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 ); +} + -- 2.26.2