diff --git a/tools/atrf-xtal/Makefile b/tools/atrf-xtal/Makefile index 5e3385a..a38e79b 100644 --- a/tools/atrf-xtal/Makefile +++ b/tools/atrf-xtal/Makefile @@ -11,37 +11,26 @@ # -ifeq ($(TARGET),) -TARGET = host -endif - -ifeq ($(TARGET),host) - -.PHONY: all install uninstall clean spotless - -all: - -install: - -uninstall: - -clean: - rm -f atben.o atrf-xtal.o - -spotless: clean - rm -f atrf-xtal - -else - MAIN = atrf-xtal include ../Makefile.common LDLIBS += -lm -CFLAGS += -O9 -OBJS_$(TARGET) = atben.o +MACROS_host += -DHAVE_ATUSB +OBJS_host = atusb.o +LDLIBS_host += -lgsl -lgslcblas + +CFLAGS_ben_openwrt += -O9 +MACROS_ben_openwrt += -DHAVE_ATBEN +OBJS_ben_openwrt = atben.o + +CFLAGS_ben_jlime += -O9 +MACROS_ben_jlime += -DHAVE_ATBEN +OBJS_ben_jlime = atben.o + $(MAIN): $(OBJS_$(TARGET)) -endif +clean:: + rm -f $(OBJS_host) $(OBJS_ben_openwrt) $(OBJS_ben_jlime) diff --git a/tools/atrf-xtal/atrf-xtal.c b/tools/atrf-xtal/atrf-xtal.c index ccfdf23..34bd8de 100644 --- a/tools/atrf-xtal/atrf-xtal.c +++ b/tools/atrf-xtal/atrf-xtal.c @@ -23,22 +23,52 @@ #define DEFAULT_SIZE 127 #define DEFAULT_TRIM 8 +#define DEFAULT_SAMPLES 1000 + + +static void atben(struct atrf_dsc *dsc, int size, int trim, int rep, + int dump_raw, double base, double ppm) +{ +#ifdef HAVE_ATBEN + do_atben(dsc, size, trim, rep, dump_raw, base, ppm); +#else + fprintf(stderr, "not compiled with ATBEN support\n"); + exit(1); +#endif +} + + +static void atusb(struct atrf_dsc *dsc, int trim, int dump_raw, double ppm, + int sequence) +{ +#ifdef HAVE_ATUSB + do_atusb(dsc, trim, dump_raw, ppm, sequence); +#else + fprintf(stderr, "not compiled with ATUSB support\n"); + exit(1); +#endif +} static void usage(const char *name) { fprintf(stderr, "usage: %s [-b count [-p ppm]] [-d driver[:arg]] [-r] [-s size] [-t trim]\n" -" %*s [repetitions]\n\n" +" %*s [repetitions]\n" +" %s [-d driver[:arg]] [-p ppm] [-r] [-t trim] [samples]\n\n" +"atben arguments:\n" " -b count base count for relative result\n" +" -s size payload size in bytes, 0-127 (default: %d bytes)\n" +" repetitions number of measurements (default: 1)\n\n" +"atusb arguments:\n" +" samples number of samples (default: %d)\n\n" +"common options\n" " -d driver[:arg] use the specified driver (default: %s)\n" " -p ppm maximum deviation from base count\n" " -r instead of printing a mean value, dump the raw samples\n" -" -s size payload size in bytes, 0-127 (default: %d bytes)\n" " -t trim trim capacitor setting, 0-15 (default: %d)\n" -" repetitions number of measurements (default: 1)\n" - , name, (int) strlen(name), "", - atrf_default_driver_name(), DEFAULT_SIZE, DEFAULT_TRIM); + , name, (int) strlen(name), "", name, + DEFAULT_SIZE, DEFAULT_SAMPLES, atrf_default_driver_name(), DEFAULT_TRIM); exit(1); } @@ -50,7 +80,7 @@ int main(int argc, char *const *argv) int size = DEFAULT_SIZE; int trim = DEFAULT_TRIM; double base = 0, ppm = 0; - int rep = 1; + int n = 0; int dump_raw = 0; char *end; int c; @@ -91,14 +121,16 @@ int main(int argc, char *const *argv) usage(*argv); } +#if 0 if (ppm && !base) usage(*argv); +#endif switch (argc-optind) { case 0: break; case 1: - rep = strtoul(argv[optind], &end, 0); + n = strtoul(argv[optind], &end, 0); if (*end) usage(*argv); break; @@ -110,7 +142,10 @@ int main(int argc, char *const *argv) if (!dsc) return 1; - do_atben(dsc, size, trim, rep, dump_raw, base, ppm); + if (atrf_usb_handle(dsc)) + atusb(dsc, trim, dump_raw, ppm, n ? n : DEFAULT_SAMPLES); + else + atben(dsc, size, trim, n ? n : 1, dump_raw, base, ppm); return 0; } diff --git a/tools/atrf-xtal/atrf-xtal.h b/tools/atrf-xtal/atrf-xtal.h index e40e84a..77cd424 100644 --- a/tools/atrf-xtal/atrf-xtal.h +++ b/tools/atrf-xtal/atrf-xtal.h @@ -19,5 +19,7 @@ void do_atben(struct atrf_dsc *dsc, int size, int trim, int rep, int dump_raw, double base, double ppm); +void do_atusb(struct atrf_dsc *dsc, int trim, int dump_raw, double ppm, + int n); #endif /* !ATRF_XTAL_H */ diff --git a/tools/atrf-xtal/atusb.c b/tools/atrf-xtal/atusb.c new file mode 100644 index 0000000..0730155 --- /dev/null +++ b/tools/atrf-xtal/atusb.c @@ -0,0 +1,100 @@ +/* + * atrf-xtal/atusb.c - ATUSB-specific driver and evaluation + * + * Written 2011 by Werner Almesberger + * Copyright 2011 Werner Almesberger + * + * This program 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. + */ + + +#include +#include +#include + +#include +#include + +#include "at86rf230.h" +#include "atusb/ep0.h" +#include "atrf.h" + +#include "atrf-xtal.h" + + +#define FROM_DEV ATUSB_FROM_DEV(0) + +#define F_NOMINAL_Hz 8000000 /* nominal frequency, in Hz */ + + +static uint64_t get_sample(struct atrf_dsc *dsc, double *t0, double *t1) +{ + struct timeval tod0, tod1; + uint64_t cnt; + int res; + + gettimeofday(&tod0, NULL); + res = usb_control_msg(atrf_usb_handle(dsc), + FROM_DEV, ATUSB_TIMER, 0, 0, (void *) &cnt, sizeof(cnt), 1000); + gettimeofday(&tod1, NULL); + if (res < 0) { + fprintf(stderr, "ATUSB_TIMER: %s\n", usb_strerror()); + exit(1); + } + *t0 = tod0.tv_sec+tod0.tv_usec/1000000.0; + *t1 = tod1.tv_sec+tod1.tv_usec/1000000.0; + return cnt; +} + + +void do_atusb(struct atrf_dsc *dsc, int trim, int dump_raw, double ppm, + int n) +{ + double t0[n], t1[n], cnt[n], w[n]; + double c0, c1, cov00, cov01, cov11, chisq; + double d; + double tz = 0, cntz = 0; + double rel; + int i; + + atrf_reg_write(dsc, REG_XOSC_CTRL, + (XTAL_MODE_INT << XTAL_MODE_SHIFT) | trim); + + for (i = 0; i != n; i++) { + cnt[i] = get_sample(dsc, t0+i, t1+i); + if (!i) { + tz = t0[0]; + cntz = cnt[0]; + } + t0[i] -= tz; + t1[i] -= tz; + cnt[i] -= cntz; + + /* + * see http://en.wikipedia.org/wiki/ + * Uniform_distribution_(continuous) + */ + d = (t1[i]-t0[i])*F_NOMINAL_Hz; + w[i] = 12/(d*d); + } + + if (dump_raw) { + for (i = 0; i != n; i++) + printf("%.6f %.6f %.0f\n", t0[i], t1[i], cnt[i]); + return; + } + + gsl_fit_wlinear (t0, 1, w, 1, cnt, 1, n, + &c0, &c1, &cov00, &cov01, &cov11, &chisq); + + rel = (c1/F_NOMINAL_Hz-1)*1000000; + printf("%+.2f ppm", rel); + if (ppm && fabs(rel) > ppm) { + printf(" (outside bounds)\n"); + exit(1); + } + putchar('\n'); +}