From 3bf61fbe4426b0d52d21953a5fb93eec4ce0867b Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Tue, 22 Apr 2003 21:20:39 +0000 Subject: [PATCH] added multi-range calibration support for pci-das4020 --- comedi_calibrate/cb64.c | 312 +++++++++++++++++++++++----------------- 1 file changed, 178 insertions(+), 134 deletions(-) diff --git a/comedi_calibrate/cb64.c b/comedi_calibrate/cb64.c index ab80af7..f0a4e32 100644 --- a/comedi_calibrate/cb64.c +++ b/comedi_calibrate/cb64.c @@ -96,32 +96,48 @@ enum calibration_source_64xx CS_64XX_DAC1 = 7, }; +enum calibration_source_4020 +{ + CS_4020_4375mV = 5, + CS_4020_625mV = 6, + CS_4020_GROUND = 7, +}; + enum cal_knobs_60xx { DAC0_OFFSET_60XX = 0, - DAC0_GAIN_60XX, - DAC1_OFFSET_60XX, - DAC1_GAIN_60XX, - ADC_OFFSET_FINE_60XX, - ADC_OFFSET_COARSE_60XX, - ADC_GAIN_COARSE_60XX, - ADC_GAIN_FINE_60XX, + DAC0_GAIN_60XX = 1, + DAC1_OFFSET_60XX = 2, + DAC1_GAIN_60XX = 3, + ADC_OFFSET_FINE_60XX = 4, + ADC_OFFSET_COARSE_60XX = 5, + ADC_GAIN_COARSE_60XX = 6, + ADC_GAIN_FINE_60XX = 7, }; enum cal_knobs_64xx { DAC0_GAIN_FINE_64XX = 0, - DAC0_GAIN_COARSE_64XX, - DAC0_OFFSET_COARSE_64XX, - DAC1_OFFSET_COARSE_64XX, - DAC1_GAIN_FINE_64XX, - DAC1_GAIN_COARSE_64XX, - DAC0_OFFSET_FINE_64XX, - DAC1_OFFSET_FINE_64XX, - ADC_GAIN_64XX, - ADC_OFFSET_64XX, + DAC0_GAIN_COARSE_64XX = 1, + DAC0_OFFSET_COARSE_64XX = 2, + DAC1_OFFSET_COARSE_64XX = 3, + DAC1_GAIN_FINE_64XX = 4, + DAC1_GAIN_COARSE_64XX = 5, + DAC0_OFFSET_FINE_64XX = 6, + DAC1_OFFSET_FINE_64XX = 7, + ADC_GAIN_64XX = 8, + ADC_OFFSET_64XX = 9, }; +static inline unsigned int ADC_OFFSET_4020( unsigned int channel ) +{ + return channel; +} +static inline unsigned int ADC_GAIN_4020( unsigned int channel ) +{ + return 4 + channel; +} + int cb64_setup( calibration_setup_t *setup, const char *device_name ) { unsigned int i; @@ -600,104 +616,104 @@ static int init_observables_60xx( calibration_setup_t *setup ) return 0; } -static int init_observables_4020( calibration_setup_t *setup ) +static unsigned int ai_low_observable_index_4020( unsigned int channel, + unsigned int ai_range ) +{ + return 4 * channel + 2 * ai_range; +} + +static unsigned int ai_high_observable_index_4020( unsigned int channel, + unsigned int ai_range ) +{ + return ai_low_observable_index_4020( channel, ai_range ) + 1; +} + +static int high_ai_cal_src_4020( calibration_setup_t *setup, unsigned int ai_range ) +{ + comedi_range *range; + + range = comedi_get_range( setup->dev, setup->ad_subdev, 0, ai_range ); + if( range == NULL ) return -1; + + if( range->max > 4.4 ) + return CS_4020_4375mV; + else if( range->max > 0.7 ) + return CS_4020_625mV; + + return -1; +} + +static int source_eeprom_addr_4020( calibration_setup_t *setup, unsigned int range_index ) { - comedi_insn tmpl;//, po_tmpl; - observable *o; - float target; - int retval; enum source_eeprom_addr { EEPROM_4375mV_CHAN = 0x30, EEPROM_625mV_CHAN = 0x32, }; - enum calibration_source - { - CAL_SRC_4375mV = 5, - CAL_SRC_625mV = 6, - CAL_SRC_GROUND = 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 + comedi_range *range; + + range = comedi_get_range( setup->dev, setup->ad_subdev, 0, range_index ); + if( range == NULL ) return -1; + + if( range->max > 4.4 ) + return EEPROM_4375mV_CHAN; + else if( range->max > 0.7 ) + return EEPROM_625mV_CHAN; + + return -1; +} + +static int init_observables_4020( calibration_setup_t *setup ) +{ + comedi_insn tmpl; + observable *o; + float target; + int retval; + int range, channel, num_ranges, num_channels; + memset( &tmpl, 0, sizeof(tmpl) ); tmpl.insn = INSN_READ; tmpl.n = 1; tmpl.subdev = setup->ad_subdev; - o = setup->observables + 0; - o->name = "ground calibration source, ch 0, 5V 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->target = 0.0; - - - o = setup->observables + 1; - o->name = "ground calibration source, ch 1, 5V bipolar range, ground referenced"; - o->reference_source = CAL_SRC_GROUND; - o->observe_insn = tmpl; - o->observe_insn.chanspec = CR_PACK( 1, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER; - o->target = 0.0; - - o = setup->observables + 2; - o->name = "ground calibration source, ch 2, 5V bipolar range, ground referenced"; - o->reference_source = CAL_SRC_GROUND; - o->observe_insn = tmpl; - o->observe_insn.chanspec = CR_PACK( 2, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER; - o->target = 0.0; - - o = setup->observables + 3; - o->name = "ground calibration source, ch 3, 5V bipolar range, ground referenced"; - o->reference_source = CAL_SRC_GROUND; - o->observe_insn = tmpl; - o->observe_insn.chanspec = CR_PACK( 3, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER; - o->target = 0.0; - - o = setup->observables + 4; - o->name = "4.375V calibration source, ch 0, 5V bipolar range, ground referenced"; - o->reference_source = CAL_SRC_4375mV; - o->observe_insn = tmpl; - o->observe_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER; - o->target = 4.375; - retval = cb_actual_source_voltage( setup->dev, setup->eeprom_subdev, EEPROM_4375mV_CHAN, &target ); - if( retval == 0 ) - o->target = target; - - o = setup->observables + 5; - o->name = "4.375V calibration source, ch 1, 5V bipolar range, ground referenced"; - o->reference_source = CAL_SRC_4375mV; - o->observe_insn = tmpl; - o->observe_insn.chanspec = CR_PACK( 1, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER; - o->target = 4.375; - retval = cb_actual_source_voltage( setup->dev, setup->eeprom_subdev, EEPROM_4375mV_CHAN, &target ); - if( retval == 0 ) - o->target = target; + num_ranges = comedi_get_n_ranges( setup->dev, setup->ad_subdev, 0 ); + if( num_ranges < 0 ) return -1; - o = setup->observables + 6; - o->name = "4.375V calibration source, ch 2, 5V bipolar range, ground referenced"; - o->reference_source = CAL_SRC_4375mV; - o->observe_insn = tmpl; - o->observe_insn.chanspec = CR_PACK( 2, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER; - o->target = 4.375; - retval = cb_actual_source_voltage( setup->dev, setup->eeprom_subdev, EEPROM_4375mV_CHAN, &target ); - if( retval == 0 ) - o->target = target; + num_channels = comedi_get_n_channels( setup->dev, setup->ad_subdev ); + if( num_channels < 0 ) return -1; - o = setup->observables + 7; - o->name = "4.375V calibration source, ch 3, 5V bipolar range, ground referenced"; - o->reference_source = CAL_SRC_4375mV; - o->observe_insn = tmpl; - o->observe_insn.chanspec = CR_PACK( 3, 0, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER; - o->target = 4.375; - retval = cb_actual_source_voltage( setup->dev, setup->eeprom_subdev, EEPROM_4375mV_CHAN, &target ); - if( retval == 0 ) - o->target = target; + setup->n_observables = 0; - setup->n_observables = 8; + for( channel = 0; channel < num_channels; channel++ ) + { + for( range = 0; range < num_ranges; range++ ) + { + o = setup->observables + ai_low_observable_index_4020( channel, range ); + assert( o->name == NULL ); + asprintf( &o->name, "ground calibration source, ch %i, range %i, ground referenced", + channel, range ); + o->reference_source = CS_4020_GROUND; + o->observe_insn = tmpl; + o->observe_insn.chanspec = CR_PACK( channel, range, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER; + o->target = 0.0; + setup->n_observables++; + + o = setup->observables + ai_high_observable_index_4020( channel, range ); + retval = high_ai_cal_src_4020( setup, range ); + if( retval < 0 ) return -1; + o->reference_source = retval; + assert( o->name == NULL ); + asprintf( &o->name, "calibration source %i, ch %i, range %i, ground referenced", + o->reference_source, channel, range ); + o->observe_insn = tmpl; + o->observe_insn.chanspec = CR_PACK( channel, range, AREF_GROUND) | CR_ALT_SOURCE | CR_ALT_FILTER; + retval = cb_actual_source_voltage( setup->dev, setup->eeprom_subdev, + source_eeprom_addr_4020( setup, range ), &target ); + if( retval < 0 ) return retval; + o->target = target; + setup->n_observables++; + } + } return 0; } @@ -790,6 +806,7 @@ static int cal_cb_pci_64xx( calibration_setup_t *setup ) saved_cals = malloc( num_calibrations * sizeof( saved_calibration_t ) ); if( saved_cals == NULL ) return -1; + memset( saved_cals, 0, num_calibrations * sizeof( saved_calibration_t ) ); current_cal = saved_cals; for( i = 0; i < num_ai_ranges ; i++ ) @@ -799,7 +816,6 @@ static int cal_cb_pci_64xx( calibration_setup_t *setup ) cal_binary( setup, ai_ground_observable_index_64xx( i ), ADC_OFFSET_64XX ); cal_binary( setup, ai_high_observable_index_64xx( i ), ADC_GAIN_64XX ); - memset( current_cal, 0, sizeof( saved_calibration_t ) ); current_cal->subdevice = setup->ad_subdev; sc_push_caldac( current_cal, setup->caldacs[ ADC_OFFSET_64XX ] ); sc_push_caldac( current_cal, setup->caldacs[ ADC_GAIN_64XX ] ); @@ -827,7 +843,6 @@ static int cal_cb_pci_64xx( calibration_setup_t *setup ) cal_binary( setup, ao_low_observable_index_64xx( setup, 0, i ), DAC0_OFFSET_FINE_64XX ); cal_binary( setup, ao_high_observable_index_64xx( setup, 0, i ), DAC0_GAIN_FINE_64XX ); - memset( current_cal, 0, sizeof( saved_calibration_t ) ); current_cal->subdevice = setup->da_subdev; sc_push_caldac( current_cal, setup->caldacs[ DAC0_OFFSET_COARSE_64XX ] ); sc_push_caldac( current_cal, setup->caldacs[ DAC0_GAIN_COARSE_64XX ] ); @@ -846,7 +861,6 @@ static int cal_cb_pci_64xx( calibration_setup_t *setup ) cal_binary( setup, ao_low_observable_index_64xx( setup, 1, i ), DAC1_OFFSET_FINE_64XX ); cal_binary( setup, ao_high_observable_index_64xx( setup, 1, i ), DAC1_GAIN_FINE_64XX ); - memset( current_cal, 0, sizeof( saved_calibration_t ) ); current_cal->subdevice = setup->da_subdev; sc_push_caldac( current_cal, setup->caldacs[ DAC1_OFFSET_COARSE_64XX ] ); sc_push_caldac( current_cal, setup->caldacs[ DAC1_GAIN_COARSE_64XX ] ); @@ -949,6 +963,8 @@ static int cal_cb_pci_60xx( calibration_setup_t *setup ) saved_cals = malloc( num_calibrations * sizeof( saved_calibration_t ) ); if( saved_cals == NULL ) return -1; + memset( saved_cals, 0, num_calibrations * sizeof( saved_calibration_t ) ); + current_cal = saved_cals; for( i = 0; i < num_ai_ranges ; i++ ) { @@ -959,7 +975,6 @@ static int cal_cb_pci_60xx( calibration_setup_t *setup ) cal_binary( setup, ai_high_observable_index_60xx( i ), ADC_GAIN_COARSE_60XX ); cal_binary( setup, ai_high_observable_index_60xx( i ), ADC_GAIN_FINE_60XX ); - memset( current_cal, 0, sizeof( saved_calibration_t ) ); current_cal->subdevice = setup->ad_subdev; sc_push_caldac( current_cal, setup->caldacs[ ADC_OFFSET_FINE_60XX ] ); sc_push_caldac( current_cal, setup->caldacs[ ADC_OFFSET_COARSE_60XX ] ); @@ -991,7 +1006,6 @@ static int cal_cb_pci_60xx( calibration_setup_t *setup ) cal_binary( setup, ao_low_observable_index_60xx( setup, 0, i ), DAC0_OFFSET_60XX ); cal_binary( setup, ao_high_observable_index_60xx( setup, 0, i ), DAC0_GAIN_60XX ); - memset( current_cal, 0, sizeof( saved_calibration_t ) ); current_cal->subdevice = setup->da_subdev; sc_push_caldac( current_cal, setup->caldacs[ DAC0_OFFSET_60XX ] ); sc_push_caldac( current_cal, setup->caldacs[ DAC0_GAIN_60XX ] ); @@ -1006,7 +1020,6 @@ static int cal_cb_pci_60xx( calibration_setup_t *setup ) cal_binary( setup, ao_low_observable_index_60xx( setup, 1, i ), DAC1_OFFSET_60XX ); cal_binary( setup, ao_high_observable_index_60xx( setup, 1, i ), DAC1_GAIN_60XX ); - memset( current_cal, 0, sizeof( saved_calibration_t ) ); current_cal->subdevice = setup->da_subdev; sc_push_caldac( current_cal, setup->caldacs[ DAC1_OFFSET_60XX ] ); sc_push_caldac( current_cal, setup->caldacs[ DAC1_GAIN_60XX ] ); @@ -1024,44 +1037,75 @@ static int cal_cb_pci_60xx( calibration_setup_t *setup ) return retval; } -static int cal_cb_pci_4020( calibration_setup_t *setup ) +static void prep_adc_caldacs_4020( calibration_setup_t *setup, + unsigned int channel, unsigned int range ) { - enum cal_knobs_4020 + int retval; + + if( setup->do_reset ) { - ADC0_OFFSET = 0, - ADC1_OFFSET, - ADC2_OFFSET, - ADC3_OFFSET, - ADC0_GAIN, - ADC1_GAIN, - ADC2_GAIN, - ADC3_GAIN, - }; + reset_caldac( setup, ADC_OFFSET_4020( channel ) ); + reset_caldac( setup, ADC_GAIN_4020( channel ) ); + }else + { + retval = comedi_apply_calibration( setup->dev, setup->ad_subdev, + channel, range, AREF_GROUND, setup->cal_save_file_path); + if( retval < 0 ) + { + reset_caldac( setup, ADC_OFFSET_4020( channel ) ); + reset_caldac( setup, ADC_GAIN_4020( channel ) ); + } + } +} + +static int cal_cb_pci_4020( calibration_setup_t *setup ) +{ + int range, channel, num_ranges, num_channels, retval, + num_calibrations, i; + saved_calibration_t *saved_cals, *current_cal; + + comedi_set_global_oor_behavior( COMEDI_OOR_NUMBER ); + + num_ranges = comedi_get_n_ranges( setup->dev, setup->ad_subdev, 0 ); + if( num_ranges < 0 ) return -1; + + num_channels = comedi_get_n_channels( setup->dev, setup->ad_subdev ); + if( num_channels < 0 ) return -1; - cal1( setup, 0, ADC0_OFFSET ); - cal1_fine( setup, 0, ADC0_OFFSET ); + num_calibrations = num_ranges * num_channels; - cal1( setup, 1, ADC1_OFFSET ); - cal1_fine( setup, 1, ADC1_OFFSET ); + saved_cals = malloc( num_calibrations * sizeof( saved_calibration_t ) ); + if( saved_cals == NULL ) return -1; - cal1( setup, 2, ADC2_OFFSET ); - cal1_fine( setup, 2, ADC2_OFFSET ); + current_cal = saved_cals; - cal1( setup, 3, ADC3_OFFSET ); - cal1_fine( setup, 3, ADC3_OFFSET ); + for( channel = 0; channel < num_channels; channel++ ) + { + for( range = 0; range < num_ranges; range++ ) + { + prep_adc_caldacs_4020( setup, channel, range ); - cal_binary( setup, 4, ADC0_GAIN ); - cal1_fine( setup, 4, ADC0_GAIN ); + cal_binary( setup, ai_low_observable_index_4020( channel, range ), + ADC_OFFSET_4020( channel ) ); - cal_binary( setup, 5, ADC1_GAIN ); - cal1_fine( setup, 5, ADC1_GAIN ); + cal_binary( setup, ai_high_observable_index_4020( channel, range ), + ADC_GAIN_4020( channel ) ); - cal_binary( setup, 6, ADC2_GAIN ); - cal1_fine( setup, 6, ADC2_GAIN ); + current_cal->subdevice = setup->ad_subdev; + sc_push_caldac( current_cal, setup->caldacs[ ADC_GAIN_4020( channel ) ] ); + sc_push_caldac( current_cal, setup->caldacs[ ADC_OFFSET_4020( channel ) ] ); + sc_push_channel( current_cal, channel ); + sc_push_range( current_cal, range ); + sc_push_aref( current_cal, SC_ALL_AREFS ); - cal_binary( setup, 7, ADC3_GAIN ); - cal1_fine( setup, 7, ADC3_GAIN ); + current_cal++; + } + } - return 0; + retval = write_calibration_file( setup, saved_cals, num_calibrations ); + for( i = 0; i < num_calibrations; i++ ) + clear_saved_calibration( &saved_cals[ i ] ); + free( saved_cals ); + return retval; } -- 2.26.2