exposed some lower-level calibration functions for more flexibility
This commit is contained in:
parent
0f45648de4
commit
0d0bfe17b9
4 changed files with 115 additions and 85 deletions
|
@ -194,10 +194,45 @@ int comedi_get_rangetype(comedi_t *it,unsigned int subdevice,
|
|||
compatibility. In practice, this is a holding place for the next
|
||||
library ABI version change.
|
||||
*/
|
||||
/* structs and functions used for parsing calibration files */
|
||||
typedef struct
|
||||
{
|
||||
unsigned int subdevice;
|
||||
unsigned int channel;
|
||||
unsigned int value;
|
||||
} comedi_caldac_t;
|
||||
|
||||
typedef struct calibration_setting
|
||||
{
|
||||
unsigned int subdevice;
|
||||
unsigned int *channels;
|
||||
unsigned int num_channels;
|
||||
unsigned int *ranges;
|
||||
unsigned int num_ranges;
|
||||
unsigned int arefs[ 4 ];
|
||||
unsigned int num_arefs;
|
||||
comedi_caldac_t *caldacs;
|
||||
unsigned int num_caldacs;
|
||||
} comedi_calibration_setting_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *driver_name;
|
||||
char *board_name;
|
||||
comedi_calibration_setting_t *calibrations;
|
||||
unsigned int num_calibrations;
|
||||
} comedi_calibration_t;
|
||||
|
||||
comedi_calibration_t* comedi_parse_calibration_file( const char *cal_file_path );
|
||||
int comedi_apply_parsed_calibration( comedi_t *dev, unsigned int subdev, unsigned int channel,
|
||||
unsigned int range, unsigned int aref, const comedi_calibration_t *calibration );
|
||||
char* comedi_get_default_calibration_path( comedi_t *dev );
|
||||
void comedi_cleanup_calibration( comedi_calibration_t *calibration );
|
||||
int comedi_apply_calibration( comedi_t *dev, unsigned int subdev, unsigned int channel,
|
||||
unsigned int range, unsigned int aref, const char *cal_file_path);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
95
lib/calib.c
95
lib/calib.c
|
@ -27,10 +27,10 @@
|
|||
#include <string.h>
|
||||
#include "libinternal.h"
|
||||
|
||||
static int set_calibration( comedi_t *dev, struct calibration_file_contents *parsed_file,
|
||||
static int set_calibration( comedi_t *dev, const comedi_calibration_t *parsed_file,
|
||||
unsigned int cal_index );
|
||||
|
||||
static int check_cal_file( comedi_t *dev, struct calibration_file_contents *parsed_file )
|
||||
static int check_cal_file( comedi_t *dev, const comedi_calibration_t *parsed_file )
|
||||
{
|
||||
if( strcmp( comedi_get_driver_name( dev ), parsed_file->driver_name ) )
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ static int check_cal_file( comedi_t *dev, struct calibration_file_contents *pars
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int valid_channel( struct calibration_file_contents *parsed_file,
|
||||
static inline int valid_channel( const comedi_calibration_t *parsed_file,
|
||||
unsigned int cal_index, unsigned int channel )
|
||||
{
|
||||
int num_channels, i;
|
||||
|
@ -65,7 +65,7 @@ static inline int valid_channel( struct calibration_file_contents *parsed_file,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int valid_range( struct calibration_file_contents *parsed_file,
|
||||
static inline int valid_range( const comedi_calibration_t *parsed_file,
|
||||
unsigned int cal_index, unsigned int range )
|
||||
{
|
||||
int num_ranges, i;
|
||||
|
@ -81,7 +81,7 @@ static inline int valid_range( struct calibration_file_contents *parsed_file,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int valid_aref( struct calibration_file_contents *parsed_file,
|
||||
static inline int valid_aref( const comedi_calibration_t *parsed_file,
|
||||
unsigned int cal_index, unsigned int aref )
|
||||
{
|
||||
int num_arefs, i;
|
||||
|
@ -97,7 +97,7 @@ static inline int valid_aref( struct calibration_file_contents *parsed_file,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int apply_calibration( comedi_t *dev, struct calibration_file_contents *parsed_file,
|
||||
static int apply_calibration( comedi_t *dev, const comedi_calibration_t *parsed_file,
|
||||
unsigned int subdev, unsigned int channel, unsigned int range, unsigned int aref )
|
||||
{
|
||||
int num_cals, i, retval;
|
||||
|
@ -125,7 +125,7 @@ static int apply_calibration( comedi_t *dev, struct calibration_file_contents *p
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int set_calibration( comedi_t *dev, struct calibration_file_contents *parsed_file,
|
||||
static int set_calibration( comedi_t *dev, const comedi_calibration_t *parsed_file,
|
||||
unsigned int cal_index )
|
||||
{
|
||||
int i, retval, num_caldacs;
|
||||
|
@ -135,7 +135,7 @@ static int set_calibration( comedi_t *dev, struct calibration_file_contents *par
|
|||
|
||||
for( i = 0; i < num_caldacs; i++ )
|
||||
{
|
||||
struct caldac_setting caldac;
|
||||
comedi_caldac_t caldac;
|
||||
|
||||
caldac = parsed_file->calibrations[ cal_index ].caldacs[ i ];
|
||||
COMEDILIB_DEBUG( 4, "subdev %i, ch %i, val %i\n", caldac.subdevice,
|
||||
|
@ -148,59 +148,74 @@ static int set_calibration( comedi_t *dev, struct calibration_file_contents *par
|
|||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(comedi_apply_calibration,0.7.20);
|
||||
int comedi_apply_parsed_calibration( comedi_t *dev, unsigned int subdev, unsigned int channel,
|
||||
unsigned int range, unsigned int aref, const comedi_calibration_t *calibration )
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = check_cal_file( dev, calibration );
|
||||
if( retval < 0 ) return retval;
|
||||
|
||||
retval = apply_calibration( dev, calibration, subdev, channel, range, aref );
|
||||
return retval;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(comedi_get_default_calibration_path,0.7.20);
|
||||
char* comedi_get_default_calibration_path( comedi_t *dev )
|
||||
{
|
||||
struct stat file_stats;
|
||||
char *file_path;
|
||||
char *board_name;
|
||||
|
||||
if( fstat( comedi_fileno( dev ), &file_stats ) < 0 )
|
||||
{
|
||||
COMEDILIB_DEBUG( 3, "failed to get file stats of comedi device file\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
board_name = comedi_get_board_name( dev );
|
||||
if( board_name == NULL )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
asprintf( &file_path, "/etc/comedi/calibrations/%s_comedi%li",
|
||||
board_name, ( unsigned long ) minor( file_stats.st_rdev ) );
|
||||
|
||||
return file_path;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(comedi_apply_calibration,0.7.20);
|
||||
int comedi_apply_calibration( comedi_t *dev, unsigned int subdev, unsigned int channel,
|
||||
unsigned int range, unsigned int aref, const char *cal_file_path )
|
||||
{
|
||||
struct stat file_stats;
|
||||
char file_path[ 1024 ];
|
||||
int retval;
|
||||
FILE *cal_file;
|
||||
struct calibration_file_contents *parsed_file;
|
||||
comedi_calibration_t *parsed_file;
|
||||
|
||||
if( cal_file_path )
|
||||
{
|
||||
strncpy( file_path, cal_file_path, sizeof( file_path ) );
|
||||
}else
|
||||
{
|
||||
if( fstat( comedi_fileno( dev ), &file_stats ) < 0 )
|
||||
{
|
||||
COMEDILIB_DEBUG( 3, "failed to get file stats of comedi device file\n" );
|
||||
return -1;
|
||||
}
|
||||
char *temp;
|
||||
|
||||
snprintf( file_path, sizeof( file_path ), "/etc/comedi/calibrations/%s_comedi%li",
|
||||
comedi_get_board_name( dev ),
|
||||
( unsigned long ) minor( file_stats.st_rdev ) );
|
||||
temp = comedi_get_default_calibration_path( dev );
|
||||
if( temp == NULL ) return -1;
|
||||
strncpy( file_path, temp, sizeof( file_path ) );
|
||||
free( temp );
|
||||
}
|
||||
|
||||
cal_file = fopen( file_path, "r" );
|
||||
if( cal_file == NULL )
|
||||
{
|
||||
COMEDILIB_DEBUG( 3, "failed to open file\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
parsed_file = parse_calibration_file( cal_file );
|
||||
parsed_file = comedi_parse_calibration_file( file_path );
|
||||
if( parsed_file == NULL )
|
||||
{
|
||||
COMEDILIB_DEBUG( 3, "failed to parse calibration file\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose( cal_file );
|
||||
retval = comedi_apply_parsed_calibration( dev, subdev, channel, range, aref, parsed_file );
|
||||
|
||||
retval = check_cal_file( dev, parsed_file );
|
||||
if( retval < 0 )
|
||||
{
|
||||
cleanup_calibration_parse( parsed_file );
|
||||
return retval;
|
||||
}
|
||||
comedi_cleanup_calibration( parsed_file );
|
||||
|
||||
retval = apply_calibration( dev, parsed_file, subdev, channel, range, aref );
|
||||
if( retval < 0 ) return retval;
|
||||
|
||||
cleanup_calibration_parse( parsed_file );
|
||||
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
|
||||
typedef struct
|
||||
{
|
||||
struct calibration_file_contents *parsed_file;
|
||||
struct caldac_setting caldac;
|
||||
comedi_calibration_t *parsed_file;
|
||||
comedi_caldac_t caldac;
|
||||
int cal_index;
|
||||
} calib_yyparse_private_t;
|
||||
|
||||
|
@ -67,7 +67,7 @@ static void free_calibration_setting( struct calibration_setting *setting )
|
|||
}
|
||||
}
|
||||
|
||||
static void free_calibrations( struct calibration_file_contents *file_contents )
|
||||
static void free_calibrations( comedi_calibration_t *file_contents )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -80,7 +80,7 @@ static void free_calibrations( struct calibration_file_contents *file_contents )
|
|||
file_contents->calibrations = NULL;
|
||||
}
|
||||
|
||||
static int add_calibration_setting( struct calibration_file_contents *file_contents )
|
||||
static int add_calibration_setting( comedi_calibration_t *file_contents )
|
||||
{
|
||||
struct calibration_setting *temp;
|
||||
|
||||
|
@ -152,25 +152,25 @@ static int add_aref( calib_yyparse_private_t *priv, int aref )
|
|||
}
|
||||
|
||||
static int add_caldac( calib_yyparse_private_t *priv,
|
||||
struct caldac_setting caldac )
|
||||
comedi_caldac_t caldac )
|
||||
{
|
||||
struct caldac_setting *temp;
|
||||
comedi_caldac_t *temp;
|
||||
struct calibration_setting *setting;
|
||||
|
||||
setting = current_setting( priv );
|
||||
if( setting == NULL ) return -1;
|
||||
|
||||
temp = realloc( setting->caldacs, ( setting->num_caldacs + 1 ) *
|
||||
sizeof( struct caldac_setting ) );
|
||||
sizeof( comedi_caldac_t ) );
|
||||
if( temp == NULL ) return -1;
|
||||
setting->caldacs = temp;
|
||||
setting->caldacs[ setting->num_caldacs++ ] = caldac;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct calibration_file_contents* alloc_calib_parse( void )
|
||||
static comedi_calibration_t* alloc_calib_parse( void )
|
||||
{
|
||||
struct calibration_file_contents *file_contents;
|
||||
comedi_calibration_t *file_contents;
|
||||
|
||||
file_contents = malloc( sizeof( *file_contents ) );
|
||||
if( file_contents == NULL ) return file_contents;
|
||||
|
@ -178,7 +178,8 @@ static struct calibration_file_contents* alloc_calib_parse( void )
|
|||
return file_contents;
|
||||
}
|
||||
|
||||
extern void cleanup_calibration_parse( struct calibration_file_contents *file_contents )
|
||||
EXPORT_SYMBOL(comedi_cleanup_calibration,0.7.20);
|
||||
extern void comedi_cleanup_calibration( comedi_calibration_t *file_contents )
|
||||
{
|
||||
if( file_contents->driver_name )
|
||||
{
|
||||
|
@ -195,19 +196,29 @@ extern void cleanup_calibration_parse( struct calibration_file_contents *file_co
|
|||
file_contents = NULL;
|
||||
}
|
||||
|
||||
extern struct calibration_file_contents* parse_calibration_file( FILE *file )
|
||||
EXPORT_SYMBOL(comedi_parse_calibration_file,0.7.20);
|
||||
extern comedi_calibration_t* comedi_parse_calibration_file( const char *cal_file_path )
|
||||
{
|
||||
calib_yyparse_private_t priv;
|
||||
FILE *file;
|
||||
|
||||
priv.parsed_file = alloc_calib_parse();
|
||||
if( priv.parsed_file == NULL ) return priv.parsed_file;
|
||||
if( priv.parsed_file == NULL ) return NULL;
|
||||
priv.cal_index = 0;
|
||||
|
||||
file = fopen( cal_file_path, "r" );
|
||||
if( file == NULL )
|
||||
{
|
||||
COMEDILIB_DEBUG( 3, "failed to open file\n" );
|
||||
return NULL;
|
||||
}
|
||||
calib_yyrestart( file );
|
||||
if( calib_yyparse( &priv ) )
|
||||
{
|
||||
cleanup_calibration_parse( priv.parsed_file );
|
||||
return NULL;
|
||||
comedi_cleanup_calibration( priv.parsed_file );
|
||||
priv.parsed_file = NULL;
|
||||
}
|
||||
fclose( file );
|
||||
return priv.parsed_file;
|
||||
}
|
||||
|
||||
|
|
|
@ -152,41 +152,10 @@ enum{
|
|||
/* used by range.c, was in comedilib.h but apparently deprecated so I put it here - fmhess */
|
||||
int comedi_get_rangetype(comedi_t *it,unsigned int subdevice,unsigned int chan);
|
||||
|
||||
/* structs and functions used for parsing calibration files */
|
||||
struct caldac_setting
|
||||
{
|
||||
unsigned int subdevice;
|
||||
unsigned int channel;
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
struct calibration_setting
|
||||
{
|
||||
unsigned int subdevice;
|
||||
unsigned int *channels;
|
||||
unsigned int num_channels;
|
||||
unsigned int *ranges;
|
||||
unsigned int num_ranges;
|
||||
unsigned int arefs[ 4 ];
|
||||
unsigned int num_arefs;
|
||||
struct caldac_setting *caldacs;
|
||||
unsigned int num_caldacs;
|
||||
};
|
||||
|
||||
struct calibration_file_contents
|
||||
{
|
||||
char *driver_name;
|
||||
char *board_name;
|
||||
struct calibration_setting *calibrations;
|
||||
unsigned int num_calibrations;
|
||||
};
|
||||
|
||||
#define YY_DECL int calib_yylex( YYSTYPE *calib_lvalp, YYLTYPE *calib_llocp )
|
||||
void calib_yyerror( char *s );
|
||||
int calib_yyparse( void *parse_arg );
|
||||
void calib_yyrestart( FILE *input );
|
||||
struct calibration_file_contents* parse_calibration_file( FILE *file );
|
||||
void cleanup_calibration_parse( struct calibration_file_contents *parsed_file );
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue