altos: Add split telemetry code
authorKeith Packard <keithp@keithp.com>
Tue, 5 Jul 2011 01:09:03 +0000 (18:09 -0700)
committerKeith Packard <keithp@keithp.com>
Tue, 5 Jul 2011 01:09:03 +0000 (18:09 -0700)
This sends every packet every time, which isn't correct, but should be
useful for testing.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/ao.h
src/ao_product.c
src/ao_telemetrum.c
src/ao_telemetry.c [new file with mode: 0644]

index 4895f016d663c8b93749b8600b4a2fa72cbcafd6..4d31f4f52dd30e65746708af477db5035a51d558 100644 (file)
--- a/src/ao.h
+++ b/src/ao.h
@@ -1040,14 +1040,15 @@ ao_gps_report_init(void);
  */
 
 #define AO_MAX_CALLSIGN                        8
+#define AO_MAX_VERSION                 8
 #define AO_MAX_TELEMETRY               128
 
 struct ao_telemetry_generic {
        uint16_t        serial;         /* 0 */
        uint16_t        tick;           /* 2 */
        uint8_t         type;           /* 4 */
-       uint8_t         payload[19];    /* 5 */
-       /* 24 */
+       uint8_t         payload[27];    /* 5 */
+       /* 32 */
 };
 
 #define AO_TELEMETRY_SENSOR_TELEMETRUM 0x01
@@ -1070,31 +1071,46 @@ struct ao_telemetry_sensor {
        int16_t         acceleration;   /* 18 m/s² * 16 */
        int16_t         speed;          /* 20 m/s * 16 */
        int16_t         height;         /* 22 m */
-       /* 24 */
-};
 
-#define AO_TELEMETRY_CONSTANT          0x10
+       int16_t         ground_pres;    /* 24 average pres on pad */
+       int16_t         ground_accel;   /* 26 average accel on pad */
+       int16_t         accel_plus_g;   /* 28 accel calibration at +1g */
+       int16_t         accel_minus_g;  /* 30 accel calibration at -1g */
+       /* 32 */
+};
 
-struct ao_telemetry_constant {
-       uint16_t        serial;         /*  0 */
-       uint16_t        tick;           /*  2 */
-       uint8_t         type;           /*  4 */
-       uint8_t         device;         /*  5 device type */
-       uint16_t        flight;         /*  6 flight number */
-       int16_t         ground_accel;   /*  8 average ground accelerometer (TM only) */
-       int16_t         ground_pres;    /* 10 average ground barometer */
-       int16_t         accel_plus_g;   /* 12 +1g accelerometer calibration value (TM only) */
-       int16_t         accel_minus_g;  /* 14 -1g accelermeter calibration value (TM only) */
-       char            callsign[AO_MAX_CALLSIGN];      /* 16 identity */
-       /* 24 */
+#define AO_TELEMETRY_CONFIGURATION     0x04
+
+struct ao_telemetry_configuration {
+       uint16_t        serial;                         /*  0 */
+       uint16_t        tick;                           /*  2 */
+       uint8_t         type;                           /*  4 */
+
+       uint8_t         device;                         /*  5 device type */
+       uint16_t        flight;                         /*  6 flight number */
+       uint8_t         config_major;                   /*  8 Config major version */
+       uint8_t         config_minor;                   /*  9 Config minor version */
+       uint16_t        main_deploy;                    /* 10 Main deploy alt in meters */
+       uint32_t        flight_log_max;                 /* 12 Maximum flight log size in bytes */
+       char            callsign[AO_MAX_CALLSIGN];      /* 16 Radio operator identity */
+       char            version[AO_MAX_VERSION];        /* 24 Software version */
+       /* 32 */
 };
 
-#define AO_TELEMETRY_LOCATION          0x11
+#define AO_TELEMETRY_LOCATION          0x05
+
+#define AO_GPS_MODE_NOT_VALID          'N'
+#define AO_GPS_MODE_AUTONOMOUS         'A'
+#define AO_GPS_MODE_DIFFERENTIAL       'D'
+#define AO_GPS_MODE_ESTIMATED          'E'
+#define AO_GPS_MODE_MANUAL             'M'
+#define AO_GPS_MODE_SIMULATED          'S'
 
 struct ao_telemetry_location {
        uint16_t        serial;         /*  0 */
        uint16_t        tick;           /*  2 */
        uint8_t         type;           /*  4 */
+
        uint8_t         flags;          /*  5 Number of sats and other flags */
        int16_t         altitude;       /*  6 GPS reported altitude (m) */
        int32_t         latitude;       /*  8 latitude (degrees * 10⁷) */
@@ -1105,25 +1121,40 @@ struct ao_telemetry_location {
        uint8_t         hour;           /* 19 (0-23) */
        uint8_t         minute;         /* 20 (0-59) */
        uint8_t         second;         /* 21 (0-59) */
-       uint8_t         hdop;           /* 22 (m * 5) */
-       uint8_t         unused;         /* 23 */
-       /* 24 */
+       uint8_t         pdop;           /* 22 (m * 5) */
+       uint8_t         hdop;           /* 23 (m * 5) */
+       uint8_t         vdop;           /* 24 (m * 5) */
+       uint8_t         mode;           /* 25 */
+       uint16_t        ground_speed;   /* 26 cm/s */
+       uint8_t         course;         /* 28 degrees / 2 */
+       uint8_t         unused[3];      /* 29 */
+       /* 32 */
 };
 
 #define AO_TELEMETRY_SATELLITE         0x12
 
+struct ao_telemetry_satellite_info {
+       uint8_t         svid;
+       uint8_t         c_n_1;
+};
+
 struct ao_telemetry_satellite {
-       uint16_t        serial;         /*  0 */
-       uint16_t        tick;           /*  2 */
-       uint8_t         type;           /*  4 */
-       uint8_t         channels;       /*  5 number of reported sats */
-       uint8_t         sats_0_1[3];    /*  6 reported sats 0 and 1 */
-       uint8_t         sats_2_3[3];
-       uint8_t         sats_4_5[3];
-       uint8_t         sats_6_7[3];
-       uint8_t         sats_8_9[3];
-       uint8_t         sats_10_11[3];
-       /* 24 */
+       uint16_t                                serial;         /*  0 */
+       uint16_t                                tick;           /*  2 */
+       uint8_t                                 type;           /*  4 */
+       uint8_t                                 channels;       /*  5 number of reported sats */
+
+       struct ao_telemetry_satellite_info      sats[12];       /* 6 */
+       uint8_t                                 unused[2];      /* 30 */
+       /* 32 */
+};
+
+union ao_telemetry_all {
+       struct ao_telemetry_generic             generic;
+       struct ao_telemetry_sensor              sensor;
+       struct ao_telemetry_configuration       configuration;
+       struct ao_telemetry_location            location;
+       struct ao_telemetry_satellite           satellite;
 };
 
 #define AO_SAT_0_SSID(s)       ((s)[0] & 0x3f)
@@ -1198,6 +1229,9 @@ ao_telemetry_set_interval(uint16_t interval);
 void
 ao_rdf_set(uint8_t rdf);
 
+void
+ao_telemetry_init(void);
+
 void
 ao_telemetry_orig_init(void);
 
index 54ba2a14e993b85017c0f203e22191e2f82e9bca..bb42e92c73768de449af11a0bd70eb9d025415f0 100644 (file)
@@ -20,7 +20,7 @@
 
 /* Defines which mark this particular AltOS product */
 
-const char ao_version[] = AO_iVersion_STRING;
+const char ao_version[AO_MAX_VERSION] = AO_iVersion_STRING;
 const char ao_manufacturer[] = AO_iManufacturer_STRING;
 const char ao_product[] = AO_iProduct_STRING;
 
index bede5868aa75083e4c81fed18fa247776e746e76..4ace415c23be7b3487f6bc9768c7a3b8b47e7bdd 100644 (file)
@@ -57,7 +57,7 @@ main(void)
        ao_serial_init();
        ao_gps_init();
        ao_gps_report_init();
-       ao_telemetry_orig_init();
+       ao_telemetry_init();
        ao_radio_init();
        ao_packet_slave_init(TRUE);
        ao_igniter_init();
diff --git a/src/ao_telemetry.c b/src/ao_telemetry.c
new file mode 100644 (file)
index 0000000..024ac6f
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright © 2011 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 "ao.h"
+#include "ao_product.h"
+
+__xdata uint16_t ao_telemetry_interval = 0;
+__xdata uint8_t ao_rdf = 0;
+__xdata uint16_t ao_rdf_time;
+
+#define AO_RDF_INTERVAL_TICKS  AO_SEC_TO_TICKS(5)
+#define AO_RDF_LENGTH_MS       500
+
+#if defined(TELEMETRUM_V_0_1) || defined(TELEMETRUM_V_0_2) || defined(TELEMETRUM_V_1_0) || defined(TELEMETRUM_V_1_1)
+#define AO_TELEMETRY_SENSOR    AO_TELEMETRY_SENSOR_TELEMETRUM
+#endif
+
+#if defined(TELEMINI_V_0_1)
+#define AO_TELEMETRY_SENSOR    AO_TELEMETRY_SENSOR_TELEMINI
+#endif
+
+#if defined(TELENANO_V_0_1)
+#define AO_TELEMETRY_SENSOR    AO_TELEMETRY_SENSOR_TELENANO
+#endif
+
+void
+ao_telemetry(void)
+{
+       uint16_t        time;
+       int16_t         delay;
+       static __xdata union ao_telemetry_all   telemetry;
+       uint8_t         sample;
+
+       ao_config_get();
+       while (!ao_flight_number)
+               ao_sleep(&ao_flight_number);
+
+       telemetry.generic.serial = ao_serial_number;
+       for (;;) {
+               while (ao_telemetry_interval == 0)
+                       ao_sleep(&ao_telemetry_interval);
+               time = ao_rdf_time = ao_time();
+               while (ao_telemetry_interval) {
+
+                       /* Send sensor packet */
+                       sample = ao_sample_adc;
+                       
+                       telemetry.generic.tick = ao_adc_ring[sample].tick;
+                       telemetry.generic.type = AO_TELEMETRY_SENSOR;
+
+                       telemetry.sensor.state = ao_flight_state;
+#if HAS_ACCEL
+                       telemetry.sensor.accel = ao_adc_ring[sample].accel;
+#else
+                       telemetry.sensor.accel = 0;
+#endif
+                       telemetry.sensor.pres = ao_adc_ring[sample].pres;
+                       telemetry.sensor.temp = ao_adc_ring[sample].temp;
+                       telemetry.sensor.v_batt = ao_adc_ring[sample].v_batt;
+#if HAS_IGNITE
+                       telemetry.sensor.sense_d = ao_adc_ring[sample].sense_d;
+                       telemetry.sensor.sense_m = ao_adc_ring[sample].sense_m;
+#else
+                       telemetry.sensor.sense_d = 0;
+                       telemetry.sensor.sense_m = 0;
+#endif
+
+                       telemetry.sensor.acceleration = ao_accel;
+                       telemetry.sensor.speed = ao_speed;
+                       telemetry.sensor.height = ao_height;
+
+                       telemetry.sensor.ground_pres = ao_ground_pres;
+                       telemetry.sensor.ground_accel = ao_ground_accel;
+                       telemetry.sensor.accel_plus_g = ao_config.accel_plus_g;
+                       telemetry.sensor.accel_minus_g = ao_config.accel_minus_g;
+
+                       ao_radio_send(&telemetry, sizeof (telemetry));
+
+                       telemetry.generic.type = AO_TELEMETRY_CONFIGURATION;
+                       telemetry.configuration.device = AO_idProduct_NUMBER;
+                       telemetry.configuration.flight = ao_flight_number;
+                       telemetry.configuration.config_major = AO_CONFIG_MAJOR;
+                       telemetry.configuration.config_minor = AO_CONFIG_MINOR;
+                       telemetry.configuration.main_deploy = ao_config.main_deploy;
+                       telemetry.configuration.flight_log_max = ao_config.flight_log_max;
+                       memcpy (telemetry.configuration.callsign,
+                               ao_config.callsign,
+                               AO_MAX_CALLSIGN);
+                       memcpy (telemetry.configuration.version,
+                               ao_version,
+                               AO_MAX_VERSION);
+
+                       if (ao_rdf &&
+                           (int16_t) (ao_time() - ao_rdf_time) >= 0)
+                       {
+                               ao_rdf_time = ao_time() + AO_RDF_INTERVAL_TICKS;
+                               ao_radio_rdf(AO_RDF_LENGTH_MS);
+                       }
+                       time += ao_telemetry_interval;
+                       delay = time - ao_time();
+                       if (delay > 0)
+                               ao_delay(delay);
+                       else
+                               time = ao_time();
+               }
+       }
+}
+
+void
+ao_telemetry_set_interval(uint16_t interval)
+{
+       ao_telemetry_interval = interval;
+       ao_wakeup(&ao_telemetry_interval);
+}
+
+void
+ao_rdf_set(uint8_t rdf)
+{
+       ao_rdf = rdf;
+       if (rdf == 0)
+               ao_radio_rdf_abort();
+       else
+               ao_rdf_time = ao_time();
+}
+
+__xdata struct ao_task ao_telemetry_task;
+
+void
+ao_telemetry_init()
+{
+       ao_add_task(&ao_telemetry_task, ao_telemetry, "telemetry");
+}