Module: xenomai-3 Branch: next Commit: 40003000e9692d89e4ec3ce930eebeb62d442935 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=40003000e9692d89e4ec3ce930eebeb62d442935
Author: Jorge Ramirez-Ortiz <j...@xenomai.org> Date: Sat Oct 11 14:25:26 2014 -0400 utils/analogy: calibration - use analogy lib to read/write the calibration file --- include/rtdm/analogy.h | 11 + include/rtdm/uapi/analogy.h | 28 +++ lib/analogy/Makefile.am | 11 +- lib/analogy/calibration.c | 211 +++++++++++++++++++ lib/analogy/calibration.h | 44 ++++ utils/analogy/Makefile.am | 5 +- utils/analogy/analogy_calibrate.c | 73 +------ utils/analogy/analogy_calibrate.h | 131 +----------- utils/analogy/calibration_ni_m.c | 422 ++++++++++++------------------------- utils/analogy/calibration_ni_m.h | 36 +--- 10 files changed, 456 insertions(+), 516 deletions(-) diff --git a/include/rtdm/analogy.h b/include/rtdm/analogy.h index 57f2ec0..fd26f58 100644 --- a/include/rtdm/analogy.h +++ b/include/rtdm/analogy.h @@ -21,9 +21,12 @@ #ifndef _RTDM_ANALOGY_H #define _RTDM_ANALOGY_H +#include <stdio.h> #include <sys/types.h> #include <rtdm/uapi/analogy.h> +#include "boilerplate/list.h" + /*! @addtogroup analogy_lib_descriptor @{ @@ -227,6 +230,14 @@ int a4l_ftoraw(a4l_chinfo_t *chan, int a4l_dtoraw(a4l_chinfo_t *chan, a4l_rnginfo_t *rng, void *dst, double *src, int cnt); +void a4l_write_calibration_file(FILE *dst, struct list *l, + struct a4l_calibration_subdev *subd, + a4l_desc_t *desc); + +int a4l_read_calibration_file(char *name, struct a4l_calibration_data *data); + + + #endif /* !DOXYGEN_CPP */ #ifdef __cplusplus diff --git a/include/rtdm/uapi/analogy.h b/include/rtdm/uapi/analogy.h index 9806c82..669ded7 100644 --- a/include/rtdm/uapi/analogy.h +++ b/include/rtdm/uapi/analogy.h @@ -706,4 +706,32 @@ typedef struct a4l_instruction_list a4l_insnlst_t; /*! @} analogy_lib_sync1 */ +struct a4l_calibration_subdev { + a4l_sbinfo_t *info; + int slen; + int idx; + char *name; +}; + +struct a4l_calibration_subdev_data { + int index; + int channel; + int range; + int expansion; + int nb_coeff; + double *coeff; + +}; + +struct a4l_calibration_data { + char *driver_name; + char *board_name; + int nb_ai; + struct a4l_calibration_subdev_data *ai; + int nb_ao; + struct a4l_calibration_subdev_data *ao; +}; + + + #endif /* _RTDM_UAPI_ANALOGY_H */ diff --git a/lib/analogy/Makefile.am b/lib/analogy/Makefile.am index 4d242ff..500453d 100644 --- a/lib/analogy/Makefile.am +++ b/lib/analogy/Makefile.am @@ -7,11 +7,16 @@ libanalogy_la_SOURCES = \ descriptor.c \ info.c \ internal.h \ + calibration.c \ range.c \ root_leaf.h \ sync.c \ sys.c -libanalogy_la_CPPFLAGS = \ - @XENO_USER_CFLAGS@ \ - -I$(top_srcdir)/include +libanalogy_la_CPPFLAGS = \ + @XENO_USER_CFLAGS@ \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/lib/boilerplate + +libanalogy_la_LIBADD = \ + ../boilerplate/libboilerplate.la diff --git a/lib/analogy/calibration.c b/lib/analogy/calibration.c new file mode 100644 index 0000000..74b2789 --- /dev/null +++ b/lib/analogy/calibration.c @@ -0,0 +1,211 @@ +#include <rtdm/analogy.h> +#include <stdio.h> +#include <errno.h> +#include <wordexp.h> +#include "iniparser/iniparser.h" +#include "boilerplate/list.h" +#include "calibration.h" + +#define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0])) + +static inline int read_dbl(double *d, struct _dictionary_ *f,const char *subd, + int subd_idx, char *type, int type_idx) +{ + char *str; + int ret; + + /* if only contains doubles as coefficients */ + if (strncmp(type, COEFF_STR, strlen(COEFF_STR) != 0)) + return -ENOENT; + + ret = asprintf(&str, COEFF_FMT, subd, subd_idx, type, type_idx); + if (ret < 0) + return ret; + + *d = iniparser_getdouble(f, str, -255.0); + if (*d == -255.0) + ret = -ENOENT; + free(str); + + return ret; +} + +static inline int read_int(int *val, struct _dictionary_ *f, const char *subd, + int subd_idx, char *type) +{ + char *str; + int ret; + + ret = (subd_idx >= 0) ? + asprintf(&str, ELEMENT_FIELD_FMT, subd, subd_idx, type): + asprintf(&str, ELEMENT_FMT, subd, type); + if (ret < 0) + return ret; + + *val = iniparser_getint(f, str, 0xFFFF); + if (*val == 0xFFFF) + ret = -ENOENT; + free(str); + + return ret; +} + +static inline int read_str(char **val, struct _dictionary_ *f, const char *subd, + const char *type) +{ + char *str; + int ret; + + ret = asprintf(&str, ELEMENT_FMT, subd, type); + if (ret < 0) + return ret; + + *val = (char *) iniparser_getstring(f, str, NULL); + if (*val == NULL) + ret = -ENOENT; + free(str); + + return ret; +} + +static inline void write_calibration(FILE *file, char *fmt, ...) +{ + va_list ap; + + if (!file) + return; + + va_start(ap, fmt); + vfprintf(file, fmt, ap); + fflush(file); + va_end(ap); +} + +int a4l_read_calibration_file(char *name, struct a4l_calibration_data *data) +{ + const char *subdevice[2] = { AI_SUBD_STR, AO_SUBD_STR }; + struct a4l_calibration_subdev_data *p = NULL; + int i, j, k, index = -1, nb_elements = -1; + struct _dictionary_ *d; + const char *filename; + wordexp_t exp; + int ret = 0; + + ret = wordexp(name, &exp, WRDE_NOCMD|WRDE_UNDEF); + if (ret) { + /* can't apply calibration */ + ret = ret == WRDE_NOSPACE ? -ENOMEM : -EINVAL; + return ret; + } + + if (exp.we_wordc != 1) { + /* "weird expansion of %s as rc file \n", params.name */ + return -1; + } + + filename = exp.we_wordv[0]; + if (access(filename, R_OK)) { + /* "cant access %s for reading \n", params.name */ + return -1; + } + + d = iniparser_load(filename); + if (d == NULL) { + /* "loading error for %s (%d)\n", params.name, errno */ + return -1; + } + + read_str(&data->driver_name, d, PLATFORM_STR, DRIVER_STR); + read_str(&data->board_name, d, PLATFORM_STR, BOARD_STR); + + for (k = 0; k < ARRAY_LEN(subdevice); k++) { + read_int(&nb_elements, d, subdevice[k], -1, ELEMENTS_STR); + read_int(&index, d, subdevice[k], -1, INDEX_STR); + + if (strncmp(subdevice[k], AI_SUBD_STR, + strlen(AI_SUBD_STR)) == 0) { + data->ai = malloc(nb_elements * + sizeof(struct a4l_calibration_subdev_data)); + data->nb_ai = nb_elements; + p = data->ai; + } + + if (strncmp(subdevice[k], AO_SUBD_STR, + strlen(AO_SUBD_STR)) == 0) { + data->ao = malloc(nb_elements * + sizeof(struct a4l_calibration_subdev_data)); + data->nb_ao = nb_elements; + p = data->ao; + } + + for (i = 0; i < nb_elements; i++) { + read_int(&p->expansion, d, subdevice[k], i, + EXPANSION_STR); + read_int(&p->nb_coeff, d, subdevice[k], i, + NBCOEFF_STR); + read_int(&p->channel, d, subdevice[k], i, + CHANNEL_STR); + read_int(&p->range, d, subdevice[k], i, + RANGE_STR); + + p->coeff = malloc(p->nb_coeff * sizeof(double)); + + for (j = 0; j < p->nb_coeff; j++) { + read_dbl(&p->coeff[j], d, subdevice[k], i, + COEFF_STR, j); + } + + p->index = index; + p++; + } + } + wordfree(&exp); + + return 0; +} + +void a4l_write_calibration_file(FILE *dst, struct list *l, + struct a4l_calibration_subdev *subd, + a4l_desc_t *desc) +{ + struct subdevice_calibration_node *e, *t; + int i, j = 0; + + if (list_empty(l)) + return; + + /* TODO: modify the meaning of board/driver in the proc */ + if (desc) { + write_calibration(dst, "[%s] \n",PLATFORM_STR); + write_calibration(dst, DRIVER_STR" = %s;\n", desc->board_name); + write_calibration(dst, BOARD_STR" = %s;\n", desc->driver_name); + } + + write_calibration(dst, "\n[%s] \n", subd->name); + write_calibration(dst, INDEX_STR" = %d;\n", subd->idx); + list_for_each_entry_safe(e, t, l, node) { + j++; + } + write_calibration(dst, ELEMENTS_STR" = %d;\n", j); + + j = 0; + list_for_each_entry_safe(e, t, l, node) { + write_calibration(dst, "[%s_%d] \n", subd->name, j); + write_calibration(dst, CHANNEL_STR" = %d;\n", e->channel); + write_calibration(dst, RANGE_STR" = %d;\n", e->range); + write_calibration(dst, EXPANSION_STR" = %g;\n", + e->polynomial->expansion_origin); + write_calibration(dst, NBCOEFF_STR"= %d;\n", + e->polynomial->nb_coefficients); + + for (i = 0; i < e->polynomial->nb_coefficients; i++) + write_calibration(dst, COEFF_STR"_%d = %g;\n", + i, + e->polynomial->coefficients[i]); + j++; + } + + return; +} + + diff --git a/lib/analogy/calibration.h b/lib/analogy/calibration.h new file mode 100644 index 0000000..04a7e72 --- /dev/null +++ b/lib/analogy/calibration.h @@ -0,0 +1,44 @@ +#ifndef __ANALOGY_CALIBRATION_H__ +#define __ANALOGY_CALIBRATION_H__ + +/* + * internal definitions between the xenomai utils and the library. + * no need to expose them to the USER + * + */ +#define ELEMENT_FIELD_FMT "%s_%d:%s" +#define ELEMENT_FMT "%s:%s" +#define COEFF_FMT ELEMENT_FIELD_FMT"_%d" + +#define PLATFORM_STR "platform" +#define CALIBRATION_SUBD_STR "calibration" +#define MEMORY_SUBD_STR "memory" +#define AI_SUBD_STR "analog_input" +#define AO_SUBD_STR "analog_output" + +#define INDEX_STR "index" +#define ELEMENTS_STR "elements" +#define CHANNEL_STR "channel" +#define RANGE_STR "range" +#define EXPANSION_STR "expansion_origin" +#define NBCOEFF_STR "nbcoeff" +#define COEFF_STR "coeff" +#define BOARD_STR "board_name" +#define DRIVER_STR "driver_name" + +struct polynomial { + double expansion_origin; + double *coefficients; + int nb_coefficients; + int order; +}; + +struct subdevice_calibration_node { + struct holder node; + struct polynomial *polynomial; + unsigned channel; + unsigned range; +}; + + +#endif diff --git a/utils/analogy/Makefile.am b/utils/analogy/Makefile.am index 40c09f3..a555260 100644 --- a/utils/analogy/Makefile.am +++ b/utils/analogy/Makefile.am @@ -13,8 +13,7 @@ CPPFLAGS = \ @XENO_USER_CFLAGS@ \ -ggdb \ -I$(top_srcdir)/include \ - -I$(top_srcdir)/lib/boilerplate - + -I$(top_srcdir)/lib/analogy LDFLAGS = @@ -29,7 +28,7 @@ analogy_config_LDADD = \ ../../lib/analogy/libanalogy.la \ ../../lib/cobalt/libcobalt.la \ @XENO_USER_LDADD@ \ - -lpthread -lrt + -lrt -lpthread analogy_calibrate_SOURCES = analogy_calibrate.c calibration_ni_m.c analogy_calibrate.c: git-stamp.h calibration_ni_m.h diff --git a/utils/analogy/analogy_calibrate.c b/utils/analogy/analogy_calibrate.c index 8404811..5963cc4 100644 --- a/utils/analogy/analogy_calibrate.c +++ b/utils/analogy/analogy_calibrate.c @@ -31,11 +31,9 @@ #include "analogy_calibrate.h" #include "calibration_ni_m.h" -struct apply_calibration_params params = {.name = NULL,} ; struct timespec calibration_start_time; static const char *revision = "0.0.1"; a4l_desc_t descriptor; -FILE *cal = NULL; static const struct option options[] = { { @@ -57,12 +55,6 @@ static const struct option options[] = { .flag = NULL, }, { -#define apply_opt 3 - .name = "apply", - .has_arg = 1, - .flag = NULL, - }, - { .name = NULL, } }; @@ -71,51 +63,22 @@ static void print_usage(void) { fprintf(stderr, "Usage: analogy_calibrate \n" - " --help : this menu \n" - " --device /dev/analogyX : analogy device to calibrate \n" - " --output filename : calibration results \n" - " --apply filename:subd,channel,range,aref : apply the calibration file \n" - " ex: /home/foo/calib.rc:0,1,255,255 - use 255 for dont care \n" + " --help : this menu \n" + " --device /dev/analogyX : analogy device to calibrate \n" + " --output filename : calibration results \n" ); } -static int -apply_calibration_set_globals(char *info) -{ - char *p; - - params.name = strtok(info, ":"); - p = strtok(NULL, ","); - if (!p) - error(EXIT, 0, "missing --apply parameter subd \n"); - params.subd = strtol(p, NULL, 0); - - p = strtok(NULL, ","); - if (!p) - error(EXIT, 0, "missing --apply parameter channel \n"); - params.channel = strtol(p, NULL, 0); - - p = strtok(NULL, ","); - if (!p) - error(EXIT, 0, "missing --apply parameter range \n"); - params.range = strtol(p, NULL, 0); - - p = strtok(NULL, ""); - if (!p) - error(EXIT, 0, "missing --apply parameter aref \n"); - params.aref = strtol(p, NULL, 0); - - return 0; -} - static void __attribute__ ((constructor)) __analogy_calibrate_init(void) { clock_gettime(CLOCK_MONOTONIC, &calibration_start_time); } + int main(int argc, char *argv[]) { - char *device = NULL, *file = NULL, *apply_info = NULL; + char *device = NULL, *file = NULL; int v, i, fd, err = 0; + FILE *p = NULL; __debug("version: git commit %s, revision %s \n", GIT_STAMP, revision); @@ -133,22 +96,17 @@ int main(int argc, char *argv[]) break; case output_opt: file = optarg; - cal = fopen(file, "w+"); - if (!cal) - error(EXIT, errno, "calibration file"); + p = fopen(file, "w+"); __debug("calibration output: %s \n", file); break; - case apply_opt: - apply_info = optarg; - break; default: print_usage(); exit(EXIT_FAILURE); } } - if (apply_info) - apply_calibration_set_globals(apply_info); + if (!p) + error(EXIT, errno, "calibration file not present"); fd = a4l_open(&descriptor, device); if (fd < 0) @@ -159,21 +117,10 @@ int main(int argc, char *argv[]) error(EXIT, 0, "board %s: driver %s not supported", descriptor.board_name, descriptor.driver_name); - /* - * TODO: modify the meaning of board/driver in the proc - */ - push_to_cal_file("[%s] \n",PLATFORM_STR); - push_to_cal_file(DRIVER_STR" = %s;\n", descriptor.board_name); - push_to_cal_file(BOARD_STR" = %s;\n", descriptor.driver_name); - - err = ni_m_software_calibrate(); + err = ni_m_software_calibrate(p); if (err) error(CONT, 0, "software calibration failed (%d)", err); - err = ni_m_apply_calibration(); - if (err) - error(CONT, 0, "applying calibration failed (%d)", err); - a4l_close(&descriptor); return err; diff --git a/utils/analogy/analogy_calibrate.h b/utils/analogy/analogy_calibrate.h index 4a30997..09812ae 100644 --- a/utils/analogy/analogy_calibrate.h +++ b/utils/analogy/analogy_calibrate.h @@ -31,7 +31,7 @@ #include <unistd.h> #include <stdlib.h> -#include "iniparser/iniparser.h" + #include "git-stamp.h" #include "error.h" @@ -39,16 +39,6 @@ extern struct timespec calibration_start_time; extern a4l_desc_t descriptor; extern FILE *cal; -struct apply_calibration_params { - int channel; - char *name; - int range; - int subd; - int aref; -}; - -extern struct apply_calibration_params params; - #define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0])) #define RETURN 1 @@ -124,18 +114,6 @@ static inline void __debug(char *fmt, ...) va_end(ap); } -static inline void __push_to_file(FILE *file, char *fmt, ...) -{ - va_list ap; - - if (!file) - return; - - va_start(ap, fmt); - vfprintf(file, fmt, ap); - fflush(file); - va_end(ap); -} static inline int __array_search(char *elem, const char *array[], int len) { @@ -148,11 +126,6 @@ static inline int __array_search(char *elem, const char *array[], int len) return -1; } -#define push_to_cal_file(fmt, ...) \ - do { \ - if (cal) \ - __push_to_file(cal, fmt, ##__VA_ARGS__); \ - } while(0) static inline double rng_max(a4l_rnginfo_t *range) { @@ -174,108 +147,6 @@ static inline double rng_min(a4l_rnginfo_t *range) return a; } -struct subd_data { - int index; - int channel; - int range; - int expansion; - int nb_coeff; - double *coeff; -}; - -struct calibration_data { - char *driver_name; - char *board_name; - int nb_ai; - struct subd_data *ai; - int nb_ao; - struct subd_data *ao; -}; - -#define ELEMENT_FIELD_FMT "%s_%d:%s" -#define ELEMENT_FMT "%s:%s" -#define COEFF_FMT ELEMENT_FIELD_FMT"_%d" - -#define PLATFORM_STR "platform" -#define CALIBRATION_SUBD_STR "calibration" -#define MEMORY_SUBD_STR "memory" -#define AI_SUBD_STR "analog_input" -#define AO_SUBD_STR "analog_output" - -#define INDEX_STR "index" -#define ELEMENTS_STR "elements" -#define CHANNEL_STR "channel" -#define RANGE_STR "range" -#define EXPANSION_STR "expansion_origin" -#define NBCOEFF_STR "nbcoeff" -#define COEFF_STR "coeff" -#define BOARD_STR "board_name" -#define DRIVER_STR "driver_name" - -static inline int -read_calfile_str(char ** val, struct _dictionary_ *f, const char *subd, char *type) -{ - char *not_found = NULL; - char *str; - int err; - - err = asprintf(&str, ELEMENT_FMT, subd, type); - if (err < 0) - error(EXIT, 0, "asprintf \n"); - *val = (char *) iniparser_getstring(f, str, not_found); - __debug("%s = %s \n", str, *val); - free(str); - if (*val == not_found) - error(EXIT, 0, "calibration file: str element not found \n"); - - return 0; -} - - -static inline int -read_calfile_integer(int *val, struct _dictionary_ *f, - const char *subd, int subd_idx, char *type) -{ - int not_found = 0xFFFF; - char *str; - int err; - - if (subd_idx < 0) - err = asprintf(&str, ELEMENT_FMT, subd, type); - else - err = asprintf(&str, ELEMENT_FIELD_FMT, subd, subd_idx, type); - if (err < 0) - error(EXIT, 0, "asprintf \n"); - *val = iniparser_getint(f, str, not_found); - __debug("%s = %d \n", str, *val); - free(str); - if (*val == not_found) - error(EXIT, 0, "calibration file: int element not found \n"); - - return 0; -} - -static inline int -read_calfile_double(double *d, struct _dictionary_ *f, - const char *subd, int subd_idx, char *type, int type_idx) -{ - const double not_found = -255.0; - char *str; - int err; - - if (strncmp(type, COEFF_STR, strlen(COEFF_STR) != 0)) - error(EXIT, 0, "only contains doubles as coefficients \n"); - err = asprintf(&str, COEFF_FMT, subd, subd_idx, type, type_idx); - if (err < 0) - error(EXIT, 0, "asprintf \n"); - *d = iniparser_getdouble(f, str, not_found); - __debug("%s = %g \n", str, *d); - free(str); - if (*d == not_found) - error(EXIT, 0, "calbration file: double element not found \n"); - - return 0; -} diff --git a/utils/analogy/calibration_ni_m.c b/utils/analogy/calibration_ni_m.c index 358c395..2115b6d 100644 --- a/utils/analogy/calibration_ni_m.c +++ b/utils/analogy/calibration_ni_m.c @@ -25,159 +25,29 @@ #include <gsl/gsl_multifit.h> #include <gsl/gsl_matrix.h> #include <gsl/gsl_vector.h> +#include <rtdm/uapi/analogy.h> #include <rtdm/analogy.h> #include <wordexp.h> #include <math.h> #include "calibration_ni_m.h" - -extern char *apply_name; - +#include "calibration.h" struct list ai_calibration_list; struct list ao_calibration_list; static struct references references; -static struct subdevice mem_subd; -static struct subdevice cal_subd; -static struct subdevice ao_subd; -static struct subdevice ai_subd; +static struct a4l_calibration_subdev mem_subd; +static struct a4l_calibration_subdev cal_subd; +static struct a4l_calibration_subdev ao_subd; +static struct a4l_calibration_subdev ai_subd; static struct subdev_ops ops; static struct eeprom eeprom; static struct gnumath math; -static int -parse_calibration_file(char *name, struct calibration_data *data) -{ - const char *subdevice[2] = { AI_SUBD_STR, AO_SUBD_STR }; - int i, j, k, index, nb_elements; - struct subd_data *p = NULL; - struct _dictionary_ *d; - const char *filename; - wordexp_t exp; - int ret = 0; - - ret = wordexp(name, &exp, WRDE_NOCMD|WRDE_UNDEF); - if (ret) { - ret = ret == WRDE_NOSPACE ? -ENOMEM : -EINVAL; - error(EXIT, 0, "cant apply calibration (%d) \n", ret); - } - - if (exp.we_wordc != 1) - error(EXIT, 0, "weird expansion of %s as rc file \n", params.name); - - filename = exp.we_wordv[0]; - if (access(filename, R_OK)) - error(EXIT, 0, "cant access %s for reading \n", params.name); - - __debug("using calibration file: %s \n", params.name); - - d = iniparser_load(filename); - if (d == NULL) - error(EXIT, 0, "iniparser loading error for %s (%d)\n", params.name, errno); - - read_calfile_str(&data->driver_name, d, PLATFORM_STR, DRIVER_STR); - read_calfile_str(&data->board_name, d, PLATFORM_STR, BOARD_STR); - for (k = 0; k < ARRAY_LEN(subdevice); k++) { - read_calfile_integer(&nb_elements, d, subdevice[k], -1, - ELEMENTS_STR); - read_calfile_integer(&index, d, subdevice[k], -1, - INDEX_STR); - - if (strncmp(subdevice[k], AI_SUBD_STR, strlen(AI_SUBD_STR)) == 0) { - data->ai = malloc(nb_elements * sizeof(struct subd_data)); - data->nb_ai = nb_elements; - p = data->ai; - } - if (strncmp(subdevice[k], AO_SUBD_STR, strlen(AO_SUBD_STR)) == 0) { - data->ao = malloc(nb_elements * sizeof(struct subd_data)); - data->nb_ao = nb_elements; - p = data->ao; - } - for (i = 0; i < nb_elements; i++) { - read_calfile_integer(&p->expansion, d, subdevice[k], i, - EXPANSION_STR); - read_calfile_integer(&p->nb_coeff, d, subdevice[k], i, - NBCOEFF_STR); - read_calfile_integer(&p->channel, d, subdevice[k], i, - CHANNEL_STR); - read_calfile_integer(&p->range, d, subdevice[k], i, - RANGE_STR); - p->coeff = malloc(p->nb_coeff * sizeof(double)); - for (j = 0; j < p->nb_coeff; j++) { - read_calfile_double(&p->coeff[j], d, subdevice[k], - i, COEFF_STR, j); - } - p->index = index; - p++; - } - } - wordfree(&exp); - - return 0; -} - - -int -ni_m_apply_calibration(void) -{ - struct calibration_data cal_data; - - if (params.name == NULL) - return 0; - - parse_calibration_file(params.name, &cal_data); - /* - * TODO: apply the calibration file. - */ - - return 0; -} - -/* - * generate the calibration file - */ -static void -write_calibration(struct list *calibration_list, struct subdevice *subd) -{ - struct subdevice_calibration_node *e, *t; - int i, j = 0; - - if (list_empty(calibration_list)) - return; - - push_to_cal_file("\n[%s] \n", subd->name); - push_to_cal_file(INDEX_STR" = %d;\n", subd->idx); - list_for_each_entry_safe(e, t, calibration_list, node) { - j++; - } - push_to_cal_file(ELEMENTS_STR" = %d;\n", j); - - j = 0; - list_for_each_entry_safe(e, t, calibration_list, node) { - push_to_cal_file("[%s_%d] \n", subd->name, j); - push_to_cal_file(CHANNEL_STR" = %d;\n", e->channel); - push_to_cal_file(RANGE_STR" = %d;\n", e->range); - push_to_cal_file(EXPANSION_STR" = %g;\n", - e->polynomial->expansion_origin); - push_to_cal_file(NBCOEFF_STR"= %d;\n", - e->polynomial->nb_coefficients); - - for (i = 0; i < e->polynomial->nb_coefficients; i++) - push_to_cal_file(COEFF_STR"_%d = %g;\n", - i, - e->polynomial->coefficients[i]); - j++; - } - - return; -} - - /* * eeprom */ -static int -eeprom_read_byte(unsigned address, unsigned *val) +static int eeprom_read_byte(unsigned address, unsigned *val) { ops.data.read(val, &mem_subd, address, 0, 0); if (*val > 0xff) @@ -186,8 +56,7 @@ eeprom_read_byte(unsigned address, unsigned *val) return 0; } -static int -eeprom_read_uint16(unsigned address, unsigned *val) +static int eeprom_read_uint16(unsigned address, unsigned *val) { unsigned a = 0, b = 0; int err; @@ -206,16 +75,14 @@ eeprom_read_uint16(unsigned address, unsigned *val) return 0; } -static int -eeprom_get_calibration_base_address(unsigned *address) +static int eeprom_get_calibration_base_address(unsigned *address) { eeprom_read_uint16(24, address); return 0; } -static int -eeprom_read_float(unsigned address, float *val) +static int eeprom_read_float(unsigned address, float *val) { union float_converter { unsigned u; @@ -241,8 +108,7 @@ eeprom_read_float(unsigned address, float *val) return 0; } -static int -eeprom_read_reference_voltage(float *val) +static int eeprom_read_reference_voltage(float *val) { unsigned address; @@ -255,8 +121,7 @@ eeprom_read_reference_voltage(float *val) /* * subdevice operations */ -static int -data_read_hint(struct subdevice *s, int channel, int range, int aref) +static int data_read_hint(struct a4l_calibration_subdev *s, int channel, int range, int aref) { sampl_t dummy_data; a4l_insn_t insn; @@ -276,8 +141,8 @@ data_read_hint(struct subdevice *s, int channel, int range, int aref) return 0; } -static int -data_read(unsigned *data, struct subdevice *s, int channel, int range, int aref) +static int data_read(unsigned *data, struct a4l_calibration_subdev *s, int channel, + int range, int aref) { a4l_insn_t insn; int err; @@ -296,8 +161,8 @@ data_read(unsigned *data, struct subdevice *s, int channel, int range, int aref) return 0; } -static int -data_write(long int *data, struct subdevice *s, int channel, int range, int aref) +static int data_write(long int *data, struct a4l_calibration_subdev *s, int channel, + int range, int aref) { a4l_insn_t insn; int err; @@ -316,9 +181,8 @@ data_write(long int *data, struct subdevice *s, int channel, int range, int aref return 0; } -static int -data_read_async(void *dst, struct subdevice *s, unsigned int nb_samples, - int speriod, int irange) +static int data_read_async(void *dst, struct a4l_calibration_subdev *s, + unsigned int nb_samples, int speriod, int irange) { int i, len, err; a4l_cmd_t cmd; @@ -373,9 +237,8 @@ data_read_async(void *dst, struct subdevice *s, unsigned int nb_samples, * math: uses the gnu statistic library and the math library * */ -static int -statistics_standard_deviation_of_mean(double *dst, double src[], int len, - double mean) +static int statistics_standard_deviation_of_mean(double *dst, double src[], + int len, double mean) { double a; @@ -386,8 +249,8 @@ statistics_standard_deviation_of_mean(double *dst, double src[], int len, return 0; } -static int -statistics_standard_deviation(double *dst, double src[], int len, double mean) +static int statistics_standard_deviation(double *dst, double src[], int len, + double mean) { double a; @@ -398,16 +261,14 @@ statistics_standard_deviation(double *dst, double src[], int len, double mean) return 0; } -static int -statistics_mean(double *dst, double src[], int len) +static int statistics_mean(double *dst, double src[], int len) { *dst = gsl_stats_mean(src, 1, len); return 0; } -static int -polynomial_fit(struct polynomial *dst, struct codes_info *src) +static int polynomial_fit(struct polynomial *dst, struct codes_info *src) { gsl_multifit_linear_workspace *work; const int nb_coeff = dst->order + 1; @@ -457,8 +318,7 @@ polynomial_fit(struct polynomial *dst, struct codes_info *src) return 0; } -static int -polynomial_linearize(double *dst, struct polynomial *p, double val) +static int polynomial_linearize(double *dst, struct polynomial *p, double val) { double a = 0.0, b = 1.0; int i; @@ -467,7 +327,6 @@ polynomial_linearize(double *dst, struct polynomial *p, double val) a = a + p->coefficients[i] * b; b = b * (val - p->expansion_origin); } - *dst = a; return 0; @@ -478,8 +337,7 @@ polynomial_linearize(double *dst, struct polynomial *p, double val) * reference * */ -static int -reference_get_min_sampling_period(int *val) +static int reference_get_min_sampling_period(int *val) { unsigned int chan_descs[] = { 0}; a4l_cmd_t cmd; @@ -510,8 +368,7 @@ reference_get_min_sampling_period(int *val) return 0; } -static int -reference_set_bits(unsigned int bits) +static int reference_set_bits(unsigned int bits) { unsigned int data[2] = { A4L_INSN_CONFIG_ALT_SOURCE, bits}; a4l_insn_t insn; @@ -530,9 +387,8 @@ reference_set_bits(unsigned int bits) return 0; } -static int -reference_set_pwm(struct subdevice *s, unsigned int h, unsigned int d, - unsigned int *rh, unsigned int *rd) +static int reference_set_pwm(struct a4l_calibration_subdev *s, unsigned int h, + unsigned int d, unsigned int *rh, unsigned int *rd) { unsigned int data[5] = { [0] = A4L_INSN_CONFIG_PWM_OUTPUT, @@ -560,9 +416,8 @@ reference_set_pwm(struct subdevice *s, unsigned int h, unsigned int d, return 0; } -static int -reference_read_doubles(double dst[], unsigned int nb_samples, - int speriod, int irange) +static int reference_read_doubles(double dst[], unsigned int nb_samples, + int speriod, int irange) { int i, err = 0; sampl_t *p; @@ -585,8 +440,8 @@ reference_read_doubles(double dst[], unsigned int nb_samples, return 0; } -static int -reference_read_samples(void *dst, unsigned int nb_samples, int speriod, int irange) +static int reference_read_samples(void *dst, unsigned int nb_samples, + int speriod, int irange) { int err; @@ -618,8 +473,7 @@ const char *ni_m_boards[] = { const int nr_ni_m_boards = ARRAY_LEN(ni_m_boards); -static inline -int pwm_period_ticks(void) +static inline int pwm_period_ticks(void) { int min_speriod, speriod_ticks, ticks; int err; @@ -636,8 +490,7 @@ int pwm_period_ticks(void) return ++ticks; } -static inline -int pwm_rounded_nsamples(void) +static inline int pwm_rounded_nsamples(void) { int pwm_period, total_speriod, min_speriod; int err; @@ -654,8 +507,7 @@ int pwm_rounded_nsamples(void) return total_speriod / min_speriod; } -static int -check_buf_size(int slen) +static int check_buf_size(int slen) { unsigned long blen, req_blen; int err; @@ -671,8 +523,7 @@ check_buf_size(int slen) return 0; } -static int -set_pwm_up_ticks(int t) +static int set_pwm_up_ticks(int t) { unsigned int up_p, down_p, real_up_p, real_down_p; int err; @@ -687,8 +538,7 @@ set_pwm_up_ticks(int t) return 0; } -static int -characterize_pwm(struct pwm_info *dst, int pref, unsigned range) +static int characterize_pwm(struct pwm_info *dst, int pref, unsigned range) { int i, up_ticks, err, speriod, len; double mean, stddev, stddev_of_mean; @@ -739,8 +589,7 @@ characterize_pwm(struct pwm_info *dst, int pref, unsigned range) return 0; } -static void -print_polynomial(struct polynomial *p) +static void print_polynomial(struct polynomial *p) { int i; @@ -753,8 +602,8 @@ print_polynomial(struct polynomial *p) i, p->coefficients[i]); } -static int -calibrate_non_linearity(struct polynomial *poly, struct pwm_info *src) +static int calibrate_non_linearity(struct polynomial *poly, + struct pwm_info *src) { unsigned int max_data = (1 << ai_subd.slen * 8) - 2; unsigned up_ticks, down_ticks, i; @@ -785,13 +634,14 @@ calibrate_non_linearity(struct polynomial *poly, struct pwm_info *src) return 0; } -static int -calibrate_ai_gain_and_offset(struct polynomial *dst, struct polynomial *src, - unsigned pos_ref, float volt_ref, unsigned range) +static int calibrate_ai_gain_and_offset(struct polynomial *dst, + struct polynomial *src, + unsigned pos_ref, float volt_ref, + unsigned range) { double *p; - double measured_ground_code, linearized_ground_code; - double measured_reference_code, linearized_reference_code; + double measured_gnd_cde, linearized_gnd_cde; + double measured_ref_cde, linearized_ref_cde; double gain, offset; int i, len, err, speriod; double a, b; @@ -809,9 +659,9 @@ calibrate_ai_gain_and_offset(struct polynomial *dst, struct polynomial *src, err = references.read_doubles(p, len/sizeof(*p), speriod, range); if (err) error(EXIT, 0, "read_doubles"); - math.stats.mean(&measured_ground_code, p, len/sizeof(*p)); - math.polynomial.linearize(&linearized_ground_code, src, - measured_ground_code); + math.stats.mean(&measured_gnd_cde, p, len/sizeof(*p)); + math.polynomial.linearize(&linearized_gnd_cde, src, + measured_gnd_cde); /* reference */ references.set_bits(pos_ref | REF_NEG_CAL_GROUND); @@ -821,11 +671,10 @@ calibrate_ai_gain_and_offset(struct polynomial *dst, struct polynomial *src, err = references.read_doubles(p, len/sizeof(*p), speriod, range); if (err) error(EXIT, 0, "read_doubles"); - math.stats.mean(&measured_reference_code, p, len/sizeof(*p)); - math.polynomial.linearize(&linearized_reference_code, src, - measured_reference_code); + math.stats.mean(&measured_ref_cde, p, len/sizeof(*p)); + math.polynomial.linearize(&linearized_ref_cde, src, measured_ref_cde); - gain = volt_ref / (linearized_reference_code - linearized_ground_code); + gain = volt_ref / (linearized_ref_cde - linearized_gnd_cde); /* * update output @@ -841,19 +690,19 @@ calibrate_ai_gain_and_offset(struct polynomial *dst, struct polynomial *src, for (i = 0; i < dst->nb_coefficients; i++) dst->coefficients[i] = src->coefficients[i] * gain; - math.polynomial.linearize(&offset, dst, measured_ground_code); + math.polynomial.linearize(&offset, dst, measured_gnd_cde); dst->coefficients[0] = dst->coefficients[0] - offset; __debug("volt_ref = %g \n", volt_ref); - __debug("measured_ground_code = %g, linearized_ground_code = %g \n", - measured_ground_code, linearized_ground_code); - __debug("measured_reference_code = %g, linearized_reference_code = %g \n", - measured_reference_code, linearized_reference_code); + __debug("measured_gnd_cde = %g, linearized_gnd_cde = %g \n", + measured_gnd_cde, linearized_gnd_cde); + __debug("measured_ref_cde = %g, linearized_ref_cde = %g \n", + measured_ref_cde, linearized_ref_cde); - math.polynomial.linearize(&a, dst, measured_ground_code); - __debug("full_correction(measured_ground_code) = %g \n", a); - math.polynomial.linearize(&b, dst, measured_reference_code); - __debug("full_correction(measured_reference_code) = %g \n", b); + math.polynomial.linearize(&a, dst, measured_gnd_cde); + __debug("full_correction(measured_gnd_cde) = %g \n", a); + math.polynomial.linearize(&b, dst, measured_ref_cde); + __debug("full_correction(measured_ref_cde) = %g \n", b); print_polynomial(dst); @@ -862,8 +711,7 @@ calibrate_ai_gain_and_offset(struct polynomial *dst, struct polynomial *src, return 0; } -static int -calibrate_base_range(struct polynomial *dst, struct polynomial *src) +static int calibrate_base_range(struct polynomial *dst, struct polynomial *src) { float volt_ref; int err; @@ -878,8 +726,10 @@ calibrate_base_range(struct polynomial *dst, struct polynomial *src) } -static struct subdevice_calibration_node * -get_calibration_node(struct list *l, unsigned channel, unsigned range) { +static struct subdevice_calibration_node *get_calibration_node(struct list *l, + unsigned channel, + unsigned range) +{ struct subdevice_calibration_node *e, *t; if (list_empty(l)) @@ -898,9 +748,8 @@ get_calibration_node(struct list *l, unsigned channel, unsigned range) { return NULL; } -static int -calibrate_pwm(struct polynomial *dst, struct pwm_info *pwm_info, - struct subdevice_calibration_node *range_calibration) +static int calibrate_pwm(struct polynomial *dst, struct pwm_info *pwm_info, + struct subdevice_calibration_node *range_calibration) { double pwm_cal, adrange_cal, lsb_error; double aprox_volts_per_bit, a, b; @@ -946,9 +795,8 @@ calibrate_pwm(struct polynomial *dst, struct pwm_info *pwm_info, return 0; } -static int -append_calibration_node(struct list *l, struct polynomial *polynomial, - unsigned channel, unsigned range) +static int append_calibration_node(struct list *l, struct polynomial *polynomial, + unsigned channel, unsigned range) { struct subdevice_calibration_node *q; @@ -964,12 +812,13 @@ append_calibration_node(struct list *l, struct polynomial *polynomial, return 0; } -static int -calibrate_ai_range(struct polynomial *dst, struct polynomial *pwm_calibration, - struct polynomial *non_linearity_correction, unsigned pos_ref, - unsigned range) +static int calibrate_ai_range(struct polynomial *dst, + struct polynomial *pwm_calibration, + struct polynomial *non_linearity_correction, + unsigned pos_ref, + unsigned range) { - struct polynomial inverse_pwm_calibration; + struct polynomial inv_pwm_cal; double reference_voltage; a4l_rnginfo_t *rng; unsigned up_ticks; @@ -979,16 +828,16 @@ calibrate_ai_range(struct polynomial *dst, struct polynomial *pwm_calibration, if (pwm_calibration->order != 1) error(EXIT, -1, "pwm_calibration order \n"); - inverse_pwm_calibration.expansion_origin = pwm_calibration->coefficients[0]; + inv_pwm_cal.expansion_origin = pwm_calibration->coefficients[0]; p = malloc((pwm_calibration->order + 1) * sizeof(double)); if (!p) error(EXIT,0,"malloc\n"); - inverse_pwm_calibration.order = pwm_calibration->order; - inverse_pwm_calibration.nb_coefficients = pwm_calibration->order + 1; - inverse_pwm_calibration.coefficients = p; - inverse_pwm_calibration.coefficients[0] = pwm_calibration->expansion_origin; - inverse_pwm_calibration.coefficients[1] = 1.0 / pwm_calibration->coefficients[1]; + inv_pwm_cal.order = pwm_calibration->order; + inv_pwm_cal.nb_coefficients = pwm_calibration->order + 1; + inv_pwm_cal.coefficients = p; + inv_pwm_cal.coefficients[0] = pwm_calibration->expansion_origin; + inv_pwm_cal.coefficients[1] = 1.0 / pwm_calibration->coefficients[1]; err = a4l_get_rnginfo(&descriptor, ai_subd.idx, 0, range, &rng); if (err < 0) @@ -996,7 +845,7 @@ calibrate_ai_range(struct polynomial *dst, struct polynomial *pwm_calibration, __debug("adjusted rng_max: %g \n", rng_max(rng) * 0.9); - math.polynomial.linearize(&val, &inverse_pwm_calibration, + math.polynomial.linearize(&val, &inv_pwm_cal, rng_max(rng) * 0.9); up_ticks = lrint(val); free(p); @@ -1013,13 +862,12 @@ calibrate_ai_range(struct polynomial *dst, struct polynomial *pwm_calibration, return 0; } -static int -calibrate_ranges_above_threshold(struct polynomial *pwm_calibration, - struct polynomial *non_linearity_correction, - unsigned pos_ref, - struct list *calibration_list, - struct calibrated_ranges *calibrated, - double max_range_threshold ) +static int calibrate_ranges_above_threshold(struct polynomial *pwm_calibration, + struct polynomial *non_lin_correct, + unsigned pos_ref, + struct list *calibration_list, + struct calibrated_ranges *calibrated, + double max_range_threshold ) { struct polynomial *dst; a4l_rnginfo_t *rnginfo; @@ -1041,7 +889,7 @@ calibrate_ranges_above_threshold(struct polynomial *pwm_calibration, error(EXIT, 0, "malloc"); __debug("calibrating range %d \n", i); - calibrate_ai_range(dst, pwm_calibration, non_linearity_correction, + calibrate_ai_range(dst, pwm_calibration, non_lin_correct, pos_ref, i); append_calibration_node(calibration_list, dst, ALL_CHANNELS, i); calibrated->ranges[i] = 1; @@ -1051,8 +899,8 @@ calibrate_ranges_above_threshold(struct polynomial *pwm_calibration, return 0; } -static int -get_min_range_containing(struct calibrated_ranges *calibrated, double value) +static int get_min_range_containing(struct calibrated_ranges *calibrated, + double value) { a4l_rnginfo_t *rnginfo, *smallest = NULL; unsigned smallest_range = 0; @@ -1067,7 +915,8 @@ get_min_range_containing(struct calibrated_ranges *calibrated, double value) error(EXIT,0,"a4l_get_rnginfo (%d)\n", err); if (rng_max(rnginfo) > value && - (smallest_range == 0 || rng_max(rnginfo) < rng_max(smallest))) { + (smallest_range == 0 || + rng_max(rnginfo) < rng_max(smallest))) { smallest_range = i; smallest = rnginfo; } @@ -1078,29 +927,27 @@ get_min_range_containing(struct calibrated_ranges *calibrated, double value) return smallest_range; } -static int -ni_m_calibrate_ai(void) +static int ni_m_calibrate_ai(void) { - const unsigned PWM_CAL_POINTS = (NI_M_TARGET_PWM_PERIOD_TICKS / NI_M_MIN_PWM_PULSE_TICKS); + const unsigned PWM_CAL_POINTS = (NI_M_TARGET_PWM_PERIOD_TICKS / + NI_M_MIN_PWM_PULSE_TICKS); const double MEDIUM_RANGE = 0.499; const double LARGE_RANGE = 1.99; const double SMALL_RANGE = 0.0; - - struct polynomial non_linearity_correction, full_correction; + struct polynomial non_lin_correct, full_correct; struct subdevice_calibration_node *node; struct calibrated_ranges calibrated; struct polynomial pwm_calibration; struct pwm_info pwm_info; a4l_chinfo_t *chan_info; int i, err; - struct calibration_loop { const char *message; unsigned ref_pos; double threshold; double item; int range; - } calibration_info [] = { + } cal_info [] = { [0] = { .message = "low gain range ", .ref_pos = REF_POS_CAL_PWM_10V, @@ -1122,8 +969,6 @@ ni_m_calibrate_ai(void) .item = MEDIUM_RANGE, .range = -1, }, - - }; list_init(&ai_calibration_list); @@ -1163,15 +1008,15 @@ ni_m_calibrate_ai(void) if (err) error(EXIT, 0, "characterize_pwm"); - err = calibrate_non_linearity(&non_linearity_correction, &pwm_info); + err = calibrate_non_linearity(&non_lin_correct, &pwm_info); if (err) error(EXIT, 0, "calibrate_non_linearity"); - err = calibrate_base_range(&full_correction, &non_linearity_correction); + err = calibrate_base_range(&full_correct, &non_lin_correct); if (err) error(EXIT, 0, "calibrate_ai_base_range"); - append_calibration_node(&ai_calibration_list, &full_correction, + append_calibration_node(&ai_calibration_list, &full_correct, ALL_CHANNELS, NI_M_BASE_RANGE); calibrated.ranges[NI_M_BASE_RANGE] = 1; @@ -1179,26 +1024,26 @@ ni_m_calibrate_ai(void) /* * calibrate low, medium and high gain ranges */ - for (i = 0; i < ARRAY_LEN(calibration_info); i++) { - __debug("Calibrating AI: %s \n", calibration_info[i]); + for (i = 0; i < ARRAY_LEN(cal_info); i++) { + __debug("Calibrating AI: %s \n", cal_info[i]); - if (calibration_info[i].range >= 0) + if (cal_info[i].range >= 0) goto calibrate; - calibration_info[i].range = get_min_range_containing(&calibrated, - calibration_info[i].item); - if (!calibrated.ranges[calibration_info[i].range]) + cal_info[i].range = get_min_range_containing(&calibrated, + cal_info[i].item); + if (!calibrated.ranges[cal_info[i].range]) error(EXIT, 0, "not calibrated yet \n" ); err = characterize_pwm(&pwm_info, - calibration_info[i].ref_pos, - calibration_info[i].range); + cal_info[i].ref_pos, + cal_info[i].range); if (err) error(EXIT, 0, "characterize_pwm \n"); calibrate: node = get_calibration_node(&ai_calibration_list, 0, - calibration_info[i].range); + cal_info[i].range); if (!node) error(EXIT, 0, "couldnt find node \n"); @@ -1207,11 +1052,11 @@ calibrate: error(EXIT, 0, "calibrate_pwm \n"); err = calibrate_ranges_above_threshold(&pwm_calibration, - &non_linearity_correction, - calibration_info[i].ref_pos, + &non_lin_correct, + cal_info[i].ref_pos, &ai_calibration_list, &calibrated, - calibration_info[i].threshold); + cal_info[i].threshold); if (err) error(EXIT, 0, "calibrate_ranges_above_threshold \n"); } @@ -1219,8 +1064,7 @@ calibrate: return 0; } -static unsigned -find_ai_range_for_ao(unsigned ao_range) +static unsigned find_ai_range_for_ao(unsigned ao_range) { a4l_rnginfo_t *ao_rng_info, *ai_rng_info, *rng_info = NULL; a4l_chinfo_t *ai_chan_info; @@ -1263,8 +1107,7 @@ find_ai_range_for_ao(unsigned ao_range) return range; } -static long int -get_high_code(unsigned ai_rng, unsigned ao_rng) +static long int get_high_code(unsigned ai_rng, unsigned ao_rng) { unsigned int ao_max_data = (1 << ao_subd.slen * 8) - 2; a4l_rnginfo_t *ai, *ao; @@ -1276,15 +1119,17 @@ get_high_code(unsigned ai_rng, unsigned ao_rng) if (rng_max(ai) > rng_max(ao)) return lrint(ao_max_data * 0.9); - fractional_code = (0.9 * rng_max(ai) - rng_min(ao)) / (rng_max(ao) - rng_min(ao)); + fractional_code = (0.9 * rng_max(ai) - rng_min(ao)) / + (rng_max(ao) - rng_min(ao)); + if (fractional_code < 0.0 || fractional_code > 1.0) error(EXIT, 0, "error looking for high code"); return lrint(ao_max_data * fractional_code); } -static int -calibrate_ao_channel_and_range(unsigned ai_rng, unsigned ao_channel, unsigned ao_rng) +static int calibrate_ao_channel_and_range(unsigned ai_rng, unsigned ao_channel, + unsigned ao_rng) { unsigned int ao_max_data = (1 << ao_subd.slen * 8) - 2; double measured_low_code, measured_high_code, tmp; @@ -1310,7 +1155,8 @@ calibrate_ao_channel_and_range(unsigned ai_rng, unsigned ao_channel, unsigned ao if ((ao_channel & 0xf) != ao_channel) error(EXIT,0, "wrong ao channel (%d)", ao_channel); - references.set_bits(REF_POS_CAL_AO | REF_NEG_CAL_GROUND | ao_channel << 15); + references.set_bits(REF_POS_CAL_AO | + REF_NEG_CAL_GROUND | ao_channel << 15); /* low nominals */ data.codes[0].nominal = low_code; @@ -1341,8 +1187,8 @@ calibrate_ao_channel_and_range(unsigned ai_rng, unsigned ao_channel, unsigned ao node->polynomial, measured_high_code); - poly.expansion_origin = 0.0; poly.order = data.nb_codes - 1; + poly.expansion_origin = 0.0; __debug("AO calibration for channel %d, range %d \n", ao_channel, ao_rng); for (i = 0; i < data.nb_codes ; i++) @@ -1369,8 +1215,7 @@ calibrate_ao_channel_and_range(unsigned ai_rng, unsigned ao_channel, unsigned ao return 0; } -static int -ni_m_calibrate_ao(void) +static int ni_m_calibrate_ao(void) { a4l_rnginfo_t *range_info; a4l_chinfo_t *chan_info; @@ -1391,8 +1236,8 @@ ni_m_calibrate_ao(void) for (channel = 0; channel < ao_subd.info->nb_chan; channel++) { for (range = 0 ; range < chan_info->nb_rng; range++) { - err = a4l_get_rnginfo(&descriptor, ao_subd.idx, 0, range, - &range_info); + err = a4l_get_rnginfo(&descriptor, ao_subd.idx, 0, + range, &range_info); if (err) error(EXIT, 0, "a4l_get_rng_info (%d)", err); @@ -1400,9 +1245,8 @@ ni_m_calibrate_ao(void) continue; ai_range = find_ai_range_for_ao(range); - - err = calibrate_ao_channel_and_range(ai_range, channel, - range); + err = calibrate_ao_channel_and_range(ai_range, + channel, range); if (err) error(EXIT, 0, "calibrate_ao"); } @@ -1414,7 +1258,7 @@ ni_m_calibrate_ao(void) /* * main entry */ -int ni_m_software_calibrate(void) +int ni_m_software_calibrate(FILE *p) { a4l_sbinfo_t *sbinfo; int i, err; @@ -1458,7 +1302,7 @@ int ni_m_software_calibrate(void) if (err) error(EXIT, 0, "ai calibration error (%d)", err); - write_calibration(&ai_calibration_list, &ai_subd); + a4l_write_calibration_file(p, &ai_calibration_list, &ai_subd, &descriptor); /* only calibrate the analog output subdevice if present */ if (ao_subd.idx < 0) { @@ -1470,7 +1314,7 @@ int ni_m_software_calibrate(void) if (err) error(EXIT, 0, "ao calibration error (%d)", err); - write_calibration(&ao_calibration_list, &ao_subd); + a4l_write_calibration_file(p, &ao_calibration_list, &ao_subd, NULL); return 0; } diff --git a/utils/analogy/calibration_ni_m.h b/utils/analogy/calibration_ni_m.h index a0cb836..7cbdce3 100644 --- a/utils/analogy/calibration_ni_m.h +++ b/utils/analogy/calibration_ni_m.h @@ -23,7 +23,8 @@ #ifndef __NI_M_SOFTWARE_CALIBRATE_H__ #define __NI_M_SOFTWARE_CALIBRATE_H__ - +#include <rtdm/uapi/analogy.h> +#include "calibration.h" #include "analogy_calibrate.h" #include "boilerplate/list.h" @@ -32,8 +33,7 @@ extern const int nr_ni_m_boards; #define ni_m_board_supported(id) __array_search(id, ni_m_boards, nr_ni_m_boards) -int ni_m_software_calibrate(void); -int ni_m_apply_calibration(void); +int ni_m_software_calibrate(FILE *p); #define init_interface(a, b) a = ((typeof(a)) INIT_##b); @@ -56,13 +56,6 @@ int ni_m_apply_calibration(void); .name = NULL, \ } -struct subdevice { - a4l_sbinfo_t *info; - int slen; - int idx; - char *name; -}; - /* * eeprom */ @@ -116,10 +109,10 @@ struct eeprom { .data = INIT_SUBDEV_DATA_OPS \ } -typedef int (*data_read_async_function)(void *, struct subdevice *, unsigned , int , int); -typedef int (*data_read_hint_function)(struct subdevice *s, int, int, int); -typedef int (*data_read_function)(unsigned *, struct subdevice *, int, int, int); -typedef int (*data_write_function)(long int *, struct subdevice *s, int, int, int); +typedef int (*data_read_async_function)(void *, struct a4l_calibration_subdev *, unsigned , int , int); +typedef int (*data_read_hint_function)(struct a4l_calibration_subdev *s, int, int, int); +typedef int (*data_read_function)(unsigned *, struct a4l_calibration_subdev *, int, int, int); +typedef int (*data_write_function)(long int *, struct a4l_calibration_subdev *s, int, int, int); struct subdev_ops { struct data_ops { @@ -153,12 +146,6 @@ struct subdev_ops { .polynomial = INIT_GNU_MATH_POLYNOMIAL, \ } -struct polynomial { - double expansion_origin; - double *coefficients; - int nb_coefficients; - int order; -}; struct codes { double measured; @@ -220,7 +207,7 @@ struct gnumath { .read_doubles = reference_read_doubles, \ } -typedef int (*reference_set_pwm_function)(struct subdevice *s, unsigned, unsigned, unsigned *, unsigned *); +typedef int (*reference_set_pwm_function)(struct a4l_calibration_subdev *s, unsigned, unsigned, unsigned *, unsigned *); typedef int (*reference_read_reference_doubles_function)(double [], unsigned, int, int); typedef int (*reference_read_reference_samples_function)(void *, unsigned, int, int); typedef int (*reference_get_min_sampling_period_function)(int *); @@ -261,13 +248,6 @@ struct pwm_info { #define NI_M_BASE_RANGE ( 0 ) -struct subdevice_calibration_node { - struct holder node; - struct polynomial *polynomial; - unsigned channel; - unsigned range; -}; - struct calibrated_ranges { unsigned *ranges; unsigned nb_ranges; _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git