3
functions for setting calibration
5
Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net
7
This library is free software; you can redistribute it and/or
8
modify it under the terms of the GNU Lesser General Public
9
License as published by the Free Software Foundation, version 2.1
12
This library is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
Lesser General Public License for more details.
17
You should have received a copy of the GNU Lesser General Public
18
License along with this library; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28
#include "libinternal.h"
30
static int set_calibration( comedi_t *dev, const comedi_calibration_t *parsed_file,
31
unsigned int cal_index );
33
static int check_cal_file( comedi_t *dev, const comedi_calibration_t *parsed_file )
35
if( strcmp( comedi_get_driver_name( dev ), parsed_file->driver_name ) )
37
COMEDILIB_DEBUG( 3, "driver name does not match '%s' from calibration file\n",
38
parsed_file->driver_name );
42
if( strcmp( comedi_get_board_name( dev ), parsed_file->board_name ) )
44
COMEDILIB_DEBUG( 3, "board name does not match '%s' from calibration file\n",
45
parsed_file->board_name );
52
static inline int valid_channel( const comedi_calibration_t *parsed_file,
53
unsigned int cal_index, unsigned int channel )
57
num_channels = parsed_file->settings[ cal_index ].num_channels;
58
if( num_channels == 0 ) return 1;
59
for( i = 0; i < num_channels; i++ )
61
if( parsed_file->settings[ cal_index ].channels[ i ] == channel )
68
static inline int valid_range( const comedi_calibration_t *parsed_file,
69
unsigned int cal_index, unsigned int range )
73
num_ranges = parsed_file->settings[ cal_index ].num_ranges;
74
if( num_ranges == 0 ) return 1;
75
for( i = 0; i < num_ranges; i++ )
77
if( parsed_file->settings[ cal_index ].ranges[ i ] == range )
84
static inline int valid_aref( const comedi_calibration_t *parsed_file,
85
unsigned int cal_index, unsigned int aref )
89
num_arefs = parsed_file->settings[ cal_index ].num_arefs;
90
if( num_arefs == 0 ) return 1;
91
for( i = 0; i < num_arefs; i++ )
93
if( parsed_file->settings[ cal_index ].arefs[ i ] == aref )
100
static int apply_calibration( comedi_t *dev, const comedi_calibration_t *parsed_file,
101
unsigned int subdev, unsigned int channel, unsigned int range, unsigned int aref )
103
int num_cals, i, retval;
106
num_cals = parsed_file->num_settings;
108
for( i = 0; i < num_cals; i++ )
110
if( parsed_file->settings[ i ].subdevice != subdev ) continue;
111
if( valid_range( parsed_file, i, range ) == 0 ) continue;
112
if( valid_channel( parsed_file, i, channel ) == 0 ) continue;
113
if( valid_aref( parsed_file, i, aref ) == 0 ) continue;
115
retval = set_calibration( dev, parsed_file, i );
116
if( retval < 0 ) return retval;
121
COMEDILIB_DEBUG( 3, "failed to find matching calibration\n" );
128
static int set_calibration( comedi_t *dev, const comedi_calibration_t *parsed_file,
129
unsigned int cal_index )
131
int i, retval, num_caldacs;
133
num_caldacs = parsed_file->settings[ cal_index ].num_caldacs;
134
COMEDILIB_DEBUG( 4, "num_caldacs %i\n", num_caldacs );
136
for( i = 0; i < num_caldacs; i++ )
138
comedi_caldac_t caldac;
140
caldac = parsed_file->settings[ cal_index ].caldacs[ i ];
141
COMEDILIB_DEBUG( 4, "subdev %i, ch %i, val %i\n", caldac.subdevice,
142
caldac.channel,caldac.value);
143
retval = comedi_data_write( dev, caldac.subdevice, caldac.channel,
144
0, 0, caldac.value );
145
if( retval < 0 ) return retval;
151
EXPORT_ALIAS_DEFAULT(_comedi_apply_parsed_calibration,comedi_apply_parsed_calibration,0.7.20);
152
int _comedi_apply_parsed_calibration( comedi_t *dev, unsigned int subdev, unsigned int channel,
153
unsigned int range, unsigned int aref, const comedi_calibration_t *calibration )
157
retval = check_cal_file( dev, calibration );
158
if( retval < 0 ) return retval;
160
retval = apply_calibration( dev, calibration, subdev, channel, range, aref );
164
/* munge characters in board name that will cause problems with file paths */
165
static void fixup_board_name( char *name )
167
while( ( name = strchr( name, '/' ) ) )
177
EXPORT_ALIAS_DEFAULT(_comedi_get_default_calibration_path,comedi_get_default_calibration_path,0.7.20);
178
char* _comedi_get_default_calibration_path( comedi_t *dev )
180
struct stat file_stats;
182
char *board_name, *temp;
185
if( fstat( comedi_fileno( dev ), &file_stats ) < 0 )
187
COMEDILIB_DEBUG( 3, "failed to get file stats of comedi device file\n" );
191
driver_name = comedi_get_driver_name( dev );
192
if( driver_name == NULL )
196
temp = comedi_get_board_name( dev );
201
board_name = strdup( temp );
203
fixup_board_name( board_name );
204
asprintf( &file_path, LOCALSTATEDIR "/comedi/calibrations/%s_%s_comedi%li",
205
driver_name, board_name, ( unsigned long ) minor( file_stats.st_rdev ) );
211
EXPORT_ALIAS_DEFAULT(_comedi_apply_calibration,comedi_apply_calibration,0.7.20);
212
int _comedi_apply_calibration( comedi_t *dev, unsigned int subdev, unsigned int channel,
213
unsigned int range, unsigned int aref, const char *cal_file_path )
215
char file_path[ 1024 ];
217
comedi_calibration_t *parsed_file;
221
strncpy( file_path, cal_file_path, sizeof( file_path ) );
226
temp = comedi_get_default_calibration_path( dev );
227
if( temp == NULL ) return -1;
228
strncpy( file_path, temp, sizeof( file_path ) );
232
parsed_file = comedi_parse_calibration_file( file_path );
233
if( parsed_file == NULL )
235
COMEDILIB_DEBUG( 3, "failed to parse calibration file\n" );
239
retval = comedi_apply_parsed_calibration( dev, subdev, channel, range, aref, parsed_file );
241
comedi_cleanup_calibration( parsed_file );