ao-tools/ao-cal-freq: Add --nosave and --output options. Check save results.
[fw/altos] / ao-tools / ao-cal-freq / ao-cal-freq.c
index 464faf0f8320a63587cdf79b1e4a5d441e2ad24d..838fbab3a6f6947844a97e692d58515b75093b44 100644 (file)
@@ -3,7 +3,8 @@
  *
  * 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; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
 static const struct option options[] = {
        { .name = "tty", .has_arg = 1, .val = 'T' },
        { .name = "device", .has_arg = 1, .val = 'D' },
-       { .name = "raw", .has_arg = 0, .val = 'r' },
-       { .name = "verbose", .has_arg = 1, .val = 'v' },
+       { .name = "verbose", .has_arg = 0, .val = 'v' },
+       { .name = "output", .has_arg = 1, .val = 'o' },
+       { .name = "nosave", .has_arg = 0, .val = 'n' },
        { 0, 0, 0, 0},
 };
 
 static void usage(char *program)
 {
-       fprintf(stderr, "usage: %s [--verbose=<verbose>] [--device=<device>] [-tty=<tty>]\n", program);
+       fprintf(stderr, "usage: %s [--verbose] [--nosave] [--device=<device>] [-tty=<tty>] [--output=<cal-value-file>]\n", program);
        exit(1);
 }
 
@@ -167,7 +169,61 @@ await_key(void)
 }
 
 int
-do_cal(struct cc_usb *usb) {
+do_save(struct cc_usb *usb)
+{
+       int ret = 0;
+
+       printf("Saving calibration to device\n");
+       cc_usb_printf(usb, "c w\nv\n");
+       for (;;) {
+               char    line[512];
+
+               cc_usb_getline(usb, line, sizeof (line));
+               if (strstr(line, "Nothing to save"))
+                       ret = 1;
+               if (strstr(line, "Saved"))
+                       ret = 1;
+               if (strstr(line, "software-version"))
+                       break;
+       }
+       if (!ret) {
+               printf("Calibration save failed\n");
+       }
+       return ret;
+}
+
+int
+do_output(char *output, int cur_cal)
+{
+       printf ("Saving calibration value to file \"%s\"\n", output);
+
+       FILE    *out = fopen(output, "w");
+       int     ret = 1;
+
+       if (!out) {
+               perror(output);
+               return 0;
+       }
+
+       if (fprintf(out, "%d\n", cur_cal) < 0) {
+               perror("fprintf");
+               ret = 0;
+       }
+       if (fflush(out) != 0) {
+               perror("fflush");
+               ret = 0;
+       }
+       if (fclose(out) != 0) {
+               perror("fclose");
+               ret = 0;
+       }
+       return ret;
+}
+
+int
+do_cal(char *tty, int save, char *output)
+{
+       struct cc_usb *usb = NULL;
        struct flash    *b;
        char    line[1024];
        double  measured_freq;
@@ -177,22 +233,19 @@ do_cal(struct cc_usb *usb) {
        int     cur_freq;
        int     cur_cal;
        int     new_cal;
-
-       cc_usb_printf(usb, "E 0\n");
+       int     ret = 1;
+       int     changed = 0;
 
        for(;;) {
-               cc_usb_printf(usb, "C 1\n");
-               cc_usb_sync(usb);
+               usb = cc_usb_open(tty);
 
-               printf("Generating RF carrier. Please enter measured frequency [enter for done]: ");
-               fflush(stdout);
-               fgets(line, sizeof (line) - 1, stdin);
-               cc_usb_printf(usb, "C 0\n");
-               cc_usb_sync(usb);
-
-               measured_freq = strtod(line, &line_end);
-               if (line_end == line)
+               if (!usb) {
+                       fprintf(stderr, "failed to open device\n");
+                       ret = 0;
                        break;
+               }
+
+               cc_usb_printf(usb, "E 0\n");
 
                b = flash(usb);
 
@@ -200,25 +253,60 @@ do_cal(struct cc_usb *usb) {
                cur_freq_words = find_flash(b, "Frequency:");
 
                if (!cur_cal_words || !cur_freq_words) {
-                       printf("no response\n");
-                       return 0;
+                       fprintf(stderr, "no response\n");
+                       ret = 0;
+                       break;
                }
 
                cur_cal = atoi(cur_cal_words[2]);
                cur_freq = atoi(cur_freq_words[1]);
 
                printf ("Current radio calibration %d\n", cur_cal);
-               printf ("Current radio frequency: %d\n", cur_freq);
+               printf ("Current radio frequency: %7.3f\n", cur_freq / 1000.0);
 
+               cc_usb_sync(usb);
+               cc_usb_printf(usb, "C 1\n");
+               cc_usb_sync(usb);
+
+               printf("Generating RF carrier. Please enter measured frequency [enter for done]: ");
+               fflush(stdout);
+               fgets(line, sizeof (line) - 1, stdin);
+               cc_usb_printf(usb, "C 0\n");
+               cc_usb_sync(usb);
+
+               measured_freq = strtod(line, &line_end);
+               if (line_end == line)
+                       break;
 
                new_cal = floor ((((double) cur_freq / 1000.0) / measured_freq) * cur_cal + 0.5);
 
-               printf ("Programming flash with cal value %d\n", new_cal);
+               if (new_cal == cur_cal) {
+                       printf("Calibration value %d unchanged\n", cur_cal);
+               } else {
+                       printf ("Setting cal value %d\n", new_cal);
 
-               cc_usb_printf (usb, "c f %d\nc w\n", new_cal);
-               cc_usb_sync(usb);
+                       cc_usb_printf (usb, "c f %d\n", new_cal);
+                       changed = 1;
+                       cc_usb_sync(usb);
+               }
+               cc_usb_close(usb);
        }
-       return 1;
+       if (usb) {
+               if (ret && save) {
+                       if (changed) {
+                               if (!do_save(usb))
+                                       ret = 0;
+                       } else {
+                               printf("Calibration unchanged, not saving\n");
+                       }
+               }
+               if (ret && output) {
+                       if (!do_output(output, cur_cal))
+                               ret = 0;
+               }
+               cc_usb_close(usb);
+       }
+       return ret;
 }
 
 int
@@ -231,14 +319,15 @@ main (int argc, char **argv)
        int                     i;
        int                     c;
        int                     tries;
-       struct cc_usb           *cc = NULL;
        char                    *tty = NULL;
        int                     success;
        int                     verbose = 0;
+       int                     save = 1;
        int                     ret = 0;
        int                     expected_size;
+       char                    *output = NULL;
 
-       while ((c = getopt_long(argc, argv, "rT:D:c:s:v:", options, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv, "vnT:D:o:", options, NULL)) != -1) {
                switch (c) {
                case 'T':
                        tty = optarg;
@@ -249,6 +338,12 @@ main (int argc, char **argv)
                case 'v':
                        verbose++;
                        break;
+               case 'n':
+                       save = 0;
+                       break;
+               case 'o':
+                       output = optarg;
+                       break;
                default:
                        usage(argv[0]);
                        break;
@@ -256,8 +351,7 @@ main (int argc, char **argv)
        }
 
        ao_verbose = verbose;
-
-       if (verbose > 1)
+       if (verbose)
                ccdbg_add_debug(CC_DEBUG_BITBANG);
 
        if (!tty)
@@ -269,12 +363,7 @@ main (int argc, char **argv)
        if (!tty)
                tty="/dev/ttyACM0";
 
-       cc = cc_usb_open(tty);
-
-       if (!cc)
-               exit(1);
-
-       if (!do_cal(cc))
+       if (!do_cal(tty, save, output))
                ret = 1;
-       done(cc, ret);
+       return ret;
 }