#include <stdlib.h>
void generic_do_cal( calibration_setup_t *setup,
- saved_calibration_t *saved_cal, int observable, int caldac )
+ comedi_calibration_setting_t *saved_cal, int observable, int caldac )
{
if( caldac < 0 || observable < 0 ) return;
}
void generic_do_relative( calibration_setup_t *setup,
- saved_calibration_t *saved_cal, int observable1, int observable2, int caldac )
+ comedi_calibration_setting_t *saved_cal, int observable1, int observable2, int caldac )
{
if( caldac < 0 || observable1 < 0 || observable2 < 0 ) return;
}
void generic_do_linearity( calibration_setup_t *setup,
- saved_calibration_t *saved_cal, int observable1, int observable2,
+ comedi_calibration_setting_t *saved_cal, int observable1, int observable2,
int observable3, int caldac )
{
if( caldac < 0 || observable1 < 0 || observable2 < 0 || observable3 < 0 )
if( setup->ad_subdev < 0 ) return;
- if( setup->do_reset )
+ if( setup->old_calibration == NULL )
{
reset_caldac( setup, layout->adc_offset( channel ) );
reset_caldac( setup, layout->adc_gain( channel ) );
reset_caldac( setup, layout->adc_gain_fine( channel ) );
}else
{
- retval = comedi_apply_calibration( setup->dev, setup->ad_subdev,
- channel, range, AREF_GROUND, setup->cal_save_file_path);
+ retval = comedi_apply_parsed_calibration( setup->dev, setup->ad_subdev,
+ channel, range, AREF_GROUND, setup->old_calibration );
if( retval < 0 )
{
DPRINT( 0, "Failed to apply existing calibration, reseting dac caldacs.\n" );
if( setup->da_subdev < 0 ) return;
- if( setup->do_reset )
+ if( setup->old_calibration == NULL )
{
reset_caldac( setup, layout->dac_offset( channel ) );
reset_caldac( setup, layout->dac_gain( channel ) );
reset_caldac( setup, layout->dac_gain_fine( channel ) );
}else
{
- retval = comedi_apply_calibration( setup->dev, setup->da_subdev,
- channel, range, AREF_GROUND, setup->cal_save_file_path);
+ retval = comedi_apply_parsed_calibration( setup->dev, setup->da_subdev,
+ channel, range, AREF_GROUND, setup->old_calibration );
if( retval < 0 )
{
DPRINT( 0, "Failed to apply existing calibration, reseting dac caldacs.\n" );
}
}
}
-static int calibration_is_valid( const saved_calibration_t *saved_cal,
- unsigned int subdevice, unsigned int channel, unsigned int range )
-{
- int i;
-
- if( saved_cal->subdevice != subdevice ) return 0;
- if( saved_cal->channels_length )
- {
- for( i = 0; i < saved_cal->channels_length; i++ )
- {
- if( saved_cal->channels[ i ] == channel )
- break;
- }
- if( i == saved_cal->channels_length ) return 0;
- }
- if( saved_cal->ranges_length )
- {
- for( i = 0; i < saved_cal->ranges_length; i++ )
- {
- if( saved_cal->ranges[ i ] == range )
- break;
- }
- if( i == saved_cal->ranges_length ) return 0;
- }
- return 1;
-}
-
-static void apply_calibration( calibration_setup_t *setup, saved_calibration_t *saved_cals,
- unsigned int saved_cals_length, unsigned int subdevice, unsigned int channel,
- unsigned int range )
-{
- int i, retval;
-
- for( i = 0; i < saved_cals_length; i++ )
- {
- int j;
-
- if( calibration_is_valid( &saved_cals[ i ], subdevice, channel, range ) )
- {
- for( j = 0; j < saved_cals[ i ].caldacs_length; j++ )
- {
- caldac_t *caldac;
-
- caldac = &saved_cals[ i ].caldacs[ j ];
- retval = comedi_data_write( setup->dev, caldac->subdev, caldac->chan,
- 0, 0, caldac->current );
- assert( retval >= 0 );
- }
- }
- }
-}
static void generic_prep_adc_for_dac( calibration_setup_t *setup, const generic_layout_t *layout,
- saved_calibration_t *saved_cals, unsigned int saved_cals_length,
- int observable )
+ comedi_calibration_t *calibration, int observable )
{
unsigned int adc_channel, adc_range;
int chanspec;
adc_channel = CR_CHAN( chanspec );
adc_range = CR_RANGE( chanspec );
- apply_calibration( setup, saved_cals, saved_cals_length, setup->ad_subdev,
- adc_channel, adc_range );
+ comedi_apply_parsed_calibration( setup->dev, setup->ad_subdev,
+ adc_channel, adc_range, 0, calibration );
}
static void generic_do_dac_channel( calibration_setup_t *setup, const generic_layout_t *layout ,
- saved_calibration_t *saved_cals, unsigned int saved_cals_length, saved_calibration_t *current_cal,
+ comedi_calibration_t *calibration, comedi_calibration_setting_t *current_cal,
unsigned int channel, unsigned int range )
{
- generic_prep_adc_for_dac( setup, layout, saved_cals, saved_cals_length,
+ generic_prep_adc_for_dac( setup, layout, calibration,
layout->dac_ground_observable( setup, channel, range ) );
generic_do_relative( setup, current_cal, layout->dac_ground_observable( setup, channel, range ),
}
static void generic_do_adc_channel( calibration_setup_t *setup, const generic_layout_t *layout,
- saved_calibration_t *current_cal, unsigned int channel, unsigned int range )
+ comedi_calibration_setting_t *current_cal, unsigned int channel, unsigned int range )
{
generic_do_relative( setup, current_cal, layout->adc_high_observable( setup, channel, range ),
layout->adc_ground_observable( setup, channel, range ), layout->adc_gain( channel ) );
}
static void generic_do_adc_postgain_offset( calibration_setup_t *setup, const generic_layout_t *layout,
- saved_calibration_t *current_cal, unsigned int channel, int unipolar )
+ comedi_calibration_setting_t *current_cal, unsigned int channel, int unipolar )
{
int lowgain, highgain;
const generic_layout_t *layout )
{
int range, channel, num_ai_ranges, num_ai_channels, num_ao_ranges,
- num_ao_channels, retval, num_calibrations, num_ai_calibrations, i;
- saved_calibration_t *saved_cals, *current_cal;
+ num_ao_channels, retval, num_ai_calibrations;
+ comedi_calibration_setting_t *current_cal;
assert( comedi_range_is_chan_specific( setup->dev, setup->ad_subdev ) == 0 );
num_ao_ranges = num_ao_channels = 0;
num_ai_calibrations = num_ai_ranges * num_ai_channels;
- num_calibrations = num_ai_calibrations + num_ao_ranges * num_ao_channels;
- for( channel = 0; channel < num_ai_channels; channel++ )
- if( layout->adc_postgain_offset( channel ) >= 0 )
- num_calibrations += 2;
- saved_cals = malloc( num_calibrations * sizeof( saved_calibration_t ) );
-
- 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++ )
{
if( layout->adc_postgain_offset( 0 ) >= 0 )
{
/* bipolar postgain */
+ current_cal = sc_alloc_calibration_setting( setup );
generic_do_adc_postgain_offset( setup, layout, current_cal, channel, 0 );
for( range = 0; range < num_ai_ranges; range++ )
if( is_bipolar( setup->dev, setup->ad_subdev, channel, range ) )
sc_push_range( current_cal, range );
postgain_bip = setup->caldacs[ layout->adc_postgain_offset( channel ) ].current;
- current_cal++;
/* unipolar postgain */
+ current_cal = sc_alloc_calibration_setting( setup );
generic_do_adc_postgain_offset( setup, layout, current_cal, channel, 1 );
for( range = 0; range < num_ai_ranges; range++ )
if( is_unipolar( setup->dev, setup->ad_subdev, channel, range ) )
sc_push_range( current_cal, range );
postgain_unip = setup->caldacs[ layout->adc_postgain_offset( channel ) ].current;
- current_cal++;
}else
postgain_bip = postgain_unip = -1;
for( range = 0; range < num_ai_ranges; range++ )
{
+ current_cal = sc_alloc_calibration_setting( setup );
generic_prep_adc_caldacs( setup, layout, channel, range );
if( is_unipolar( setup->dev, setup->ad_subdev, channel, range ) )
update_caldac( setup, layout->adc_postgain_offset( channel ), postgain_bip );
else
update_caldac( setup, layout->adc_postgain_offset( channel ), postgain_unip );
generic_do_adc_channel( setup, layout, current_cal, channel, range );
- current_cal++;
}
}
for( channel = 0; channel < num_ao_channels; channel++ )
{
for( range = 0; range < num_ao_ranges; range++ )
{
+ current_cal = sc_alloc_calibration_setting( setup );
generic_prep_dac_caldacs( setup, layout, channel, range );
- generic_do_dac_channel( setup, layout, saved_cals, num_ai_calibrations,
+ generic_do_dac_channel( setup, layout, setup->new_calibration,
current_cal, channel, range );
- 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 );
+ retval = write_calibration_file( setup );
return retval;
}
const generic_layout_t *layout )
{
int channel, range, num_ai_ranges, num_ao_ranges,
- num_ao_channels, retval, num_calibrations, i;
- saved_calibration_t *saved_cals, *current_cal;
+ num_ao_channels, retval;
+ comedi_calibration_setting_t *current_cal;
int postgain_bip, postgain_unip;
assert( comedi_range_is_chan_specific( setup->dev, setup->ad_subdev ) == 0 );
}else
num_ao_ranges = num_ao_channels = 0;
- num_calibrations = num_ai_ranges + num_ao_ranges * num_ao_channels;
- if( layout->adc_postgain_offset( 0 ) >= 0 )
- num_calibrations += 2;
- saved_cals = malloc( num_calibrations * sizeof( saved_calibration_t ) );
- if( saved_cals == NULL ) return -1;
-
- current_cal = saved_cals;
-
if( layout->adc_postgain_offset( 0 ) >= 0 )
{
/* bipolar postgain */
+ current_cal = sc_alloc_calibration_setting( setup );
generic_do_adc_postgain_offset( setup, layout, current_cal, 0, 0 );
sc_push_channel( current_cal, SC_ALL_CHANNELS );
for( range = 0; range < num_ai_ranges; range++ )
if( is_bipolar( setup->dev, setup->ad_subdev, 0, range ) )
sc_push_range( current_cal, range );
postgain_bip = setup->caldacs[ layout->adc_postgain_offset( 0 ) ].current;
- current_cal++;
/* unipolar postgain */
+ current_cal = sc_alloc_calibration_setting( setup );
generic_do_adc_postgain_offset( setup, layout, current_cal, 0, 1 );
sc_push_channel( current_cal, SC_ALL_CHANNELS );
for( range = 0; range < num_ai_ranges; range++ )
if( is_unipolar( setup->dev, setup->ad_subdev, 0, range ) )
sc_push_range( current_cal, range );
postgain_unip = setup->caldacs[ layout->adc_postgain_offset( 0 ) ].current;
- current_cal++;
}else
postgain_bip = postgain_unip = -1;
for( range = 0; range < num_ai_ranges; range++ )
{
+ current_cal = sc_alloc_calibration_setting( setup );
generic_prep_adc_caldacs( setup, layout, 0, range );
if( is_unipolar( setup->dev, setup->ad_subdev, 0, range ) )
update_caldac( setup, layout->adc_postgain_offset( 0 ), postgain_bip );
update_caldac( setup, layout->adc_postgain_offset( 0 ), postgain_unip );
generic_do_adc_channel( setup, layout, current_cal, 0, range );
sc_push_channel( current_cal, SC_ALL_CHANNELS );
- current_cal++;
}
for( channel = 0; channel < num_ao_channels; channel++ )
{
for( range = 0; range < num_ao_ranges; range++ )
{
+ current_cal = sc_alloc_calibration_setting( setup );
generic_prep_dac_caldacs( setup, layout, channel, range );
- generic_do_dac_channel( setup, layout, saved_cals, num_ai_ranges,
+ generic_do_dac_channel( setup, layout, setup->new_calibration,
current_cal, channel, range );
- 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 );
+ retval = write_calibration_file( setup );
return retval;
}
unsigned int n_caldacs;
int (*do_cal) ( calibration_setup_t *setup );
char *cal_save_file_path;
- unsigned do_reset : 1;
unsigned do_output : 1;
void *private_data;
+ comedi_calibration_t *old_calibration;
+ comedi_calibration_t *new_calibration;
};
extern int verbose;
int new_sv_init(new_sv_t *sv,comedi_t *dev,int subdev,unsigned int chanspec);
/* saving calibrations to file */
-#define SC_MAX_AREFS_LENGTH 4
-typedef struct
-{
- unsigned int subdevice;
- caldac_t *caldacs;
- unsigned int caldacs_length;
- /* channels that caldac settings are restricted to */
- int *channels;
- /* number of elements in channels array, 0 means allow all channels */
- unsigned int channels_length;
- /* ranges that caldac settings are restricted to */
- int *ranges;
- /* number of elements in ranges array, 0 means allow all ranges */
- unsigned int ranges_length;
- /* arefs that caldac settings are used restricted to */
- int arefs[ SC_MAX_AREFS_LENGTH ];
- /* number of elements in arefs array, 0 means allow any aref */
- unsigned int arefs_length;
-} saved_calibration_t;
-
static const int SC_ALL_CHANNELS = -1;
static const int SC_ALL_RANGES = -1;
static const int SC_ALL_AREFS = -1;
-int write_calibration_file( calibration_setup_t *setup, saved_calibration_t settings[],
- unsigned int num_settings );
-void sc_push_caldac( saved_calibration_t *saved_cal, caldac_t caldac );
-void sc_push_channel( saved_calibration_t *saved_cal, int channel );
-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 );
+int write_calibration_file( calibration_setup_t *setup );
+comedi_calibration_setting_t* sc_alloc_calibration_setting( calibration_setup_t *setup );
+void sc_push_caldac( comedi_calibration_setting_t *saved_cal, caldac_t caldac );
+void sc_push_channel( comedi_calibration_setting_t *saved_cal, int channel );
+void sc_push_range( comedi_calibration_setting_t *saved_cal, int range );
+void sc_push_aref( comedi_calibration_setting_t *saved_cal, int aref );
/* generic calibration support */
typedef struct
int generic_cal_by_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 );
+ comedi_calibration_setting_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 );
+ comedi_calibration_setting_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,
+ comedi_calibration_setting_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 );
{
generic_layout_t layout;
+ if( comedi_get_version_code( setup->dev ) <= COMEDI_VERSION_CODE( 0, 7, 66 ) )
+ {
+ DPRINT(0, "WARNING: you need comedi driver version 0.7.67 or later\n"
+ "for this calibration to work properly\n" );
+ }
+
init_generic_layout( &layout );
layout.adc_gain = adc_gain_1xxx;
layout.adc_offset = adc_offset_coarse_1xxx;
return generic_cal_by_range( setup, &layout );
}
-#if 0
-static int cal_cb_pci_1602_16( calibration_setup_t *setup )
-{
- enum cal_knobs_1602_16
- {
- DAC0_GAIN_FINE = 0,
- DAC0_GAIN_COARSE,
- DAC0_OFFSET_COARSE,
- DAC1_OFFSET_COARSE,
- DAC1_GAIN_FINE,
- DAC1_GAIN_COARSE,
- DAC0_OFFSET_FINE,
- DAC1_OFFSET_FINE,
- ADC_GAIN,
- ADC_POSTGAIN_OFFSET,
- ADC_PREGAIN_OFFSET,
- };
-
- cal_binary( setup, OBS_0V_RANGE_10V_BIP_1602_16, ADC_PREGAIN_OFFSET );
- cal_binary( setup, OBS_0V_RANGE_10V_BIP_1602_16, ADC_POSTGAIN_OFFSET );
- cal_binary( setup, OBS_7V_RANGE_10V_BIP_1602_16, ADC_GAIN );
-
- return 0;
-}
-#endif
-
// converts calibration source voltages from two 16 bit eeprom values to a floating point value
static float eeprom16_to_source( uint16_t *data )
{
};
#define n_drivers (sizeof(drivers)/sizeof(drivers[0]))
-static int do_dump = 0;
-static int do_reset = 1;
-static int do_calibrate = 1;
-static int do_results = 0;
-static int do_output = 1;
-
void help(void)
{
printf("comedi_calibrate [options] - autocalibrates a Comedi device\n");
unsigned int aref;
} parsed_options_t;
-void parse_options( int argc, char *argv[], parsed_options_t *settings )
+static void parse_options( int argc, char *argv[], parsed_options_t *settings )
{
int c, index;
{ 0 },
};
- memset( settings, 0, sizeof( *settings ) );
- settings->do_dump = 0;
- settings->do_reset = 1;
- settings->do_calibrate = 1;
- settings->do_results = 0;
- settings->do_output = 1;
-
- settings->file_path = "/dev/comedi0";
while (1) {
c = getopt_long(argc, argv, "f:S:vqs:c:r:a:", options, &index);
if (c == -1)break;
memset( &setup, 0, sizeof( setup ) );
setup.settling_time_ns = 99999;
+ memset( &options, 0, sizeof( options ) );
+ options.do_dump = 0;
+ options.do_reset = 0;
+ options.do_calibrate = -1;
+ options.do_results = 0;
+ options.do_output = 1;
+ options.file_path = "/dev/comedi0";
parse_options( argc, argv, &options );
setup.cal_save_file_path = options.save_file_path;
- do_reset = options.do_reset;
- do_dump = options.do_dump;
- do_calibrate = options.do_calibrate;
- do_results = options.do_results;
- do_output = options.do_output;
setup.dev = comedi_open( options.file_path );
if( setup.dev == NULL ) {
"quickly in the future.\n");
if(verbose<1)verbose=1;
if(device_status==STATUS_UNKNOWN){
- do_reset=1;
- do_dump=1;
- do_calibrate=0;
- do_results=0;
+ options.do_reset=1;
+ options.do_dump=1;
+ options.do_calibrate=0;
+ options.do_results=0;
}
if(device_status==STATUS_SOME){
- do_reset=1;
- do_dump=1;
- do_calibrate=1;
- do_results=1;
+ options.do_reset=1;
+ options.do_dump=1;
+ options.do_calibrate=1;
+ options.do_results=1;
}
if(device_status==STATUS_GUESS){
- do_reset=1;
- do_dump=1;
- do_calibrate=1;
- do_results=1;
+ options.do_reset=1;
+ options.do_dump=1;
+ options.do_calibrate=1;
+ options.do_results=1;
}
}
if(verbose>=0){
(comedi_get_version_code(setup.dev))&0xff);
}
- setup.do_reset = do_reset;
- setup.do_output = do_output;
+ if( options.do_reset == 0 )
+ setup.old_calibration = comedi_parse_calibration_file( options.save_file_path );
+ else
+ setup.old_calibration = NULL;
+ if( options.do_calibrate < 0 )
+ {
+ if( setup.old_calibration ) options.do_calibrate = 0;
+ else options.do_calibrate = 1;
+ }
+ setup.do_output = options.do_output;
- if(do_reset)reset_caldacs( &setup );
- if(do_dump) observe( &setup );
- if(do_calibrate && setup.do_cal)
+ if(options.do_dump) observe( &setup );
+ if(options.do_calibrate && setup.do_cal)
{
+ setup.new_calibration = malloc( sizeof( comedi_calibration_t ) );
+ assert( setup.new_calibration );
+ memset( setup.new_calibration, 0, sizeof( comedi_calibration_t ) );
+ setup.new_calibration->driver_name = strdup( comedi_get_driver_name( setup.dev ) );
+ assert( setup.new_calibration->driver_name != NULL );
+ setup.new_calibration->board_name = strdup( comedi_get_board_name( setup.dev ) );
+ assert( setup.new_calibration->board_name != NULL );
retval = setup.do_cal( &setup );
if( retval < 0 )
{
return -1;
}
}
- if(do_results) observe( &setup );
+ if(options.do_results) observe( &setup );
+
+ if( setup.old_calibration ) comedi_cleanup_calibration( setup.old_calibration );
+ if( setup.new_calibration ) comedi_cleanup_calibration( setup.new_calibration );
retval = comedi_apply_calibration( setup.dev, options.subdevice,
options.channel, options.range, options.aref, setup.cal_save_file_path );
static void apply_appropriate_cal( calibration_setup_t *setup, comedi_insn insn )
{
- int retval;
+ int retval = 0;
- retval = comedi_apply_calibration( setup->dev, insn.subdev,
- CR_CHAN( insn.chanspec ), CR_RANGE( insn.chanspec ),
- CR_AREF( insn.chanspec ), setup->cal_save_file_path );
+ if( setup->new_calibration == NULL && setup->old_calibration == NULL )
+ {
+ reset_caldacs( setup );
+ return;
+ }
+
+ if( setup->new_calibration )
+ {
+ retval = comedi_apply_parsed_calibration( setup->dev, insn.subdev,
+ CR_CHAN( insn.chanspec ), CR_RANGE( insn.chanspec ),
+ CR_AREF( insn.chanspec ), setup->new_calibration );
+ }else if( setup->old_calibration )
+ {
+ retval = comedi_apply_parsed_calibration( setup->dev, insn.subdev,
+ CR_CHAN( insn.chanspec ), CR_RANGE( insn.chanspec ),
+ CR_AREF( insn.chanspec ), setup->old_calibration );
+ }
if( retval < 0 )
DPRINT( 0, "failed to apply ");
else
{
int retval;
- if( setup->do_reset )
+ if( setup->old_calibration == NULL )
{
reset_caldac( setup, layout->adc_pregain_offset );
reset_caldac( setup, layout->adc_postgain_offset );
reset_caldac( setup, layout->adc_unip_offset );
}else
{
- retval = comedi_apply_calibration( setup->dev, setup->ad_subdev,
- 0, 0, AREF_GROUND, setup->cal_save_file_path);
+ retval = comedi_apply_parsed_calibration( setup->dev, setup->ad_subdev,
+ 0, 0, AREF_GROUND, setup->old_calibration );
if( retval < 0 )
{
DPRINT( 0, "Failed to apply existing calibration, reseting adc caldacs.\n" );
if( setup->da_subdev < 0 ) return;
- if( setup->do_reset )
+ if( setup->old_calibration == NULL )
{
reset_caldac( setup, layout->dac_offset[ channel ] );
reset_caldac( setup, layout->dac_gain[ channel ] );
reset_caldac( setup, layout->dac_linearity[ channel ] );
}else
{
- retval = comedi_apply_calibration( setup->dev, setup->da_subdev,
- channel, range, AREF_GROUND, setup->cal_save_file_path);
+ retval = comedi_apply_parsed_calibration( setup->dev, setup->da_subdev,
+ channel, range, AREF_GROUND, setup->old_calibration );
if( retval < 0 )
{
DPRINT( 0, "Failed to apply existing calibration, reseting dac caldacs.\n" );
static int cal_ni_generic( calibration_setup_t *setup, const ni_caldac_layout_t *layout )
{
- saved_calibration_t saved_cals[ 5 ], *current_cal;
- int i, retval;
- int num_calibrations;
-
- current_cal = saved_cals;
-
- memset( saved_cals, 0, sizeof( saved_cals ) );
+ comedi_calibration_setting_t *current_cal;
+ int retval;
prep_adc_caldacs_generic( setup, layout );
+ current_cal = sc_alloc_calibration_setting( setup );
current_cal->subdevice = setup->ad_subdev;
generic_do_relative( setup, current_cal, ni_zero_offset_low,
ni_reference_low, layout->adc_gain );
sc_push_channel( current_cal, SC_ALL_CHANNELS );
sc_push_range( current_cal, SC_ALL_RANGES );
sc_push_aref( current_cal, SC_ALL_AREFS );
- current_cal++;
if( setup->da_subdev >= 0 && setup->do_output )
{
num_ao_ranges = comedi_get_n_ranges( setup->dev, setup->da_subdev, channel );
prep_dac_caldacs_generic( setup, layout, channel, ao_bipolar_lowgain );
+ current_cal = sc_alloc_calibration_setting( setup );
current_cal->subdevice = setup->da_subdev;
generic_do_linearity( setup, current_cal, ni_ao_linearity( channel ),
ni_ao_zero_offset( channel ), ni_ao_reference( channel ),
sc_push_range( current_cal, range );
}
sc_push_aref( current_cal, SC_ALL_AREFS );
- current_cal++;
if( ao_unipolar_lowgain >= 0 )
{
prep_dac_caldacs_generic( setup, layout, channel, ao_unipolar_lowgain );
+ current_cal = sc_alloc_calibration_setting( setup );
current_cal->subdevice = setup->da_subdev;
generic_do_linearity( setup, current_cal, ni_ao_unip_zero_offset( channel ),
ni_ao_unip_linearity( channel ), ni_ao_unip_reference( channel ),
sc_push_range( current_cal, range );
}
sc_push_aref( current_cal, SC_ALL_AREFS );
- current_cal++;
}
}
}
- num_calibrations = current_cal - saved_cals;
- retval = write_calibration_file( setup, saved_cals, num_calibrations );
- for( i = 0; i < num_calibrations; i++ )
- clear_saved_calibration( &saved_cals[ i ] );
+ retval = write_calibration_file( setup );
return retval;
}
#include "calib.h"
-void write_caldac( FILE *file, caldac_t caldac )
+void write_caldac( FILE *file, comedi_caldac_t caldac )
{
static const char *indent = "\t\t\t\t";
fprintf( file, "%s", indent );
fprintf( file, "{\n" );
fprintf( file, "%s", indent );
- fprintf( file, "\tsubdevice => %i,\n", caldac.subdev );
+ fprintf( file, "\tsubdevice => %i,\n", caldac.subdevice );
fprintf( file, "%s", indent );
- fprintf( file, "\tchannel => %i,\n", caldac.chan );
+ fprintf( file, "\tchannel => %i,\n", caldac.channel );
fprintf( file, "%s", indent );
- fprintf( file, "\tvalue => %i,\n", caldac.current );
+ fprintf( file, "\tvalue => %i,\n", caldac.value );
fprintf( file, "%s", indent );
fprintf( file, "}" );
}
-void write_calibration_setting( FILE *file, saved_calibration_t setting )
+void write_calibration_setting( FILE *file, comedi_calibration_setting_t setting )
{
static const char *indent = "\t\t";
int i;
fprintf( file, "\tsubdevice => %i,\n", setting.subdevice );
fprintf( file, "%s", indent );
fprintf( file, "\tchannels => [" );
- for( i = 0; i < setting.channels_length; i++ )
+ for( i = 0; i < setting.num_channels; i++ )
fprintf( file, "%i,", setting.channels[ i ] );
fprintf( file, "],\n" );
fprintf( file, "%s", indent );
fprintf( file, "\tranges => [" );
- for( i = 0; i < setting.ranges_length; i++ )
+ for( i = 0; i < setting.num_ranges; i++ )
fprintf( file, "%i,", setting.ranges[ i ] );
fprintf( file, "],\n" );
fprintf( file, "%s", indent );
fprintf( file, "\tarefs => [" );
- for( i = 0; i < setting.arefs_length; i++ )
+ for( i = 0; i < setting.num_arefs; i++ )
fprintf( file, "%i,", setting.arefs[ i ] );
fprintf( file, "],\n" );
fprintf( file, "%s", indent );
fprintf( file, "\tcaldacs =>\n" );
fprintf( file, "%s", indent );
fprintf( file, "\t[\n" );
- for( i = 0; i < setting.caldacs_length; i++ )
+ for( i = 0; i < setting.num_caldacs; i++ )
{
write_caldac( file, setting.caldacs[ i ] );
fprintf( file, ",\n" );
fprintf( file, "}" );
}
-int write_calibration_perl_hash( FILE *file, comedi_t *dev,
- saved_calibration_t settings[], unsigned int num_settings )
+int write_calibration_perl_hash( FILE *file, const comedi_calibration_t *calibration )
{
int i;
time_t now;
fprintf( file, "#calibration file generated by comedi_calibrate\n"
"#%s\n", ctime( &now ) );
fprintf( file, "{\n" );
- fprintf( file, "\tdriver_name => \"%s\",\n", comedi_get_driver_name( dev ) );
- fprintf( file, "\tboard_name => \"%s\",\n", comedi_get_board_name( dev ) );
+ fprintf( file, "\tdriver_name => \"%s\",\n", calibration->driver_name );
+ fprintf( file, "\tboard_name => \"%s\",\n", calibration->board_name );
fprintf( file, "\tcalibrations =>\n"
"\t[\n" );
- for( i = 0; i < num_settings; i++ )
+ for( i = 0; i < calibration->num_settings; i++ )
{
- write_calibration_setting( file, settings[ i ] );
+ write_calibration_setting( file, calibration->settings[ i ] );
fprintf( file, ",\n" );
}
fprintf( file, "\t],\n"
return 0;
}
-int write_calibration_file( calibration_setup_t *setup, saved_calibration_t settings[],
- unsigned int num_settings )
+int write_calibration_file( calibration_setup_t *setup )
{
FILE *file;
int retval;
struct stat file_stats;
comedi_t *dev = setup->dev;
+ assert( setup->new_calibration != NULL );
+
if( setup->cal_save_file_path == NULL )
{
if( fstat( comedi_fileno( dev ), &file_stats ) < 0 )
return -1;
}
- retval = write_calibration_perl_hash( file, dev, settings, num_settings );
+ retval = write_calibration_perl_hash( file, setup->new_calibration );
fclose( file );
return retval;
}
-void sc_push_caldac( saved_calibration_t *saved_cal, caldac_t caldac )
+comedi_calibration_setting_t* sc_alloc_calibration_setting( calibration_setup_t *setup )
+{
+ comedi_calibration_setting_t *temp;
+
+ temp = realloc( setup->new_calibration->settings,
+ ( setup->new_calibration->num_settings + 1 ) * sizeof( comedi_calibration_setting_t ) );
+ assert( temp != NULL );
+ setup->new_calibration->settings = temp;
+ memset( &setup->new_calibration->settings[ setup->new_calibration->num_settings ],
+ 0, sizeof( comedi_calibration_setting_t ) );
+
+ setup->new_calibration->num_settings++;
+
+ return &setup->new_calibration->settings[ setup->new_calibration->num_settings - 1 ];
+}
+
+void sc_push_caldac( comedi_calibration_setting_t *saved_cal, caldac_t caldac )
{
saved_cal->caldacs = realloc( saved_cal->caldacs,
- ( saved_cal->caldacs_length + 1 ) * sizeof( caldac_t ) );
+ ( saved_cal->num_caldacs + 1 ) * sizeof( caldac_t ) );
if( saved_cal->caldacs == NULL )
{
fprintf( stderr, "memory allocation failure\n" );
abort();
}
- saved_cal->caldacs[ saved_cal->caldacs_length++ ] = caldac;
+ saved_cal->caldacs[ saved_cal->num_caldacs ].subdevice = caldac.subdev;
+ saved_cal->caldacs[ saved_cal->num_caldacs ].channel = caldac.chan;
+ saved_cal->caldacs[ saved_cal->num_caldacs ].value = caldac.current;
+ saved_cal->num_caldacs++;
}
-void sc_push_channel( saved_calibration_t *saved_cal, int channel )
+void sc_push_channel( comedi_calibration_setting_t *saved_cal, int channel )
{
if( channel == SC_ALL_CHANNELS )
{
- saved_cal->channels_length = 0;
+ saved_cal->num_channels = 0;
if( saved_cal->channels )
{
free( saved_cal->channels );
}else
{
saved_cal->channels = realloc( saved_cal->channels,
- ( saved_cal->channels_length + 1 ) * sizeof( int ) );
+ ( saved_cal->num_channels + 1 ) * sizeof( int ) );
if( saved_cal->channels == NULL )
{
fprintf( stderr, "memory allocation failure\n" );
abort();
}
- saved_cal->channels[ saved_cal->channels_length++ ] = channel;
+ saved_cal->channels[ saved_cal->num_channels++ ] = channel;
}
}
-void sc_push_range( saved_calibration_t *saved_cal, int range )
+void sc_push_range( comedi_calibration_setting_t *saved_cal, int range )
{
if( range == SC_ALL_RANGES )
{
- saved_cal->ranges_length = 0;
+ saved_cal->num_ranges = 0;
if( saved_cal->ranges )
{
free( saved_cal->ranges );
else
{
saved_cal->ranges = realloc( saved_cal->ranges,
- ( saved_cal->ranges_length + 1 ) * sizeof( int ) );
+ ( saved_cal->num_ranges + 1 ) * sizeof( int ) );
if( saved_cal->ranges == NULL )
{
fprintf( stderr, "memory allocation failure\n" );
abort();
}
- saved_cal->ranges[ saved_cal->ranges_length++ ] = range;
+ saved_cal->ranges[ saved_cal->num_ranges++ ] = range;
}
}
-void sc_push_aref( saved_calibration_t *saved_cal, int aref )
+void sc_push_aref( comedi_calibration_setting_t *saved_cal, int aref )
{
- assert( saved_cal->arefs_length < SC_MAX_AREFS_LENGTH );
+ assert( saved_cal->num_arefs < CS_MAX_AREFS_LENGTH );
if( aref == SC_ALL_AREFS )
- saved_cal->arefs_length = 0;
+ saved_cal->num_arefs = 0;
else
- saved_cal->arefs[ saved_cal->arefs_length++ ] = aref;
+ saved_cal->arefs[ saved_cal->num_arefs++ ] = aref;
}
-void clear_saved_calibration( saved_calibration_t *saved_cal )
-{
- if( saved_cal->caldacs )
- {
- free( saved_cal->caldacs );
- saved_cal->caldacs = NULL;
- saved_cal->caldacs_length = 0;
- }
- if( saved_cal->channels )
- {
- free( saved_cal->channels );
- saved_cal->channels = NULL;
- saved_cal->channels_length = 0;
- }
- if( saved_cal->ranges )
- {
- free( saved_cal->ranges );
- saved_cal->ranges = NULL;
- saved_cal->ranges_length = 0;
- }
-}
unsigned int channel;
unsigned int value;
} comedi_caldac_t;
-
-typedef struct calibration_setting
+#define CS_MAX_AREFS_LENGTH 4
+typedef struct
{
unsigned int subdevice;
unsigned int *channels;
unsigned int num_channels;
unsigned int *ranges;
unsigned int num_ranges;
- unsigned int arefs[ 4 ];
+ unsigned int arefs[ CS_MAX_AREFS_LENGTH ];
unsigned int num_arefs;
comedi_caldac_t *caldacs;
unsigned int num_caldacs;
{
char *driver_name;
char *board_name;
- comedi_calibration_setting_t *calibrations;
- unsigned int num_calibrations;
+ comedi_calibration_setting_t *settings;
+ unsigned int num_settings;
} comedi_calibration_t;
comedi_calibration_t* comedi_parse_calibration_file( const char *cal_file_path );
{
int num_channels, i;
- num_channels = parsed_file->calibrations[ cal_index ].num_channels;
+ num_channels = parsed_file->settings[ cal_index ].num_channels;
if( num_channels == 0 ) return 1;
for( i = 0; i < num_channels; i++ )
{
- if( parsed_file->calibrations[ cal_index ].channels[ i ] == channel )
+ if( parsed_file->settings[ cal_index ].channels[ i ] == channel )
return 1;
}
{
int num_ranges, i;
- num_ranges = parsed_file->calibrations[ cal_index ].num_ranges;
+ num_ranges = parsed_file->settings[ cal_index ].num_ranges;
if( num_ranges == 0 ) return 1;
for( i = 0; i < num_ranges; i++ )
{
- if( parsed_file->calibrations[ cal_index ].ranges[ i ] == range )
+ if( parsed_file->settings[ cal_index ].ranges[ i ] == range )
return 1;
}
{
int num_arefs, i;
- num_arefs = parsed_file->calibrations[ cal_index ].num_arefs;
+ num_arefs = parsed_file->settings[ cal_index ].num_arefs;
if( num_arefs == 0 ) return 1;
for( i = 0; i < num_arefs; i++ )
{
- if( parsed_file->calibrations[ cal_index ].arefs[ i ] == aref )
+ if( parsed_file->settings[ cal_index ].arefs[ i ] == aref )
return 1;
}
int num_cals, i, retval;
int found_cal = 0;
- num_cals = parsed_file->num_calibrations;
+ num_cals = parsed_file->num_settings;
for( i = 0; i < num_cals; i++ )
{
- if( parsed_file->calibrations[ i ].subdevice != subdev ) continue;
+ if( parsed_file->settings[ i ].subdevice != subdev ) continue;
if( valid_range( parsed_file, i, range ) == 0 ) continue;
if( valid_channel( parsed_file, i, channel ) == 0 ) continue;
if( valid_aref( parsed_file, i, aref ) == 0 ) continue;
{
int i, retval, num_caldacs;
- num_caldacs = parsed_file->calibrations[ cal_index ].num_caldacs;
+ num_caldacs = parsed_file->settings[ cal_index ].num_caldacs;
COMEDILIB_DEBUG( 4, "num_caldacs %i\n", num_caldacs );
for( i = 0; i < num_caldacs; i++ )
{
comedi_caldac_t caldac;
- caldac = parsed_file->calibrations[ cal_index ].caldacs[ i ];
+ caldac = parsed_file->settings[ cal_index ].caldacs[ i ];
COMEDILIB_DEBUG( 4, "subdev %i, ch %i, val %i\n", caldac.subdevice,
caldac.channel,caldac.value);
retval = comedi_data_write( dev, caldac.subdevice, caldac.channel,
return parse_arg;
}
-static void free_calibration_setting( struct calibration_setting *setting )
+static void free_calibration_setting( comedi_calibration_setting_t *setting )
{
if( setting->channels );
{
}
}
-static void free_calibrations( comedi_calibration_t *file_contents )
+static void free_settings( comedi_calibration_t *file_contents )
{
int i;
- if( file_contents->calibrations == NULL ) return;
+ if( file_contents->settings == NULL ) return;
- for( i = 0; i < file_contents->num_calibrations; i++ )
+ for( i = 0; i < file_contents->num_settings; i++ )
{
- free_calibration_setting( &file_contents->calibrations[ i ] );
+ free_calibration_setting( &file_contents->settings[ i ] );
}
- file_contents->calibrations = NULL;
+ file_contents->settings = NULL;
}
static int add_calibration_setting( comedi_calibration_t *file_contents )
{
- struct calibration_setting *temp;
+ comedi_calibration_setting_t *temp;
- temp = realloc( file_contents->calibrations,
- ( file_contents->num_calibrations + 1 ) * sizeof( struct calibration_setting ) );
+ temp = realloc( file_contents->settings,
+ ( file_contents->num_settings + 1 ) * sizeof( comedi_calibration_setting_t ) );
if( temp == NULL ) return -1;
- file_contents->calibrations = temp;
- memset( &file_contents->calibrations[ file_contents->num_calibrations ],
- 0, sizeof( struct calibration_setting ) );
+ file_contents->settings = temp;
+ memset( &file_contents->settings[ file_contents->num_settings ],
+ 0, sizeof( comedi_calibration_setting_t ) );
- file_contents->num_calibrations++;
+ file_contents->num_settings++;
return 0;
}
-static struct calibration_setting* current_setting( calib_yyparse_private_t *priv )
+static comedi_calibration_setting_t* current_setting( calib_yyparse_private_t *priv )
{
int retval;
- while( priv->cal_index >= priv->parsed_file->num_calibrations )
+ while( priv->cal_index >= priv->parsed_file->num_settings )
{
retval = add_calibration_setting( priv->parsed_file );
if( retval < 0 ) return NULL;
}
- return &priv->parsed_file->calibrations[ priv->cal_index ];
+ return &priv->parsed_file->settings[ priv->cal_index ];
}
static int add_channel( calib_yyparse_private_t *priv, int channel )
{
int *temp;
- struct calibration_setting *setting;
+ comedi_calibration_setting_t *setting;
setting = current_setting( priv );
if( setting == NULL ) return -1;
static int add_range( calib_yyparse_private_t *priv, int range )
{
int *temp;
- struct calibration_setting *setting;
+ comedi_calibration_setting_t *setting;
setting = current_setting( priv );
if( setting == NULL ) return -1;
static int add_aref( calib_yyparse_private_t *priv, int aref )
{
- struct calibration_setting *setting;
+ comedi_calibration_setting_t *setting;
setting = current_setting( priv );
if( setting == NULL ) return -1;
comedi_caldac_t caldac )
{
comedi_caldac_t *temp;
- struct calibration_setting *setting;
+ comedi_calibration_setting_t *setting;
setting = current_setting( priv );
if( setting == NULL ) return -1;
free( file_contents->board_name );
file_contents->board_name = NULL;
}
- free_calibrations( file_contents );
+ free_settings( file_contents );
free( file_contents );
file_contents = NULL;
}
calib_yyparse_private_t priv;
FILE *file;
+ if( cal_file_path == NULL ) return NULL;
+
priv.parsed_file = alloc_calib_parse();
if( priv.parsed_file == NULL ) return NULL;
priv.cal_index = 0;
calibration_setting_element: T_SUBDEVICE T_ASSIGN T_NUMBER
{
- struct calibration_setting *setting;
+ comedi_calibration_setting_t *setting;
setting = current_setting( parse_arg );
if( setting == NULL ) YYABORT;
setting->subdevice = $3;
pass is not sufficient, and you wish to perform another calibration
pass starting from the results of the previous pass.
-\fB-s, --save-file <file path>\fR save calibration information to specified file,
+\fB-S, --save-file <file path>\fR save calibration information to specified file,
instead of default location
\fB-v, --verbose\fR generate more verbose output to stdout, can be specified multiple times