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 12c2a3ae9f6c845b809025a37068844d7d1c7e8b..838fbab3a6f6947844a97e692d58515b75093b44 100644 (file)
 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 = 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] [--device=<device>] [-tty=<tty>]\n", program);
+       fprintf(stderr, "usage: %s [--verbose] [--nosave] [--device=<device>] [-tty=<tty>] [--output=<cal-value-file>]\n", program);
        exit(1);
 }
 
@@ -168,7 +169,60 @@ await_key(void)
 }
 
 int
-do_cal(char *tty) {
+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];
@@ -180,36 +234,26 @@ do_cal(char *tty) {
        int     cur_cal;
        int     new_cal;
        int     ret = 1;
+       int     changed = 0;
 
        for(;;) {
                usb = cc_usb_open(tty);
 
-               if (!usb)
-                       exit(1);
+               if (!usb) {
+                       fprintf(stderr, "failed to open device\n");
+                       ret = 0;
+                       break;
+               }
 
                cc_usb_printf(usb, "E 0\n");
 
-               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;
-
                b = flash(usb);
 
                cur_cal_words = find_flash(b, "Radio cal:");
                cur_freq_words = find_flash(b, "Frequency:");
 
                if (!cur_cal_words || !cur_freq_words) {
-                       printf("no response\n");
+                       fprintf(stderr, "no response\n");
                        ret = 0;
                        break;
                }
@@ -218,19 +262,50 @@ do_cal(char *tty) {
                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);
        }
-       if (usb)
+       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;
 }
 
@@ -247,10 +322,12 @@ main (int argc, char **argv)
        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, "vrT:D:c:s:", options, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv, "vnT:D:o:", options, NULL)) != -1) {
                switch (c) {
                case 'T':
                        tty = optarg;
@@ -261,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;
@@ -268,8 +351,7 @@ main (int argc, char **argv)
        }
 
        ao_verbose = verbose;
-
-       if (verbose > 1)
+       if (verbose)
                ccdbg_add_debug(CC_DEBUG_BITBANG);
 
        if (!tty)
@@ -281,6 +363,7 @@ main (int argc, char **argv)
        if (!tty)
                tty="/dev/ttyACM0";
 
-       if (!do_cal(tty))
+       if (!do_cal(tty, save, output))
                ret = 1;
+       return ret;
 }