added 'write to file' support for ni 611x boards, and calibration

of all their input ranges.
This commit is contained in:
Frank Mori Hess 2003-05-02 21:58:23 +00:00
parent 827370aa90
commit c3551c8ccc
7 changed files with 443 additions and 277 deletions

View file

@ -4,7 +4,7 @@ bin_PROGRAMS = comedi_calibrate
noinst_HEADERS = calib.h
comedi_calibrate_SOURCES = \
comedi_calibrate.c ni.c cb.c cb64.c other.c save_cal.c
comedi_calibrate.c ni.c cb.c cb64.c other.c save_cal.c cal_common.c
comedi_calibrate_CFLAGS = $(COMEDILIB_CFLAGS)
comedi_calibrate_LDADD = $(COMEDILIB_LIBS)

View file

@ -0,0 +1,206 @@
/***************************************************************************
cal_common.c - shared calibration routines
-------------------
begin : Fri May 2, 2003
copyright : (C) 2003 by Frank Mori Hess
email : fmhess@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by *
* the Free Software Foundation; either version 2.1 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "calib.h"
#include <assert.h>
#include <stdlib.h>
void generic_do_cal( calibration_setup_t *setup,
saved_calibration_t *saved_cal, int observable, int caldac )
{
if( caldac < 0 || observable < 0 ) return;
cal_binary( setup, observable, caldac );
sc_push_caldac( saved_cal, setup->caldacs[ caldac ] );
}
void generic_do_relative( calibration_setup_t *setup,
saved_calibration_t *saved_cal, int observable1, int observable2, int caldac )
{
if( caldac < 0 || observable1 < 0 || observable2 < 0 ) return;
cal_relative_binary( setup, observable1, observable2, caldac );
sc_push_caldac( saved_cal, setup->caldacs[ caldac ] );
}
void generic_do_linearity( calibration_setup_t *setup,
saved_calibration_t *saved_cal, int observable1, int observable2,
int observable3, int caldac )
{
if( caldac < 0 || observable1 < 0 || observable2 < 0 || observable3 < 0 )
return;
cal_linearity_binary( setup, observable1, observable2, observable3, caldac );
sc_push_caldac( saved_cal, setup->caldacs[ caldac ] );
}
void generic_prep_adc_caldacs( calibration_setup_t *setup,
const generic_layout_t *layout, unsigned int channel, unsigned int range )
{
int retval;
if( setup->ad_subdev < 0 ) return;
if( setup->do_reset )
{
reset_caldac( setup, layout->adc_offset( channel ) );
reset_caldac( setup, layout->adc_gain( channel ) );
}else
{
retval = comedi_apply_calibration( setup->dev, setup->ad_subdev,
channel, range, AREF_GROUND, setup->cal_save_file_path);
if( retval < 0 )
{
DPRINT( 0, "Failed to apply existing calibration, reseting dac caldacs.\n" );
reset_caldac( setup, layout->adc_offset( channel ) );
reset_caldac( setup, layout->adc_gain( channel ) );
}
}
}
void generic_prep_dac_caldacs( calibration_setup_t *setup,
const generic_layout_t *layout, unsigned int channel, unsigned int range )
{
int retval;
if( setup->da_subdev < 0 ) return;
if( setup->do_reset )
{
reset_caldac( setup, layout->dac_offset( channel ) );
reset_caldac( setup, layout->dac_gain( channel ) );
}else
{
retval = comedi_apply_calibration( setup->dev, setup->da_subdev,
channel, range, AREF_GROUND, setup->cal_save_file_path);
if( retval < 0 )
{
DPRINT( 0, "Failed to apply existing calibration, reseting dac caldacs.\n" );
reset_caldac( setup, layout->dac_offset( channel ) );
reset_caldac( setup, layout->dac_gain( channel ) );
}
}
}
int generic_cal_by_channel_and_range( calibration_setup_t *setup,
const generic_layout_t *layout )
{
int range, channel, num_ai_ranges, num_ai_channels, num_ao_ranges,
num_ao_channels, retval, num_calibrations, i;
saved_calibration_t *saved_cals, *current_cal;
assert( comedi_range_is_chan_specific( setup->dev, setup->ad_subdev ) == 0 );
num_ai_ranges = comedi_get_n_ranges( setup->dev, setup->ad_subdev, 0 );
if( num_ai_ranges < 0 ) return -1;
num_ai_channels = comedi_get_n_channels( setup->dev, setup->ad_subdev );
if( num_ai_channels < 0 ) return -1;
if( setup->da_subdev && setup->do_output )
{
assert( comedi_range_is_chan_specific( setup->dev, setup->da_subdev ) == 0 );
num_ao_ranges = comedi_get_n_ranges( setup->dev, setup->da_subdev, 0 );
if( num_ao_ranges < 0 ) return -1;
num_ao_channels = comedi_get_n_channels( setup->dev, setup->da_subdev );
if( num_ao_channels < 0 ) return -1;
}else
num_ao_ranges = num_ao_channels = 0;
num_calibrations = num_ai_ranges * num_ai_channels + num_ao_ranges * num_ao_channels;
saved_cals = malloc( num_calibrations * sizeof( saved_calibration_t ) );
if( saved_cals == NULL ) return -1;
current_cal = saved_cals;
for( channel = 0; channel < num_ai_channels; channel++ )
{
for( range = 0; range < num_ai_ranges; range++ )
{
generic_prep_adc_caldacs( setup, layout, channel, range );
generic_do_cal( setup, current_cal, layout->adc_ground_observable( channel, range ),
layout->adc_offset( channel ) );
generic_do_cal( setup, current_cal, layout->adc_high_observable( channel, range ),
layout->adc_gain( channel ) );
current_cal->subdevice = setup->ad_subdev;
sc_push_caldac( current_cal, setup->caldacs[ layout->adc_gain( channel ) ] );
sc_push_caldac( current_cal, setup->caldacs[ layout->adc_offset( channel ) ] );
sc_push_channel( current_cal, channel );
sc_push_range( current_cal, range );
sc_push_aref( current_cal, SC_ALL_AREFS );
current_cal++;
}
}
for( channel = 0; channel < num_ao_channels; channel++ )
{
for( range = 0; range < num_ao_ranges; range++ )
{
generic_prep_dac_caldacs( setup, layout, channel, range );
generic_do_cal( setup, current_cal, layout->dac_ground_observable( channel, range ),
layout->dac_offset( channel ) );
generic_do_cal( setup, current_cal, layout->dac_high_observable( channel, range ),
layout->dac_gain( channel ) );
current_cal->subdevice = setup->da_subdev;
sc_push_caldac( current_cal, setup->caldacs[ layout->dac_gain( channel ) ] );
sc_push_caldac( current_cal, setup->caldacs[ layout->dac_offset( channel ) ] );
sc_push_channel( current_cal, channel );
sc_push_range( current_cal, range );
sc_push_aref( current_cal, SC_ALL_AREFS );
current_cal++;
}
}
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;
}
static int dummy_caldac( unsigned int channel )
{
return -1;
}
static int dummy_observable( unsigned int channel, unsigned int range )
{
return -1;
}
void init_generic_layout( generic_layout_t *layout )
{
layout->adc_offset = dummy_caldac;
layout->adc_gain = dummy_caldac;
layout->dac_offset = dummy_caldac;
layout->dac_gain = dummy_caldac;
layout->adc_high_observable = dummy_observable;
layout->adc_ground_observable = dummy_observable;
layout->dac_high_observable = dummy_observable;
layout->dac_ground_observable = dummy_observable;
}

View file

@ -11,7 +11,7 @@
#ifndef __CALIB_H_
#define __CALIB_H_
#include <comedilib.h>
#include "comedilib.h"
#if 0
#include <stdio.h>
#include <fcntl.h>
@ -93,7 +93,7 @@ void observe( calibration_setup_t *setup );
int preobserve( calibration_setup_t *setup, int obs);
void observable_dependence( calibration_setup_t *setup, int obs);
void measure_observable( calibration_setup_t *setup, int obs);
void reset_caldac( calibration_setup_t *setup, unsigned int caldac_index );
void reset_caldac( calibration_setup_t *setup, int caldac_index );
void reset_caldacs( calibration_setup_t *setup);
/* drivers */
@ -246,5 +246,32 @@ void sc_push_range( saved_calibration_t *saved_cal, int range );
void sc_push_aref( saved_calibration_t *saved_cal, int aref );
void clear_saved_calibration( saved_calibration_t *saved_cal );
/* generic calibration support */
typedef struct
{
int (*adc_offset)( unsigned int channel );
int (*adc_gain)( unsigned int channel );
int (*dac_offset)( unsigned int channel );
int (*dac_gain)( unsigned int channel );
int (*adc_high_observable)( unsigned int channel, unsigned int range );
int (*adc_ground_observable)( unsigned int channel, unsigned int range );
int (*dac_high_observable)( unsigned int channel, unsigned int range );
int (*dac_ground_observable)( unsigned int channel, unsigned int range );
} generic_layout_t;
void init_generic_layout( generic_layout_t *layout );
int generic_cal_by_channel_and_range( calibration_setup_t *setup,
const generic_layout_t *layout );
void generic_do_cal( calibration_setup_t *setup,
saved_calibration_t *saved_cal, int observable, int caldac );
void generic_do_relative( calibration_setup_t *setup,
saved_calibration_t *saved_cal, int observable1, int observable2, int caldac );
void generic_do_linearity( calibration_setup_t *setup,
saved_calibration_t *saved_cal, int observable1, int observable2,
int observable3, int caldac );
void generic_prep_adc_caldacs( calibration_setup_t *setup,
const generic_layout_t *layout, unsigned int channel, unsigned int range );
void generic_prep_dac_caldacs( calibration_setup_t *setup,
const generic_layout_t *layout, unsigned int channel, unsigned int range );
#endif

View file

@ -21,7 +21,6 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <comedilib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

View file

@ -21,7 +21,6 @@
#define _GNU_SOURCE
#include <stdio.h>
#include "comedilib.h"
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
@ -128,15 +127,6 @@ enum cal_knobs_64xx
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;
@ -615,13 +605,13 @@ static int init_observables_60xx( calibration_setup_t *setup )
return 0;
}
static unsigned int ai_low_observable_index_4020( unsigned int channel,
static 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,
static int ai_high_observable_index_4020( unsigned int channel,
unsigned int ai_range )
{
return ai_low_observable_index_4020( channel, ai_range ) + 1;
@ -1032,73 +1022,24 @@ static int cal_cb_pci_60xx( calibration_setup_t *setup )
return retval;
}
static void prep_adc_caldacs_4020( calibration_setup_t *setup,
unsigned int channel, unsigned int range )
static int adc_offset_4020( unsigned int channel )
{
int retval;
if( setup->do_reset )
{
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 ) );
}
}
return channel;
}
static int adc_gain_4020( unsigned int channel )
{
return 4 + 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;
generic_layout_t layout;
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;
num_calibrations = num_ranges * num_channels;
saved_cals = malloc( num_calibrations * sizeof( saved_calibration_t ) );
if( saved_cals == NULL ) return -1;
current_cal = saved_cals;
for( channel = 0; channel < num_channels; channel++ )
{
for( range = 0; range < num_ranges; range++ )
{
prep_adc_caldacs_4020( setup, channel, range );
cal_binary( setup, ai_low_observable_index_4020( channel, range ),
ADC_OFFSET_4020( channel ) );
cal_binary( setup, ai_high_observable_index_4020( channel, range ),
ADC_GAIN_4020( channel ) );
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 );
current_cal++;
}
}
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;
init_generic_layout( &layout );
layout.adc_offset = adc_offset_4020;
layout.adc_gain = adc_gain_4020;
layout.adc_high_observable = ai_high_observable_index_4020;
layout.adc_ground_observable = ai_low_observable_index_4020;
return generic_cal_by_channel_and_range( setup, &layout );
}

View file

@ -786,9 +786,10 @@ void setup_caldacs( calibration_setup_t *setup, int caldac_subdev )
setup->n_caldacs += n_chan;
}
void reset_caldac( calibration_setup_t *setup, unsigned int caldac_index )
void reset_caldac( calibration_setup_t *setup, int caldac_index )
{
assert( caldac_index < setup->n_caldacs );
if( caldac_index < 0 ) return;
update_caldac( setup, caldac_index, setup->caldacs[ caldac_index ].maxdata / 2 );
}
@ -1442,3 +1443,4 @@ double very_low_target( comedi_t *dev, unsigned int subdevice,
return comedi_to_phys( 1, range_ptr, max_data ) / 2.0;
}

View file

@ -26,7 +26,6 @@
#define _GNU_SOURCE
#include <stdio.h>
#include "comedilib.h"
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
@ -173,17 +172,20 @@ static inline unsigned int ni_ao_unip_linearity( unsigned int channel )
else return ni_ao0_unip_linearity;
}
enum observables_611x{
ni_ao0_zero_offset_611x = 0,
ni_ao0_reference_611x = 1,
ni_ao1_zero_offset_611x = 2,
ni_ao1_reference_611x = 3,
static const int num_ao_observables_611x = 4;
static int ni_ao_zero_offset_611x( unsigned int channel, unsigned int range ) {
assert( range = 0 );
return 2 * channel;
};
static inline unsigned int ni_zero_offset_611x( unsigned int channel ) {
return 4 + 2 * channel;
static int ni_ao_reference_611x( unsigned int channel, unsigned int range ) {
assert( range = 0 );
return 2 * channel + 1;
};
static inline unsigned int ni_reference_611x( unsigned int channel ) {
return 5 + 2 * channel;
static int ni_zero_offset_611x( unsigned int channel, unsigned int range ) {
return num_ao_observables_611x + 8 * range + 2 * channel;
};
static int ni_reference_611x( unsigned int channel, unsigned int range ) {
return num_ao_observables_611x + 8 * range + 2 * channel + 1;
};
enum reference_sources {
@ -490,7 +492,7 @@ static void ni_setup_observables( calibration_setup_t *setup )
ni_setup_ao_observables( setup );
}
/* XXX for +-50V and +-20V ranges, the reference source goes 0V
/* for +-50V and +-20V ranges, the reference source goes 0V
* to 50V instead of 0V to 5V */
static unsigned int cal_gain_register_bits_611x( double reference, double *voltage )
{
@ -508,52 +510,76 @@ static unsigned int ref_source_611x( unsigned int ref_source, unsigned int cal_g
return ( ref_source & 0xf ) | ( ( cal_gain_bits << 4 ) & 0xff0 );
}
static void reference_target_611x( calibration_setup_t *setup,
observable *o, double master_reference, unsigned int range )
{
int cal_gain_reg_bits;
double reference;
double target;
comedi_range *range_ptr;
range_ptr = comedi_get_range( setup->dev, setup->ad_subdev, 0, range );
assert( range_ptr != NULL );
if( range_ptr->max > 19.0 ) reference = 10 * master_reference;
else reference = master_reference;
target = range_ptr->max * 0.9;
cal_gain_reg_bits = cal_gain_register_bits_611x( reference, &target );
o->reference_source = ref_source_611x( REF_CALSRC_GND, cal_gain_reg_bits );
o->target = target;
}
static void ni_setup_observables_611x( calibration_setup_t *setup )
{
comedi_insn tmpl;
comedi_insn po_tmpl;
int range, ai_range_for_ao;
double voltage_reference, master_reference;
int range, channel;
double master_reference;
observable *o;
int ai_chan;
int num_chans;
int cal_gain_reg_bits;
int num_ai_channels, num_ai_ranges;
static const int num_ao_channels = 2;
setup->settling_time_ns = 1000000;
range = 2;
master_reference = ni_get_reference( setup,
ni_board( setup )->ref_eeprom_lsb, ni_board( setup )->ref_eeprom_msb );
voltage_reference = 5.0;
cal_gain_reg_bits = cal_gain_register_bits_611x( master_reference, &voltage_reference );
memset(&tmpl,0,sizeof(tmpl));
tmpl.insn = INSN_READ;
tmpl.n = 1;
tmpl.subdev = setup->ad_subdev;
num_chans = comedi_get_n_channels( setup->dev, setup->ad_subdev );
num_ai_channels = comedi_get_n_channels( setup->dev, setup->ad_subdev );
assert( num_ai_channels >= 0 );
num_ai_ranges = comedi_get_n_ranges( setup->dev, setup->ad_subdev, 0 );
assert( num_ai_ranges >= 0 );
for( ai_chan = 0; ai_chan < num_chans; ai_chan++ )
for( channel = 0; channel < num_ai_channels; channel++ )
{
/* 0 offset */
o = setup->observables + ni_zero_offset_611x( ai_chan );
o->name = "ai, bipolar zero offset";
o->observe_insn = tmpl;
o->observe_insn.chanspec = CR_PACK(ai_chan, range, AREF_DIFF)
| CR_ALT_SOURCE | CR_ALT_FILTER;
o->reference_source = REF_GND_GND;
o->target = 0.0;
for( range = 0; range < num_ai_ranges; range++ )
{
/* 0 offset */
o = setup->observables + ni_zero_offset_611x( channel, range );
assert( o->name == NULL );
asprintf( &o->name, "ai, ch %i, range %i, zero offset",
channel, range );
o->observe_insn = tmpl;
o->observe_insn.chanspec = CR_PACK( channel, range, AREF_DIFF )
| CR_ALT_SOURCE | CR_ALT_FILTER;
o->reference_source = REF_GND_GND;
o->target = 0.0;
/* voltage reference */
o = setup->observables + ni_reference_611x( ai_chan );
o->name = "ai, bipolar voltage reference";
o->observe_insn = tmpl;
o->observe_insn.chanspec = CR_PACK(ai_chan, range, AREF_DIFF)
| CR_ALT_SOURCE | CR_ALT_FILTER;
o->reference_source = ref_source_611x( REF_CALSRC_GND, cal_gain_reg_bits );
o->target = voltage_reference;
/* voltage reference */
o = setup->observables + ni_reference_611x( channel, range );
assert( o->name == NULL );
asprintf( &o->name, "ai, ch %i, range %i, voltage reference",
channel, range );
o->observe_insn = tmpl;
o->observe_insn.chanspec = CR_PACK( channel, range, AREF_DIFF )
| CR_ALT_SOURCE | CR_ALT_FILTER;
reference_target_611x( setup, o, master_reference, range );
}
}
memset(&po_tmpl,0,sizeof(po_tmpl));
@ -561,57 +587,38 @@ static void ni_setup_observables_611x( calibration_setup_t *setup )
po_tmpl.n = 1;
po_tmpl.subdev = setup->da_subdev;
ai_range_for_ao = 2;
for( channel = 0; channel < num_ao_channels; channel ++ )
{
static const int ai_range_for_ao = 2;
/* ao 0, zero offset */
o = setup->observables + ni_ao0_zero_offset_611x;
o->name = "ao 0, zero offset";
o->preobserve_insn = po_tmpl;
o->preobserve_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND );
o->preobserve_insn.data = o->preobserve_data;
o->observe_insn = tmpl;
o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
| CR_ALT_SOURCE | CR_ALT_FILTER;
o->reference_source = REF_DAC0_GND;
set_target( setup, ni_ao0_zero_offset_611x, 0.0 );
/* ao zero offset */
o = setup->observables + ni_ao_zero_offset_611x( channel, 0 );
assert( o->name == NULL );
asprintf( &o->name, "ao ch %i, zero offset", channel );
o->preobserve_insn = po_tmpl;
o->preobserve_insn.chanspec = CR_PACK( channel, 0, AREF_GROUND );
o->preobserve_insn.data = o->preobserve_data;
o->observe_insn = tmpl;
o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
| CR_ALT_SOURCE | CR_ALT_FILTER;
o->reference_source = REF_DAC0_GND;
set_target( setup, ni_ao_zero_offset_611x( channel, 0 ), 0.0 );
/* ao 0, gain */
o = setup->observables + ni_ao0_reference_611x;
o->name = "ao 0, reference voltage";
o->preobserve_insn = po_tmpl;
o->preobserve_insn.chanspec = CR_PACK( 0, 0, AREF_GROUND );
o->preobserve_insn.data = o->preobserve_data;
o->observe_insn = tmpl;
o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
| CR_ALT_SOURCE | CR_ALT_FILTER;
o->reference_source = REF_DAC0_GND;
set_target( setup, ni_ao0_reference_611x, 5.0 );
/* ao gain */
o = setup->observables + ni_ao_reference_611x( channel, 0 );
assert( o->name == NULL );
asprintf( &o->name, "ao ch %i, reference voltage", channel );
o->preobserve_insn = po_tmpl;
o->preobserve_insn.chanspec = CR_PACK( channel, 0, AREF_GROUND );
o->preobserve_insn.data = o->preobserve_data;
o->observe_insn = tmpl;
o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
| CR_ALT_SOURCE | CR_ALT_FILTER;
o->reference_source = REF_DAC0_GND;
set_target( setup, ni_ao_reference_611x( channel, 0 ), 5.0 );
}
/* ao 1, zero offset */
o = setup->observables + ni_ao1_zero_offset_611x;
o->name = "ao 1, zero offset";
o->preobserve_insn = po_tmpl;
o->preobserve_insn.chanspec = CR_PACK( 1, 0, AREF_GROUND );
o->preobserve_insn.data = o->preobserve_data;
o->observe_insn = tmpl;
o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF)
| CR_ALT_SOURCE | CR_ALT_FILTER;
o->reference_source = REF_DAC1_GND;
set_target( setup, ni_ao1_zero_offset_611x, 0.0 );
/* ao 1, gain */
o = setup->observables + ni_ao1_reference_611x;
o->name = "ao 1, reference voltage";
o->preobserve_insn = po_tmpl;
o->preobserve_insn.chanspec = CR_PACK( 1, 0, AREF_GROUND );
o->preobserve_insn.data = o->preobserve_data;
o->observe_insn = tmpl;
o->observe_insn.chanspec = CR_PACK( 0, ai_range_for_ao, AREF_DIFF )
| CR_ALT_SOURCE | CR_ALT_FILTER;
o->reference_source = REF_DAC1_GND;
set_target( setup, ni_ao1_reference_611x, 5.0 );
setup->n_observables = 4 + 2 * num_chans;
setup->n_observables = num_ao_observables_611x + 2 * num_ai_ranges * num_ai_channels;
}
static int cal_ni_at_mio_16e_2(calibration_setup_t *setup)
@ -890,34 +897,41 @@ static int cal_ni_pci_6052e(calibration_setup_t *setup)
/*
* This board has noisy caldacs
*
* The NI documentation says:
* 0, 8 AI pregain (coarse, fine) 3, 11
* 4, 12 AI postgain 15,7
* 2, 10 AI reference 1, 9
* 14, 7 AI unipolar offset 5, 13
* The NI documentation says (true mb88341 addressing):
* 0, 8 AI pregain (coarse, fine)
* 4, 12 AI postgain
* 2, 10 AI reference
* 14, 7 AI unipolar offset
*
* 0 AO0 linearity
* 8, 4 AO0 reference 23, 19 7, 3
* 12 AO0 offset 27 11
* 8, 4 AO0 reference
* 12 AO0 offset
* 2 AO1 linearity
* 10, 6 AO1 reference 25, 21 9, 5
* 14 AO1 offset 29, 17 13, 1
* 10, 6 AO1 reference
* 14 AO1 offset
*
* 0 3 x 0011
* For us, these map to (ad8804 channels)
*
* 2 1 x 0001
* 0, 1 AI pregain (coarse, fine)
* 2, 3 AI postgain
* 4, 5 AI reference
* 7 AI unipolar offset
*
* 4 7 15 3 0111 0011
* 0 AO0 linearity
* 1, 2 AO0 reference
* 3 AO0 offset
* 4 AO1 linearity
* 5, 6 AO1 reference
* 7 AO1 offset
*
* 6 17 5 0101
* 7 x
* 8 11 19 7 1011 0111
* or, with mb88341 channels
*
* 10 9 21 9 1001 1001
*
* 12 x 23 11 1011
*
* 14 5 13 1 0101 0001
* xxx AO0 linearity
* 7, 3 AO0 reference
* 11 AO0 offset
* 1 AO1 linearity
* 9, 5 AO1 reference
* xxx AO1 offset
*
*/
ni_caldac_layout_t layout;
@ -966,26 +980,37 @@ static int cal_ni_daqcard_ai_16e_4(calibration_setup_t *setup)
return cal_ni_generic( setup, &layout );
}
static int adc_offset_611x( unsigned int channel )
{
return 2 * channel + 2;
}
static int adc_gain_611x( unsigned int channel )
{
return 2 * channel + 1;
}
static int dac_offset_611x( unsigned int channel )
{
return 12 + 2 + 2 * channel;
}
static int dac_gain_611x( unsigned int channel )
{
return 12 + 1 + 2 * channel;
}
static int cal_ni_pci_611x( calibration_setup_t *setup )
{
int i;
int num_chans;
generic_layout_t layout;
num_chans = comedi_get_n_channels( setup->dev, setup->ad_subdev );
init_generic_layout( &layout );
layout.adc_offset = adc_offset_611x;
layout.adc_gain = adc_gain_611x;
layout.dac_offset = dac_offset_611x;
layout.dac_gain = dac_gain_611x;
layout.adc_high_observable = ni_reference_611x;
layout.adc_ground_observable = ni_zero_offset_611x;
layout.dac_high_observable = ni_ao_reference_611x;
layout.dac_ground_observable = ni_ao_zero_offset_611x;
for( i = 0; i < num_chans; i++ ){
cal_binary( setup, ni_zero_offset_611x( i ), ( 2 * i + 2 ) );
cal_binary( setup, ni_reference_611x( i ), ( 2 * i + 1 ) );
}
if(setup->do_output){
cal_binary( setup, ni_ao0_zero_offset_611x, 14 );
cal_binary( setup, ni_ao0_reference_611x, 13 );
cal_binary( setup, ni_ao1_zero_offset_611x, 16 );
cal_binary( setup, ni_ao1_reference_611x, 15 );
}
return 0;
return generic_cal_by_channel_and_range( setup, &layout );
}
static int cal_ni_pci_mio_16e_4( calibration_setup_t *setup )
@ -1026,13 +1051,6 @@ static int cal_ni_daqcard_6062e( calibration_setup_t *setup )
return cal_ni_generic( setup, &layout );
}
static void ni_generic_reset_caldac( calibration_setup_t *setup,
int caldac )
{
if( caldac < 0 ) return;
reset_caldac( setup, caldac );
}
static void prep_adc_caldacs_generic( calibration_setup_t *setup,
const ni_caldac_layout_t *layout )
{
@ -1040,13 +1058,13 @@ static void prep_adc_caldacs_generic( calibration_setup_t *setup,
if( setup->do_reset )
{
ni_generic_reset_caldac( setup, layout->adc_pregain_offset );
ni_generic_reset_caldac( setup, layout->adc_postgain_offset );
ni_generic_reset_caldac( setup, layout->adc_gain );
ni_generic_reset_caldac( setup, layout->adc_pregain_offset_fine );
ni_generic_reset_caldac( setup, layout->adc_postgain_offset_fine );
ni_generic_reset_caldac( setup, layout->adc_gain_fine );
ni_generic_reset_caldac( setup, layout->adc_unip_offset );
reset_caldac( setup, layout->adc_pregain_offset );
reset_caldac( setup, layout->adc_postgain_offset );
reset_caldac( setup, layout->adc_gain );
reset_caldac( setup, layout->adc_pregain_offset_fine );
reset_caldac( setup, layout->adc_postgain_offset_fine );
reset_caldac( setup, layout->adc_gain_fine );
reset_caldac( setup, layout->adc_unip_offset );
}else
{
retval = comedi_apply_calibration( setup->dev, setup->ad_subdev,
@ -1054,19 +1072,19 @@ static void prep_adc_caldacs_generic( calibration_setup_t *setup,
if( retval < 0 )
{
DPRINT( 0, "Failed to apply existing calibration, reseting adc caldacs.\n" );
ni_generic_reset_caldac( setup, layout->adc_pregain_offset );
ni_generic_reset_caldac( setup, layout->adc_postgain_offset );
ni_generic_reset_caldac( setup, layout->adc_gain );
ni_generic_reset_caldac( setup, layout->adc_pregain_offset_fine );
ni_generic_reset_caldac( setup, layout->adc_postgain_offset_fine );
ni_generic_reset_caldac( setup, layout->adc_gain_fine );
ni_generic_reset_caldac( setup, layout->adc_unip_offset );
reset_caldac( setup, layout->adc_pregain_offset );
reset_caldac( setup, layout->adc_postgain_offset );
reset_caldac( setup, layout->adc_gain );
reset_caldac( setup, layout->adc_pregain_offset_fine );
reset_caldac( setup, layout->adc_postgain_offset_fine );
reset_caldac( setup, layout->adc_gain_fine );
reset_caldac( setup, layout->adc_unip_offset );
}
}
}
static void prep_dac_caldacs_generic( calibration_setup_t *setup,
const ni_caldac_layout_t *layout, unsigned int channel )
const ni_caldac_layout_t *layout, unsigned int channel, unsigned int range )
{
int retval;
@ -1074,53 +1092,25 @@ static void prep_dac_caldacs_generic( calibration_setup_t *setup,
if( setup->do_reset )
{
ni_generic_reset_caldac( setup, layout->dac_offset[ channel ] );
ni_generic_reset_caldac( setup, layout->dac_gain[ channel ] );
ni_generic_reset_caldac( setup, layout->dac_gain_fine[ channel ] );
ni_generic_reset_caldac( setup, layout->dac_linearity[ channel ] );
reset_caldac( setup, layout->dac_offset[ channel ] );
reset_caldac( setup, layout->dac_gain[ channel ] );
reset_caldac( setup, layout->dac_gain_fine[ channel ] );
reset_caldac( setup, layout->dac_linearity[ channel ] );
}else
{
retval = comedi_apply_calibration( setup->dev, setup->da_subdev,
channel, 0, AREF_GROUND, setup->cal_save_file_path);
channel, range, AREF_GROUND, setup->cal_save_file_path);
if( retval < 0 )
{
DPRINT( 0, "Failed to apply existing calibration, reseting dac caldacs.\n" );
ni_generic_reset_caldac( setup, layout->dac_offset[ channel ] );
ni_generic_reset_caldac( setup, layout->dac_gain[ channel ] );
ni_generic_reset_caldac( setup, layout->dac_gain_fine[ channel ] );
ni_generic_reset_caldac( setup, layout->dac_linearity[ channel ] );
reset_caldac( setup, layout->dac_offset[ channel ] );
reset_caldac( setup, layout->dac_gain[ channel ] );
reset_caldac( setup, layout->dac_gain_fine[ channel ] );
reset_caldac( setup, layout->dac_linearity[ channel ] );
}
}
}
static void ni_generic_binary( calibration_setup_t *setup,
saved_calibration_t *saved_cal, int observable, int caldac )
{
if( caldac < 0 ) return;
cal_binary( setup, observable, caldac );
sc_push_caldac( saved_cal, setup->caldacs[ caldac ] );
}
static void ni_generic_relative( calibration_setup_t *setup,
saved_calibration_t *saved_cal, int observable1, int observable2, int caldac )
{
if( caldac < 0 ) return;
cal_relative_binary( setup, observable1, observable2, caldac );
sc_push_caldac( saved_cal, setup->caldacs[ caldac ] );
}
static void ni_generic_linearity( calibration_setup_t *setup,
saved_calibration_t *saved_cal, int observable1, int observable2,
int observable3, int caldac )
{
if( caldac < 0 ) return;
cal_linearity_binary( setup, observable1, observable2, observable3, caldac );
sc_push_caldac( saved_cal, setup->caldacs[ caldac ] );
}
static int cal_ni_generic( calibration_setup_t *setup, const ni_caldac_layout_t *layout )
{
saved_calibration_t saved_cals[ 5 ], *current_cal;
@ -1134,18 +1124,18 @@ static int cal_ni_generic( calibration_setup_t *setup, const ni_caldac_layout_t
prep_adc_caldacs_generic( setup, layout );
current_cal->subdevice = setup->ad_subdev;
ni_generic_relative( setup, current_cal, ni_zero_offset_low,
generic_do_relative( setup, current_cal, ni_zero_offset_low,
ni_reference_low, layout->adc_gain );
ni_generic_relative( setup, current_cal, ni_zero_offset_low,
generic_do_relative( setup, current_cal, ni_zero_offset_low,
ni_zero_offset_high, layout->adc_postgain_offset );
ni_generic_binary( setup, current_cal, ni_zero_offset_high, layout->adc_pregain_offset );
ni_generic_relative( setup, current_cal, ni_zero_offset_low,
generic_do_cal( setup, current_cal, ni_zero_offset_high, layout->adc_pregain_offset );
generic_do_relative( setup, current_cal, ni_zero_offset_low,
ni_reference_low, layout->adc_gain_fine );
ni_generic_relative( setup, current_cal, ni_zero_offset_low,
generic_do_relative( setup, current_cal, ni_zero_offset_low,
ni_zero_offset_high, layout->adc_postgain_offset_fine );
ni_generic_binary( setup, current_cal, ni_zero_offset_high,
generic_do_cal( setup, current_cal, ni_zero_offset_high,
layout->adc_pregain_offset_fine );
ni_generic_binary( setup, current_cal, ni_unip_zero_offset_high, layout->adc_unip_offset );
generic_do_cal( setup, current_cal, ni_unip_zero_offset_high, layout->adc_unip_offset );
sc_push_channel( current_cal, SC_ALL_CHANNELS );
sc_push_range( current_cal, SC_ALL_RANGES );
sc_push_aref( current_cal, SC_ALL_AREFS );
@ -1155,22 +1145,23 @@ static int cal_ni_generic( calibration_setup_t *setup, const ni_caldac_layout_t
{
unsigned int channel, range;
int ao_unipolar_lowgain = get_unipolar_lowgain( setup->dev, setup->da_subdev );
int ao_bipolar_lowgain = get_bipolar_lowgain( setup->dev, setup->da_subdev );
int num_ao_ranges;
for( channel = 0; channel < 2; channel++ )
{
num_ao_ranges = comedi_get_n_ranges( setup->dev, setup->da_subdev, channel );
prep_dac_caldacs_generic( setup, layout, channel );
prep_dac_caldacs_generic( setup, layout, channel, ao_bipolar_lowgain );
current_cal->subdevice = setup->da_subdev;
ni_generic_linearity( setup, current_cal, ni_ao_linearity( channel ),
generic_do_linearity( setup, current_cal, ni_ao_linearity( channel ),
ni_ao_zero_offset( channel ), ni_ao_reference( channel ),
layout->dac_linearity[ channel ] );
ni_generic_binary( setup, current_cal, ni_ao_zero_offset( channel ),
generic_do_cal( setup, current_cal, ni_ao_zero_offset( channel ),
layout->dac_offset[ channel ] );
ni_generic_binary( setup, current_cal, ni_ao_reference( channel ),
generic_do_cal( setup, current_cal, ni_ao_reference( channel ),
layout->dac_gain[ channel ] );
ni_generic_binary( setup, current_cal, ni_ao_reference( channel ),
generic_do_cal( setup, current_cal, ni_ao_reference( channel ),
layout->dac_gain_fine[ channel ] );
sc_push_channel( current_cal, channel );
for( range = 0; range < num_ao_ranges; range++ )
@ -1183,17 +1174,17 @@ static int cal_ni_generic( calibration_setup_t *setup, const ni_caldac_layout_t
if( ao_unipolar_lowgain >= 0 )
{
prep_dac_caldacs_generic( setup, layout, channel );
prep_dac_caldacs_generic( setup, layout, channel, ao_unipolar_lowgain );
current_cal->subdevice = setup->da_subdev;
ni_generic_linearity( setup, current_cal, ni_ao_unip_zero_offset( channel ),
generic_do_linearity( setup, current_cal, ni_ao_unip_zero_offset( channel ),
ni_ao_unip_linearity( channel ), ni_ao_unip_reference( channel ),
layout->dac_linearity[ channel ] );
ni_generic_binary( setup, current_cal, ni_ao_unip_zero_offset( channel),
generic_do_cal( setup, current_cal, ni_ao_unip_zero_offset( channel),
layout->dac_offset[ channel ] );
ni_generic_binary( setup, current_cal, ni_ao_unip_reference( channel ),
generic_do_cal( setup, current_cal, ni_ao_unip_reference( channel ),
layout->dac_gain[ channel ] );
ni_generic_binary( setup, current_cal, ni_ao_unip_reference( channel ),
generic_do_cal( setup, current_cal, ni_ao_unip_reference( channel ),
layout->dac_gain_fine[ channel ] );
sc_push_channel( current_cal, channel );
for( range = 0; range < num_ao_ranges; range++ )