summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2012-04-12 14:51:07 -0700
committerKeith Packard <keithp@keithp.com>2012-04-14 14:04:29 -0700
commit040a6eb119451026e1ec7c3a6a8e76b439c632d5 (patch)
treec334b0f83d8202626c544238b53def46339042b0 /src/core
parentf952f9c285e2718a433c8c720c9b5d9c369e7036 (diff)
altos: Massive product config cleanup
Support multiple serial ports more cleanly Split out parts of ao.h into separate feature header files Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/ao.h704
-rw-r--r--src/core/ao_adc.h62
-rw-r--r--src/core/ao_beep.h74
-rw-r--r--src/core/ao_dbg.h62
-rw-r--r--src/core/ao_flight.h59
-rw-r--r--src/core/ao_led.h55
-rw-r--r--src/core/ao_log.h196
-rw-r--r--src/core/ao_log_telem.c4
-rw-r--r--src/core/ao_product.c8
-rw-r--r--src/core/ao_report.c2
-rw-r--r--src/core/ao_sample.h137
-rw-r--r--src/core/ao_serial.h86
-rw-r--r--src/core/ao_stdio.c6
-rw-r--r--src/core/ao_storage.c2
-rw-r--r--src/core/ao_storage.h84
-rw-r--r--src/core/ao_usb.h136
16 files changed, 994 insertions, 683 deletions
diff --git a/src/core/ao.h b/src/core/ao.h
index 9a3b5829..28d0ba87 100644
--- a/src/core/ao.h
+++ b/src/core/ao.h
@@ -154,182 +154,14 @@ void
ao_clock_init(void);
/*
- * One set of samples read from the A/D converter or telemetry
- */
-
-#if HAS_ADC
-
-/*
- * ao_adc.c
- */
-
-#define ao_adc_ring_next(n) (((n) + 1) & (AO_ADC_RING - 1))
-#define ao_adc_ring_prev(n) (((n) - 1) & (AO_ADC_RING - 1))
-
-
-/*
- * A/D data is stored in a ring, with the next sample to be written
- * at ao_adc_head
- */
-extern volatile __xdata struct ao_adc ao_adc_ring[AO_ADC_RING];
-extern volatile __data uint8_t ao_adc_head;
-#if HAS_ACCEL_REF
-extern volatile __xdata uint16_t ao_accel_ref[AO_ADC_RING];
-#endif
-
-/* Trigger a conversion sequence (called from the timer interrupt) */
-void
-ao_adc_poll(void);
-
-/* Suspend the current task until another A/D sample is converted */
-void
-ao_adc_sleep(void);
-
-/* Get a copy of the last complete A/D sample set */
-void
-ao_adc_get(__xdata struct ao_adc *packet);
-
-/* The A/D interrupt handler */
-
-void
-ao_adc_isr(void) ao_arch_interrupt(1);
-
-/* Initialize the A/D converter */
-void
-ao_adc_init(void);
-
-#endif /* HAS_ADC */
-
-/*
- * ao_beep.c
- */
-
-/*
- * Various pre-defined beep frequencies
- *
- * frequency = 1/2 (24e6/32) / beep
- */
-
-#define AO_BEEP_LOW 150 /* 2500Hz */
-#define AO_BEEP_MID 94 /* 3989Hz */
-#define AO_BEEP_HIGH 75 /* 5000Hz */
-#define AO_BEEP_OFF 0 /* off */
-
-#define AO_BEEP_g 240 /* 1562.5Hz */
-#define AO_BEEP_gs 227 /* 1652Hz (1655Hz) */
-#define AO_BEEP_aa 214 /* 1752Hz (1754Hz) */
-#define AO_BEEP_bbf 202 /* 1856Hz (1858Hz) */
-#define AO_BEEP_bb 190 /* 1974Hz (1969Hz) */
-#define AO_BEEP_cc 180 /* 2083Hz (2086Hz) */
-#define AO_BEEP_ccs 170 /* 2205Hz (2210Hz) */
-#define AO_BEEP_dd 160 /* 2344Hz (2341Hz) */
-#define AO_BEEP_eef 151 /* 2483Hz (2480Hz) */
-#define AO_BEEP_ee 143 /* 2622Hz (2628Hz) */
-#define AO_BEEP_ff 135 /* 2778Hz (2784Hz) */
-#define AO_BEEP_ffs 127 /* 2953Hz (2950Hz) */
-#define AO_BEEP_gg 120 /* 3125Hz */
-#define AO_BEEP_ggs 113 /* 3319Hz (3311Hz) */
-#define AO_BEEP_aaa 107 /* 3504Hz (3508Hz) */
-#define AO_BEEP_bbbf 101 /* 3713Hz (3716Hz) */
-#define AO_BEEP_bbb 95 /* 3947Hz (3937Hz) */
-#define AO_BEEP_ccc 90 /* 4167Hz (4171Hz) */
-#define AO_BEEP_cccs 85 /* 4412Hz (4419Hz) */
-#define AO_BEEP_ddd 80 /* 4688Hz (4682Hz) */
-#define AO_BEEP_eeef 76 /* 4934Hz (4961Hz) */
-#define AO_BEEP_eee 71 /* 5282Hz (5256Hz) */
-#define AO_BEEP_fff 67 /* 5597Hz (5568Hz) */
-#define AO_BEEP_fffs 64 /* 5859Hz (5899Hz) */
-#define AO_BEEP_ggg 60 /* 6250Hz */
-
-/* Set the beeper to the specified tone */
-void
-ao_beep(uint8_t beep);
-
-/* Turn on the beeper for the specified time */
-void
-ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant;
-
-/* Initialize the beeper */
-void
-ao_beep_init(void);
-
-/*
- * ao_led.c
- */
-
-#define AO_LED_NONE 0
-
-#ifndef AO_LED_TYPE
-#define AO_LED_TYPE uint8_t
-#endif
-
-/* Turn on the specified LEDs */
-void
-ao_led_on(AO_LED_TYPE colors);
-
-/* Turn off the specified LEDs */
-void
-ao_led_off(AO_LED_TYPE colors);
-
-/* Set all of the LEDs to the specified state */
-void
-ao_led_set(AO_LED_TYPE colors);
-
-/* Toggle the specified LEDs */
-void
-ao_led_toggle(AO_LED_TYPE colors);
-
-/* Turn on the specified LEDs for the indicated interval */
-void
-ao_led_for(AO_LED_TYPE colors, uint16_t ticks) __reentrant;
-
-/* Initialize the LEDs */
-void
-ao_led_init(AO_LED_TYPE enable);
-
-/*
- * ao_usb.c
- */
-
-/* Put one character to the USB output queue */
-void
-ao_usb_putchar(char c);
-
-/* Get one character from the USB input queue */
-char
-ao_usb_getchar(void);
-
-/* Poll for a charcter on the USB input queue.
- * returns AO_READ_AGAIN if none are available
+ * ao_mutex.c
*/
-char
-ao_usb_pollchar(void);
-
-/* Flush the USB output queue */
-void
-ao_usb_flush(void);
-
-#if HAS_USB
-/* USB interrupt handler */
-void
-ao_usb_isr(void) ao_arch_interrupt(6);
-#endif
-/* Enable the USB controller */
void
-ao_usb_enable(void);
-
-/* Disable the USB controller */
-void
-ao_usb_disable(void);
+ao_mutex_get(__xdata uint8_t *ao_mutex) __reentrant;
-/* Initialize the USB system */
void
-ao_usb_init(void);
-
-#if HAS_USB
-extern __code __at (0x00aa) uint8_t ao_usb_descriptors [];
-#endif
+ao_mutex_put(__xdata uint8_t *ao_mutex) __reentrant;
/*
* ao_cmd.c
@@ -396,405 +228,36 @@ ao_cmd_filter(void);
#endif
/*
- * ao_mutex.c
- */
-
-void
-ao_mutex_get(__xdata uint8_t *ao_mutex) __reentrant;
-
-void
-ao_mutex_put(__xdata uint8_t *ao_mutex) __reentrant;
-
-/*
- * Storage interface, provided by one of the eeprom or flash
- * drivers
- */
-
-/* Total bytes of available storage */
-extern __pdata uint32_t ao_storage_total;
-
-/* Block size - device is erased in these units. At least 256 bytes */
-extern __pdata uint32_t ao_storage_block;
-
-/* Byte offset of config block. Will be ao_storage_block bytes long */
-extern __pdata uint32_t ao_storage_config;
-
-/* Storage unit size - device reads and writes must be within blocks of this size. Usually 256 bytes. */
-extern __pdata uint16_t ao_storage_unit;
-
-#define AO_STORAGE_ERASE_LOG (ao_storage_config + AO_CONFIG_MAX_SIZE)
-
-/* Initialize above values. Can only be called once the OS is running */
-void
-ao_storage_setup(void) __reentrant;
-
-/* Write data. Returns 0 on failure, 1 on success */
-uint8_t
-ao_storage_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant;
-
-/* Read data. Returns 0 on failure, 1 on success */
-uint8_t
-ao_storage_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant;
-
-/* Erase a block of storage. This always clears ao_storage_block bytes */
-uint8_t
-ao_storage_erase(uint32_t pos) __reentrant;
-
-/* Flush any pending writes to stable storage */
-void
-ao_storage_flush(void) __reentrant;
-
-/* Initialize the storage code */
-void
-ao_storage_init(void);
-
-/*
- * Low-level functions wrapped by ao_storage.c
- */
-
-/* Read data within a storage unit */
-uint8_t
-ao_storage_device_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant;
-
-/* Write data within a storage unit */
-uint8_t
-ao_storage_device_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant;
-
-/* Initialize low-level device bits */
-void
-ao_storage_device_init(void);
-
-/* Print out information about flash chips */
-void
-ao_storage_device_info(void) __reentrant;
-
-/*
- * ao_log.c
- */
-
-/* We record flight numbers in the first record of
- * the log. Tasks may wait for this to be initialized
- * by sleeping on this variable.
- */
-extern __xdata uint16_t ao_flight_number;
-
-extern __pdata uint32_t ao_log_current_pos;
-extern __pdata uint32_t ao_log_end_pos;
-extern __pdata uint32_t ao_log_start_pos;
-extern __xdata uint8_t ao_log_running;
-extern __pdata enum flight_state ao_log_state;
-
-/* required functions from the underlying log system */
-
-#define AO_LOG_FORMAT_UNKNOWN 0 /* unknown; altosui will have to guess */
-#define AO_LOG_FORMAT_FULL 1 /* 8 byte typed log records */
-#define AO_LOG_FORMAT_TINY 2 /* two byte state/baro records */
-#define AO_LOG_FORMAT_TELEMETRY 3 /* 32 byte ao_telemetry records */
-#define AO_LOG_FORMAT_TELESCIENCE 4 /* 32 byte typed telescience records */
-#define AO_LOG_FORMAT_NONE 127 /* No log at all */
-
-extern __code uint8_t ao_log_format;
-
-/* Return the flight number from the given log slot, 0 if none */
-uint16_t
-ao_log_flight(uint8_t slot);
-
-/* Flush the log */
-void
-ao_log_flush(void);
-
-/* Logging thread main routine */
-void
-ao_log(void);
-
-/* functions provided in ao_log.c */
-
-/* Figure out the current flight number */
-void
-ao_log_scan(void) __reentrant;
-
-/* Return the position of the start of the given log slot */
-uint32_t
-ao_log_pos(uint8_t slot);
-
-/* 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);
-
-/* Write out the current flight number to the erase log */
-void
-ao_log_write_erase(uint8_t pos);
-
-/* Returns true if there are any logs stored in eeprom */
-uint8_t
-ao_log_present(void);
-
-/* Returns true if there is no more storage space available */
-uint8_t
-ao_log_full(void);
-
-/*
- * ao_log_big.c
+ * Various drivers
*/
-
-/*
- * 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_GPS_SAT 'V'
-#define AO_LOG_GPS_DATE 'Y'
-
-#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;
- int32_t gps_latitude;
- int32_t gps_longitude;
- struct {
- int16_t altitude;
- uint16_t unused;
- } gps_altitude;
- struct {
- uint16_t svid;
- uint8_t unused;
- uint8_t c_n;
- } gps_sat;
- struct {
- uint8_t year;
- uint8_t month;
- uint8_t day;
- uint8_t extra;
- } gps_date;
- struct {
- uint16_t d0;
- uint16_t d1;
- } anon;
- } u;
-};
-
-/* Write a record to the eeprom log */
-uint8_t
-ao_log_data(__xdata struct ao_log_record *log) __reentrant;
-
-/*
- * ao_flight.c
- */
-
-enum ao_flight_state {
- ao_flight_startup = 0,
- ao_flight_idle = 1,
- ao_flight_pad = 2,
- ao_flight_boost = 3,
- ao_flight_fast = 4,
- ao_flight_coast = 5,
- ao_flight_drogue = 6,
- ao_flight_main = 7,
- ao_flight_landed = 8,
- ao_flight_invalid = 9
-};
-
-extern __pdata enum ao_flight_state ao_flight_state;
-
-extern __pdata uint16_t ao_launch_time;
-extern __pdata uint8_t ao_flight_force_idle;
-
-/* Flight thread */
-void
-ao_flight(void);
-
-/* Initialize flight thread */
-void
-ao_flight_init(void);
-
-/*
- * ao_flight_nano.c
- */
-
-void
-ao_flight_nano_init(void);
-
-/*
- * ao_sample.c
- */
-
-/*
- * Barometer calibration
- *
- * We directly sample the barometer. The specs say:
- *
- * Pressure range: 15-115 kPa
- * Voltage at 115kPa: 2.82
- * Output scale: 27mV/kPa
- *
- * If we want to detect launch with the barometer, we need
- * a large enough bump to not be fooled by noise. At typical
- * launch elevations (0-2000m), a 200Pa pressure change cooresponds
- * to about a 20m elevation change. This is 5.4mV, or about 3LSB.
- * As all of our calculations are done in 16 bits, we'll actually see a change
- * of 16 times this though
- *
- * 27 mV/kPa * 32767 / 3300 counts/mV = 268.1 counts/kPa
- */
-
-/* Accelerometer calibration
- *
- * We're sampling the accelerometer through a resistor divider which
- * consists of 5k and 10k resistors. This multiplies the values by 2/3.
- * That goes into the cc1111 A/D converter, which is running at 11 bits
- * of precision with the bits in the MSB of the 16 bit value. Only positive
- * values are used, so values should range from 0-32752 for 0-3.3V. The
- * specs say we should see 40mV/g (uncalibrated), multiply by 2/3 for what
- * the A/D converter sees (26.67 mV/g). We should see 32752/3300 counts/mV,
- * for a final computation of:
- *
- * 26.67 mV/g * 32767/3300 counts/mV = 264.8 counts/g
- *
- * Zero g was measured at 16000 (we would expect 16384).
- * Note that this value is only require to tell if the
- * rocket is standing upright. Once that is determined,
- * the value of the accelerometer is averaged for 100 samples
- * to find the resting accelerometer value, which is used
- * for all further flight computations
- */
-
-#define GRAVITY 9.80665
-
-/*
- * Above this height, the baro sensor doesn't work
- */
-#define AO_MAX_BARO_HEIGHT 12000
-
-/*
- * Above this speed, baro measurements are unreliable
- */
-#define AO_MAX_BARO_SPEED 200
-
-#define ACCEL_NOSE_UP (ao_accel_2g >> 2)
-
-/*
- * Speed and acceleration are scaled by 16 to provide a bit more
- * resolution while still having reasonable range. Note that this
- * limits speed to 2047m/s (around mach 6) and acceleration to
- * 2047m/s² (over 200g)
- */
-
-#define AO_M_TO_HEIGHT(m) ((int16_t) (m))
-#define AO_MS_TO_SPEED(ms) ((int16_t) ((ms) * 16))
-#define AO_MSS_TO_ACCEL(mss) ((int16_t) ((mss) * 16))
-
-extern __pdata uint16_t ao_sample_tick; /* time of last data */
-extern __pdata int16_t ao_sample_pres; /* most recent pressure sensor reading */
-extern __pdata int16_t ao_sample_alt; /* MSL of ao_sample_pres */
-extern __pdata int16_t ao_sample_height; /* AGL of ao_sample_pres */
-extern __data uint8_t ao_sample_adc; /* Ring position of last processed sample */
-
-#if HAS_ACCEL
-extern __pdata int16_t ao_sample_accel; /* most recent accel sensor reading */
+#if HAS_ADC
+#include <ao_adc.h>
#endif
-extern __pdata int16_t ao_ground_pres; /* startup pressure */
-extern __pdata int16_t ao_ground_height; /* MSL of ao_ground_pres */
-
-#if HAS_ACCEL
-extern __pdata int16_t ao_ground_accel; /* startup acceleration */
-extern __pdata int16_t ao_accel_2g; /* factory accel calibration */
-extern __pdata int32_t ao_accel_scale; /* sensor to m/s² conversion */
+#if HAS_BEEP
+#include <ao_beep.h>
#endif
-void ao_sample_init(void);
-
-/* returns FALSE in preflight mode, TRUE in flight mode */
-uint8_t ao_sample(void);
-
-/*
- * ao_kalman.c
- */
-
-#define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5))
-#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5))
-#define from_fix(x) ((x) >> 16)
+#if LEDS_AVAILABLE
+#include <ao_led.h>
+#endif
-extern __pdata int16_t ao_height; /* meters */
-extern __pdata int16_t ao_speed; /* m/s * 16 */
-extern __pdata int16_t ao_accel; /* m/s² * 16 */
-extern __pdata int16_t ao_max_height; /* max of ao_height */
-extern __pdata int16_t ao_avg_height; /* running average of height */
+#if HAS_USB
+#include <ao_usb.h>
+#endif
-extern __pdata int16_t ao_error_h;
-extern __pdata int16_t ao_error_h_sq_avg;
+#if HAS_EEPROM
+#include <ao_storage.h>
+#endif
-#if HAS_ACCEL
-extern __pdata int16_t ao_error_a;
+#if HAS_LOG
+#include <ao_log.h>
#endif
-void ao_kalman(void);
+#if HAS_FLIGHT
+#include <ao_flight.h>
+#include <ao_sample.h>
+#endif
/*
* ao_report.c
@@ -819,125 +282,12 @@ 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
- */
-
-#ifndef HAS_SERIAL_1
-#error Please define HAS_SERIAL_1
+#if HAS_DBG
+#include <ao_dbg.h>
#endif
-#if HAS_SERIAL_1 | HAS_SERIAL_2 | HAS_SERIAL_3
-#ifndef USE_SERIAL_STDIN
-#error Please define USE_SERIAL_STDIN
-#endif
-
-void
-ao_serial_rx1_isr(void) ao_arch_interrupt(3);
-
-void
-ao_serial_tx1_isr(void) ao_arch_interrupt(14);
-
-char
-ao_serial_getchar(void) __critical;
-
-#if USE_SERIAL_STDIN
-char
-ao_serial_pollchar(void) __critical;
-
-void
-ao_serial_set_stdin(uint8_t in);
-#endif
-
-void
-ao_serial_putchar(char c) __critical;
-
-void
-ao_serial_drain(void) __critical;
-
-#define AO_SERIAL_SPEED_4800 0
-#define AO_SERIAL_SPEED_9600 1
-#define AO_SERIAL_SPEED_19200 2
-#define AO_SERIAL_SPEED_57600 3
-
-void
-ao_serial_set_speed(uint8_t speed);
-
-void
-ao_serial_init(void);
-#endif
-
-#ifndef HAS_SERIAL_0
-#define HAS_SERIAL_0 0
-#endif
-
-#if HAS_SERIAL_0
-
-extern volatile __xdata struct ao_fifo ao_usart0_rx_fifo;
-extern volatile __xdata struct ao_fifo ao_usart0_tx_fifo;
-
-void
-ao_serial0_rx0_isr(void) ao_arch_interrupt(2);
-
-void
-ao_serial0_tx0_isr(void) ao_arch_interrupt(7);
-
-char
-ao_serial0_getchar(void) __critical;
-
-void
-ao_serial0_putchar(char c) __critical;
-
-void
-ao_serial0_drain(void) __critical;
-
-void
-ao_serial0_set_speed(uint8_t speed);
-
-void
-ao_serial0_init(void);
-
+#if HAS_SERIAL_0 || HAS_SERIAL_1 || HAS_SERIAL_2 || HAS_SERIAL_3
+#include <ao_serial.h>
#endif
diff --git a/src/core/ao_adc.h b/src/core/ao_adc.h
new file mode 100644
index 00000000..db5bfab3
--- /dev/null
+++ b/src/core/ao_adc.h
@@ -0,0 +1,62 @@
+/*
+ * 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_ADC_H_
+#define _AO_ADC_H_
+
+
+
+/*
+ * One set of samples read from the A/D converter or telemetry
+ */
+
+
+/*
+ * ao_adc.c
+ */
+
+#define ao_adc_ring_next(n) (((n) + 1) & (AO_ADC_RING - 1))
+#define ao_adc_ring_prev(n) (((n) - 1) & (AO_ADC_RING - 1))
+
+
+/*
+ * A/D data is stored in a ring, with the next sample to be written
+ * at ao_adc_head
+ */
+extern volatile __xdata struct ao_adc ao_adc_ring[AO_ADC_RING];
+extern volatile __data uint8_t ao_adc_head;
+#if HAS_ACCEL_REF
+extern volatile __xdata uint16_t ao_accel_ref[AO_ADC_RING];
+#endif
+
+/* Trigger a conversion sequence (called from the timer interrupt) */
+void
+ao_adc_poll(void);
+
+/* Suspend the current task until another A/D sample is converted */
+void
+ao_adc_sleep(void);
+
+/* Get a copy of the last complete A/D sample set */
+void
+ao_adc_get(__xdata struct ao_adc *packet);
+
+/* Initialize the A/D converter */
+void
+ao_adc_init(void);
+
+#endif /* _AO_ADC_H_ */
diff --git a/src/core/ao_beep.h b/src/core/ao_beep.h
new file mode 100644
index 00000000..55f61171
--- /dev/null
+++ b/src/core/ao_beep.h
@@ -0,0 +1,74 @@
+/*
+ * 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_BEEP_H_
+#define _AO_BEEP_H_
+
+/*
+ * ao_beep.c
+ */
+
+/*
+ * Various pre-defined beep frequencies
+ *
+ * frequency = 1/2 (24e6/32) / beep
+ */
+
+#define AO_BEEP_LOW 150 /* 2500Hz */
+#define AO_BEEP_MID 94 /* 3989Hz */
+#define AO_BEEP_HIGH 75 /* 5000Hz */
+#define AO_BEEP_OFF 0 /* off */
+
+#define AO_BEEP_g 240 /* 1562.5Hz */
+#define AO_BEEP_gs 227 /* 1652Hz (1655Hz) */
+#define AO_BEEP_aa 214 /* 1752Hz (1754Hz) */
+#define AO_BEEP_bbf 202 /* 1856Hz (1858Hz) */
+#define AO_BEEP_bb 190 /* 1974Hz (1969Hz) */
+#define AO_BEEP_cc 180 /* 2083Hz (2086Hz) */
+#define AO_BEEP_ccs 170 /* 2205Hz (2210Hz) */
+#define AO_BEEP_dd 160 /* 2344Hz (2341Hz) */
+#define AO_BEEP_eef 151 /* 2483Hz (2480Hz) */
+#define AO_BEEP_ee 143 /* 2622Hz (2628Hz) */
+#define AO_BEEP_ff 135 /* 2778Hz (2784Hz) */
+#define AO_BEEP_ffs 127 /* 2953Hz (2950Hz) */
+#define AO_BEEP_gg 120 /* 3125Hz */
+#define AO_BEEP_ggs 113 /* 3319Hz (3311Hz) */
+#define AO_BEEP_aaa 107 /* 3504Hz (3508Hz) */
+#define AO_BEEP_bbbf 101 /* 3713Hz (3716Hz) */
+#define AO_BEEP_bbb 95 /* 3947Hz (3937Hz) */
+#define AO_BEEP_ccc 90 /* 4167Hz (4171Hz) */
+#define AO_BEEP_cccs 85 /* 4412Hz (4419Hz) */
+#define AO_BEEP_ddd 80 /* 4688Hz (4682Hz) */
+#define AO_BEEP_eeef 76 /* 4934Hz (4961Hz) */
+#define AO_BEEP_eee 71 /* 5282Hz (5256Hz) */
+#define AO_BEEP_fff 67 /* 5597Hz (5568Hz) */
+#define AO_BEEP_fffs 64 /* 5859Hz (5899Hz) */
+#define AO_BEEP_ggg 60 /* 6250Hz */
+
+/* Set the beeper to the specified tone */
+void
+ao_beep(uint8_t beep);
+
+/* Turn on the beeper for the specified time */
+void
+ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant;
+
+/* Initialize the beeper */
+void
+ao_beep_init(void);
+
+#endif /* _AO_BEEP_H_ */
diff --git a/src/core/ao_dbg.h b/src/core/ao_dbg.h
new file mode 100644
index 00000000..181e6ec2
--- /dev/null
+++ b/src/core/ao_dbg.h
@@ -0,0 +1,62 @@
+/*
+ * 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_DBG_H_
+#define _AO_DBG_H_
+
+/*
+ * 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);
+
+#endif /* _AO_DBG_H_ */
diff --git a/src/core/ao_flight.h b/src/core/ao_flight.h
new file mode 100644
index 00000000..aa5ab60d
--- /dev/null
+++ b/src/core/ao_flight.h
@@ -0,0 +1,59 @@
+/*
+ * 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_FLIGHT_H_
+#define _AO_FLIGHT_H_
+
+
+/*
+ * ao_flight.c
+ */
+
+enum ao_flight_state {
+ ao_flight_startup = 0,
+ ao_flight_idle = 1,
+ ao_flight_pad = 2,
+ ao_flight_boost = 3,
+ ao_flight_fast = 4,
+ ao_flight_coast = 5,
+ ao_flight_drogue = 6,
+ ao_flight_main = 7,
+ ao_flight_landed = 8,
+ ao_flight_invalid = 9
+};
+
+extern __pdata enum ao_flight_state ao_flight_state;
+
+extern __pdata uint16_t ao_launch_time;
+extern __pdata uint8_t ao_flight_force_idle;
+
+/* Flight thread */
+void
+ao_flight(void);
+
+/* Initialize flight thread */
+void
+ao_flight_init(void);
+
+/*
+ * ao_flight_nano.c
+ */
+
+void
+ao_flight_nano_init(void);
+
+#endif /* _AO_FLIGHT_H_ */
diff --git a/src/core/ao_led.h b/src/core/ao_led.h
new file mode 100644
index 00000000..edc5fd1f
--- /dev/null
+++ b/src/core/ao_led.h
@@ -0,0 +1,55 @@
+/*
+ * 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_LED_H_
+#define _AO_LED_H_
+
+/*
+ * ao_led.c
+ */
+
+#define AO_LED_NONE 0
+
+#ifndef AO_LED_TYPE
+#define AO_LED_TYPE uint8_t
+#endif
+
+/* Turn on the specified LEDs */
+void
+ao_led_on(AO_LED_TYPE colors);
+
+/* Turn off the specified LEDs */
+void
+ao_led_off(AO_LED_TYPE colors);
+
+/* Set all of the LEDs to the specified state */
+void
+ao_led_set(AO_LED_TYPE colors);
+
+/* Toggle the specified LEDs */
+void
+ao_led_toggle(AO_LED_TYPE colors);
+
+/* Turn on the specified LEDs for the indicated interval */
+void
+ao_led_for(AO_LED_TYPE colors, uint16_t ticks) __reentrant;
+
+/* Initialize the LEDs */
+void
+ao_led_init(AO_LED_TYPE enable);
+
+#endif /* _AO_LED_H_ */
diff --git a/src/core/ao_log.h b/src/core/ao_log.h
new file mode 100644
index 00000000..611c00d5
--- /dev/null
+++ b/src/core/ao_log.h
@@ -0,0 +1,196 @@
+/*
+ * 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_LOG_H_
+#define _AO_LOG_H_
+
+/*
+ * ao_log.c
+ */
+
+/* We record flight numbers in the first record of
+ * the log. Tasks may wait for this to be initialized
+ * by sleeping on this variable.
+ */
+extern __xdata uint16_t ao_flight_number;
+
+extern __pdata uint32_t ao_log_current_pos;
+extern __pdata uint32_t ao_log_end_pos;
+extern __pdata uint32_t ao_log_start_pos;
+extern __xdata uint8_t ao_log_running;
+extern __pdata enum flight_state ao_log_state;
+
+/* required functions from the underlying log system */
+
+#define AO_LOG_FORMAT_UNKNOWN 0 /* unknown; altosui will have to guess */
+#define AO_LOG_FORMAT_FULL 1 /* 8 byte typed log records */
+#define AO_LOG_FORMAT_TINY 2 /* two byte state/baro records */
+#define AO_LOG_FORMAT_TELEMETRY 3 /* 32 byte ao_telemetry records */
+#define AO_LOG_FORMAT_TELESCIENCE 4 /* 32 byte typed telescience records */
+#define AO_LOG_FORMAT_NONE 127 /* No log at all */
+
+extern __code uint8_t ao_log_format;
+
+/* Return the flight number from the given log slot, 0 if none */
+uint16_t
+ao_log_flight(uint8_t slot);
+
+/* Flush the log */
+void
+ao_log_flush(void);
+
+/* Logging thread main routine */
+void
+ao_log(void);
+
+/* functions provided in ao_log.c */
+
+/* Figure out the current flight number */
+void
+ao_log_scan(void) __reentrant;
+
+/* Return the position of the start of the given log slot */
+uint32_t
+ao_log_pos(uint8_t slot);
+
+/* 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);
+
+/* Write out the current flight number to the erase log */
+void
+ao_log_write_erase(uint8_t pos);
+
+/* Returns true if there are any logs stored in eeprom */
+uint8_t
+ao_log_present(void);
+
+/* Returns true if there is no more storage space available */
+uint8_t
+ao_log_full(void);
+
+/*
+ * ao_log_big.c
+ */
+
+/*
+ * 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_GPS_SAT 'V'
+#define AO_LOG_GPS_DATE 'Y'
+
+#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;
+ int32_t gps_latitude;
+ int32_t gps_longitude;
+ struct {
+ int16_t altitude;
+ uint16_t unused;
+ } gps_altitude;
+ struct {
+ uint16_t svid;
+ uint8_t unused;
+ uint8_t c_n;
+ } gps_sat;
+ struct {
+ uint8_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t extra;
+ } gps_date;
+ struct {
+ uint16_t d0;
+ uint16_t d1;
+ } anon;
+ } u;
+};
+
+/* Write a record to the eeprom log */
+uint8_t
+ao_log_data(__xdata struct ao_log_record *log) __reentrant;
+
+#endif /* _AO_LOG_H_ */
diff --git a/src/core/ao_log_telem.c b/src/core/ao_log_telem.c
index 9e1b06d3..18ab85dd 100644
--- a/src/core/ao_log_telem.c
+++ b/src/core/ao_log_telem.c
@@ -15,7 +15,9 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "ao.h"
+#include <ao.h>
+#include <ao_flight.h>
+#include <ao_sample.h>
__code uint8_t ao_log_format = AO_LOG_FORMAT_TELEMETRY;
diff --git a/src/core/ao_product.c b/src/core/ao_product.c
index fb59580b..f79922f5 100644
--- a/src/core/ao_product.c
+++ b/src/core/ao_product.c
@@ -70,26 +70,26 @@ __code __at(0x00aa) uint8_t ao_usb_descriptors [] =
/* Header functional descriptor */
0x05,
- CS_INTERFACE,
+ AO_USB_CS_INTERFACE,
0x00, /* bDescriptor SubType Header */
LE_WORD(0x0110), /* CDC version 1.1 */
/* Call management functional descriptor */
0x05,
- CS_INTERFACE,
+ AO_USB_CS_INTERFACE,
0x01, /* bDescriptor SubType Call Management */
0x01, /* bmCapabilities = device handles call management */
0x01, /* bDataInterface call management interface number */
/* ACM functional descriptor */
0x04,
- CS_INTERFACE,
+ AO_USB_CS_INTERFACE,
0x02, /* bDescriptor SubType Abstract Control Management */
0x02, /* bmCapabilities = D1 (Set_line_Coding, Set_Control_Line_State, Get_Line_Coding and Serial_State) */
/* Union functional descriptor */
0x05,
- CS_INTERFACE,
+ AO_USB_CS_INTERFACE,
0x06, /* bDescriptor SubType Union Functional descriptor */
0x00, /* bMasterInterface */
0x01, /* bSlaveInterface0 */
diff --git a/src/core/ao_report.c b/src/core/ao_report.c
index 7c928792..eb90a4f8 100644
--- a/src/core/ao_report.c
+++ b/src/core/ao_report.c
@@ -16,6 +16,8 @@
*/
#include "ao.h"
+#include <ao_flight.h>
+#include <ao_sample.h>
#define BIT(i,x) ((x) ? (1 << (i)) : 0)
#define MORSE1(a) (1 | BIT(3,a))
diff --git a/src/core/ao_sample.h b/src/core/ao_sample.h
new file mode 100644
index 00000000..fb0e69e8
--- /dev/null
+++ b/src/core/ao_sample.h
@@ -0,0 +1,137 @@
+/*
+ * 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_SAMPLE_H_
+#define _AO_SAMPLE_H_
+
+/*
+ * ao_sample.c
+ */
+
+/*
+ * Barometer calibration
+ *
+ * We directly sample the barometer. The specs say:
+ *
+ * Pressure range: 15-115 kPa
+ * Voltage at 115kPa: 2.82
+ * Output scale: 27mV/kPa
+ *
+ * If we want to detect launch with the barometer, we need
+ * a large enough bump to not be fooled by noise. At typical
+ * launch elevations (0-2000m), a 200Pa pressure change cooresponds
+ * to about a 20m elevation change. This is 5.4mV, or about 3LSB.
+ * As all of our calculations are done in 16 bits, we'll actually see a change
+ * of 16 times this though
+ *
+ * 27 mV/kPa * 32767 / 3300 counts/mV = 268.1 counts/kPa
+ */
+
+/* Accelerometer calibration
+ *
+ * We're sampling the accelerometer through a resistor divider which
+ * consists of 5k and 10k resistors. This multiplies the values by 2/3.
+ * That goes into the cc1111 A/D converter, which is running at 11 bits
+ * of precision with the bits in the MSB of the 16 bit value. Only positive
+ * values are used, so values should range from 0-32752 for 0-3.3V. The
+ * specs say we should see 40mV/g (uncalibrated), multiply by 2/3 for what
+ * the A/D converter sees (26.67 mV/g). We should see 32752/3300 counts/mV,
+ * for a final computation of:
+ *
+ * 26.67 mV/g * 32767/3300 counts/mV = 264.8 counts/g
+ *
+ * Zero g was measured at 16000 (we would expect 16384).
+ * Note that this value is only require to tell if the
+ * rocket is standing upright. Once that is determined,
+ * the value of the accelerometer is averaged for 100 samples
+ * to find the resting accelerometer value, which is used
+ * for all further flight computations
+ */
+
+#define GRAVITY 9.80665
+
+/*
+ * Above this height, the baro sensor doesn't work
+ */
+#define AO_MAX_BARO_HEIGHT 12000
+
+/*
+ * Above this speed, baro measurements are unreliable
+ */
+#define AO_MAX_BARO_SPEED 200
+
+#define ACCEL_NOSE_UP (ao_accel_2g >> 2)
+
+/*
+ * Speed and acceleration are scaled by 16 to provide a bit more
+ * resolution while still having reasonable range. Note that this
+ * limits speed to 2047m/s (around mach 6) and acceleration to
+ * 2047m/s² (over 200g)
+ */
+
+#define AO_M_TO_HEIGHT(m) ((int16_t) (m))
+#define AO_MS_TO_SPEED(ms) ((int16_t) ((ms) * 16))
+#define AO_MSS_TO_ACCEL(mss) ((int16_t) ((mss) * 16))
+
+extern __pdata uint16_t ao_sample_tick; /* time of last data */
+extern __pdata int16_t ao_sample_pres; /* most recent pressure sensor reading */
+extern __pdata int16_t ao_sample_alt; /* MSL of ao_sample_pres */
+extern __pdata int16_t ao_sample_height; /* AGL of ao_sample_pres */
+extern __data uint8_t ao_sample_adc; /* Ring position of last processed sample */
+
+#if HAS_ACCEL
+extern __pdata int16_t ao_sample_accel; /* most recent accel sensor reading */
+#endif
+
+extern __pdata int16_t ao_ground_pres; /* startup pressure */
+extern __pdata int16_t ao_ground_height; /* MSL of ao_ground_pres */
+
+#if HAS_ACCEL
+extern __pdata int16_t ao_ground_accel; /* startup acceleration */
+extern __pdata int16_t ao_accel_2g; /* factory accel calibration */
+extern __pdata int32_t ao_accel_scale; /* sensor to m/s² conversion */
+#endif
+
+void ao_sample_init(void);
+
+/* returns FALSE in preflight mode, TRUE in flight mode */
+uint8_t ao_sample(void);
+
+/*
+ * ao_kalman.c
+ */
+
+#define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5))
+#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5))
+#define from_fix(x) ((x) >> 16)
+
+extern __pdata int16_t ao_height; /* meters */
+extern __pdata int16_t ao_speed; /* m/s * 16 */
+extern __pdata int16_t ao_accel; /* m/s² * 16 */
+extern __pdata int16_t ao_max_height; /* max of ao_height */
+extern __pdata int16_t ao_avg_height; /* running average of height */
+
+extern __pdata int16_t ao_error_h;
+extern __pdata int16_t ao_error_h_sq_avg;
+
+#if HAS_ACCEL
+extern __pdata int16_t ao_error_a;
+#endif
+
+void ao_kalman(void);
+
+#endif /* _AO_SAMPLE_H_ */
diff --git a/src/core/ao_serial.h b/src/core/ao_serial.h
new file mode 100644
index 00000000..53aa8a89
--- /dev/null
+++ b/src/core/ao_serial.h
@@ -0,0 +1,86 @@
+/*
+ * 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_SERIAL_H_
+#define _AO_SERIAL_H_
+
+#define AO_SERIAL_SPEED_4800 0
+#define AO_SERIAL_SPEED_9600 1
+#define AO_SERIAL_SPEED_19200 2
+#define AO_SERIAL_SPEED_57600 3
+
+#if HAS_SERIAL_0
+extern volatile __xdata struct ao_fifo ao_serial0_rx_fifo;
+extern volatile __xdata struct ao_fifo ao_serial0_tx_fifo;
+
+char
+ao_serial0_getchar(void);
+
+void
+ao_serial0_putchar(char c);
+
+void
+ao_serial0_drain(void);
+
+void
+ao_serial0_set_speed(uint8_t speed);
+#endif
+
+#if HAS_SERIAL_1
+extern volatile __xdata struct ao_fifo ao_serial1_rx_fifo;
+extern volatile __xdata struct ao_fifo ao_serial1_tx_fifo;
+
+char
+ao_serial1_getchar(void);
+
+char
+ao_serial1_pollchar(void);
+
+void
+ao_serial1_putchar(char c);
+
+void
+ao_serial1_drain(void);
+
+void
+ao_serial1_set_speed(uint8_t speed);
+#endif
+
+#if HAS_SERIAL_2
+extern volatile __xdata struct ao_fifo ao_serial2_rx_fifo;
+extern volatile __xdata struct ao_fifo ao_serial2_tx_fifo;
+
+char
+ao_serial2_getchar(void);
+
+char
+ao_serial2_pollchar(void);
+
+void
+ao_serial2_putchar(char c);
+
+void
+ao_serial2_drain(void);
+
+void
+ao_serial2_set_speed(uint8_t speed);
+#endif
+
+void
+ao_serial_init(void);
+
+#endif /* _AO_SERIAL_H_ */
diff --git a/src/core/ao_stdio.c b/src/core/ao_stdio.c
index 2967e705..18fa913e 100644
--- a/src/core/ao_stdio.c
+++ b/src/core/ao_stdio.c
@@ -21,6 +21,12 @@
* Basic I/O functions to support SDCC stdio package
*/
+#ifdef SERIAL_STDIN_PORT
+#define USE_SERIAL_STDIN 1
+#else
+#define USE_SERIAL_STDIN 0
+#endif
+
#define AO_NUM_STDIOS (HAS_USB + PACKET_HAS_SLAVE + USE_SERIAL_STDIN)
__xdata struct ao_stdio ao_stdios[AO_NUM_STDIOS];
diff --git a/src/core/ao_storage.c b/src/core/ao_storage.c
index ff4747d0..66394e01 100644
--- a/src/core/ao_storage.c
+++ b/src/core/ao_storage.c
@@ -15,7 +15,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "ao.h"
+#include <ao.h>
uint8_t
ao_storage_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant
diff --git a/src/core/ao_storage.h b/src/core/ao_storage.h
new file mode 100644
index 00000000..873fe097
--- /dev/null
+++ b/src/core/ao_storage.h
@@ -0,0 +1,84 @@
+/*
+ * 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_STORAGE_H_
+#define _AO_STORAGE_H_
+
+/*
+ * Storage interface, provided by one of the eeprom or flash
+ * drivers
+ */
+
+/* Total bytes of available storage */
+extern __pdata uint32_t ao_storage_total;
+
+/* Block size - device is erased in these units. At least 256 bytes */
+extern __pdata uint32_t ao_storage_block;
+
+/* Byte offset of config block. Will be ao_storage_block bytes long */
+extern __pdata uint32_t ao_storage_config;
+
+/* Storage unit size - device reads and writes must be within blocks of this size. Usually 256 bytes. */
+extern __pdata uint16_t ao_storage_unit;
+
+#define AO_STORAGE_ERASE_LOG (ao_storage_config + AO_CONFIG_MAX_SIZE)
+
+/* Initialize above values. Can only be called once the OS is running */
+void
+ao_storage_setup(void) __reentrant;
+
+/* Write data. Returns 0 on failure, 1 on success */
+uint8_t
+ao_storage_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant;
+
+/* Read data. Returns 0 on failure, 1 on success */
+uint8_t
+ao_storage_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant;
+
+/* Erase a block of storage. This always clears ao_storage_block bytes */
+uint8_t
+ao_storage_erase(uint32_t pos) __reentrant;
+
+/* Flush any pending writes to stable storage */
+void
+ao_storage_flush(void) __reentrant;
+
+/* Initialize the storage code */
+void
+ao_storage_init(void);
+
+/*
+ * Low-level functions wrapped by ao_storage.c
+ */
+
+/* Read data within a storage unit */
+uint8_t
+ao_storage_device_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant;
+
+/* Write data within a storage unit */
+uint8_t
+ao_storage_device_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant;
+
+/* Initialize low-level device bits */
+void
+ao_storage_device_init(void);
+
+/* Print out information about flash chips */
+void
+ao_storage_device_info(void) __reentrant;
+
+#endif /* _AO_STORAGE_H_ */
diff --git a/src/core/ao_usb.h b/src/core/ao_usb.h
new file mode 100644
index 00000000..e051db93
--- /dev/null
+++ b/src/core/ao_usb.h
@@ -0,0 +1,136 @@
+/*
+ * 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_USB_H_
+#define _AO_USB_H_
+
+/*
+ * ao_usb.c
+ */
+
+/* Put one character to the USB output queue */
+void
+ao_usb_putchar(char c);
+
+/* Get one character from the USB input queue */
+char
+ao_usb_getchar(void);
+
+/* Poll for a charcter on the USB input queue.
+ * returns AO_READ_AGAIN if none are available
+ */
+char
+ao_usb_pollchar(void);
+
+/* Flush the USB output queue */
+void
+ao_usb_flush(void);
+
+/* Enable the USB controller */
+void
+ao_usb_enable(void);
+
+/* Disable the USB controller */
+void
+ao_usb_disable(void);
+
+/* Initialize the USB system */
+void
+ao_usb_init(void);
+
+extern __code __at (0x00aa) uint8_t ao_usb_descriptors [];
+
+#define AO_USB_SETUP_DIR_MASK (0x01 << 7)
+#define AO_USB_SETUP_TYPE_MASK (0x03 << 5)
+#define AO_USB_SETUP_RECIP_MASK (0x1f)
+
+#define AO_USB_DIR_OUT 0
+#define AO_USB_DIR_IN (1 << 7)
+
+#define AO_USB_TYPE_STANDARD 0
+#define AO_USB_TYPE_CLASS (1 << 5)
+#define AO_USB_TYPE_VENDOR (2 << 5)
+#define AO_USB_TYPE_RESERVED (3 << 5)
+
+#define AO_USB_RECIP_DEVICE 0
+#define AO_USB_RECIP_INTERFACE 1
+#define AO_USB_RECIP_ENDPOINT 2
+#define AO_USB_RECIP_OTHER 3
+
+/* standard requests */
+#define AO_USB_REQ_GET_STATUS 0x00
+#define AO_USB_REQ_CLEAR_FEATURE 0x01
+#define AO_USB_REQ_SET_FEATURE 0x03
+#define AO_USB_REQ_SET_ADDRESS 0x05
+#define AO_USB_REQ_GET_DESCRIPTOR 0x06
+#define AO_USB_REQ_SET_DESCRIPTOR 0x07
+#define AO_USB_REQ_GET_CONFIGURATION 0x08
+#define AO_USB_REQ_SET_CONFIGURATION 0x09
+#define AO_USB_REQ_GET_INTERFACE 0x0A
+#define AO_USB_REQ_SET_INTERFACE 0x0B
+#define AO_USB_REQ_SYNCH_FRAME 0x0C
+
+#define AO_USB_DESC_DEVICE 1
+#define AO_USB_DESC_CONFIGURATION 2
+#define AO_USB_DESC_STRING 3
+#define AO_USB_DESC_INTERFACE 4
+#define AO_USB_DESC_ENDPOINT 5
+#define AO_USB_DESC_DEVICE_QUALIFIER 6
+#define AO_USB_DESC_OTHER_SPEED 7
+#define AO_USB_DESC_INTERFACE_POWER 8
+
+#define AO_USB_GET_DESC_TYPE(x) (((x)>>8)&0xFF)
+#define AO_USB_GET_DESC_INDEX(x) ((x)&0xFF)
+
+#define AO_USB_CONTROL_EP 0
+#define AO_USB_CONTROL_SIZE 32
+
+#define AO_USB_INT_EP 1
+#define AO_USB_INT_SIZE 8
+
+#define AO_USB_OUT_EP 4
+#define AO_USB_IN_EP 5
+/*
+ * USB bulk packets can only come in 8, 16, 32 and 64
+ * byte sizes, so we'll use 64 for everything
+ */
+#define AO_USB_IN_SIZE 64
+#define AO_USB_OUT_SIZE 64
+
+#define AO_USB_EP0_IDLE 0
+#define AO_USB_EP0_DATA_IN 1
+#define AO_USB_EP0_DATA_OUT 2
+
+#define LE_WORD(x) ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8))
+
+/* CDC definitions */
+#define AO_USB_CS_INTERFACE 0x24
+#define AO_USB_CS_ENDPOINT 0x25
+
+#define AO_USB_SET_LINE_CODING 0x20
+#define AO_USB_GET_LINE_CODING 0x21
+#define AO_USB_SET_CONTROL_LINE_STATE 0x22
+
+/* Data structure for GET_LINE_CODING / SET_LINE_CODING class requests */
+struct ao_usb_line_coding {
+ uint32_t rate;
+ uint8_t char_format;
+ uint8_t parity;
+ uint8_t data_bits;
+} ;
+
+#endif /* _AO_USB_H_ */