+/*
+ * ao_log.c
+ */
+
+/* Structure containing GPS position, either lat or lon */
+
+struct ao_gps_pos {
+ uint8_t degrees;
+ uint8_t minutes;
+ uint16_t minutes_fraction; /* in units of 1/10000 minutes */
+};
+
+/*
+ * The data log is recorded in the eeprom as a sequence
+ * of data packets.
+ *
+ * Each packet starts with a 4-byte header that has the
+ * packet type, the packet checksum and the tick count. Then
+ * they all contain 2 16 bit values which hold packet-specific
+ * data.
+ *
+ * For each flight, the first packet
+ * is FLIGHT packet, indicating the serial number of the
+ * device and a unique number marking the number of flights
+ * recorded by this device.
+ *
+ * During flight, data from the accelerometer and barometer
+ * are recorded in SENSOR packets, using the raw 16-bit values
+ * read from the A/D converter.
+ *
+ * Also during flight, but at a lower rate, the deployment
+ * sensors are recorded in DEPLOY packets. The goal here is to
+ * detect failure in the deployment circuits.
+ *
+ * STATE packets hold state transitions as the flight computer
+ * transitions through different stages of the flight.
+ */
+#define AO_LOG_FLIGHT 'F'
+#define AO_LOG_SENSOR 'A'
+#define AO_LOG_TEMP_VOLT 'T'
+#define AO_LOG_DEPLOY 'D'
+#define AO_LOG_STATE 'S'
+#define AO_LOG_GPS_TIME 'G'
+#define AO_LOG_GPS_LAT 'N'
+#define AO_LOG_GPS_LON 'W'
+#define AO_LOG_GPS_ALT 'H'
+
+#define AO_LOG_POS_NONE (~0UL)
+
+struct ao_log_record {
+ char type;
+ uint8_t csum;
+ uint16_t tick;
+ union {
+ struct {
+ int16_t ground_accel;
+ uint16_t flight;
+ } flight;
+ struct {
+ int16_t accel;
+ int16_t pres;
+ } sensor;
+ struct {
+ int16_t temp;
+ int16_t v_batt;
+ } temp_volt;
+ struct {
+ int16_t drogue;
+ int16_t main;
+ } deploy;
+ struct {
+ uint16_t state;
+ uint16_t reason;
+ } state;
+ struct {
+ uint8_t hour;
+ uint8_t minute;
+ uint8_t second;
+ uint8_t flags;
+ } gps_time;
+ struct ao_gps_pos gps_latitude;
+ struct ao_gps_pos gps_longitude;
+ struct {
+ int16_t altitude;
+ uint16_t unused;
+ } gps_altitude;
+ struct {
+ uint16_t d0;
+ uint16_t d1;
+ } anon;
+ } u;
+};
+
+/* Write a record to the eeprom log */
+void
+ao_log_data(struct ao_log_record *log);
+
+/* Flush the log */
+void
+ao_log_flush(void);
+
+/* Log dumping API:
+ * ao_log_dump_first() - get first log record
+ * ao_log_dump_next() - get next log record
+ */
+extern __xdata struct ao_log_record ao_log_dump;
+
+/* Retrieve first log record for the current flight */
+uint8_t
+ao_log_dump_first(void);
+
+/* return next log record for the current flight */
+uint8_t
+ao_log_dump_next(void);
+
+/* Logging thread main routine */
+void
+ao_log(void);
+
+/* Start logging to eeprom */
+void
+ao_log_start(void);
+
+/* Stop logging */
+void
+ao_log_stop(void);
+
+/* Initialize the logging system */
+void
+ao_log_init(void);
+
+/*
+ * ao_flight.c
+ */
+
+enum ao_flight_state {
+ ao_flight_startup = 0,
+ ao_flight_idle = 1,
+ ao_flight_launchpad = 2,
+ ao_flight_boost = 3,
+ ao_flight_coast = 4,
+ ao_flight_apogee = 5,
+ ao_flight_drogue = 6,
+ ao_flight_main = 7,
+ ao_flight_landed = 8,
+ ao_flight_invalid = 9
+};
+
+extern __xdata struct ao_adc ao_flight_data;
+extern __pdata enum ao_flight_state ao_flight_state;
+extern __pdata uint16_t ao_flight_tick;
+extern __pdata int16_t ao_flight_accel;
+extern __pdata int16_t ao_flight_pres;
+extern __pdata int16_t ao_ground_pres;
+extern __pdata int16_t ao_ground_accel;
+extern __pdata int16_t ao_min_pres;
+extern __pdata uint16_t ao_launch_time;
+
+/* Flight thread */
+void
+ao_flight(void);
+
+/* Initialize flight thread */
+void
+ao_flight_init(void);
+
+/*
+ * ao_report.c
+ */
+
+void
+ao_report_init(void);
+
+/*
+ * ao_convert.c
+ *
+ * Given raw data, convert to SI units
+ */
+
+/* pressure from the sensor to altitude in meters */
+int16_t
+ao_pres_to_altitude(int16_t pres) __reentrant;
+
+int16_t
+ao_altitude_to_pres(int16_t alt) __reentrant;
+
+int16_t
+ao_temp_to_dC(int16_t temp) __reentrant;
+
+/*
+ * ao_dbg.c
+ *
+ * debug another telemetrum board
+ */
+
+/* Send a byte to the dbg target */
+void
+ao_dbg_send_byte(uint8_t byte);
+
+/* Receive a byte from the dbg target */
+uint8_t
+ao_dbg_recv_byte(void);
+
+/* Start a bulk transfer to/from dbg target memory */
+void
+ao_dbg_start_transfer(uint16_t addr);
+
+/* End a bulk transfer to/from dbg target memory */
+void
+ao_dbg_end_transfer(void);
+
+/* Write a byte to dbg target memory */
+void
+ao_dbg_write_byte(uint8_t byte);
+
+/* Read a byte from dbg target memory */
+uint8_t
+ao_dbg_read_byte(void);
+
+/* Enable dbg mode, switching use of the pins */
+void
+ao_dbg_debug_mode(void);
+
+/* Reset the dbg target */
+void
+ao_dbg_reset(void);
+
+void
+ao_dbg_init(void);
+
+/*
+ * ao_serial.c
+ */
+
+#if !AO_NO_SERIAL_ISR
+void
+ao_serial_rx1_isr(void) interrupt 3;
+
+void
+ao_serial_tx1_isr(void) interrupt 14;
+#endif
+
+char
+ao_serial_getchar(void) __critical;
+
+void
+ao_serial_putchar(char c) __critical;
+
+void
+ao_serial_init(void);
+
+/*
+ * ao_gps.c
+ */
+
+#define AO_GPS_NUM_SAT_MASK (0xf << 0)
+#define AO_GPS_NUM_SAT_SHIFT (0)
+
+#define AO_GPS_VALID (1 << 4)
+#define AO_GPS_LONGITUDE_MASK (1 << 5)
+#define AO_GPS_LONGITUDE_EAST (0 << 5)
+#define AO_GPS_LONGITUDE_WEST (1 << 5)
+
+#define AO_GPS_LATITUDE_MASK (1 << 6)
+#define AO_GPS_LATITUDE_NORTH (0 << 6)
+#define AO_GPS_LATITUDE_SOUTH (1 << 6)
+
+struct ao_gps_data {
+ uint8_t hour;
+ uint8_t minute;
+ uint8_t second;
+ uint8_t flags;
+ struct ao_gps_pos latitude;
+ struct ao_gps_pos longitude;
+ int16_t altitude;
+};
+
+extern __xdata uint8_t ao_gps_mutex;
+extern __xdata struct ao_gps_data ao_gps_data;
+
+void
+ao_gps(void);
+
+void
+ao_gps_print(__xdata struct ao_gps_data *gps_data);
+
+void
+ao_gps_init(void);
+
+/*
+ * ao_gps_report.c
+ */
+
+void
+ao_gps_report(void);
+
+void
+ao_gps_report_init(void);
+
+/*
+ * ao_telemetry.c
+ */
+
+#define AO_MAX_CALLSIGN 8
+
+struct ao_telemetry {
+ uint8_t addr;
+ uint8_t flight_state;
+ struct ao_adc adc;
+ struct ao_gps_data gps;
+ char callsign[AO_MAX_CALLSIGN];
+};
+
+/* Set delay between telemetry reports (0 to disable) */
+
+#define AO_TELEMETRY_INTERVAL_PAD AO_MS_TO_TICKS(1000)
+#define AO_TELEMETRY_INTERVAL_FLIGHT AO_MS_TO_TICKS(50)
+#define AO_TELEMETRY_INTERVAL_RECOVER AO_MS_TO_TICKS(1000)
+
+void
+ao_telemetry_set_interval(uint16_t interval);
+
+void
+ao_rdf_set(uint8_t rdf);
+
+void
+ao_telemetry_init(void);
+
+/*
+ * ao_radio.c
+ */
+
+void
+ao_radio_send(__xdata struct ao_telemetry *telemetry) __reentrant;
+
+struct ao_radio_recv {
+ struct ao_telemetry telemetry;
+ int8_t rssi;
+ uint8_t status;
+};
+
+void
+ao_radio_recv(__xdata struct ao_radio_recv *recv) __reentrant;
+
+void
+ao_radio_rdf(void);
+
+void
+ao_radio_rdf_abort(void);
+
+void
+ao_radio_init(void);
+
+/*
+ * ao_monitor.c
+ */
+
+extern const char const * const ao_state_names[];
+
+void
+ao_monitor(void);
+
+void
+ao_monitor_init(uint8_t led);
+
+/*
+ * ao_stdio.c
+ */
+
+void
+flush(void);
+
+/*
+ * ao_ignite.c
+ */
+
+enum ao_igniter {
+ ao_igniter_drogue = 0,
+ ao_igniter_main = 1
+};
+
+void
+ao_ignite(enum ao_igniter igniter);
+
+enum ao_igniter_status {
+ ao_igniter_unknown, /* unknown status (ambiguous voltage) */
+ ao_igniter_ready, /* continuity detected */
+ ao_igniter_active, /* igniter firing */
+ ao_igniter_open, /* open circuit detected */
+};
+
+enum ao_igniter_status
+ao_igniter_status(enum ao_igniter igniter);
+
+void
+ao_igniter_init(void);
+
+/*
+ * ao_config.c
+ */
+
+#define AO_CONFIG_MAJOR 1
+#define AO_CONFIG_MINOR 0
+
+struct ao_config {
+ uint8_t major;
+ uint8_t minor;
+ uint16_t main_deploy;
+ int16_t accel_zero_g;
+ uint8_t radio_channel;
+ char callsign[AO_MAX_CALLSIGN + 1];
+};
+
+extern __xdata struct ao_config ao_config;
+
+void
+ao_config_get(void);
+
+void
+ao_config_init(void);
+
+/*
+ * ao_rssi.c
+ */
+
+void
+ao_rssi_set(int rssi_value);
+
+void
+ao_rssi_init(uint8_t rssi_led);
+
+/*
+ * ao_product.c
+ *
+ * values which need to be defined for
+ * each instance of a product
+ */
+
+extern const uint8_t ao_usb_descriptors [];
+extern const uint16_t ao_serial_number;
+extern const char ao_version[];
+extern const char ao_manufacturer[];
+extern const char ao_product[];
+