doc: add flash-force instructions for TeleBT v3.0
[fw/altos] / ao-tools / ao-cal-freq / ao-cal-freq.c
index 12c2a3ae9f6c845b809025a37068844d7d1c7e8b..b9efb8f68a46e55539400754c8a2959fcd3dbb74 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);
 }
 
-void
-done(struct cc_usb *cc, int code)
-{
-       cc_usb_close(cc);
-       exit (code);
-}
-
-static int
-ends_with(char *whole, char *suffix)
-{
-       int whole_len = strlen(whole);
-       int suffix_len = strlen(suffix);
-
-       if (suffix_len > whole_len)
-               return 0;
-       return strcmp(whole + whole_len - suffix_len, suffix) == 0;
-}
-
-static int
-starts_with(char *whole, char *prefix)
-{
-       int whole_len = strlen(whole);
-       int prefix_len = strlen(prefix);
-
-       if (prefix_len > whole_len)
-               return 0;
-       return strncmp(whole, prefix, prefix_len) == 0;
-}
-
 static char **
 tok(char *line) {
        char    **strs = malloc (sizeof (char *)), *str;
@@ -93,16 +65,6 @@ tok(char *line) {
        return strs;
 }
 
-static void
-free_strs(char **strs) {
-       char    *str;
-       int     i;
-
-       for (i = 0; (str = strs[i]) != NULL; i++)
-               free(str);
-       free(strs);
-}
-
 struct flash {
        struct flash    *next;
        char            line[512];
@@ -131,21 +93,8 @@ flash(struct cc_usb *usb)
        return head;
 }
 
-static void
-free_flash(struct flash *b) {
-       struct flash *n;
-
-       while (b) {
-               n = b->next;
-               free_strs(b->strs);
-               free(b);
-               b = n;
-       }
-}
-
-char **
+static char **
 find_flash(struct flash *b, char *word0) {
-       int i;
        for (;b; b = b->next) {
                if (strstr(b->line, word0))
                        return b->strs;
@@ -153,22 +102,61 @@ find_flash(struct flash *b, char *word0) {
        return NULL;
 }
 
-void
-await_key(void)
+static int
+do_save(struct cc_usb *usb)
 {
-       struct termios  termios, termios_save;
-       char    buf[512];
-
-       tcgetattr(0, &termios);
-       termios_save = termios;
-       cfmakeraw(&termios);
-       tcsetattr(0, TCSAFLUSH, &termios);
-       read(0, buf, sizeof (buf));
-       tcsetattr(0, TCSAFLUSH, &termios_save);
+       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_cal(char *tty) {
+static 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;
+}
+
+static int
+do_cal(char *tty, int save, char *output)
+{
        struct cc_usb *usb = NULL;
        struct flash    *b;
        char    line[1024];
@@ -180,36 +168,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 +196,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;
 }
 
@@ -238,19 +247,14 @@ int
 main (int argc, char **argv)
 {
        char                    *device = NULL;
-       char                    *filename;
-       Elf                     *e;
-       unsigned int            s;
-       int                     i;
        int                     c;
-       int                     tries;
        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 +265,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 +278,7 @@ main (int argc, char **argv)
        }
 
        ao_verbose = verbose;
-
-       if (verbose > 1)
+       if (verbose)
                ccdbg_add_debug(CC_DEBUG_BITBANG);
 
        if (!tty)
@@ -281,6 +290,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;
 }