/* * Analogy for Linux, calibration program * * Copyright (C) 2014 Jorge A. Ramirez-Ortiz * * from original code from the Comedi project * * Xenomai is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Xenomai is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Xenomai; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __ANALOGY_CALIBRATE_H__ #define __ANALOGY_CALIBRATE_H__ #include #include #include #include #include #include #include "error.h" extern struct timespec calibration_start_time; extern a4l_desc_t descriptor; extern FILE *cal; #define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0])) #define RETURN 1 #define CONT 0 #define EXIT -1 #define error(action, code, fmt, ...) \ do { \ error_at_line(action, code, __FILE__, __LINE__, fmt, ##__VA_ARGS__ ); \ if (action == RETURN) \ return -1; \ }while(0) struct breakdown_time { int ms; int us; int ns; }; static inline void do_time_breakdown(struct breakdown_time *p, const struct timespec *t) { unsigned long long ms, us, ns; ns = t->tv_sec * 1000000000ULL; ns += t->tv_nsec; ms = ns / 1000000ULL; us = (ns % 1000000ULL) / 1000ULL; p->ms = (int)ms; p->us = (int)us; p->ns = (int)ns; } static inline void timespec_sub(struct timespec *r, const struct timespec *__restrict t1, const struct timespec *__restrict t2) { r->tv_sec = t1->tv_sec - t2->tv_sec; r->tv_nsec = t1->tv_nsec - t2->tv_nsec; if (r->tv_nsec < 0) { r->tv_sec--; r->tv_nsec += 1000000000; } } static inline void __debug(char *fmt, ...) { struct timespec now, delta; struct breakdown_time tm; char *header, *msg; int hlen, mlen; va_list ap; __attribute__((unused)) int err; va_start(ap, fmt); clock_gettime(CLOCK_MONOTONIC, &now); timespec_sub(&delta, &now, &calibration_start_time); do_time_breakdown(&tm, &delta); hlen = asprintf(&header, "%4d\"%.3d.%.3d| ", tm.ms / 1000, tm.ms % 1000, tm.us); mlen = vasprintf(&msg, fmt, ap); err = write(fileno(stdout), header, hlen); err = write(fileno(stdout), msg, mlen); free(header); free(msg); va_end(ap); } static inline int __array_search(char *elem, const char *array[], int len) { int i; for (i = 0; i < len; i++) if (strncmp(elem, array[i], strlen(array[i])) == 0) return 0; return -1; } static inline double rng_max(a4l_rnginfo_t *range) { double a, b; b = A4L_RNG_FACTOR * 1.0; a = (double) range->max; a = a / b; return a; } static inline double rng_min(a4l_rnginfo_t *range) { double a, b; b = A4L_RNG_FACTOR * 1.0; a = (double) range->min; a = a / b; return a; } #endif