First pass at parsing additional calibration file elements which

support software calibration.
This commit is contained in:
Frank Mori Hess 2006-08-22 18:14:22 +00:00
parent c17577318d
commit d686d1278f
5 changed files with 132 additions and 24 deletions

View file

@ -205,6 +205,18 @@ typedef struct
unsigned int channel;
unsigned int value;
} comedi_caldac_t;
#define COMEDI_MAX_NUM_POLYNOMIAL_COEFFICIENTS (4)
typedef struct
{
double coefficients[COMEDI_MAX_NUM_POLYNOMIAL_COEFFICIENTS];
double expansion_origin;
unsigned order;
} comedi_polynomial_t;
typedef struct
{
comedi_polynomial_t *to_phys;
comedi_polynomial_t *from_phys;
} comedi_softcal_t;
#define CS_MAX_AREFS_LENGTH 4
typedef struct
{
@ -217,6 +229,7 @@ typedef struct
unsigned int num_arefs;
comedi_caldac_t *caldacs;
unsigned int num_caldacs;
comedi_softcal_t soft_calibration;
} comedi_calibration_setting_t;
typedef struct

View file

@ -7,7 +7,7 @@ CLEANFILES = grammar.output
EXTRA_DIST = calib_lex.l calib_yacc.y version_script
BUILT_SOURCES = calib_lex.c calib_yacc.c calib_yacc.h
BUILT_SOURCES = calib_lex.c calib_lex.h calib_yacc.c calib_yacc.h
libcomedi_la_SOURCES = \
buffer.c calib.c cmd.c comedi.c data.c dio.c error.c \
@ -22,9 +22,9 @@ libcomedi_la_LDFLAGS = -soname libcomedi \
-Wl,--version-script=$(srcdir)/version_script
$(srcdir)/calib_yacc.c + $(srcdir)/calib_yacc.h: $(srcdir)/calib_yacc.y
$(srcdir)/calib_yacc.c $(srcdir)/calib_yacc.h: $(srcdir)/calib_yacc.y
$(YACC) -d -p calib_yy -o $(srcdir)/calib_yacc.c $<
$(srcdir)/calib_lex.c: $(srcdir)/calib_lex.l
$(LEX) -Pcalib_yy -o$@ $<
$(srcdir)/calib_lex.c $(srcdir)/calib_lex.h: $(srcdir)/calib_lex.l
$(LEX) --header-file=$(srcdir)/calib_lex.h -Pcalib_yy -o$(srcdir)/calib_lex.c $<

View file

@ -1,5 +1,7 @@
%option noyywrap
%option nounput
%option yylineno
%option reentrant
%{
@ -7,7 +9,7 @@
lib/calib_lex.l
code for parsing calibration file, generated by flex
Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net
Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -36,21 +38,17 @@
%%
%{
calib_llocp->first_line = 1;
%}
<STRING,INITIAL>\n { calib_llocp->first_line++; }
<STRING,INITIAL>\n
"#" { BEGIN(COMMENT); }
<COMMENT>\n { calib_llocp->first_line++; BEGIN(INITIAL); }
<COMMENT>\n {BEGIN(INITIAL); }
<COMMENT>.
\" { BEGIN(STRING); }
<STRING>[^\"]*\" {
if( strlen( calib_yytext ) > 0 )
calib_yytext[ strlen( calib_yytext ) - 1 ] = 0;
calib_lvalp->sval = calib_yytext;
if(strlen(calib_yyget_text(yyscanner)) > 0)
calib_yyget_text(yyscanner)[strlen(calib_yyget_text(yyscanner)) - 1] = 0;
calib_lvalp->sval = calib_yyget_text(yyscanner);
BEGIN(INITIAL);
return ( T_STRING );
}
@ -65,14 +63,24 @@ arefs { return ( T_AREFS ); }
caldacs { return ( T_CALDACS ); }
channel { return ( T_CHANNEL ); }
value { return ( T_VALUE ); }
coefficients {return (T_COEFFICIENTS);}
expansion_origin {return (T_EXPANSION_ORIGIN);}
softcal_to_phys {return T_SOFTCAL_TO_PHYS;}
softcal_from_phys {return T_SOFTCAL_FROM_PHYS;}
=> { return ( T_ASSIGN ); };
(0[xX])?(00)?[0-9a-fA-F]+ { calib_lvalp->ival = strtol( calib_yytext, NULL, 0 );
(0[xX])?(00)?[0-9a-fA-F]+ {calib_lvalp->ival = strtol(calib_yyget_text(yyscanner), NULL, 0);
return( T_NUMBER ); }
[0-9]+\.*[0-9]* { calib_lvalp->dval = strtod(calib_yyget_text(yyscanner), 0);
return( T_FLOAT ); }
[0-9]*\.*[0-9]+ { calib_lvalp->dval = strtod(calib_yyget_text(yyscanner), 0);
return( T_FLOAT ); }
[ \t]
. { return( calib_yytext[0] ); }
. {return(calib_yyget_text(yyscanner)[0]);}
%%

View file

@ -26,15 +26,27 @@
#include <string.h>
#include <stdlib.h>
#include "calib_yacc.h"
#include "calib_lex.h"
#define YYERROR_VERBOSE
#define YYPARSE_PARAM parse_arg
#define YYLEX_PARAM priv(YYPARSE_PARAM)->yyscanner
enum polynomial_direction
{
POLYNOMIAL_TO_PHYS,
POLYNOMIAL_FROM_PHYS
};
typedef struct
{
yyscan_t yyscanner;
comedi_calibration_t *parsed_file;
comedi_caldac_t caldac;
int cal_index;
enum polynomial_direction polynomial_direction;
unsigned num_coefficients;
comedi_polynomial_t polynomial;
} calib_yyparse_private_t;
YY_DECL;
@ -65,6 +77,16 @@ static void free_calibration_setting( comedi_calibration_setting_t *setting )
setting->caldacs = NULL;
setting->num_caldacs = 0;
}
if(setting->soft_calibration.to_phys)
{
free(setting->soft_calibration.to_phys);
setting->soft_calibration.to_phys = NULL;
}
if(setting->soft_calibration.from_phys)
{
free(setting->soft_calibration.from_phys);
setting->soft_calibration.from_phys = NULL;
}
}
static void free_settings( comedi_calibration_t *file_contents )
@ -168,6 +190,27 @@ static int add_caldac( calib_yyparse_private_t *priv,
return 0;
}
static int add_polynomial(calib_yyparse_private_t *priv)
{
comedi_calibration_setting_t *setting;
setting = current_setting( priv );
if( setting == NULL ) return -1;
if(priv->num_coefficients < 1) return -1;
if(priv->polynomial_direction == POLYNOMIAL_TO_PHYS)
{
if(setting->soft_calibration.to_phys) return -1;
setting->soft_calibration.to_phys = malloc(sizeof(comedi_polynomial_t));
*setting->soft_calibration.to_phys = priv->polynomial;
}else
{
if(setting->soft_calibration.from_phys) return -1;
setting->soft_calibration.from_phys = malloc(sizeof(comedi_polynomial_t));
*setting->soft_calibration.from_phys = priv->polynomial;
}
return 0;
}
static comedi_calibration_t* alloc_calib_parse( void )
{
comedi_calibration_t *file_contents;
@ -193,7 +236,6 @@ extern void _comedi_cleanup_calibration( comedi_calibration_t *file_contents )
}
free_settings( file_contents );
free( file_contents );
file_contents = NULL;
}
EXPORT_ALIAS_DEFAULT(_comedi_parse_calibration_file,comedi_parse_calibration_file,0.7.20);
@ -203,7 +245,7 @@ extern comedi_calibration_t* _comedi_parse_calibration_file( const char *cal_fil
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;
@ -214,12 +256,14 @@ extern comedi_calibration_t* _comedi_parse_calibration_file( const char *cal_fil
COMEDILIB_DEBUG( 3, "failed to open file\n" );
return NULL;
}
calib_yyrestart( file );
calib_yylex_init(&priv.yyscanner);
calib_yyrestart(file, priv.yyscanner);
if( calib_yyparse( &priv ) )
{
comedi_cleanup_calibration( priv.parsed_file );
priv.parsed_file = NULL;
}
calib_yylex_destroy(priv.yyscanner);
fclose( file );
return priv.parsed_file;
}
@ -231,15 +275,18 @@ extern comedi_calibration_t* _comedi_parse_calibration_file( const char *cal_fil
%union
{
int ival;
double dval;
char *sval;
}
%token T_DRIVER_NAME T_BOARD_NAME T_CALIBRATIONS T_SUBDEVICE T_CHANNELS
%token T_RANGES T_AREFS T_CALDACS T_CHANNEL T_VALUE T_NUMBER T_STRING
%token T_ASSIGN
%token T_COEFFICIENTS T_EXPANSION_ORIGIN T_SOFTCAL_TO_PHYS T_SOFTCAL_FROM_PHYS
%token T_ASSIGN T_FLOAT
%type <ival> T_NUMBER
%type <sval> T_STRING
%type <dval> T_FLOAT
%%
@ -290,6 +337,14 @@ extern comedi_calibration_t* _comedi_parse_calibration_file( const char *cal_fil
| T_RANGES T_ASSIGN '[' ranges_array ']'
| T_AREFS T_ASSIGN '[' arefs_array ']'
| T_CALDACS T_ASSIGN '[' caldacs_array ']'
| T_SOFTCAL_TO_PHYS T_ASSIGN '{' polynomial '}'
{
priv(parse_arg)->polynomial_direction = POLYNOMIAL_TO_PHYS;
}
| T_SOFTCAL_FROM_PHYS T_ASSIGN '{' polynomial '}'
{
priv(parse_arg)->polynomial_direction = POLYNOMIAL_FROM_PHYS;
}
;
channels_array: /* empty */
@ -331,6 +386,39 @@ extern comedi_calibration_t* _comedi_parse_calibration_file( const char *cal_fil
| T_VALUE T_ASSIGN T_NUMBER { priv(parse_arg)->caldac.value = $3; }
;
polynomial: /* empty */ { add_polynomial(parse_arg);}
| polynomial_element { add_polynomial(parse_arg);}
| polynomial_element ',' polynomial
;
polynomial_element: T_COEFFICIENTS T_ASSIGN '[' coefficient_array ']' {priv(parse_arg)->num_coefficients = 0;}
| T_EXPANSION_ORIGIN T_ASSIGN expansion_origin
;
coefficient_array: /* empty */
| coefficient
| coefficient ',' coefficient_array
;
coefficient: T_FLOAT
{
if(priv(parse_arg)->num_coefficients >= COMEDI_MAX_NUM_POLYNOMIAL_COEFFICIENTS)
{
fprintf(stderr, "too many coefficients for polynomial on line %i ,\n", @1.first_line );
fprintf(stderr, "max is %i .\n", COMEDI_MAX_NUM_POLYNOMIAL_COEFFICIENTS);
YYABORT;
}
priv(parse_arg)->polynomial.order = priv(parse_arg)->num_coefficients;
priv(parse_arg)->polynomial.coefficients[priv(parse_arg)->num_coefficients++] = $1;
}
;
expansion_origin: T_FLOAT
{
priv(parse_arg)->polynomial.expansion_origin = $1;
}
;
%%
void calib_yyerror(char *s)

View file

@ -152,10 +152,9 @@ 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);
#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 );
#define YY_DECL int calib_yylex(YYSTYPE *calib_lvalp, YYLTYPE *calib_llocp, yyscan_t yyscanner)
void calib_yyerror(char *s);
int calib_yyparse(void *parse_arg);
#endif