Merge remote-tracking branch 'origin/telemini'
authorKeith Packard <keithp@keithp.com>
Thu, 29 Aug 2013 04:52:58 +0000 (22:52 -0600)
committerKeith Packard <keithp@keithp.com>
Thu, 29 Aug 2013 04:52:58 +0000 (22:52 -0600)
Signed-off-by: Keith Packard <keithp@keithp.com>
Conflicts:
src/core/ao_telemetry.c
src/core/ao_telemetry.h

Added both Mini and Metrum telemetry defines

21 files changed:
src/core/ao_data.h
src/core/ao_gps_report_metrum.c [new file with mode: 0644]
src/core/ao_log.h
src/core/ao_log_metrum.c [new file with mode: 0644]
src/core/ao_sample_profile.c
src/core/ao_task.c
src/core/ao_telemetry.c
src/core/ao_telemetry.h
src/drivers/ao_gps_ublox.c
src/stm/Makefile-flash.defs
src/stm/ao_arch.h
src/stm/ao_arch_funcs.h
src/stm/ao_beep_stm.c
src/stm/ao_timer.c
src/stm/stm32l.h
src/telemetrum-v2.0/.gitignore [new file with mode: 0644]
src/telemetrum-v2.0/Makefile [new file with mode: 0644]
src/telemetrum-v2.0/ao_pins.h [new file with mode: 0644]
src/telemetrum-v2.0/ao_telemetrum.c [new file with mode: 0644]
src/telemetrum-v2.0/flash-loader/Makefile [new file with mode: 0644]
src/telemetrum-v2.0/flash-loader/ao_pins.h [new file with mode: 0644]

index 080a534f98d992fa2ccb3e77420278cdb65f69bd..339afe69882602e3730ff66543236b9f17e644b7 100644 (file)
@@ -272,7 +272,11 @@ typedef int16_t accel_t;
 /* MMA655X is hooked up so that positive values represent negative acceleration */
 
 #define ao_data_accel(packet)                  ((packet)->mma655x)
+#if AO_MMA655X_INVERT
+#define ao_data_accel_cook(packet)             (4095 - (packet)->mma655x)
+#else
 #define ao_data_accel_cook(packet)             ((packet)->mma655x)
+#endif
 #define ao_data_set_accel(packet, accel)       ((packet)->mma655x = (accel))
 #define ao_data_accel_invert(accel)            (4095 - (accel))
 
diff --git a/src/core/ao_gps_report_metrum.c b/src/core/ao_gps_report_metrum.c
new file mode 100644 (file)
index 0000000..4fefe22
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * 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 "ao.h"
+#include "ao_log.h"
+
+void
+ao_gps_report_metrum(void)
+{
+       static __xdata struct ao_log_metrum             gps_log;
+       static __xdata struct ao_telemetry_location     gps_data;
+       uint8_t date_reported = 0;
+
+       for (;;) {
+               ao_sleep(&ao_gps_data);
+               ao_mutex_get(&ao_gps_mutex);
+               ao_xmemcpy(&gps_data, &ao_gps_data, sizeof (ao_gps_data));
+               ao_mutex_put(&ao_gps_mutex);
+
+               if (!(gps_data.flags & AO_GPS_VALID))
+                       continue;
+
+               gps_log.tick = ao_gps_tick;
+               gps_log.type = AO_LOG_GPS_POS;
+               gps_log.u.gps.latitude = gps_data.latitude;
+               gps_log.u.gps.longitude = gps_data.longitude;
+               gps_log.u.gps.altitude = gps_data.altitude;
+               ao_log_metrum(&gps_log);
+
+               gps_log.type = AO_LOG_GPS_TIME;
+               gps_log.u.gps_time.hour = gps_data.hour;
+               gps_log.u.gps_time.minute = gps_data.minute;
+               gps_log.u.gps_time.second = gps_data.second;
+               gps_log.u.gps_time.flags = gps_data.flags;
+               gps_log.u.gps_time.year = gps_data.year;
+               gps_log.u.gps_time.month = gps_data.month;
+               gps_log.u.gps_time.day = gps_data.day;
+               ao_log_metrum(&gps_log);
+       }
+}
+
+void
+ao_gps_tracking_report_metrum(void)
+{
+       static __xdata struct ao_log_metrum             gps_log;
+       static __xdata struct ao_telemetry_satellite    gps_tracking_data;
+       uint8_t c, n, i, p, valid, packets;
+       uint8_t svid;
+
+       for (;;) {
+               ao_sleep(&ao_gps_tracking_data);
+               ao_mutex_get(&ao_gps_mutex);
+               ao_xmemcpy(&gps_tracking_data, &ao_gps_tracking_data, sizeof (ao_gps_tracking_data));
+               ao_mutex_put(&ao_gps_mutex);
+
+               if (!(n = gps_tracking_data.channels))
+                       continue;
+
+               gps_log.type = AO_LOG_GPS_SAT;
+               gps_log.tick = ao_gps_tick;
+               i = 0;
+               for (c = 0; c < n; c++) {
+                       svid = gps_tracking_data.sats[c].svid;
+                       if (svid != 0) {
+                               if (i == 4) {
+                                       gps_log.u.gps_sat.channels = i;
+                                       gps_log.u.gps_sat.more = 1;
+                                       ao_log_metrum(&gps_log);
+                                       i = 0;
+                               }
+                               gps_log.u.gps_sat.sats[i].svid = svid;
+                               gps_log.u.gps_sat.sats[i].c_n = gps_tracking_data.sats[c].c_n_1;
+                               i++;
+                       }
+               }
+               if (i) {
+                       gps_log.u.gps_sat.channels = i;
+                       gps_log.u.gps_sat.more = 0;
+                       ao_log_metrum(&gps_log);
+               }
+       }
+}
+
+__xdata struct ao_task ao_gps_report_metrum_task;
+__xdata struct ao_task ao_gps_tracking_report_metrum_task;
+
+void
+ao_gps_report_metrum_init(void)
+{
+       ao_add_task(&ao_gps_report_metrum_task,
+                   ao_gps_report_metrum,
+                   "gps_report");
+       ao_add_task(&ao_gps_tracking_report_metrum_task,
+                   ao_gps_tracking_report_metrum,
+                   "gps_tracking_report");
+}
index dce12f02279a19ae7c44acb4f5382dad1e68799e..f6ab45209913ed73a76c8185d5e9d2300b995e30 100644 (file)
@@ -45,6 +45,7 @@ extern __pdata enum ao_flight_state ao_log_state;
 #define AO_LOG_FORMAT_TELESCIENCE      4       /* 32 byte typed telescience records */
 #define AO_LOG_FORMAT_TELEMEGA         5       /* 32 byte typed telemega records */
 #define AO_LOG_FORMAT_MINI             6       /* 16-byte MS5607 baro only */
+#define AO_LOG_FORMAT_TELEMETRUM       7       /* 16-byte typed telemetrum records */
 #define AO_LOG_FORMAT_NONE             127     /* No log at all */
 
 extern __code uint8_t ao_log_format;
@@ -135,6 +136,7 @@ ao_log_full(void);
 #define AO_LOG_GPS_ALT         'H'
 #define AO_LOG_GPS_SAT         'V'
 #define AO_LOG_GPS_DATE                'Y'
+#define AO_LOG_GPS_POS         'P'
 
 #define AO_LOG_POS_NONE                (~0UL)
 
@@ -263,6 +265,64 @@ struct ao_log_mega {
        } u;
 };
 
+struct ao_log_metrum {
+       char                    type;                   /* 0 */
+       uint8_t                 csum;                   /* 1 */
+       uint16_t                tick;                   /* 2 */
+       union {                                         /* 4 */
+               /* AO_LOG_FLIGHT */
+               struct {
+                       uint16_t        flight;         /* 4 */
+                       int16_t         ground_accel;   /* 6 */
+                       uint32_t        ground_pres;    /* 8 */
+               } flight;       /* 12 */
+               /* AO_LOG_STATE */
+               struct {
+                       uint16_t        state;          /* 4 */
+                       uint16_t        reason;         /* 6 */
+               } state;        /* 8 */
+               /* AO_LOG_SENSOR */
+               struct {
+                       uint32_t        pres;           /* 4 */
+                       uint32_t        temp;           /* 8 */
+                       int16_t         accel;          /* 12 */
+               } sensor;       /* 14 */
+               /* AO_LOG_TEMP_VOLT */
+               struct {
+                       int16_t         v_batt;         /* 4 */
+                       int16_t         sense_a;        /* 6 */
+                       int16_t         sense_m;        /* 8 */
+               } volt;         /* 10 */
+               /* AO_LOG_GPS_POS */
+               struct {
+                       int32_t         latitude;       /* 4 */
+                       int32_t         longitude;      /* 8 */
+                       int16_t         altitude;       /* 12 */
+               } gps;          /* 14 */
+               /* AO_LOG_GPS_TIME */
+               struct {
+                       uint8_t         hour;           /* 4 */
+                       uint8_t         minute;         /* 5 */
+                       uint8_t         second;         /* 6 */
+                       uint8_t         flags;          /* 7 */
+                       uint8_t         year;           /* 8 */
+                       uint8_t         month;          /* 9 */
+                       uint8_t         day;            /* 10 */
+                       uint8_t         pad;            /* 11 */
+               } gps_time;     /* 12 */
+               /* AO_LOG_GPS_SAT (up to three packets) */
+               struct {
+                       uint8_t channels;               /* 4 */
+                       uint8_t more;                   /* 5 */
+                       struct {
+                               uint8_t svid;
+                               uint8_t c_n;
+                       } sats[4];                      /* 6 */
+               } gps_sat;                              /* 14 */
+               uint8_t         raw[12];                /* 4 */
+       } u;    /* 16 */
+};
+
 struct ao_log_mini {
        char            type;                           /* 0 */
        uint8_t         csum;                           /* 1 */
@@ -303,10 +363,16 @@ ao_log_data(__xdata struct ao_log_record *log) __reentrant;
 uint8_t
 ao_log_mega(__xdata struct ao_log_mega *log) __reentrant;
 
+uint8_t
+ao_log_metrum(__xdata struct ao_log_metrum *log) __reentrant;
+
 uint8_t
 ao_log_mini(__xdata struct ao_log_mini *log) __reentrant;
 
 void
 ao_log_flush(void);
 
+void
+ao_gps_report_metrum_init(void);
+
 #endif /* _AO_LOG_H_ */
diff --git a/src/core/ao_log_metrum.c b/src/core/ao_log_metrum.c
new file mode 100644 (file)
index 0000000..43441e7
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright © 2012 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_log.h>
+#include <ao_data.h>
+#include <ao_flight.h>
+
+static __xdata uint8_t ao_log_mutex;
+static __xdata struct ao_log_metrum log;
+
+__code uint8_t ao_log_format = AO_LOG_FORMAT_TELEMETRUM;
+
+static uint8_t
+ao_log_csum(__xdata uint8_t *b) __reentrant
+{
+       uint8_t sum = 0x5a;
+       uint8_t i;
+
+       for (i = 0; i < sizeof (struct ao_log_metrum); i++)
+               sum += *b++;
+       return -sum;
+}
+
+uint8_t
+ao_log_metrum(__xdata struct ao_log_metrum *log) __reentrant
+{
+       uint8_t wrote = 0;
+       /* set checksum */
+       log->csum = 0;
+       log->csum = ao_log_csum((__xdata uint8_t *) log);
+       ao_mutex_get(&ao_log_mutex); {
+               if (ao_log_current_pos >= ao_log_end_pos && ao_log_running)
+                       ao_log_stop();
+               if (ao_log_running) {
+                       wrote = 1;
+                       ao_storage_write(ao_log_current_pos,
+                                        log,
+                                        sizeof (struct ao_log_metrum));
+                       ao_log_current_pos += sizeof (struct ao_log_metrum);
+               }
+       } ao_mutex_put(&ao_log_mutex);
+       return wrote;
+}
+
+static uint8_t
+ao_log_dump_check_data(void)
+{
+       if (ao_log_csum((uint8_t *) &log) != 0)
+               return 0;
+       return 1;
+}
+
+#if HAS_ADC
+static __data uint8_t  ao_log_data_pos;
+
+/* a hack to make sure that ao_log_metrums fill the eeprom block in even units */
+typedef uint8_t check_log_size[1-(256 % sizeof(struct ao_log_metrum))] ;
+
+#ifndef AO_SENSOR_INTERVAL_ASCENT
+#define AO_SENSOR_INTERVAL_ASCENT      1
+#define AO_SENSOR_INTERVAL_DESCENT     10
+#define AO_OTHER_INTERVAL              32
+#endif
+
+void
+ao_log(void)
+{
+       __pdata uint16_t        next_sensor, next_other;
+       uint8_t                 i;
+
+       ao_storage_setup();
+
+       ao_log_scan();
+
+       while (!ao_log_running)
+               ao_sleep(&ao_log_running);
+
+#if HAS_FLIGHT
+       log.type = AO_LOG_FLIGHT;
+       log.tick = ao_sample_tick;
+#if HAS_ACCEL
+       log.u.flight.ground_accel = ao_ground_accel;
+#endif
+       log.u.flight.ground_pres = ao_ground_pres;
+       log.u.flight.flight = ao_flight_number;
+       ao_log_metrum(&log);
+#endif
+
+       /* Write the whole contents of the ring to the log
+        * when starting up.
+        */
+       ao_log_data_pos = ao_data_ring_next(ao_data_head);
+       next_other = next_sensor = ao_data_ring[ao_log_data_pos].tick;
+       ao_log_state = ao_flight_startup;
+       for (;;) {
+               /* Write samples to EEPROM */
+               while (ao_log_data_pos != ao_data_head) {
+                       log.tick = ao_data_ring[ao_log_data_pos].tick;
+                       if ((int16_t) (log.tick - next_sensor) >= 0) {
+                               log.type = AO_LOG_SENSOR;
+#if HAS_MS5607
+                               log.u.sensor.pres = ao_data_ring[ao_log_data_pos].ms5607_raw.pres;
+                               log.u.sensor.temp = ao_data_ring[ao_log_data_pos].ms5607_raw.temp;
+#endif
+                               log.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]);
+                               ao_log_metrum(&log);
+                               if (ao_log_state <= ao_flight_coast)
+                                       next_sensor = log.tick + AO_SENSOR_INTERVAL_ASCENT;
+                               else
+                                       next_sensor = log.tick + AO_SENSOR_INTERVAL_DESCENT;
+                       }
+                       if ((int16_t) (log.tick - next_other) >= 0) {
+                               log.type = AO_LOG_TEMP_VOLT;
+                               log.u.volt.v_batt = ao_data_ring[ao_log_data_pos].adc.v_batt;
+                               log.u.volt.sense_a = ao_data_ring[ao_log_data_pos].adc.sense_a;
+                               log.u.volt.sense_m = ao_data_ring[ao_log_data_pos].adc.sense_m;
+                               ao_log_metrum(&log);
+                               next_other = log.tick + AO_OTHER_INTERVAL;
+                       }
+                       ao_log_data_pos = ao_data_ring_next(ao_log_data_pos);
+               }
+#if HAS_FLIGHT
+               /* Write state change to EEPROM */
+               if (ao_flight_state != ao_log_state) {
+                       ao_log_state = ao_flight_state;
+                       log.type = AO_LOG_STATE;
+                       log.tick = ao_time();
+                       log.u.state.state = ao_log_state;
+                       log.u.state.reason = 0;
+                       ao_log_metrum(&log);
+
+                       if (ao_log_state == ao_flight_landed)
+                               ao_log_stop();
+               }
+#endif
+
+               ao_log_flush();
+
+               /* Wait for a while */
+               ao_delay(AO_MS_TO_TICKS(100));
+
+               /* Stop logging when told to */
+               while (!ao_log_running)
+                       ao_sleep(&ao_log_running);
+       }
+}
+#endif
+
+uint16_t
+ao_log_flight(uint8_t slot)
+{
+       if (!ao_storage_read(ao_log_pos(slot),
+                            &log,
+                            sizeof (struct ao_log_metrum)))
+               return 0;
+
+       if (ao_log_dump_check_data() && log.type == AO_LOG_FLIGHT)
+               return log.u.flight.flight;
+       return 0;
+}
index 1d9ed41492bba22d094deac324f62fcbd104cc08..e682bd98e466a6031899d6e8744950d5a15bc665 100644 (file)
 #include <ao_task.h>
 
 #ifndef AO_SAMPLE_PROFILE_LOW_PC
-#define AO_SAMPLE_PROFILE_LOW_PC       0x08000000
+#define AO_SAMPLE_PROFILE_LOW_PC       0x08002000
 #endif
 
 #ifndef AO_SAMPLE_PROFILE_HIGH_PC
-#define AO_SAMPLE_PROFILE_HIGH_PC      (AO_SAMPLE_PROFILE_LOW_PC + 44 * 1024)
+#define AO_SAMPLE_PROFILE_HIGH_PC      0x08003000
 #endif
 
 #ifndef AO_SAMPLE_PROFILE_SHIFT
-#define AO_SAMPLE_PROFILE_SHIFT                6
+#define AO_SAMPLE_PROFILE_SHIFT                3
 #endif
 
 #define AO_SAMPLE_PROFILE_RANGE                (AO_SAMPLE_PROFILE_HIGH_PC - AO_SAMPLE_PROFILE_LOW_PC)
index 18315b1fddcd625a0cde0de9e6a48156b4d8be2d..bafb49439d4441022be1b9159947f30a9f8d7bff 100644 (file)
@@ -109,6 +109,8 @@ ao_task_validate_alarm_queue(void)
                                ao_panic(3);
                }
        }
+       if (ao_task_alarm_tick != ao_list_first_entry(&alarm_queue, struct ao_task, alarm_queue)->alarm)
+               ao_panic(4);
 }
 #else
 #define ao_task_validate_alarm_queue()
@@ -123,6 +125,7 @@ ao_task_to_alarm_queue(struct ao_task *task)
        ao_list_for_each_entry(alarm, &alarm_queue, struct ao_task, alarm_queue) {
                if ((int16_t) (alarm->alarm - task->alarm) >= 0) {
                        ao_list_insert(&task->alarm_queue, alarm->alarm_queue.prev);
+                       ao_task_alarm_tick = ao_list_first_entry(&alarm_queue, struct ao_task, alarm_queue)->alarm;
                        ao_task_validate_alarm_queue();
                        return;
                }
index 9c67303081aeb71e0cda739b9da2800fbf7b8913..cd95aa6bce3d0a995d70b6fd30a90d49a75ca07a 100644 (file)
@@ -40,6 +40,10 @@ static __pdata uint16_t ao_aprs_time;
 #define AO_SEND_MEGA   1
 #endif
 
+#if defined (TELEMETRUM_V_2_0)
+#define AO_SEND_METRUM 1
+#endif
+
 #if defined(TELEMETRUM_V_0_1) || defined(TELEMETRUM_V_0_2) || defined(TELEMETRUM_V_1_0) || defined(TELEMETRUM_V_1_1) || defined(TELEBALLOON_V_1_1) || defined(TELEMETRUM_V_1_2)
 #define AO_TELEMETRY_SENSOR    AO_TELEMETRY_SENSOR_TELEMETRUM
 #endif
@@ -171,6 +175,56 @@ ao_send_mega_data(void)
 }
 #endif /* AO_SEND_MEGA */
 
+#ifdef AO_SEND_METRUM
+/* Send telemetrum sensor packet */
+static void
+ao_send_metrum_sensor(void)
+{
+       __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)];
+
+       telemetry.generic.type = AO_TELEMETRY_METRUM_SENSOR;
+
+       telemetry.metrum_sensor.state = ao_flight_state;
+       telemetry.metrum_sensor.accel = ao_data_accel(packet);
+       telemetry.metrum_sensor.pres = ao_data_pres(packet);
+       telemetry.metrum_sensor.temp = ao_data_temp(packet);
+
+       telemetry.metrum_sensor.acceleration = ao_accel;
+       telemetry.metrum_sensor.speed = ao_speed;
+       telemetry.metrum_sensor.height = ao_height;
+
+       telemetry.metrum_sensor.v_batt = packet->adc.v_batt;
+       telemetry.metrum_sensor.sense_a = packet->adc.sense_a;
+       telemetry.metrum_sensor.sense_m = packet->adc.sense_m;
+
+       ao_radio_send(&telemetry, sizeof (telemetry));
+}
+
+static __pdata int8_t ao_telemetry_metrum_data_max;
+static __pdata int8_t ao_telemetry_metrum_data_cur;
+
+/* Send telemetrum data packet */
+static void
+ao_send_metrum_data(void)
+{
+       if (--ao_telemetry_metrum_data_cur <= 0) {
+               __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)];
+               uint8_t i;
+
+               telemetry.generic.tick = packet->tick;
+               telemetry.generic.type = AO_TELEMETRY_METRUM_DATA;
+
+               telemetry.metrum_data.ground_pres = ao_ground_pres;
+               telemetry.metrum_data.ground_accel = ao_ground_accel;
+               telemetry.metrum_data.accel_plus_g = ao_config.accel_plus_g;
+               telemetry.metrum_data.accel_minus_g = ao_config.accel_minus_g;
+
+               ao_radio_send(&telemetry, sizeof (telemetry));
+               ao_telemetry_metrum_data_cur = ao_telemetry_metrum_data_max;
+       }
+}
+#endif /* AO_SEND_METRUM */
+
 #ifdef AO_SEND_MINI
 
 static void
@@ -199,7 +253,7 @@ ao_send_mini(void)
        ao_radio_send(&telemetry, sizeof (telemetry));
 }
 
-#endif
+#endif /* AO_SEND_MINI */
 
 #ifdef AO_SEND_ALL_BARO
 static uint8_t         ao_baro_sample;
@@ -344,7 +398,6 @@ ao_telemetry(void)
                ao_aprs_time = time;
 #endif
                while (ao_telemetry_interval) {
-
 #if HAS_APRS
                        if (!(ao_config.radio_enable & AO_RADIO_DISABLE_TELEMETRY))
 #endif
@@ -352,18 +405,23 @@ ao_telemetry(void)
 #ifdef AO_SEND_ALL_BARO
                                ao_send_baro();
 #endif
+
 #if HAS_FLIGHT
 # ifdef AO_SEND_MEGA
                                ao_send_mega_sensor();
                                ao_send_mega_data();
-# else
-#  ifdef AO_SEND_MINI
+# endif
+# ifdef AO_SEND_METRUM
+                               ao_send_metrum_sensor();
+                               ao_send_metrum_data();
+# endif
+# ifdef AO_SEND_MINI
                                ao_send_mini();
-#  else
+# endif
+# ifdef AO_TELEMETRY_SENSOR
                                ao_send_sensor();
-#  endif
 # endif
-#endif
+#endif /* HAS_FLIGHT */
 
 #if HAS_COMPANION
                                if (ao_companion_running)
@@ -380,18 +438,18 @@ ao_telemetry(void)
                        if (ao_rdf &&
 #if HAS_APRS
                            !(ao_config.radio_enable & AO_RADIO_DISABLE_RDF) &&
-#endif
+#endif /* HAS_APRS */
                            (int16_t) (ao_time() - ao_rdf_time) >= 0)
                        {
 #if HAS_IGNITE_REPORT
                                uint8_t c;
-#endif
+#endif /* HAS_IGNITE_REPORT */
                                ao_rdf_time = ao_time() + AO_RDF_INTERVAL_TICKS;
 #if HAS_IGNITE_REPORT
                                if (ao_flight_state == ao_flight_pad && (c = ao_report_igniter()))
                                        ao_radio_continuity(c);
                                else
-#endif
+#endif /* HAS_IGNITE_REPORT*/
                                        ao_radio_rdf();
                        }
 #endif /* HAS_RDF */
@@ -402,8 +460,8 @@ ao_telemetry(void)
                                ao_aprs_time = ao_time() + AO_SEC_TO_TICKS(ao_config.aprs_interval);
                                ao_aprs_send();
                        }
-#endif
-#endif
+#endif /* HAS_APRS */
+#endif /* !AO_SEND_ALL_BARO */
                        time += ao_telemetry_interval;
                        delay = time - ao_time();
                        if (delay > 0) {
@@ -433,6 +491,12 @@ ao_telemetry_set_interval(uint16_t interval)
                cur++;
        ao_telemetry_mega_data_cur = cur;
 #endif
+#if AO_SEND_METRUM
+       ao_telemetry_metrum_data_max = AO_SEC_TO_TICKS(1) / interval;
+       if (ao_telemetry_metrum_data_max > cur)
+               cur++;
+       ao_telemetry_metrum_data_cur = cur;
+#endif
 
 #if HAS_COMPANION
        if (!ao_companion_setup.update_period)
index 776015291dddde49a3d49adfb1615eb8f0bf5631..fd6b76b37375114519621258642d6a0c4ee25bc1 100644 (file)
@@ -207,6 +207,47 @@ struct ao_telemetry_mega_data {
 };
 
 
+#define AO_TELEMETRY_METRUM_SENSOR     0x0A
+
+struct ao_telemetry_metrum_sensor {
+       uint16_t        serial;         /*  0 */
+       uint16_t        tick;           /*  2 */
+       uint8_t         type;           /*  4 */
+
+       uint8_t         state;          /*  5 flight state */
+       int16_t         accel;          /*  6 Z axis */
+
+       int32_t         pres;           /*  8 Pa * 10 */
+       int16_t         temp;           /* 12 °C * 100 */
+
+       int16_t         acceleration;   /* 14 m/s² * 16 */
+       int16_t         speed;          /* 16 m/s * 16 */
+       int16_t         height;         /* 18 m */
+
+       int16_t         v_batt;         /* 20 battery voltage */
+       int16_t         sense_a;        /* 22 apogee continuity sense */
+       int16_t         sense_m;        /* 24 main continuity sense */
+
+       uint8_t         pad[6];         /* 26 */
+       /* 32 */
+};
+       
+#define AO_TELEMETRY_METRUM_DATA       0x0B
+
+struct ao_telemetry_metrum_data {
+       uint16_t        serial;         /*  0 */
+       uint16_t        tick;           /*  2 */
+       uint8_t         type;           /*  4 */
+
+       int32_t         ground_pres;    /* 8 average pres on pad */
+       int16_t         ground_accel;   /* 12 average accel on pad */
+       int16_t         accel_plus_g;   /* 14 accel calibration at +1g */
+       int16_t         accel_minus_g;  /* 16 accel calibration at -1g */
+
+       uint8_t         pad[14];        /* 18 */
+       /* 32 */
+};
+
 #define AO_TELEMETRY_MINI              0x10
 
 struct ao_telemetry_mini {
@@ -215,7 +256,6 @@ struct ao_telemetry_mini {
        uint8_t         type;           /*  4 */
 
        uint8_t         state;          /*  5 flight state */
-
        int16_t         v_batt;         /*  6 battery voltage */
        int16_t         sense_a;        /*  8 apogee continuity */
        int16_t         sense_m;        /* 10 main continuity */
@@ -266,6 +306,8 @@ union ao_telemetry_all {
        struct ao_telemetry_companion           companion;
        struct ao_telemetry_mega_sensor         mega_sensor;
        struct ao_telemetry_mega_data           mega_data;
+       struct ao_telemetry_metrum_sensor       metrum_sensor;
+       struct ao_telemetry_metrum_data         metrum_data;
        struct ao_telemetry_mini                mini;
        struct ao_telemetry_baro                baro;
 };
index fa6ff0e0724b8290a483ee651bc6583c623851fc..1bc2a68fdb6a66616bdecc1d8a6bd041a8f55897 100644 (file)
 
 #include "ao_gps_ublox.h"
 
+#define AO_UBLOX_DEBUG 1
+
+#include <stdarg.h>
+
 __xdata uint8_t ao_gps_mutex;
 __pdata uint16_t ao_gps_tick;
 __xdata struct ao_telemetry_location   ao_gps_data;
 __xdata struct ao_telemetry_satellite  ao_gps_tracking_data;
 
+#undef AO_SERIAL_SPEED_UBLOX
+
 #ifndef AO_SERIAL_SPEED_UBLOX
-#define AO_SERIAL_SPEED_UBLOX AO_SERIAL_SPEED_57600
+#define AO_SERIAL_SPEED_UBLOX AO_SERIAL_SPEED_9600
 #endif
 
 #if AO_SERIAL_SPEED_UBLOX == AO_SERIAL_SPEED_57600
 #define SERIAL_SPEED_STRING    "57600"
+#define SERIAL_SPEED_CHECKSUM  "2d"
 #endif
 #if AO_SERIAL_SPEED_UBLOX == AO_SERIAL_SPEED_19200
 #define SERIAL_SPEED_STRING    "19200"
+#define SERIAL_SPEED_CHECKSUM  "23"
 #endif
 #if AO_SERIAL_SPEED_UBLOX == AO_SERIAL_SPEED_9600
 #define SERIAL_SPEED_STRING    "9600"
+#define SERIAL_SPEED_CHECKSUM  "16"
 #endif
 
-static const char ao_gps_set_nmea[] = "\r\n$PUBX,41,1,3,1," SERIAL_SPEED_STRING ",0*2d\r\n";
+static const char ao_gps_set_nmea[] =
+       "\r\n$PUBX,41,1,3,1," SERIAL_SPEED_STRING ",0*" SERIAL_SPEED_CHECKSUM "\r\n";
 
 struct ao_ublox_cksum {
        uint8_t a, b;
@@ -49,7 +59,34 @@ struct ao_ublox_cksum {
 static __pdata struct ao_ublox_cksum ao_ublox_cksum;
 static __pdata uint16_t ao_ublox_len;
 
-#define ao_ublox_byte()        ((uint8_t) ao_gps_getchar())
+#if AO_UBLOX_DEBUG
+
+static uint8_t ao_gps_dbg_enable;
+
+#define DBG_PROTO      1
+#define DBG_CHAR       2
+#define DBG_INIT       4
+
+static void ao_gps_dbg(int level, char *format, ...) {
+       va_list a;
+
+       if (level & ao_gps_dbg_enable) {
+               va_start(a, format);
+               vprintf(format, a);
+               va_end(a);
+               flush();
+       }
+}
+
+#else
+#define ao_gps_dbg(fmt, ...)
+#endif
+
+static inline uint8_t ao_ublox_byte(void) {
+       uint8_t c = (uint8_t) ao_gps_getchar();
+       ao_gps_dbg(DBG_CHAR, " %02x", c);
+       return c;
+}
 
 static inline void add_cksum(struct ao_ublox_cksum *cksum, uint8_t c)
 {
@@ -65,6 +102,7 @@ static void ao_ublox_init_cksum(void)
 static void ao_ublox_put_u8(uint8_t c)
 {
        add_cksum(&ao_ublox_cksum, c);
+       ao_gps_dbg(DBG_CHAR, " (%02x)", c);
        ao_gps_putchar(c);
 }
 
@@ -187,6 +225,7 @@ ao_ublox_parse(void __xdata *target, const struct ublox_packet_parse *parse) __r
                        break;
                }
        }
+       ao_gps_dbg(DBG_PROTO, "\n");
 }
 
 /*
@@ -330,6 +369,7 @@ ao_ublox_parse_nav_svinfo(void)
 {
        uint8_t nsat;
        nav_svinfo_nsat = 0;
+
        ao_ublox_parse(&nav_svinfo, nav_svinfo_packet);
        for (nsat = 0; nsat < nav_svinfo.num_ch && ao_ublox_len >= 12; nsat++) {
                if (nsat < NAV_SVINFO_MAX_SAT) {
@@ -338,6 +378,17 @@ ao_ublox_parse_nav_svinfo(void)
                        ublox_discard(12);
                }
        }
+#if AO_UBLOX_DEBUG
+       ao_gps_dbg(DBG_PROTO, "svinfo num_ch %d flags %02x\n", nav_svinfo.num_ch, nav_svinfo.flags);
+       for (nsat = 0; nsat < nav_svinfo.num_ch; nsat++)
+               ao_gps_dbg(DBG_PROTO, "\t%d: chn %d svid %d flags %02x quality %d cno %d\n",
+                           nsat,
+                           nav_svinfo_sat[nsat].chn,
+                           nav_svinfo_sat[nsat].svid,
+                           nav_svinfo_sat[nsat].flags,
+                           nav_svinfo_sat[nsat].quality,
+                           nav_svinfo_sat[nsat].cno);
+#endif
 }
 
 /*
@@ -406,42 +457,52 @@ ao_ublox_parse_nav_velned(void)
  */
 
 static void
-ao_gps_setup(void)
+ao_gps_delay(void)
 {
-       uint8_t i, k;
-
-       ao_delay(AO_SEC_TO_TICKS(3));
-
-       ao_gps_set_speed(AO_SERIAL_SPEED_9600);
+       uint8_t i;
 
        /*
         * A bunch of nulls so the start bit
         * is clear
         */
+
        for (i = 0; i < 64; i++)
                ao_gps_putchar(0x00);
+}
+
+static void
+ao_gps_setup(void)
+{
+       uint8_t i, k;
+
+       ao_delay(AO_SEC_TO_TICKS(3));
+
+       ao_gps_dbg(DBG_INIT, "Set speed 9600\n");
+       ao_gps_set_speed(AO_SERIAL_SPEED_9600);
 
        /*
         * Send the baud-rate setting and protocol-setting
         * command three times
         */
-       for (k = 0; k < 3; k++)
+       for (k = 0; k < 3; k++) {
+               ao_gps_delay();
+
+               ao_gps_dbg(DBG_INIT, "Send initial setting\n");
                for (i = 0; i < sizeof (ao_gps_set_nmea); i++)
                        ao_gps_putchar(ao_gps_set_nmea[i]);
+       }
+
+       ao_gps_delay();
 
 #if AO_SERIAL_SPEED_UBLOX != AO_SERIAL_SPEED_9600
+       ao_gps_dbg(DBG_INIT, "Set speed high\n");
        /*
         * Increase the baud rate
         */
        ao_gps_set_speed(AO_SERIAL_SPEED_UBLOX);
 #endif
 
-       /*
-        * Pad with nulls to give the chip
-        * time to see the baud rate switch
-        */
-       for (i = 0; i < 64; i++)
-               ao_gps_putchar(0x00);
+       ao_gps_delay();
 }
 
 static void
@@ -556,7 +617,7 @@ ao_gps(void) __reentrant
        /* Enable all of the messages we want */
        for (i = 0; i < sizeof (ublox_enable_nav); i++)
                ao_ublox_set_message_rate(UBLOX_NAV, ublox_enable_nav[i], 1);
-       
+
        ao_ublox_set_navigation_settings((1 << UBLOX_CFG_NAV5_MASK_DYN) | (1 << UBLOX_CFG_NAV5_MASK_FIXMODE),
                                         UBLOX_CFG_NAV5_DYNMODEL_AIRBORNE_4G,
                                         UBLOX_CFG_NAV5_FIXMODE_3D,
@@ -587,6 +648,8 @@ ao_gps(void) __reentrant
                ao_ublox_len = header_byte();
                ao_ublox_len |= header_byte() << 8;
 
+               ao_gps_dbg(DBG_PROTO, "class %02x id %02x len %d\n", class, id, ao_ublox_len);
+
                if (ao_ublox_len > 1023)
                        continue;
 
@@ -627,8 +690,10 @@ ao_gps(void) __reentrant
                        break;
                }
 
-               if (ao_ublox_len != 0)
+               if (ao_ublox_len != 0) {
+                       ao_gps_dbg(DBG_PROTO, "len left %d\n", ao_ublox_len);
                        continue;
+               }
 
                /* verify checksum and end sequence */
                cksum.a = ao_ublox_byte();
@@ -654,7 +719,7 @@ ao_gps(void) __reentrant
                                }
                                if (nav_timeutc.valid & (1 << NAV_TIMEUTC_VALID_UTC))
                                        ao_gps_data.flags |= AO_GPS_DATE_VALID;
-                               
+
                                ao_gps_data.altitude = nav_posllh.alt_msl / 1000;
                                ao_gps_data.latitude = nav_posllh.lat;
                                ao_gps_data.longitude = nav_posllh.lon;
@@ -676,7 +741,7 @@ ao_gps(void) __reentrant
                                ao_gps_data.ground_speed = nav_velned.g_speed;
                                ao_gps_data.climb_rate = -nav_velned.vel_d;
                                ao_gps_data.course = nav_velned.heading / 200000;
-                               
+
                                ao_gps_tracking_data.channels = 0;
 
                                struct ao_telemetry_satellite_info *dst = &ao_gps_tracking_data.sats[0];
@@ -704,8 +769,24 @@ ao_gps(void) __reentrant
        }
 }
 
+#if AO_UBLOX_DEBUG
+static void ao_gps_option(void)
+{
+       ao_cmd_hex();
+       if (ao_cmd_status != ao_cmd_success) {
+               ao_cmd_status = ao_cmd_success;
+               ao_gps_show();
+       } else {
+               ao_gps_dbg_enable = ao_cmd_lex_i;
+               printf ("gps debug set to %d\n", ao_gps_dbg_enable);
+       }
+}
+#else
+#define ao_gps_option ao_gps_show
+#endif
+
 __code struct ao_cmds ao_gps_cmds[] = {
-       { ao_gps_show,  "g\0Display GPS" },
+       { ao_gps_option,        "g\0Display GPS" },
        { 0, NULL },
 };
 
index 016bb7e7d4a6891072e056c222a4f5e81e5a14b3..86f76d46e74f66b0e286ce0257436ab991b3f886 100644 (file)
@@ -6,7 +6,7 @@ vpath ao-make-product.5c $(TOPDIR)/util
 .elf.ihx:
        objcopy -O ihex $*.elf $@
 
-CC=arm-none-eabi-gcc
+CC=/opt/cortex/bin/arm-none-eabi-gcc
 SAT=/opt/cortex
 SAT_CLIB=$(SAT)/lib/pdclib-cortex-m3.a
 SAT_CFLAGS=-I$(SAT)/include
index adc288c31bd1efc5fa5f9380f05dcb299fabb575..42fe727a84139d0ff47351681c868f81240ab435 100644 (file)
@@ -34,6 +34,8 @@
 #define AO_TICK_SIGNED int16_t
 #endif
 
+#define AO_PORT_TYPE   uint16_t
+
 /* Various definitions to make GCC look more like SDCC */
 
 #define ao_arch_naked_declare  __attribute__((naked))
index 6fe86e62c4dc5718a6c159d1cb15e8324423488c..9bb2d7cd5d830c158bd0dbbeb01ec3a39b63d64c 100644 (file)
@@ -338,6 +338,11 @@ static inline void ao_arch_restore_stack(void) {
        asm("bx lr");
 }
 
+#ifndef HAS_SAMPLE_PROFILE
+#define HAS_SAMPLE_PROFILE 0
+#endif
+
+#if !HAS_SAMPLE_PROFILE
 #define HAS_ARCH_START_SCHEDULER       1
 
 static inline void ao_arch_start_scheduler(void) {
@@ -350,15 +355,17 @@ static inline void ao_arch_start_scheduler(void) {
        control |= (1 << 1);
        asm("msr control,%0" : : "r" (control));
 }
+#endif
 
 #define ao_arch_isr_stack()
 
 #endif
 
-#define ao_arch_wait_interrupt() do {                  \
-               asm(".global ao_idle_loc\n\twfi\nao_idle_loc:");        \
-               ao_arch_release_interrupts();                           \
-               ao_arch_block_interrupts();                             \
+#define ao_arch_wait_interrupt() do {                          \
+               asm("\twfi\n");                                 \
+               ao_arch_release_interrupts();                   \
+               asm(".global ao_idle_loc\nao_idle_loc:");       \
+               ao_arch_block_interrupts();                     \
        } while (0)
 
 #define ao_arch_critical(b) do {                               \
index 4761fbfc87d5fbf8f05bc0a48364a0a47e8e15eb..a95d869bdf7caacfd6eca90e66899196cacdf8bb 100644 (file)
 
 #include "ao.h"
 
+#ifndef BEEPER_CHANNEL
+#define BEEPER_CHANNEL 1
+#endif
+
 void
 ao_beep(uint8_t beep)
 {
@@ -56,6 +60,7 @@ ao_beep(uint8_t beep)
                 *  is enabled and active high.
                 */
 
+#if BEEPER_CHANNEL == 1
                stm_tim3.ccmr1 = ((0 << STM_TIM234_CCMR1_OC2CE) |
                                  (STM_TIM234_CCMR1_OC2M_FROZEN << STM_TIM234_CCMR1_OC2M) |
                                  (0 << STM_TIM234_CCMR1_OC2PE) |
@@ -68,7 +73,6 @@ ao_beep(uint8_t beep)
                                  (0 << STM_TIM234_CCMR1_OC1FE) |
                                  (STM_TIM234_CCMR1_CC1S_OUTPUT << STM_TIM234_CCMR1_CC1S));
 
-
                stm_tim3.ccer = ((0 << STM_TIM234_CCER_CC4NP) |
                                 (0 << STM_TIM234_CCER_CC4P) |
                                 (0 << STM_TIM234_CCER_CC4E) |
@@ -81,6 +85,33 @@ ao_beep(uint8_t beep)
                                 (0 << STM_TIM234_CCER_CC1NP) |
                                 (0 << STM_TIM234_CCER_CC1P) |
                                 (1 << STM_TIM234_CCER_CC1E));
+#endif
+#if BEEPER_CHANNEL == 4
+               stm_tim3.ccmr2 = ((0 << STM_TIM234_CCMR2_OC4CE) |
+                                 (STM_TIM234_CCMR2_OC4M_TOGGLE << STM_TIM234_CCMR2_OC4M) |
+                                 (0 << STM_TIM234_CCMR2_OC4PE) |
+                                 (0 << STM_TIM234_CCMR2_OC4FE) |
+                                 (STM_TIM234_CCMR2_CC4S_OUTPUT << STM_TIM234_CCMR2_CC4S) |
+
+                                 (0 << STM_TIM234_CCMR2_OC3CE) |
+                                 (STM_TIM234_CCMR2_OC3M_FROZEN << STM_TIM234_CCMR2_OC3M) |
+                                 (0 << STM_TIM234_CCMR2_OC3PE) |
+                                 (0 << STM_TIM234_CCMR2_OC3FE) |
+                                 (STM_TIM234_CCMR2_CC3S_OUTPUT << STM_TIM234_CCMR2_CC3S));
+
+               stm_tim3.ccer = ((0 << STM_TIM234_CCER_CC4NP) |
+                                (0 << STM_TIM234_CCER_CC4P) |
+                                (1 << STM_TIM234_CCER_CC4E) |
+                                (0 << STM_TIM234_CCER_CC3NP) |
+                                (0 << STM_TIM234_CCER_CC3P) |
+                                (0 << STM_TIM234_CCER_CC3E) |
+                                (0 << STM_TIM234_CCER_CC2NP) |
+                                (0 << STM_TIM234_CCER_CC2P) |
+                                (0 << STM_TIM234_CCER_CC2E) |
+                                (0 << STM_TIM234_CCER_CC1NP) |
+                                (0 << STM_TIM234_CCER_CC1P) |
+                                (0 << STM_TIM234_CCER_CC1E));
+#endif
 
 
                /* 5. Enable the counter by setting the CEN bit in the TIMx_CR1 register. */
@@ -110,13 +141,22 @@ ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant
 void
 ao_beep_init(void)
 {
-       /* Our beeper is on PC6, which is hooked to TIM3_CH1,
-        * which is on PC6
-        */
+#if BEEPER_CHANNEL == 1
 
+       /* Our beeper is on PC6, which is hooked to TIM3_CH1.
+        */
        stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOCEN);
 
        stm_afr_set(&stm_gpioc, 6, STM_AFR_AF2);
+#endif
+#if BEEPER_CHANNEL == 4
+
+       /* Our beeper is on PB1, which is hooked to TIM3_CH4.
+        */
+       stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN);
+
+       stm_afr_set(&stm_gpiob, 1, STM_AFR_AF2);
+#endif
 
        /* Leave the timer off until requested */
        
index daf2f4000f3a7c3fc012064ac431e5edc1378fdd..34f9edb90b084d40b5fbee14cdca7d313a03d30c 100644 (file)
@@ -67,20 +67,6 @@ ao_timer_set_adc_interval(uint8_t interval)
 }
 #endif
 
-/*
- * According to the STM clock-configuration, timers run
- * twice as fast as the APB1 clock *if* the APB1 prescaler
- * is greater than 1.
- */
-
-#if AO_APB1_PRESCALER > 1
-#define TIMER_23467_SCALER 2
-#else
-#define TIMER_23467_SCALER 1
-#endif
-
-#define TIMER_10kHz    ((AO_PCLK1 * TIMER_23467_SCALER) / 10000)
-
 #define SYSTICK_RELOAD (AO_SYSTICK / 100 - 1)
 
 void
@@ -104,7 +90,15 @@ ao_clock_init(void)
        /* Switch to MSI while messing about */
        stm_rcc.cr |= (1 << STM_RCC_CR_MSION);
        while (!(stm_rcc.cr & (1 << STM_RCC_CR_MSIRDY)))
-               asm("nop");
+               ao_arch_nop();
+
+       stm_rcc.cfgr = (stm_rcc.cfgr & ~(STM_RCC_CFGR_SW_MASK << STM_RCC_CFGR_SW)) |
+               (STM_RCC_CFGR_SW_MSI << STM_RCC_CFGR_SW);
+
+       /* wait for system to switch to MSI */
+       while ((stm_rcc.cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) !=
+              (STM_RCC_CFGR_SWS_MSI << STM_RCC_CFGR_SWS))
+               ao_arch_nop();
 
        /* reset SW, HPRE, PPRE1, PPRE2, MCOSEL and MCOPRE */
        stm_rcc.cfgr &= (uint32_t)0x88FFC00C;
@@ -155,7 +149,6 @@ ao_clock_init(void)
        stm_flash.acr |= (1 << STM_FLASH_ACR_PRFEN);
 
        /* Enable 1 wait state so the CPU can run at 32MHz */
-       /* (haven't managed to run the CPU at 32MHz yet, it's at 16MHz) */
        stm_flash.acr |= (1 << STM_FLASH_ACR_LATENCY);
 
        /* Enable power interface clock */
index 1868468f45ad5cf3f5ddcb5dce591bbfef04361a..ff3f53366904d277e4e4a3fc9a7d07fb048c35c3 100644 (file)
@@ -1739,7 +1739,7 @@ extern struct stm_tim234 stm_tim2, stm_tim3, stm_tim4;
 #define  STM_TIM234_CCMR1_CC1S_INPUT_TRC               3
 #define  STM_TIM234_CCMR1_CC1S_MASK                    3
 
-#define STM_TIM234_CCMR2_OC2CE 15
+#define STM_TIM234_CCMR2_OC4CE 15
 #define STM_TIM234_CCMR2_OC4M  12
 #define  STM_TIM234_CCMR2_OC4M_FROZEN                  0
 #define  STM_TIM234_CCMR2_OC4M_SET_HIGH_ON_MATCH       1
diff --git a/src/telemetrum-v2.0/.gitignore b/src/telemetrum-v2.0/.gitignore
new file mode 100644 (file)
index 0000000..35ce24d
--- /dev/null
@@ -0,0 +1,2 @@
+ao_product.h
+telemetrum-*.elf
diff --git a/src/telemetrum-v2.0/Makefile b/src/telemetrum-v2.0/Makefile
new file mode 100644 (file)
index 0000000..c03a553
--- /dev/null
@@ -0,0 +1,122 @@
+#
+# AltOS build
+#
+#
+
+include ../stm/Makefile.defs
+
+INC = \
+       ao.h \
+       ao_arch.h \
+       ao_arch_funcs.h \
+       ao_companion.h \
+       ao_data.h \
+       ao_sample.h \
+       ao_pins.h \
+       altitude-pa.h \
+       ao_kalman.h \
+       ao_product.h \
+       ao_ms5607.h \
+       ao_mma655x.h \
+       ao_cc1120_CC1120.h \
+       ao_profile.h \
+       ao_task.h \
+       ao_whiten.h \
+       ao_sample_profile.h \
+       ao_mpu.h \
+       stm32l.h \
+       Makefile
+
+#PROFILE=ao_profile.c
+#PROFILE_DEF=-DAO_PROFILE=1
+
+#SAMPLE_PROFILE=ao_sample_profile.c \
+#      ao_sample_profile_timer.c
+#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1
+
+#STACK_GUARD=ao_mpu_stm.c
+#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1
+
+ALTOS_SRC = \
+       ao_boot_chain.c \
+       ao_interrupt.c \
+       ao_product.c \
+       ao_romconfig.c \
+       ao_cmd.c \
+       ao_config.c \
+       ao_task.c \
+       ao_led.c \
+       ao_stdio.c \
+       ao_panic.c \
+       ao_timer.c \
+       ao_mutex.c \
+       ao_serial_stm.c \
+       ao_gps_ublox.c \
+       ao_gps_show.c \
+       ao_gps_report_metrum.c \
+       ao_ignite.c \
+       ao_freq.c \
+       ao_dma_stm.c \
+       ao_spi_stm.c \
+       ao_cc1120.c \
+       ao_fec_tx.c \
+       ao_fec_rx.c \
+       ao_data.c \
+       ao_ms5607.c \
+       ao_mma655x.c \
+       ao_adc_stm.c \
+       ao_beep_stm.c \
+       ao_storage.c \
+       ao_m25.c \
+       ao_usb_stm.c \
+       ao_exti_stm.c \
+       ao_report.c \
+       ao_convert_pa.c \
+       ao_log.c \
+       ao_log_metrum.c \
+       ao_sample.c \
+       ao_kalman.c \
+       ao_flight.c \
+       ao_telemetry.c \
+       ao_packet_slave.c \
+       ao_packet.c \
+       ao_companion.c \
+       ao_aprs.c \
+       $(PROFILE) \
+       $(SAMPLE_PROFILE) \
+       $(STACK_GUARD)
+
+PRODUCT=TeleMetrum-v2.0
+PRODUCT_DEF=-DTELEMETRUM_V_2_0
+IDPRODUCT=0x000b
+
+CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g
+
+PROGNAME=telemetrum-v2.0
+PROG=$(PROGNAME)-$(VERSION).elf
+
+SRC=$(ALTOS_SRC) ao_telemetrum.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG)
+
+$(PROG): Makefile $(OBJ) altos.ld
+       $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc
+
+../altitude-pa.h: make-altitude-pa
+       nickle $< > $@
+
+$(OBJ): $(INC)
+
+ao_product.h: ao-make-product.5c ../Version
+       $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
+
+distclean:     clean
+
+clean:
+       rm -f *.o $(PROGNAME)-*.elf
+       rm -f ao_product.h
+
+install:
+
+uninstall:
diff --git a/src/telemetrum-v2.0/ao_pins.h b/src/telemetrum-v2.0/ao_pins.h
new file mode 100644 (file)
index 0000000..a7236b8
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * Copyright © 2012 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.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+#define HAS_TASK_QUEUE         1
+
+/* 8MHz High speed external crystal */
+#define AO_HSE                 8000000
+
+/* PLLVCO = 96MHz (so that USB will work) */
+#define AO_PLLMUL              12
+#define AO_RCC_CFGR_PLLMUL     (STM_RCC_CFGR_PLLMUL_12)
+
+/* SYSCLK = 32MHz (no need to go faster than CPU) */
+#define AO_PLLDIV              3
+#define AO_RCC_CFGR_PLLDIV     (STM_RCC_CFGR_PLLDIV_3)
+
+/* HCLK = 32MHz (CPU clock) */
+#define AO_AHB_PRESCALER       1
+#define AO_RCC_CFGR_HPRE_DIV   STM_RCC_CFGR_HPRE_DIV_1
+
+/* Run APB1 at 16MHz (HCLK/2) */
+#define AO_APB1_PRESCALER      2
+#define AO_RCC_CFGR_PPRE1_DIV  STM_RCC_CFGR_PPRE2_DIV_2
+
+/* Run APB2 at 16MHz (HCLK/2) */
+#define AO_APB2_PRESCALER      2
+#define AO_RCC_CFGR_PPRE2_DIV  STM_RCC_CFGR_PPRE2_DIV_2
+
+#define HAS_SERIAL_1           0
+#define USE_SERIAL_1_STDIN     0
+#define SERIAL_1_PB6_PB7       0
+#define SERIAL_1_PA9_PA10      1
+
+#define HAS_SERIAL_2           0
+#define USE_SERIAL_2_STDIN     0
+#define SERIAL_2_PA2_PA3       0
+#define SERIAL_2_PD5_PD6       0
+
+#define HAS_SERIAL_3           1
+#define USE_SERIAL_3_STDIN     0
+#define SERIAL_3_PB10_PB11     1
+#define SERIAL_3_PC10_PC11     0
+#define SERIAL_3_PD8_PD9       0
+
+#define HAS_EEPROM             1
+#define USE_INTERNAL_FLASH     0
+#define HAS_USB                        1
+#define HAS_BEEP               1
+#define BEEPER_CHANNEL         4
+#define HAS_RADIO              1
+#define HAS_TELEMETRY          1
+#define HAS_APRS               1
+
+#define HAS_SPI_1              1
+#define SPI_1_PA5_PA6_PA7      1       /* Barometer */
+#define SPI_1_PB3_PB4_PB5      1       /* Accelerometer */
+#define SPI_1_PE13_PE14_PE15   0
+#define SPI_1_OSPEEDR          STM_OSPEEDR_10MHz
+
+#define HAS_SPI_2              1
+#define SPI_2_PB13_PB14_PB15   1       /* Flash, Companion, Radio */
+#define SPI_2_PD1_PD3_PD4      0
+#define SPI_2_OSPEEDR          STM_OSPEEDR_10MHz
+
+#define SPI_2_PORT             (&stm_gpiob)
+#define SPI_2_SCK_PIN          13
+#define SPI_2_MISO_PIN         14
+#define SPI_2_MOSI_PIN         15
+
+#define HAS_I2C_1              0
+#define I2C_1_PB8_PB9          0
+
+#define HAS_I2C_2              0
+#define I2C_2_PB10_PB11                0
+
+#define PACKET_HAS_SLAVE       1
+#define PACKET_HAS_MASTER      0
+
+#define LOW_LEVEL_DEBUG                0
+
+#define LED_PORT_ENABLE                STM_RCC_AHBENR_GPIOCEN
+#define LED_PORT               (&stm_gpioc)
+#define LED_PIN_RED            14
+#define LED_PIN_GREEN          15
+#define AO_LED_RED             (1 << LED_PIN_RED)
+#define AO_LED_GREEN           (1 << LED_PIN_GREEN)
+
+#define LEDS_AVAILABLE         (AO_LED_RED | AO_LED_GREEN)
+
+#define HAS_GPS                        1
+#define HAS_FLIGHT             1
+#define HAS_ADC                        1
+#define HAS_ADC_TEMP           1
+#define HAS_LOG                        1
+
+/*
+ * Igniter
+ */
+
+#define HAS_IGNITE             1
+#define HAS_IGNITE_REPORT      1
+
+#define AO_SENSE_DROGUE(p)     ((p)->adc.sense_a)
+#define AO_SENSE_MAIN(p)       ((p)->adc.sense_m)
+#define AO_IGNITER_CLOSED      400
+#define AO_IGNITER_OPEN                60
+
+/* Drogue */
+#define AO_IGNITER_DROGUE_PORT (&stm_gpioa)
+#define AO_IGNITER_DROGUE_PIN  8
+
+/* Main */
+#define AO_IGNITER_MAIN_PORT   (&stm_gpioa)
+#define AO_IGNITER_MAIN_PIN    9
+
+#define AO_IGNITER_SET_DROGUE(v)       stm_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, v)
+#define AO_IGNITER_SET_MAIN(v)         stm_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, v)
+
+/*
+ * ADC
+ */
+#define AO_DATA_RING           32
+#define AO_ADC_NUM_SENSE       2
+
+struct ao_adc {
+       int16_t                 sense_a;
+       int16_t                 sense_m;
+       int16_t                 v_batt;
+       int16_t                 temp;
+};
+
+#define AO_ADC_DUMP(p) \
+       printf("tick: %5u drogue: %5d main: %5d batt: %5d\n", \
+              (p)->tick, \
+              (p)->adc.sense_a, (p)->adc.sense_m, \
+              (p)->adc.v_batt);
+
+#define AO_ADC_SENSE_DROGUE    0
+#define AO_ADC_SENSE_DROGUE_PORT       (&stm_gpioa)
+#define AO_ADC_SENSE_DROGUE_PIN        0
+
+#define AO_ADC_SENSE_MAIN      1
+#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioa)
+#define AO_ADC_SENSE_MAIN_PIN  1
+
+#define AO_ADC_V_BATT          8
+#define AO_ADC_V_BATT_PORT     (&stm_gpiob)
+#define AO_ADC_V_BATT_PIN      0
+
+#define AO_ADC_TEMP            16
+
+#define AO_ADC_RCC_AHBENR      ((1 << STM_RCC_AHBENR_GPIOAEN) | \
+                                (1 << STM_RCC_AHBENR_GPIOEEN) | \
+                                (1 << STM_RCC_AHBENR_GPIOBEN))
+
+#define AO_NUM_ADC_PIN         3
+
+#define AO_ADC_PIN0_PORT       AO_ADC_SENSE_DROGUE_PORT
+#define AO_ADC_PIN0_PIN                AO_ADC_SENSE_DROGUE_PIN
+#define AO_ADC_PIN1_PORT       AO_ADC_SENSE_MAIN_PORT
+#define AO_ADC_PIN1_PIN                AO_ADC_SENSE_MAIN_PIN
+#define AO_ADC_PIN2_PORT       AO_ADC_V_BATT_PORT
+#define AO_ADC_PIN2_PIN                AO_ADC_V_BATT_PIN
+
+#define AO_NUM_ADC             (AO_NUM_ADC_PIN + 1)
+
+#define AO_ADC_SQ1             AO_ADC_SENSE_DROGUE
+#define AO_ADC_SQ2             AO_ADC_SENSE_MAIN
+#define AO_ADC_SQ3             AO_ADC_V_BATT
+#define AO_ADC_SQ4             AO_ADC_TEMP
+
+/*
+ * GPS
+ */
+
+#define AO_SERIAL_SPEED_UBLOX  AO_SERIAL_SPEED_9600
+
+#define ao_gps_getchar         ao_serial3_getchar
+#define ao_gps_putchar         ao_serial3_putchar
+#define ao_gps_set_speed       ao_serial3_set_speed
+#define ao_gps_fifo            (ao_stm_usart3.rx_fifo)
+
+/*
+ * Pressure sensor settings
+ */
+#define HAS_MS5607             1
+#define HAS_MS5611             0
+#define AO_MS5607_PRIVATE_PINS 1
+#define AO_MS5607_CS_PORT      (&stm_gpiob)
+#define AO_MS5607_CS_PIN       12
+#define AO_MS5607_CS_MASK      (1 << AO_MS5607_CS)
+#define AO_MS5607_MISO_PORT    (&stm_gpioa)
+#define AO_MS5607_MISO_PIN     6
+#define AO_MS5607_MISO_MASK    (1 << AO_MS5607_MISO)
+#define AO_MS5607_SPI_INDEX    AO_SPI_1_PA5_PA6_PA7
+
+/*
+ * SPI Flash memory
+ */
+
+#define M25_MAX_CHIPS          1
+#define AO_M25_SPI_CS_PORT     (&stm_gpiob)
+#define AO_M25_SPI_CS_MASK     (1 << 8)
+#define AO_M25_SPI_BUS         AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Radio (cc1120)
+ */
+
+/* gets pretty close to 434.550 */
+
+#define AO_RADIO_CAL_DEFAULT   0x6ca333
+
+#define AO_FEC_DEBUG           0
+#define AO_CC1120_SPI_CS_PORT  (&stm_gpioa)
+#define AO_CC1120_SPI_CS_PIN   2
+#define AO_CC1120_SPI_BUS      AO_SPI_2_PB13_PB14_PB15
+#define AO_CC1120_SPI          stm_spi2
+
+#define AO_CC1120_INT_PORT             (&stm_gpioa)
+#define AO_CC1120_INT_PIN              (3)
+#define AO_CC1120_MCU_WAKEUP_PORT      (&stm_gpioa)
+#define AO_CC1120_MCU_WAKEUP_PIN       (4)
+
+#define AO_CC1120_INT_GPIO     2
+#define AO_CC1120_INT_GPIO_IOCFG       CC1120_IOCFG2
+
+#define AO_CC1120_MARC_GPIO    3
+#define AO_CC1120_MARC_GPIO_IOCFG      CC1120_IOCFG3
+
+#define HAS_BOOT_RADIO         0
+
+#define HAS_HIGHG_ACCEL                1
+
+/*
+ * mma655x
+ */
+
+#define HAS_MMA655X            1
+#define AO_MMA655X_SPI_INDEX   AO_SPI_1_PB3_PB4_PB5
+#define AO_MMA655X_CS_PORT     (&stm_gpiob)
+#define AO_MMA655X_CS_PIN      9
+#define AO_MMA655X_INVERT      1
+
+#define NUM_CMDS               16
+
+/*
+ * Companion
+ */
+
+#define AO_COMPANION_CS_PORT   (&stm_gpiob)
+#define AO_COMPANION_CS_PIN    (6)
+#define AO_COMPANION_SPI_BUS   AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Monitor
+ */
+
+#define HAS_MONITOR            0
+#define LEGACY_MONITOR         0
+#define HAS_MONITOR_PUT                1
+#define AO_MONITOR_LED         0
+#define HAS_RSSI               0
+
+/*
+ * Profiling Viterbi decoding
+ */
+
+#ifndef AO_PROFILE
+#define AO_PROFILE             0
+#endif
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telemetrum-v2.0/ao_telemetrum.c b/src/telemetrum-v2.0/ao_telemetrum.c
new file mode 100644 (file)
index 0000000..e365417
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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_ms5607.h>
+#include <ao_mma655x.h>
+#include <ao_log.h>
+#include <ao_exti.h>
+#include <ao_packet.h>
+#include <ao_companion.h>
+#include <ao_profile.h>
+#if HAS_SAMPLE_PROFILE
+#include <ao_sample_profile.h>
+#endif
+#if HAS_STACK_GUARD
+#include <ao_mpu.h>
+#endif
+
+int
+main(void)
+{
+       ao_clock_init();
+       
+#if HAS_STACK_GUARD
+       ao_mpu_init();
+#endif
+
+       ao_task_init();
+       ao_serial_init();
+       ao_led_init(LEDS_AVAILABLE);
+       ao_led_on(AO_LED_GREEN);
+       ao_timer_init();
+
+       ao_spi_init();
+       ao_dma_init();
+       ao_exti_init();
+
+       ao_adc_init();
+#if HAS_BEEP
+       ao_beep_init();
+#endif
+       ao_cmd_init();
+
+#if HAS_MS5607
+       ao_ms5607_init();
+#endif
+#if HAS_MMA655X
+       ao_mma655x_init();
+#endif
+
+       ao_storage_init();
+       
+       ao_flight_init();
+       ao_log_init();
+       ao_report_init();
+
+       ao_usb_init();
+       ao_gps_init();
+       ao_gps_report_metrum_init();
+       ao_telemetry_init();
+       ao_radio_init();
+       ao_packet_slave_init(FALSE);
+       ao_igniter_init();
+       ao_companion_init();
+
+       ao_config_init();
+#if AO_PROFILE
+       ao_profile_init();
+#endif
+#if HAS_SAMPLE_PROFILE
+       ao_sample_profile_init();
+#endif
+       
+       ao_start_scheduler();
+       return 0;
+}
diff --git a/src/telemetrum-v2.0/flash-loader/Makefile b/src/telemetrum-v2.0/flash-loader/Makefile
new file mode 100644 (file)
index 0000000..cb99c51
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=telemetrum-v2.0
+include $(TOPDIR)/stm/Makefile-flash.defs
diff --git a/src/telemetrum-v2.0/flash-loader/ao_pins.h b/src/telemetrum-v2.0/flash-loader/ao_pins.h
new file mode 100644 (file)
index 0000000..304bb7c
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+/* External crystal at 8MHz */
+#define AO_HSE         8000000
+
+#include <ao_flash_stm_pins.h>
+
+/* Companion port cs_companion0 PB6 */
+
+#define AO_BOOT_PIN                    1
+#define AO_BOOT_APPLICATION_GPIO       stm_gpiob
+#define AO_BOOT_APPLICATION_PIN                6
+#define AO_BOOT_APPLICATION_VALUE      1
+#define AO_BOOT_APPLICATION_MODE       AO_EXTI_MODE_PULL_UP
+
+#endif /* _AO_PINS_H_ */