Added outline of code for loading pci-6052 caldacs from eeprom

(doesn't work yet).
This commit is contained in:
Frank Mori Hess 2005-09-10 22:20:43 +00:00
parent 47f1100bf9
commit 43c7a043b7

View 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 );
}