Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos 0.5
authorBdale Garbee <bdale@gag.com>
Wed, 19 Aug 2009 06:49:24 +0000 (00:49 -0600)
committerBdale Garbee <bdale@gag.com>
Wed, 19 Aug 2009 06:49:24 +0000 (00:49 -0600)
15 files changed:
ao-view/aoview.glade
ao-view/aoview.h
ao-view/aoview_monitor.c
ao-view/aoview_state.c
ao-view/aoview_table.c
src/Makefile
src/ao.h
src/ao_dbg.c
src/ao_gps.c
src/ao_gps_print.c
src/ao_gps_report.c
src/ao_gps_test.c
src/ao_host.h
src/ao_monitor.c
src/ao_telemetry.c

index 3481a7798996367616bb7ad879014b0de0f999e2..9a7461108af227c299ed86860d017ce00521e328 100644 (file)
@@ -3,7 +3,7 @@
   <!-- interface-requires gtk+ 2.16 -->
   <!-- interface-naming-policy project-wide -->
   <widget class="GtkWindow" id="aoview">
-    <property name="width_request">550</property>
+    <property name="width_request">900</property>
     <property name="height_request">700</property>
     <property name="visible">True</property>
     <property name="title" translatable="yes">AltOS View</property>
                 <property name="position">1</property>
               </packing>
             </child>
+            <child>
+              <widget class="GtkTreeView" id="dataview_2">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="show_expanders">False</property>
+                <property name="enable_grid_lines">both</property>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
           </widget>
           <packing>
             <property name="position">2</property>
             <property name="layout_style">end</property>
             <child>
               <widget class="GtkButton" id="cancel_button">
-                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="label">gtk-cancel</property>
                 <property name="response_id">1</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
             </child>
             <child>
               <widget class="GtkButton" id="connect_button">
-                <property name="label" translatable="yes">gtk-connect</property>
+                <property name="label">gtk-connect</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
             <property name="layout_style">end</property>
             <child>
               <widget class="GtkButton" id="file_configure_cancel">
-                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="label">gtk-cancel</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
             </child>
             <child>
               <widget class="GtkButton" id="file_configure_ok">
-                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="label">gtk-ok</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
@@ -693,7 +704,7 @@ You should have received a copy of the GNU General Public License along with AoV
             <property name="layout_style">end</property>
             <child>
               <widget class="GtkButton" id="ao_replay_cancel">
-                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="label">gtk-cancel</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -708,7 +719,7 @@ You should have received a copy of the GNU General Public License along with AoV
             </child>
             <child>
               <widget class="GtkButton" id="ao_replay_ok">
-                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="label">gtk-ok</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
index e8334e5b2693388117036e8ddca79f6f206626ae..9ca65298b7a75839a6c3c2807cb4b1edefe4ad5f 100644 (file)
@@ -75,6 +75,26 @@ struct aogps {
        int     v_error;        /* m */
 };
 
+#define SIRF_SAT_STATE_ACQUIRED                        (1 << 0)
+#define SIRF_SAT_STATE_CARRIER_PHASE_VALID     (1 << 1)
+#define SIRF_SAT_BIT_SYNC_COMPLETE             (1 << 2)
+#define SIRF_SAT_SUBFRAME_SYNC_COMPLETE                (1 << 3)
+#define SIRF_SAT_CARRIER_PULLIN_COMPLETE       (1 << 4)
+#define SIRF_SAT_CODE_LOCKED                   (1 << 5)
+#define SIRF_SAT_ACQUISITION_FAILED            (1 << 6)
+#define SIRF_SAT_EPHEMERIS_AVAILABLE           (1 << 7)
+
+struct aogps_sat {
+       int     svid;
+       int     state;
+       int     c_n0;
+};
+
+struct aogps_tracking {
+       int                     channels;
+       struct aogps_sat        sats[12];
+};
+
 struct aodata {
        char    callsign[16];
        int     serial;
@@ -93,6 +113,7 @@ struct aodata {
        int     flight_pres;
        int     ground_pres;
        struct aogps    gps;
+       struct aogps_tracking   gps_tracking;
 };
 
 struct aostate {
@@ -121,6 +142,7 @@ struct aostate {
        double  max_speed;
 
        struct aogps    gps;
+       struct aogps_tracking   gps_tracking;
 
        int     gps_valid;
        double  pad_lat;
index 9265a1992ac439294dbec034e1b0b2ca0a204b84..1f4c8f728100f9627d2ddf735fcc96a1dc81c971 100644 (file)
@@ -47,6 +47,12 @@ aoview_parse_int(int *target, char *source)
        *target = strtol(source, NULL, 0);
 }
 
+static void
+aoview_parse_hex(int *target, char *source)
+{
+       *target = strtol(source, NULL, 16);
+}
+
 static void
 aoview_parse_pos(double *target, char *source)
 {
@@ -65,20 +71,23 @@ aoview_parse_pos(double *target, char *source)
        *target = r;
 }
 
+#define PARSE_MAX_WORDS        256
+
 gboolean
 aoview_monitor_parse(const char *input_line)
 {
        char *saveptr;
-       char *words[64];
+       char *words[PARSE_MAX_WORDS];
        int nword;
        char line_buf[8192], *line;
        struct aodata   data;
+       int     tracking_pos;
 
        /* avoid smashing our input parameter */
        strncpy (line_buf, input_line, sizeof (line_buf)-1);
        line_buf[sizeof(line_buf) - 1] = '\0';
        line = line_buf;
-       for (nword = 0; nword < 64; nword++) {
+       for (nword = 0; nword < PARSE_MAX_WORDS; nword++) {
                words[nword] = strtok_r(line, " \t\n", &saveptr);
                line = NULL;
                if (words[nword] == NULL)
@@ -112,6 +121,7 @@ aoview_monitor_parse(const char *input_line)
                data.gps.gps_time.hour = data.gps.gps_time.minute = data.gps.gps_time.second = 0;
                data.gps.lat = data.gps.lon = 0;
                data.gps.alt = 0;
+               tracking_pos = 37;
        } else if (nword >= 40) {
                data.gps.gps_locked = 1;
                data.gps.gps_connected = 1;
@@ -119,6 +129,7 @@ aoview_monitor_parse(const char *input_line)
                aoview_parse_pos(&data.gps.lat, words[37]);
                aoview_parse_pos(&data.gps.lon, words[38]);
                sscanf(words[39], "%dm", &data.gps.alt);
+               tracking_pos = 46;
        } else {
                data.gps.gps_connected = 0;
                data.gps.gps_locked = 0;
@@ -143,6 +154,25 @@ aoview_monitor_parse(const char *input_line)
                data.gps.h_error = 0;
                data.gps.v_error = 0;
        }
+       if (nword >= tracking_pos + 2 && strcmp(words[tracking_pos], "SAT") == 0) {
+               int     c, n, pos;
+               aoview_parse_int(&n, words[tracking_pos + 1]);
+               pos = tracking_pos + 2;
+               if (nword >= pos + n * 3) {
+                       data.gps_tracking.channels = n;
+                       for (c = 0; c < n; c++) {
+                               aoview_parse_int(&data.gps_tracking.sats[c].svid,
+                                                words[pos + 0]);
+                               aoview_parse_hex(&data.gps_tracking.sats[c].state,
+                                                words[pos + 1]);
+                               aoview_parse_int(&data.gps_tracking.sats[c].c_n0,
+                                                words[pos + 2]);
+                               pos += 3;
+                       }
+               } else {
+                       data.gps_tracking.channels = 0;
+               }
+       }
        aoview_state_notify(&data);
        return TRUE;
 }
index 7efd33b0ebf5a62942a00a88e520c96c9b8d18f4..f75066dde24d64b5100f2d7d00481e660d9a4d82 100644 (file)
@@ -168,6 +168,8 @@ aoview_state_derive(struct aodata *data, struct aostate *state)
                        aoview_great_circle(state->pad_lat, state->pad_lon, state->gps.lat, state->gps.lon,
                                            &state->distance, &state->bearing);
        }
+       if (data->gps_tracking.channels)
+               state->gps_tracking = data->gps_tracking;
        if (state->npad) {
                state->gps_height = state->gps.alt - state->pad_alt;
        } else {
@@ -308,6 +310,7 @@ aoview_state_notify(struct aodata *data)
        if (state->gps_valid) {
                aoview_state_add_deg(1, "Latitude", state->gps.lat, 'N', 'S');
                aoview_state_add_deg(1, "Longitude", state->gps.lon, 'E', 'W');
+               aoview_table_add_row(1, "GPS altitude", "%d", state->gps.alt);
                aoview_table_add_row(1, "GPS height", "%d", state->gps_height);
                aoview_table_add_row(1, "GPS time", "%02d:%02d:%02d",
                                     state->gps.gps_time.hour,
@@ -330,6 +333,27 @@ aoview_state_notify(struct aodata *data)
                aoview_state_add_deg(1, "Pad longitude", state->pad_lon, 'E', 'W');
                aoview_table_add_row(1, "Pad GPS alt", "%gm", state->pad_alt);
        }
+       if (state->gps.gps_connected) {
+               int     nsat_vis = 0;
+               int     nsat_locked = 0;
+               int     c;
+
+               for (c = 0; c < state->gps_tracking.channels; c++) {
+                       if ((state->gps_tracking.sats[c].state & 0xff) == 0xbf)
+                               nsat_locked++;
+               }
+               aoview_table_add_row(2, "Satellites Visible", "%d", state->gps_tracking.channels);
+               aoview_table_add_row(2, "Satellites Locked", "%d", nsat_locked);
+               for (c = 0; c < state->gps_tracking.channels; c++) {
+                       aoview_table_add_row(2, "Satellite id,state,C/N0",
+                                            "%3d,%02x,%2d%s",
+                                            state->gps_tracking.sats[c].svid,
+                                            state->gps_tracking.sats[c].state,
+                                            state->gps_tracking.sats[c].c_n0,
+                                            (state->gps_tracking.sats[c].state & 0xff) == 0xbf ?
+                                            " LOCKED" : "");
+               }
+       }
        aoview_table_finish();
        aoview_label_show(state);
        aoview_speak_state(state);
index 931430096590a8d9f8337af717da980a11b5199a..e75ae670c8037c90520b121e8e0fd3d6363f7330 100644 (file)
@@ -17,7 +17,7 @@
 
 #include "aoview.h"
 
-#define NCOL   2
+#define NCOL   3
 
 static GtkTreeView     *dataview[NCOL];
 static GtkListStore    *datalist[NCOL];
index 5a8afe0b9a5859a55abd80e313973d307d06eefd..96049c65f11af939d736518695badd6554b4ec90 100644 (file)
@@ -262,8 +262,8 @@ clean:
 
 install:
 
-ao_flight_test: ao_flight.c ao_flight_test.c
+ao_flight_test: ao_flight.c ao_flight_test.c ao_host.h
        cc -g -o $@ ao_flight_test.c
 
-ao_gps_test: ao_gps.c ao_gps_test.c ao_host.h
+ao_gps_test: ao_gps.c ao_gps_test.c ao_gps_print.c ao_host.h
        cc -g -o $@ ao_gps_test.c
index 85b7825f759fdd73fd3473250933aaee92fa5200..27ec010f68cd6ac42bb42822ee7496d59ee5a878 100644 (file)
--- a/src/ao.h
+++ b/src/ao.h
@@ -458,6 +458,7 @@ ao_ee_init(void);
 #define AO_LOG_GPS_LAT         'N'
 #define AO_LOG_GPS_LON         'W'
 #define AO_LOG_GPS_ALT         'H'
+#define AO_LOG_GPS_SAT         'V'
 
 #define AO_LOG_POS_NONE                (~0UL)
 
@@ -498,6 +499,12 @@ struct ao_log_record {
                        int16_t         altitude;
                        uint16_t        unused;
                } gps_altitude;
+               struct {
+                       uint16_t        svid;
+                       uint8_t         state;
+                       uint8_t         c_n;
+                       uint8_t         unused;
+               } gps_sat;
                struct {
                        uint16_t        d0;
                        uint16_t        d1;
@@ -696,8 +703,29 @@ struct ao_gps_data {
        uint16_t                v_error;        /* m */
 };
 
+#define SIRF_SAT_STATE_ACQUIRED                        (1 << 0)
+#define SIRF_SAT_STATE_CARRIER_PHASE_VALID     (1 << 1)
+#define SIRF_SAT_BIT_SYNC_COMPLETE             (1 << 2)
+#define SIRF_SAT_SUBFRAME_SYNC_COMPLETE                (1 << 3)
+#define SIRF_SAT_CARRIER_PULLIN_COMPLETE       (1 << 4)
+#define SIRF_SAT_CODE_LOCKED                   (1 << 5)
+#define SIRF_SAT_ACQUISITION_FAILED            (1 << 6)
+#define SIRF_SAT_EPHEMERIS_AVAILABLE           (1 << 7)
+
+struct ao_gps_sat_data {
+       uint8_t         svid;
+       uint8_t         state;
+       uint8_t         c_n_1;
+};
+
+struct ao_gps_tracking_data {
+       uint8_t                 channels;
+       struct ao_gps_sat_data  sats[12];
+};
+
 extern __xdata uint8_t ao_gps_mutex;
 extern __xdata struct ao_gps_data ao_gps_data;
+extern __xdata struct ao_gps_tracking_data ao_gps_tracking_data;
 
 void
 ao_gps(void);
@@ -705,6 +733,9 @@ ao_gps(void);
 void
 ao_gps_print(__xdata struct ao_gps_data *gps_data);
 
+void
+ao_gps_tracking_print(__xdata struct ao_gps_tracking_data *gps_tracking_data);
+
 void
 ao_gps_init(void);
 
@@ -735,6 +766,7 @@ struct ao_telemetry {
        struct ao_adc           adc;
        struct ao_gps_data      gps;
        char                    callsign[AO_MAX_CALLSIGN];
+       struct ao_gps_tracking_data     gps_tracking;
 };
 
 /* Set delay between telemetry reports (0 to disable) */
index c8dc6ddcc0c867dc9aad10c2875fc6ad89fbfd9b..b218897c627fd7664aa041a394e14243a553ec95 100644 (file)
@@ -26,7 +26,7 @@
 #define DBG_RESET_N_PIN        (P0_5)
 
 static void
-ao_dbg_send_bits(uint8_t msk, uint8_t val)
+ao_dbg_send_bits(uint8_t msk, uint8_t val) __reentrant
 {
        P0 = (P0 & ~msk) | (val & msk);
        _asm
index c4c434fdba41885384d2ffa8fbf638b42018f3d8..7d68b325c77ccfbe3b8ed97d0fcf39b2646dcc13 100644 (file)
@@ -21,6 +21,7 @@
 
 __xdata uint8_t ao_gps_mutex;
 __xdata struct ao_gps_data     ao_gps_data;
+__xdata struct ao_gps_tracking_data    ao_gps_tracking_data;
 
 static const char ao_gps_set_nmea[] = "\r\n$PSRF100,0,57600,8,1,0*37\r\n";
 
@@ -105,6 +106,21 @@ struct sirf_geodetic_nav_data {
 
 static __xdata struct sirf_geodetic_nav_data   ao_sirf_data;
 
+struct sirf_measured_sat_data {
+       uint8_t         svid;
+       uint16_t        state;
+       uint8_t         c_n_1;
+};
+
+struct sirf_measured_tracker_data {
+       int16_t                         gps_week;
+       uint32_t                        gps_tow;
+       uint8_t                         channels;
+       struct sirf_measured_sat_data   sats[12];
+};
+
+static __xdata struct sirf_measured_tracker_data       ao_sirf_tracker_data;
+
 static __pdata uint16_t ao_sirf_cksum;
 static __pdata uint16_t ao_sirf_len;
 
@@ -118,9 +134,11 @@ static uint8_t data_byte(void)
        return c;
 }
 
+static char __xdata *sirf_target;
+
 static void sirf_u16(uint8_t offset)
 {
-       uint16_t __xdata *ptr = (uint16_t __xdata *) (((char __xdata *) &ao_sirf_data) + offset);
+       uint16_t __xdata *ptr = (uint16_t __xdata *) (sirf_target + offset);
        uint16_t val;
 
        val = data_byte() << 8;
@@ -130,16 +148,16 @@ static void sirf_u16(uint8_t offset)
 
 static void sirf_u8(uint8_t offset)
 {
-       uint8_t __xdata *ptr = (uint8_t __xdata *) (((char __xdata *) &ao_sirf_data) + offset);
+       uint8_t __xdata *ptr = (uint8_t __xdata *) (sirf_target + offset);
        uint8_t val;
 
        val = data_byte ();
        *ptr = val;
 }
 
-static void sirf_u32(uint8_t offset)
+static void sirf_u32(uint8_t offset) __reentrant
 {
-       uint32_t __xdata *ptr = (uint32_t __xdata *) (((char __xdata *) &ao_sirf_data) + offset);
+       uint32_t __xdata *ptr = (uint32_t __xdata *) (sirf_target + offset);
        uint32_t val;
 
        val = ((uint32_t) data_byte ()) << 24;
@@ -160,12 +178,44 @@ static void sirf_discard(uint8_t len)
 #define SIRF_U8                2
 #define SIRF_U16       3
 #define SIRF_U32       4
+#define SIRF_U8X10     5
 
 struct sirf_packet_parse {
        uint8_t type;
        uint8_t offset;
 };
 
+static void
+ao_sirf_parse(void __xdata *target, const struct sirf_packet_parse *parse) __reentrant
+{
+       uint8_t i, offset, j;
+
+       sirf_target = target;
+       for (i = 0; ; i++) {
+               offset = parse[i].offset;
+               switch (parse[i].type) {
+               case SIRF_END:
+                       return;
+               case SIRF_DISCARD:
+                       sirf_discard(offset);
+                       break;
+               case SIRF_U8:
+                       sirf_u8(offset);
+                       break;
+               case SIRF_U16:
+                       sirf_u16(offset);
+                       break;
+               case SIRF_U32:
+                       sirf_u32(offset);
+                       break;
+               case SIRF_U8X10:
+                       for (j = 10; j--;)
+                               sirf_u8(offset++);
+                       break;
+               }
+       }
+}
+
 static const struct sirf_packet_parse geodetic_nav_data_packet[] = {
        { SIRF_DISCARD, 2 },                                                    /* 1 nav valid */
        { SIRF_U16, offsetof(struct sirf_geodetic_nav_data, nav_type) },        /* 3 */
@@ -200,29 +250,34 @@ static const struct sirf_packet_parse geodetic_nav_data_packet[] = {
 };
 
 static void
-ao_sirf_parse_41(void)
+ao_sirf_parse_41(void) __reentrant
 {
-       uint8_t i, offset;
+       ao_sirf_parse(&ao_sirf_data, geodetic_nav_data_packet);
+}
 
-       for (i = 0; ; i++) {
-               offset = geodetic_nav_data_packet[i].offset;
-               switch (geodetic_nav_data_packet[i].type) {
-               case SIRF_END:
-                       return;
-               case SIRF_DISCARD:
-                       sirf_discard(offset);
-                       break;
-               case SIRF_U8:
-                       sirf_u8(offset);
-                       break;
-               case SIRF_U16:
-                       sirf_u16(offset);
-                       break;
-               case SIRF_U32:
-                       sirf_u32(offset);
-                       break;
-               }
-       }
+static const struct sirf_packet_parse measured_tracker_data_packet[] = {
+       { SIRF_U16, offsetof (struct sirf_measured_tracker_data, gps_week) },   /* 1 week */
+       { SIRF_U32, offsetof (struct sirf_measured_tracker_data, gps_tow) },    /* 3 time of week */
+       { SIRF_U8, offsetof (struct sirf_measured_tracker_data, channels) },    /* 7 channels */
+       { SIRF_END, 0 },
+};
+
+static const struct sirf_packet_parse measured_sat_data_packet[] = {
+       { SIRF_U8, offsetof (struct sirf_measured_sat_data, svid) },            /* 0 SV id */
+       { SIRF_DISCARD, 2 },                                                    /* 1 azimuth, 2 elevation */
+       { SIRF_U16, offsetof (struct sirf_measured_sat_data, state) },          /* 2 state */
+       { SIRF_U8, offsetof (struct sirf_measured_sat_data, c_n_1) },           /* C/N0 1 */
+       { SIRF_DISCARD, 9 },                                                    /* C/N0 2-10 */
+       { SIRF_END, 0 },
+};
+
+static void
+ao_sirf_parse_4(void) __reentrant
+{
+       uint8_t i;
+       ao_sirf_parse(&ao_sirf_tracker_data, measured_tracker_data_packet);
+       for (i = 0; i < 12; i++)
+               ao_sirf_parse(&ao_sirf_tracker_data.sats[i], measured_sat_data_packet);
 }
 
 static void
@@ -267,7 +322,6 @@ ao_sirf_set_message_rate(uint8_t msg, uint8_t rate)
 
 static const uint8_t sirf_disable[] = {
        2,
-       4,
        9,
        10,
        27,
@@ -289,6 +343,7 @@ ao_gps(void) __reentrant
                for (i = 0; i < sizeof (sirf_disable); i++)
                        ao_sirf_set_message_rate(sirf_disable[i], 0);
                ao_sirf_set_message_rate(41, 1);
+               ao_sirf_set_message_rate(4, 1);
        }
        for (;;) {
                /* Locate the begining of the next record */
@@ -314,6 +369,11 @@ ao_gps(void) __reentrant
                                break;
                        ao_sirf_parse_41();
                        break;
+               case 4:
+                       if (ao_sirf_len < 187)
+                               break;
+                       ao_sirf_parse_4();
+                       break;
                }
                if (ao_sirf_len != 0)
                        continue;
@@ -356,6 +416,17 @@ ao_gps(void) __reentrant
                        ao_mutex_put(&ao_gps_mutex);
                        ao_wakeup(&ao_gps_data);
                        break;
+               case 4:
+                       ao_mutex_get(&ao_gps_mutex);
+                       ao_gps_tracking_data.channels = ao_sirf_tracker_data.channels;
+                       for (i = 0; i < 12; i++) {
+                               ao_gps_tracking_data.sats[i].svid = ao_sirf_tracker_data.sats[i].svid;
+                               ao_gps_tracking_data.sats[i].state = (uint8_t) ao_sirf_tracker_data.sats[i].state;
+                               ao_gps_tracking_data.sats[i].c_n_1 = ao_sirf_tracker_data.sats[i].c_n_1;
+                       }
+                       ao_mutex_put(&ao_gps_mutex);
+                       ao_wakeup(&ao_gps_tracking_data);
+                       break;
                }
        }
 }
@@ -367,6 +438,9 @@ gps_dump(void) __reentrant
 {
        ao_mutex_get(&ao_gps_mutex);
        ao_gps_print(&ao_gps_data);
+       putchar('\n');
+       ao_gps_tracking_print(&ao_gps_tracking_data);
+       putchar('\n');
        ao_mutex_put(&ao_gps_mutex);
 }
 
index 8cc07c85790e5264d49bb695090cb6c66bb5af71..cc75133728884550d1e092c8992ecfb6527cbb00 100644 (file)
@@ -82,14 +82,44 @@ ao_gps_print(__xdata struct ao_gps_data *gps_data) __reentrant
                       gps_data->course * 2,
                       climb / 100,
                       climb % 100);
-               printf(" %d.%d(hdop) %5u(herr) %5u(verr)\n",
+               printf(" %d.%d(hdop) %5u(herr) %5u(verr)",
                       gps_data->hdop / 5,
                       (gps_data->hdop * 2) % 10,
                       gps_data->h_error,
                       gps_data->v_error);
        } else if (gps_data->flags & AO_GPS_RUNNING) {
-               printf(" unlocked\n");
+               printf(" unlocked");
        } else {
-               printf (" not-connected\n");
+               printf (" not-connected");
+       }
+}
+
+void
+ao_gps_tracking_print(__xdata struct ao_gps_tracking_data *gps_tracking_data) __reentrant
+{
+       uint8_t c, n, v;
+       __xdata struct ao_gps_sat_data  *sat;
+       printf("SAT ");
+       n = gps_tracking_data->channels;
+       if (n == 0) {
+               printf("not-connected");
+               return;
+       }
+       sat = gps_tracking_data->sats;
+       v = 0;
+       for (c = 0; c < n; c++) {
+               if (sat->svid && sat->state)
+                       v++;
+               sat++;
+       }
+       printf("%d ", v);
+       sat = gps_tracking_data->sats;
+       for (c = 0; c < n; c++) {
+               if (sat->svid && sat->state)
+                       printf (" %3d %02x %3d",
+                               sat->svid,
+                               sat->state,
+                               sat->c_n_1);
+               sat++;
        }
 }
index dce12adbdc8e87c6ac0f085230afa42652005abe..acf8bb4022552c8d43bd938fe256da22be177aa8 100644 (file)
@@ -52,10 +52,41 @@ ao_gps_report(void)
        }
 }
 
+void
+ao_gps_tracking_report(void)
+{
+       static __xdata struct ao_log_record     gps_log;
+       static __xdata struct ao_gps_tracking_data      gps_tracking_data;
+       uint8_t c, n;
+
+       for (;;) {
+               ao_sleep(&ao_gps_tracking_data);
+               ao_mutex_get(&ao_gps_mutex);
+               memcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (struct ao_gps_tracking_data));
+               ao_mutex_put(&ao_gps_mutex);
+
+               if (!(n = gps_tracking_data.channels))
+                       continue;
+
+               gps_log.tick = ao_time();
+               gps_log.type = AO_LOG_GPS_SAT;
+               for (c = 0; c < n; c++)
+                       if ((gps_log.u.gps_sat.svid = gps_tracking_data.sats[c].svid) &&
+                           (gps_log.u.gps_sat.state = gps_tracking_data.sats[c].state))
+                       {
+                               gps_log.u.gps_sat.c_n = gps_tracking_data.sats[c].c_n_1;
+                               gps_log.u.gps_sat.unused = 0;
+                               ao_log_data(&gps_log);
+                       }
+       }
+}
+
 __xdata struct ao_task ao_gps_report_task;
+__xdata struct ao_task ao_gps_tracking_report_task;
 
 void
 ao_gps_report_init(void)
 {
        ao_add_task(&ao_gps_report_task, ao_gps_report, "gps_report");
+       ao_add_task(&ao_gps_tracking_report_task, ao_gps_tracking_report, "gps_tracking_report");
 }
index fb9b0d10f12d438f1b860f634799ff123278aa6c..c94128d91adc9b0f1c5799dffab77f0917bdcb77 100644 (file)
@@ -44,6 +44,26 @@ struct ao_gps_data {
        uint16_t                v_error;        /* m */
 };
 
+#define SIRF_SAT_STATE_ACQUIRED                        (1 << 0)
+#define SIRF_SAT_STATE_CARRIER_PHASE_VALID     (1 << 1)
+#define SIRF_SAT_BIT_SYNC_COMPLETE             (1 << 2)
+#define SIRF_SAT_SUBFRAME_SYNC_COMPLETE                (1 << 3)
+#define SIRF_SAT_CARRIER_PULLIN_COMPLETE       (1 << 4)
+#define SIRF_SAT_CODE_LOCKED                   (1 << 5)
+#define SIRF_SAT_ACQUISITION_FAILED            (1 << 6)
+#define SIRF_SAT_EPHEMERIS_AVAILABLE           (1 << 7)
+
+struct ao_gps_sat_data {
+       uint8_t         svid;
+       uint8_t         state;
+       uint8_t         c_n_1;
+};
+
+struct ao_gps_tracking_data {
+       uint8_t                 channels;
+       struct ao_gps_sat_data  sats[12];
+};
+
 void
 ao_mutex_get(uint8_t *mutex)
 {
@@ -78,6 +98,15 @@ ao_dbg_char(char c)
 static char    input_queue[QUEUE_LEN];
 int            input_head, input_tail;
 
+#include <sys/time.h>
+
+int
+get_millis(void)
+{
+       struct timeval  tv;
+       gettimeofday(&tv, NULL);
+       return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
 
 static void
 check_sirf_message(char *from, uint8_t *msg, int len)
@@ -101,9 +130,11 @@ check_sirf_message(char *from, uint8_t *msg, int len)
        }
        encoded_len = (msg[2] << 8) | msg[3];
        id = msg[4];
+/*     printf ("%9d: %3d\n", get_millis(), id); */
        if (encoded_len != len - 8) {
-               printf ("length mismatch (got %d, wanted %d)\n",
-                       len - 8, encoded_len);
+               if (id != 52)
+                       printf ("length mismatch (got %d, wanted %d)\n",
+                               len - 8, encoded_len);
                return;
        }
        encoded_cksum = (msg[len - 4] << 8) | msg[len-3];
@@ -116,7 +147,8 @@ check_sirf_message(char *from, uint8_t *msg, int len)
                return;
        }
        id = msg[4];
-       if (id == 41) {
+       switch (id) {
+       case 41:{
                int     off = 4;
 
                uint8_t         id;
@@ -181,29 +213,83 @@ check_sirf_message(char *from, uint8_t *msg, int len)
                printf ("Geodetic Navigation Data (41):\n");
                printf ("\tNav valid %04x\n", nav_valid);
                printf ("\tNav type %04x\n", nav_type);
-               printf ("\tWeek %d\n", week);
-               printf ("\tTOW %d\n", tow);
-               printf ("\tyear %d\n", year);
-               printf ("\tmonth %d\n", month);
-               printf ("\tday %d\n", day);
-               printf ("\thour %d\n", hour);
-               printf ("\tminute %d\n", minute);
-               printf ("\tsecond %g\n", second / 1000.0);
+               printf ("\tWeek %5d", week);
+               printf (" TOW %9d", tow);
+               printf (" %4d-%2d-%2d %02d:%02d:%07.4f\n",
+                       year, month, day,
+                       hour, minute, second / 1000.0);
                printf ("\tsats: %08x\n", sat_list);
-               printf ("\tlat: %g\n", lat / 1.0e7);
-               printf ("\tlon: %g\n", lon / 1.0e7);
-               printf ("\talt_ell: %g\n", alt_ell / 100.0);
-               printf ("\talt_msll: %g\n", alt_msl / 100.0);
-               printf ("\tdatum: %d\n", datum);
-               printf ("\tground speed: %g\n", sog / 100.0);
-               printf ("\tcourse: %g\n", cog / 100.0);
-               printf ("\tclimb: %g\n", climb_rate / 100.0);
-               printf ("\theading rate: %g\n", heading_rate / 100.0);
-               printf ("\th error: %g\n", h_error / 100.0);
-               printf ("\tv error: %g\n", v_error / 100.0);
-               printf ("\tt error: %g\n", t_error / 100.0);
-               printf ("\th vel error: %g\n", h_v_error / 100.0);
-       } else {
+               printf ("\tlat: %g", lat / 1.0e7);
+               printf (" lon: %g", lon / 1.0e7);
+               printf (" alt_ell: %g", alt_ell / 100.0);
+               printf (" alt_msll: %g", alt_msl / 100.0);
+               printf (" datum: %d\n", datum);
+               printf ("\tground speed: %g", sog / 100.0);
+               printf (" course: %g", cog / 100.0);
+               printf (" climb: %g", climb_rate / 100.0);
+               printf (" heading rate: %g\n", heading_rate / 100.0);
+               printf ("\th error: %g", h_error / 100.0);
+               printf (" v error: %g", v_error / 100.0);
+               printf (" t error: %g", t_error / 100.0);
+               printf (" h vel error: %g\n", h_v_error / 100.0);
+               break;
+       }
+       case 4: {
+               int off = 4;
+               uint8_t         id;
+               int16_t         gps_week;
+               uint32_t        gps_tow;
+               uint8_t         channels;
+               int             j, k;
+
+               get_u8(id);
+               get_u16(gps_week);
+               get_u32(gps_tow);
+               get_u8(channels);
+
+               printf ("Measured Tracker Data (4):\n");
+               printf ("GPS week: %d\n", gps_week);
+               printf ("GPS time of week: %d\n", gps_tow);
+               printf ("channels: %d\n", channels);
+               for (j = 0; j < 12; j++) {
+                       uint8_t svid, azimuth, elevation;
+                       uint16_t state;
+                       uint8_t c_n[10];
+                       get_u8(svid);
+                       get_u8(azimuth);
+                       get_u8(elevation);
+                       get_u16(state);
+                       for (k = 0; k < 10; k++) {
+                               get_u8(c_n[k]);
+                       }
+                       printf ("Sat %3d:", svid);
+                       printf (" aziumuth: %6.1f", azimuth * 1.5);
+                       printf (" elevation: %6.1f", elevation * 0.5);
+                       printf (" state: 0x%02x", state);
+                       printf (" c_n:");
+                       for (k = 0; k < 10; k++)
+                               printf(" %3d", c_n[k]);
+                       if (state & SIRF_SAT_STATE_ACQUIRED)
+                               printf(" acq,");
+                       if (state & SIRF_SAT_STATE_CARRIER_PHASE_VALID)
+                               printf(" car,");
+                       if (state & SIRF_SAT_BIT_SYNC_COMPLETE)
+                               printf(" bit,");
+                       if (state & SIRF_SAT_SUBFRAME_SYNC_COMPLETE)
+                               printf(" sub,");
+                       if (state & SIRF_SAT_CARRIER_PULLIN_COMPLETE)
+                               printf(" pullin,");
+                       if (state & SIRF_SAT_CODE_LOCKED)
+                               printf(" code,");
+                       if (state & SIRF_SAT_ACQUISITION_FAILED)
+                               printf(" fail,");
+                       if (state & SIRF_SAT_EPHEMERIS_AVAILABLE)
+                               printf(" ephem,");
+                       printf ("\n");
+               }
+               break;
+       }
+       default:
                return;
                printf ("%s %4d:", from, encoded_len);
                for (i = 4; i < len - 4; i++) {
@@ -315,9 +401,16 @@ ao_serial_set_speed(uint8_t speed)
 #include "ao_gps.c"
 
 void
-ao_dump_state(void)
+ao_dump_state(void *wchan)
 {
        double  lat, lon;
+       int     i;
+       if (wchan == &ao_gps_data)
+               ao_gps_print(&ao_gps_data);
+       else
+               ao_gps_tracking_print(&ao_gps_tracking_data);
+       putchar('\n');
+       return;
        printf ("%02d:%02d:%02d",
                ao_gps_data.hour, ao_gps_data.minute,
                ao_gps_data.second);
@@ -336,6 +429,12 @@ ao_dump_state(void)
                ao_gps_data.hdop / 5.0,
                ao_gps_data.h_error, ao_gps_data.v_error);
        printf("\n");
+       printf ("\t");
+       for (i = 0; i < 12; i++)
+               printf (" %2d(%02x)",
+                       ao_gps_tracking_data.sats[i].svid,
+                       ao_gps_tracking_data.sats[i].state);
+       printf ("\n");
 }
 
 int
@@ -358,14 +457,38 @@ ao_gps_open(const char *tty)
        return fd;
 }
 
+#include <getopt.h>
+
+static const struct option options[] = {
+       { .name = "tty", .has_arg = 1, .val = 'T' },
+       { 0, 0, 0, 0},
+};
+
+static void usage(char *program)
+{
+       fprintf(stderr, "usage: %s [--tty <tty-name>]\n", program);
+       exit(1);
+}
+
 int
 main (int argc, char **argv)
 {
-       char    *gps_file = "/dev/ttyUSB0";
+       char    *tty = "/dev/ttyUSB0";
+       int     c;
 
-       ao_gps_fd = ao_gps_open(gps_file);
+       while ((c = getopt_long(argc, argv, "T:", options, NULL)) != -1) {
+               switch (c) {
+               case 'T':
+                       tty = optarg;
+                       break;
+               default:
+                       usage(argv[0]);
+                       break;
+               }
+       }
+       ao_gps_fd = ao_gps_open(tty);
        if (ao_gps_fd < 0) {
-               perror (gps_file);
+               perror (tty);
                exit (1);
        }
        ao_gps_setup();
index 38ff84acedcfeb8439f03119bae152276bacc001..6b42f9f93e8775c8b3d1a1e9e34eee752948e2b4 100644 (file)
@@ -65,7 +65,7 @@ uint8_t ao_adc_head;
 #define ao_led_on(l)
 #define ao_led_off(l)
 #define ao_timer_set_adc_interval(i)
-#define ao_wakeup(wchan) ao_dump_state()
+#define ao_wakeup(wchan) ao_dump_state(wchan)
 #define ao_cmd_register(c)
 #define ao_usb_disable()
 #define ao_telemetry_set_interval(x)
@@ -100,7 +100,7 @@ struct ao_adc ao_adc_static;
 FILE *emulator_in;
 
 void
-ao_dump_state(void);
+ao_dump_state(void *wchan);
 
 void
 ao_sleep(void *wchan);
index 5997d427a4388536687bf1a0c3a4c93238d655bb..e57ea14528fba2379573bf7ea7345df9110143f3 100644 (file)
@@ -55,6 +55,9 @@ ao_monitor(void)
                               recv.telemetry.flight_pres,
                               recv.telemetry.ground_pres);
                        ao_gps_print(&recv.telemetry.gps);
+                       putchar(' ');
+                       ao_gps_tracking_print(&recv.telemetry.gps_tracking);
+                       putchar('\n');
                        ao_rssi_set((int) recv.rssi - 74);
                } else {
                        printf("CRC INVALID RSSI %3d\n", (int) recv.rssi - 74);
index 463bcd91137f571dde8590b1ecd0523f10e44dc4..9f57f3a9cacbc803bc62217802d930cb3bf0cc8e 100644 (file)
@@ -39,6 +39,7 @@ ao_telemetry(void)
                ao_adc_get(&telemetry.adc);
                ao_mutex_get(&ao_gps_mutex);
                memcpy(&telemetry.gps, &ao_gps_data, sizeof (struct ao_gps_data));
+               memcpy(&telemetry.gps_tracking, &ao_gps_tracking_data, sizeof (struct ao_gps_tracking_data));
                ao_mutex_put(&ao_gps_mutex);
                ao_radio_send(&telemetry);
                ao_delay(ao_telemetry_interval);