altos: Initial TeleMetrum v2.0 bits
authorKeith Packard <keithp@keithp.com>
Tue, 20 Aug 2013 18:40:17 +0000 (11:40 -0700)
committerKeith Packard <keithp@keithp.com>
Wed, 28 Aug 2013 03:56:42 +0000 (21:56 -0600)
Adds new telemetry and logging formats along with code for TeleMetrum
v2.0 design.

Signed-off-by: Keith Packard <keithp@keithp.com>
12 files changed:
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_telemetry.c
src/core/ao_telemetry.h
src/stm/ao_arch.h
src/stm/ao_beep_stm.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]

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..9c17eee
--- /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[0];
+                               log.u.volt.sense_m = ao_data_ring[ao_log_data_pos].adc.sense[1];
+                               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 03a8a273c9d24eaea09d90ba6de9853a7012e6c9..fb40451c0c31c5e2aac587bc0c63faf924439819 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,57 @@ 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.tick = packet->tick;
+       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[0];
+       telemetry.metrum_sensor.sense_m = packet->adc.sense[1];
+
+       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_MEGA_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_MEGA */
+
 #ifdef AO_SEND_ALL_BARO
 static uint8_t         ao_baro_sample;
 
@@ -326,10 +381,15 @@ ao_telemetry(void)
 #ifdef AO_SEND_MEGA
                                ao_send_mega_sensor();
                                ao_send_mega_data();
+#else
+#ifdef AO_SEND_METRUM
+                               ao_send_metrum_sensor();
+                               ao_send_metrum_data();
 #else
                                ao_send_sensor();
 #endif
 #endif
+#endif
 
 #if HAS_COMPANION
                                if (ao_companion_running)
@@ -399,6 +459,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 f2d201ded4fc7614d048899313d3a8fc7ca32372..17dc3e934f669f9ca515a3209d4993ec0f9bffc9 100644 (file)
@@ -207,6 +207,48 @@ 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_SEND_ALL_BARO */
 
 #define AO_TELEMETRY_BARO              0x80
@@ -240,6 +282,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_baro                baro;
 };
 
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 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 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..36cfc7e
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * 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 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)
+
+#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[0])
+#define AO_SENSE_MAIN(p)       ((p)->adc.sense[1])
+#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[AO_ADC_NUM_SENSE];
+       int16_t                 v_batt;
+       int16_t                 temp;
+};
+
+#define AO_ADC_DUMP(p) \
+       printf("tick: %5u drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \
+              (p)->tick, \
+              (p)->adc.sense[0], (p)->adc.sense[1], \
+              (p)->adc.v_batt, (p)->adc.temp)
+
+#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
+
+/*
+ * 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_PE13_PE14_PE15
+#define AO_MMA655X_CS_PORT     (&stm_gpiod)
+#define AO_MMA655X_CS_PIN      4
+
+#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;
+}