First pass at parsing additional calibration file elements which
support software calibration.
This commit is contained in:
parent
c17577318d
commit
d686d1278f
5 changed files with 132 additions and 24 deletions
|
@ -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
|
||||
|
|
|
@ -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 $<
|
||||
|
||||
|
|
|
@ -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]);}
|
||||
|
||||
|
||||
%%
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue