Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
authorBdale Garbee <bdale@gag.com>
Sat, 10 Oct 2009 21:05:50 +0000 (15:05 -0600)
committerBdale Garbee <bdale@gag.com>
Sat, 10 Oct 2009 21:05:50 +0000 (15:05 -0600)
ao-tools/ao-dumplog/ao-dumplog.c
ao-tools/ao-postflight/ao-postflight.c
ao-tools/ao-view/Makefile.am
ao-tools/ao-view/aoview.glade
ao-tools/ao-view/aoview.h
ao-tools/ao-view/aoview_channel.c [new file with mode: 0644]
ao-tools/ao-view/aoview_flite.c
ao-tools/ao-view/aoview_main.c
ao-tools/ao-view/aoview_monitor.c
src/ao_usb.c

index b930f0e5769ad4c1f2818663ada6a25df9e560c8..158a445b48978eab213c8c3ec0cdd282aea2baef 100644 (file)
@@ -37,6 +37,30 @@ static void usage(char *program)
        exit(1);
 }
 
+static uint8_t
+log_checksum(int d[8])
+{
+       uint8_t sum = 0x5a;
+       int     i;
+
+       for (i = 0; i < 8; i++)
+               sum += (uint8_t) d[i];
+       return -sum;
+}
+
+static const char *state_names[] = {
+       "startup",
+       "idle",
+       "pad",
+       "boost",
+       "fast",
+       "coast",
+       "drogue",
+       "main",
+       "landed",
+       "invalid"
+};
+
 int
 main (int argc, char **argv)
 {
@@ -50,6 +74,12 @@ main (int argc, char **argv)
        int             serial_number;
        char            cmd;
        int             tick, a, b;
+       int             block;
+       int             addr;
+       int             received_addr;
+       int             data[8];
+       int             done;
+       int             column;
 
        while ((c = getopt_long(argc, argv, "T:D:", options, NULL)) != -1) {
                switch (c) {
@@ -74,12 +104,10 @@ main (int argc, char **argv)
        if (!cc)
                exit(1);
        /* send a 'version' command followed by a 'log' command */
-       cc_usb_printf(cc, "v\nl\n");
+       cc_usb_printf(cc, "v\n");
        out = NULL;
        for (;;) {
                cc_usb_getline(cc, line, sizeof (line));
-               if (!strcmp (line, "end"))
-                       break;
                if (sscanf(line, "serial-number %u", &serial_number) == 1) {
                        filename = cc_make_filename(serial_number, "eeprom");
                        out = fopen (filename, "w");
@@ -87,16 +115,65 @@ main (int argc, char **argv)
                                perror(filename);
                        }
                        fprintf (out, "%s\n", line);
-               } else if (sscanf(line, "%c %x %x %x", &cmd, &tick, &a, &b) == 4) {
-                       if (out) {
-                               fprintf(out, "%s\n", line);
-                               if (cmd == 'S' && a == 8) {
-                                       fclose(out);
-                                       out = NULL;
+               }
+               if (!strncmp(line, "software-version", 16))
+                       break;
+       }
+       if (!out) {
+               fprintf(stderr, "no serial number found\n");
+               cc_usb_close(cc);
+               exit(1);
+       }
+       printf ("Serial number: %d\n", serial_number);
+       printf ("File name:     %s\n", filename);
+       done = 0;
+       column = 0;
+       for (block = 0; !done && block < 511; block++) {
+               cc_usb_printf(cc, "e %x\n", block);
+               if (column == 64) {
+                       putchar('\n');
+                       column = 0;
+               }
+               putchar('.'); fflush(stdout); column++;
+               for (addr = 0; addr < 0x100;) {
+                       cc_usb_getline(cc, line, sizeof (line));
+                       if (sscanf(line, "00%x %x %x %x %x %x %x %x %x",
+                                         &received_addr,
+                                         &data[0], &data[1], &data[2], &data[3],
+                                         &data[4], &data[5], &data[6], &data[7]) == 9)
+                       {
+                               if (received_addr != addr)
+                                       fprintf(stderr, "data out of sync at 0x%x\n",
+                                               block * 256 + received_addr);
+
+                               if (log_checksum(data) != 0)
+                                       fprintf (stderr, "invalid checksum at 0x%x\n",
+                                                block * 256 + received_addr);
+
+                               cmd = data[0];
+                               tick = data[2] + (data[3] << 8);
+                               a = data[4] + (data[5] << 8);
+                               b = data[6] + (data[7] << 8);
+                               if (cmd == 'S' && a <= 8) {
+                                       if (column) putchar('\n');
+                                       printf("%s\n", state_names[a]);
+                                       column = 0;
+                               }
+                               if (out) {
+                                       fprintf(out, "%c %4x %4x %4x\n",
+                                               cmd, tick, a, b);
+                                       if (cmd == 'S' && a == 8) {
+                                               fclose(out);
+                                               out = NULL;
+                                               done = 1;
+                                       }
                                }
+                               addr += 8;
                        }
                }
        }
+       if (column)
+               putchar('\n');
        if (out)
                fclose (out);
        cc_usb_close(cc);
index 6418521e39c8a47117a88b920b6f6fca493e469e..cc9f64b484f92d6ea8ae3b7a9c2299001d1a9a09 100644 (file)
@@ -313,14 +313,30 @@ analyse_flight(struct cc_flightraw *f, FILE *summary_file, FILE *detail_file, FI
                }
        }
        if (gps_file) {
+               int     j = 0;
                fprintf(gps_file, "%9s %12s %12s %12s\n",
                        "time", "lat", "lon", "alt");
                for (i = 0; i < f->gps.num; i++) {
-                       fprintf(gps_file, "%12.7f %12.7f %12.7f %12.7f\n",
+                       int     nsat = 0;
+                       int     k;
+                       while (j < f->gps.numsats - 1) {
+                               if (f->gps.sats[j].sat[0].time <= f->gps.data[i].time &&
+                                   f->gps.data[i].time < f->gps.sats[j+1].sat[0].time)
+                                       break;
+                               j++;
+                       }
+                       fprintf(gps_file, "%12.7f %12.7f %12.7f %12.7f",
                                (f->gps.data[i].time - boost_start) / 100.0,
                                f->gps.data[i].lat,
                                f->gps.data[i].lon,
                                f->gps.data[i].alt);
+                       nsat = 0;
+                       for (k = 0; k < f->gps.sats[j].nsat; k++) {
+                               fprintf (gps_file, " %12.7f", (double) f->gps.sats[j].sat[k].c_n);
+                               if (f->gps.sats[j].sat[k].state == 0xbf)
+                                       nsat++;
+                       }
+                       fprintf(gps_file, " %d\n", nsat);
                }
        }
        if (cooked && plot_name) {
index 7b274a40484e6e94f51624ef7a4c6a93273bc7cc..7a288417b10f161d874a607fc2764191e40c25a7 100644 (file)
@@ -25,6 +25,7 @@ ao_view_SOURCES = \
        aoview_replay.c \
        aoview_label.c \
        aoview_flite.c \
+       aoview_channel.c \
        aoview.h
 
 BUILT_SOURCES = aoview_glade.h
index 9a7461108af227c299ed86860d017ce00521e328..c302ad0db1be69a3a34b4cd86720324a2c0ef2c8 100644 (file)
                 </child>
               </widget>
             </child>
+            <child>
+              <widget class="GtkMenuItem" id="channel_menu_item">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">_Channel</property>
+                <property name="use_underline">True</property>
+                <child>
+                  <widget class="GtkMenu" id="menu7">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkRadioMenuItem" id="channel_0">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Channel 0 (434.550MHz)</property>
+                        <property name="use_underline">True</property>
+                        <property name="draw_as_radio">True</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkRadioMenuItem" id="channel_1">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Channel 1 (434.650MHz)</property>
+                        <property name="use_underline">True</property>
+                        <property name="draw_as_radio">True</property>
+                        <property name="group">channel_0</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkRadioMenuItem" id="channel_2">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Channel 2 (434.750MHz)</property>
+                        <property name="use_underline">True</property>
+                        <property name="draw_as_radio">True</property>
+                        <property name="group">channel_0</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkRadioMenuItem" id="channel_3">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Channel 3 (434.850MHz)</property>
+                        <property name="use_underline">True</property>
+                        <property name="draw_as_radio">True</property>
+                        <property name="group">channel_0</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkRadioMenuItem" id="channel_4">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Channel 4 (434.950MHz)</property>
+                        <property name="use_underline">True</property>
+                        <property name="draw_as_radio">True</property>
+                        <property name="group">channel_0</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkRadioMenuItem" id="channel_5">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Channel 5 (435.050MHz)</property>
+                        <property name="use_underline">True</property>
+                        <property name="draw_as_radio">True</property>
+                        <property name="group">channel_0</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkRadioMenuItem" id="channel_6">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Channel 6 (435.150MHz)</property>
+                        <property name="use_underline">True</property>
+                        <property name="draw_as_radio">True</property>
+                        <property name="group">channel_0</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkRadioMenuItem" id="channel_7">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Channel 7 (435.250MHz)</property>
+                        <property name="use_underline">True</property>
+                        <property name="draw_as_radio">True</property>
+                        <property name="group">channel_0</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkRadioMenuItem" id="channel_8">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Channel 8 (435.350MHz)</property>
+                        <property name="use_underline">True</property>
+                        <property name="draw_as_radio">True</property>
+                        <property name="group">channel_0</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkRadioMenuItem" id="channel_9">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Channel 9 (435.450MHz)</property>
+                        <property name="use_underline">True</property>
+                        <property name="draw_as_radio">True</property>
+                        <property name="group">channel_0</property>
+                      </widget>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+            </child>
             <child>
               <widget class="GtkMenuItem" id="menuitem4">
                 <property name="visible">True</property>
index 6a4753acb761a8590fdb87c0b1cee5bbeefb1725..c582159c86001c9a016cd169b29b3685ce46476a 100644 (file)
@@ -168,6 +168,9 @@ aoview_monitor_connect(char *tty);
 gboolean
 aoview_monitor_parse(const char *line);
 
+void
+aoview_monitor_set_channel(int channel);
+
 void
 aoview_monitor_reset(void);
 
@@ -320,4 +323,12 @@ aoview_flite_stop(void);
 
 extern char *aoview_tty;
 
+/* aoview_channel.c */
+
+int
+aoview_channel_current(void);
+
+void
+aoview_channel_init(GladeXML *xml);
+
 #endif /* _AOVIEW_H_ */
diff --git a/ao-tools/ao-view/aoview_channel.c b/ao-tools/ao-view/aoview_channel.c
new file mode 100644 (file)
index 0000000..959173c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * 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.
+ *
+ * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+
+#define NUM_CHANNEL    10
+
+static GtkRadioMenuItem *channel_item[NUM_CHANNEL];
+
+int
+aoview_channel_current(void)
+{
+       int     c;
+
+       for (c = 0; c < NUM_CHANNEL; c++)
+               if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(channel_item[c])))
+                       return c;
+       return -1;
+}
+
+static void
+aoview_channel_notify(int channel)
+{
+       if (0 <= channel && channel < NUM_CHANNEL)
+               gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(channel_item[channel]), TRUE);
+}
+
+#define ALTOS_CHANNEL_PATH     "/apps/aoview/channel"
+
+static void
+aoview_channel_change(GtkWidget *widget, gpointer data)
+{
+       gboolean        enabled = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+       int             c = (int) data;
+       GConfClient     *gconf_client;
+       GError          *error;
+
+       if (enabled) {
+               aoview_monitor_set_channel(c);
+               gconf_client = gconf_client_get_default();
+               gconf_client_set_int(gconf_client, ALTOS_CHANNEL_PATH, c, &error);
+       }
+}
+
+void
+aoview_channel_init(GladeXML *xml)
+{
+       int     c;
+       GConfClient     *gconf_client;
+
+       for (c = 0; c < NUM_CHANNEL; c++) {
+               char    name[32];
+
+               sprintf(name, "channel_%d", c);
+               channel_item[c] = GTK_RADIO_MENU_ITEM(glade_xml_get_widget(xml, name));
+               assert(channel_item[c]);
+               g_signal_connect(G_OBJECT(channel_item[c]), "toggled",
+                                G_CALLBACK(aoview_channel_change),
+                                (gpointer) c);
+       }
+       gconf_client = gconf_client_get_default();
+       c = 0;
+       if (gconf_client)
+       {
+               GError  *error;
+
+               error = NULL;
+               c = gconf_client_get_int(gconf_client,
+                                        ALTOS_CHANNEL_PATH,
+                                        &error);
+               if (error)
+                       c = 0;
+       }
+       aoview_channel_notify(c);
+}
index e1b758983d171211d5ee9ade5ec578e7dfa02575..bc702b0f4cd29275810a574636176378c9ac4a0a 100644 (file)
@@ -42,12 +42,10 @@ aoview_flite_task(gpointer data)
 
        err = snd_pcm_open(&alsa_handle, "default",
                           SND_PCM_STREAM_PLAYBACK, 0);
-       if (err >= 0)
-       {
-               if (err < 0) {
-                       snd_pcm_close(alsa_handle);
-                       alsa_handle = 0;
-               }
+       if (err < 0) {
+               fprintf(stderr, "alsa open failed %s\n",
+                       strerror(-err));
+               alsa_handle = NULL;
        }
        rate = 0;
        channels = 0;
index 64c1c0273a90c2c5e857af4b53d5fa07077a41db..714bee9a2677924c8369cf79540b3bcea9c81edd 100644 (file)
@@ -86,6 +86,8 @@ int main(int argc, char **argv)
 
        aoview_voice_init(xml);
 
+       aoview_channel_init(xml);
+
        aoview_dev_dialog_init(xml);
 
        aoview_state_init(xml);
index 8564014b31c7a9f7e4703891d526aab721f7450d..48e203209f51db2ec4c79e57bfe98fc2f48b309b 100644 (file)
@@ -82,6 +82,7 @@ aoview_monitor_parse(const char *input_line)
        char line_buf[8192], *line;
        struct aodata   data;
        int     tracking_pos;
+       int channel;
 
        /* avoid smashing our input parameter */
        strncpy (line_buf, input_line, sizeof (line_buf)-1);
@@ -214,15 +215,26 @@ aoview_monitor_callback(gpointer user_data,
        }
 }
 
+void
+aoview_monitor_set_channel(int channel)
+{
+       if (monitor_serial)
+               aoview_serial_printf(monitor_serial, "c r %d\n", channel);
+}
+
 gboolean
 aoview_monitor_connect(char *tty)
 {
+       int     channel;
        aoview_monitor_disconnect();
        monitor_serial = aoview_serial_open(tty);
        if (!monitor_serial)
                return FALSE;
        aoview_table_clear();
        aoview_state_reset();
+       channel = aoview_channel_current();
+       if (channel >= 0)
+               aoview_monitor_set_channel(channel);
        aoview_serial_set_callback(monitor_serial,
                                   aoview_monitor_callback);
        return TRUE;
index 99f0715bb9536f658b8fd60c7567fcdec5b9e28b..2266572541c820b661897b22b3a6530152b71fa9 100644 (file)
@@ -21,6 +21,7 @@
 struct ao_task __xdata ao_usb_task;
 
 static __xdata uint16_t        ao_usb_in_bytes;
+static __xdata uint16_t ao_usb_in_bytes_last;
 static __xdata uint16_t        ao_usb_out_bytes;
 static __xdata uint8_t ao_usb_iif;
 static __xdata uint8_t ao_usb_running;
@@ -321,13 +322,40 @@ ao_usb_ep0(void)
        }
 }
 
+/* Wait for a free IN buffer */
+static void
+ao_usb_in_wait(void)
+{
+       for (;;) {
+               USBINDEX = AO_USB_IN_EP;
+               if ((USBCSIL & USBCSIL_INPKT_RDY) == 0)
+                       break;
+               ao_sleep(&ao_usb_in_bytes);
+       }
+}
+
+/* Send the current IN packet */
+static void
+ao_usb_in_send(void)
+{
+       USBINDEX = AO_USB_IN_EP;
+       USBCSIL |= USBCSIL_INPKT_RDY;
+       ao_usb_in_bytes_last = ao_usb_in_bytes;
+       ao_usb_in_bytes = 0;
+}
+
 void
 ao_usb_flush(void) __critical
 {
-       if (ao_usb_in_bytes) {
-               USBINDEX = AO_USB_IN_EP;
-               USBCSIL |= USBCSIL_INPKT_RDY;
-               ao_usb_in_bytes = 0;
+       if (!ao_usb_running)
+               return;
+
+       /* If there are pending bytes, or if the last packet was full,
+        * send another IN packet
+        */
+       if (ao_usb_in_bytes || (ao_usb_in_bytes_last == AO_USB_IN_SIZE)) {
+               ao_usb_in_wait();
+               ao_usb_in_send();
        }
 }
 
@@ -336,18 +364,13 @@ ao_usb_putchar(char c) __critical
 {
        if (!ao_usb_running)
                return;
-       for (;;) {
-               USBINDEX = AO_USB_IN_EP;
-               if ((USBCSIL & USBCSIL_INPKT_RDY) == 0)
-                       break;
-               ao_sleep(&ao_usb_in_bytes);
-       }
+
+       ao_usb_in_wait();
+
+       /* Queue a byte, sending the packet when full */
        USBFIFO[AO_USB_IN_EP << 1] = c;
-       if (++ao_usb_in_bytes == AO_USB_IN_SIZE) {
-               USBINDEX = AO_USB_IN_EP;
-               USBCSIL |= USBCSIL_INPKT_RDY;
-               ao_usb_in_bytes = 0;
-       }
+       if (++ao_usb_in_bytes == AO_USB_IN_SIZE)
+               ao_usb_in_send();
 }
 
 char