telebt-v0.0 telebt-v0.1 \
telemetrum-v0.1-sky telemetrum-v0.1-sirf \
telelaunch-v0.1 tidongle test \
- teleterra-v0.2 teleshield-v0.1
+ teleterra-v0.2 teleshield-v0.1 \
+ telefire-v0.1
endif
ifneq ($(shell which avr-gcc),)
}
#endif /* telemini || telenano */
+#ifdef TELEFIRE_V_0_1
+ a = (uint8_t __xdata *) (&ao_data_ring[ao_data_head].adc.sense[0] + sequence);
+ a[0] = ADCL;
+ a[1] = ADCH;
+ if (sequence < 5)
+ ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | (sequence + 1);
+#define GOT_ADC
+#endif /* TELEFIRE_V_0_1 */
+
#ifndef GOT_ADC
#error No known ADC configuration set
#endif
{
static __xdata struct ao_data packet;
ao_data_get(&packet);
+#ifndef AO_ADC_DUMP
printf("tick: %5u accel: %5d pres: %5d temp: %5d batt: %5d drogue: %5d main: %5d\n",
packet.tick, packet.adc.accel, packet.adc.pres, packet.adc.temp,
packet.adc.v_batt, packet.adc.sense_d, packet.adc.sense_m);
+#else
+ AO_ADC_DUMP(&packet);
+#endif
}
__code struct ao_cmds ao_adc_cmds[] = {
void
ao_adc_init(void)
{
+#ifdef AO_ADC_PINS
+ ADCCFG = AO_ADC_PINS;
+
+#else
+
#if IGNITE_ON_P2
/* TeleMetrum configuration */
ADCCFG = ((1 << 0) | /* acceleration */
(1 << 3)); /* battery voltage */
#endif
+#endif /* else AO_ADC_PINS */
+
/* enable interrupts */
ADCIF = 0;
IEN0 |= IEN0_ADCIE;
#define ao_arch_critical(b) __critical { b }
-struct ao_adc {
- int16_t accel; /* accelerometer */
- int16_t pres; /* pressure sensor */
- int16_t temp; /* temperature sensor */
- int16_t v_batt; /* battery voltage */
- int16_t sense_d; /* drogue continuity sense */
- int16_t sense_m; /* main continuity sense */
-#if HAS_ACCEL_REF
- uint16_t accel_ref; /* acceleration reference */
-#endif
-};
-
#define AO_DATA_RING 32
/* ao_button.c */
#define AO_IGNITER_FIRE_TIME AO_MS_TO_TICKS(50)
#define AO_IGNITER_CHARGE_TIME AO_MS_TO_TICKS(2000)
+struct ao_adc {
+ int16_t accel; /* accelerometer */
+ int16_t pres; /* pressure sensor */
+ int16_t temp; /* temperature sensor */
+ int16_t v_batt; /* battery voltage */
+ int16_t sense_d; /* drogue continuity sense */
+ int16_t sense_m; /* main continuity sense */
+#if HAS_ACCEL_REF
+ uint16_t accel_ref; /* acceleration reference */
+#endif
+};
+
#endif /* _AO_PINS_H_ */
* ao_telemetry_orig.c
*/
+#if LEGACY_MONITOR
struct ao_adc_orig {
uint16_t tick; /* tick when the sample was read */
int16_t accel; /* accelerometer */
uint8_t status;
};
+#endif /* LEGACY_MONITOR */
+
/* Unfortunately, we've exposed the CC1111 rssi units as the 'usual' method
* for reporting RSSI. So, now we use these values everywhere
*/
* ao_monitor.c
*/
+#if HAS_MONITOR
+
extern const char const * const ao_state_names[];
#define AO_MONITOR_RING 8
void
ao_monitor_init(void) __reentrant;
+#endif
+
/*
* ao_stdio.c
*/
#include "ao.h"
#include "ao_log.h"
+#include <ao_storage.h>
+#if HAS_FLIGHT
#include <ao_sample.h>
#include <ao_data.h>
+#endif
__xdata struct ao_config ao_config;
__pdata uint8_t ao_config_loaded;
*/
#include <ao.h>
+#include <ao_storage.h>
uint8_t
ao_storage_read(ao_pos_t pos, __xdata void *buf, uint16_t len) __reentrant
--- /dev/null
+/*
+ * 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.
+ */
+
+/*
+ * 74HC597 driver.
+ * Reads a single byte from the shift register
+ */
+
+#include <ao.h>
+#include <ao_74hc497.h>
+
+uint8_t
+ao_74hc497_read(void)
+{
+ static __xdata state;
+ ao_spi_get_bit(AO_74HC497_CS_PORT, AO_74HC497_CS_PIN, AO_74HC497_CS, AO_74HC497_SPI_BUS, AO_SPI_SPEED_FAST);
+ ao_spi_send(&state, 1, AO_74HC497_SPI_BUS);
+ ao_spi_put_bit(AO_74HC497_CS_PORT, AO_74HC497_CS_PIN, AO_74HC497_CS, AO_74HC497_SPI_BUS);
+ return state;
+}
+
+void
+ao_74hc497_init(void)
+{
+ ao_enable_output(AO_74HC497_CS_PORT, AO_74HC497_CS_PIN, AO_74HC497_CS, 1);
+}
--- /dev/null
+/*
+ * 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_74HC497_H_
+#define _AO_74HC497_H_
+
+uint8_t
+ao_74hc497_read(void);
+
+void
+ao_74hc497_init(void);
+
+#endif /* _AO_74HC497_H_ */
--- /dev/null
+/*
+ * 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_pad.h>
+#include <ao_74hc497.h>
+
+__xdata uint8_t ao_pad_ignite;
+
+#define ao_pad_igniter_status(c) AO_PAD_IGNITER_STATUS_UNKNOWN
+#define ao_pad_arm_status() AO_PAD_ARM_STATUS_UNKNOWN
+
+#if 0
+#define PRINTD(...) printf(__VA_ARGS__)
+#else
+#define PRINTD(...)
+#endif
+
+static void
+ao_pad_run(void)
+{
+ for (;;) {
+ while (!ao_pad_ignite)
+ ao_sleep(&ao_pad_ignite);
+ /*
+ * Actually set the pad bits
+ */
+ AO_PAD_PORT = (AO_PAD_PORT & (~AO_PAD_ALL_PINS)) | ao_pad_ignite;
+ while (ao_pad_ignite) {
+ ao_pad_ignite = 0;
+ ao_delay(AO_PAD_FIRE_TIME);
+ }
+ AO_PAD_PORT &= ~(AO_PAD_ALL_PINS);
+ }
+}
+
+static void
+ao_pad_status(void)
+{
+ for (;;) {
+ ao_delay(AO_SEC_TO_TICKS(1));
+#if 0
+ if (ao_igniter_status(ao_igniter_drogue) == ao_igniter_ready) {
+ if (ao_igniter_status(ao_igniter_main) == ao_igniter_ready) {
+ for (i = 0; i < 5; i++) {
+ ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(50));
+ ao_delay(AO_MS_TO_TICKS(100));
+ }
+ } else {
+ ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200));
+ }
+ }
+#endif
+ }
+}
+
+static __pdata uint8_t ao_pad_armed;
+static __pdata uint16_t ao_pad_arm_time;
+static __pdata uint8_t ao_pad_box;
+
+static void
+ao_pad(void)
+{
+ static __xdata struct ao_pad_command command;
+ static __xdata struct ao_pad_query query;
+ int16_t time_difference;
+ uint8_t c;
+
+ ao_led_off(AO_LED_RED);
+ ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200));
+ ao_pad_box = ao_74hc497_read();
+ for (;;) {
+ flush();
+ if (ao_radio_cmac_recv(&command, sizeof (command), 0) != AO_RADIO_CMAC_OK)
+ continue;
+
+ PRINTD ("tick %d serial %d cmd %d channel %d\n",
+ command.tick, command.serial, command.cmd, command.channel);
+
+ switch (command.cmd) {
+ case AO_LAUNCH_ARM:
+ if (command.box != ao_pad_box) {
+ PRINTD ("box number mismatch\n");
+ break;
+ }
+
+ if (command.channels & ~(AO_PAD_ALL_PINS))
+ break;
+
+ time_difference = command.tick - ao_time();
+ PRINTD ("arm tick %d local tick %d\n", command.tick, ao_time());
+ if (time_difference < 0)
+ time_difference = -time_difference;
+ if (time_difference > 10) {
+ PRINTD ("time difference too large %d\n", time_difference);
+ break;
+ }
+ PRINTD ("armed\n");
+ ao_pad_armed = command.channels;
+ ao_pad_arm_time = ao_time();
+
+ /* fall through ... */
+
+ case AO_LAUNCH_QUERY:
+ if (command.box != ao_pad_box) {
+ PRINTD ("box number mismatch\n");
+ break;
+ }
+
+ query.tick = ao_time();
+ query.box = ao_pad_box;
+ query.channels = AO_PAD_ALL_PINS;
+ query.armed = ao_pad_armed;
+ query.arm_status = ao_pad_arm_status();
+ for (c = 0; c < AO_PAD_NUM; c++)
+ query.igniter_status[c] = ao_pad_igniter_status(c);
+ PRINTD ("query tick %d serial %d channel %d valid %d arm %d igniter %d\n",
+ query.tick, query.serial, query.channel, query.valid, query.arm_status,
+ query.igniter_status);
+ ao_radio_cmac_send(&query, sizeof (query));
+ break;
+ case AO_LAUNCH_FIRE:
+ if (!ao_pad_armed) {
+ PRINTD ("not armed\n");
+ break;
+ }
+ if ((uint16_t) (ao_time() - ao_pad_arm_time) > AO_SEC_TO_TICKS(20)) {
+ PRINTD ("late pad arm_time %d time %d\n",
+ ao_pad_arm_time, ao_time());
+ break;
+ }
+ time_difference = command.tick - ao_time();
+ if (time_difference < 0)
+ time_difference = -time_difference;
+ if (time_difference > 10) {
+ PRINTD ("time different too large %d\n", time_difference);
+ break;
+ }
+ PRINTD ("ignite\n");
+ ao_pad_ignite = ao_pad_armed;
+ ao_wakeup(&ao_pad_ignite);
+ break;
+ }
+ }
+}
+
+void
+ao_pad_test(void)
+{
+#if 0
+ switch (ao_igniter_status(ao_igniter_drogue)) {
+ case ao_igniter_ready:
+ case ao_igniter_active:
+ printf ("Armed: ");
+ switch (ao_igniter_status(ao_igniter_main)) {
+ default:
+ printf("unknown status\n");
+ break;
+ case ao_igniter_ready:
+ printf("igniter good\n");
+ break;
+ case ao_igniter_open:
+ printf("igniter bad\n");
+ break;
+ }
+ break;
+ default:
+ printf("Disarmed\n");
+ }
+#endif
+}
+
+void
+ao_pad_manual(void)
+{
+ ao_cmd_white();
+ if (!ao_match_word("DoIt"))
+ return;
+ ao_cmd_white();
+ ao_pad_ignite = 1;
+ ao_wakeup(&ao_pad_ignite);
+}
+
+static __xdata struct ao_task ao_pad_task;
+static __xdata struct ao_task ao_pad_ignite_task;
+static __xdata struct ao_task ao_pad_status_task;
+
+__code struct ao_cmds ao_pad_cmds[] = {
+ { ao_pad_test, "t\0Test pad continuity" },
+ { ao_pad_manual, "i <key>\0Fire igniter. <key> is doit with D&I" },
+ { 0, NULL }
+};
+
+void
+ao_pad_init(void)
+{
+#if AO_PAD_NUM > 0
+ ao_enable_output(AO_PAD_PORT, AO_PAD_PIN_0, AO_PAD_0, 0);
+#endif
+#if AO_PAD_NUM > 1
+ ao_enable_output(AO_PAD_PORT, AO_PAD_PIN_1, AO_PAD_1, 0);
+#endif
+#if AO_PAD_NUM > 2
+ ao_enable_output(AO_PAD_PORT, AO_PAD_PIN_2, AO_PAD_2, 0);
+#endif
+#if AO_PAD_NUM > 3
+ ao_enable_output(AO_PAD_PORT, AO_PAD_PIN_3, AO_PAD_3, 0);
+#endif
+ ao_cmd_register(&ao_pad_cmds[0]);
+ ao_add_task(&ao_pad_task, ao_pad, "pad listener");
+ ao_add_task(&ao_pad_ignite_task, ao_pad_run, "pad igniter");
+ ao_add_task(&ao_pad_status_task, ao_pad_status, "pad status");
+}
--- /dev/null
+/*
+ * 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_PAD_H_
+#define _AO_PAD_H_
+
+#define AO_PAD_MAX_CHANNELS 8
+
+struct ao_pad_command {
+ uint16_t tick;
+ uint16_t box;
+ uint8_t cmd;
+ uint8_t channels;
+};
+
+/* Report current telefire status.
+ */
+
+#define AO_PAD_QUERY 1
+
+struct ao_pad_query {
+ uint16_t tick; /* telefire tick */
+ uint16_t box; /* telefire box number */
+ uint8_t channels; /* which chanels are present */
+ uint8_t armed; /* which channels are armed */
+ uint8_t arm_status; /* status of arming switch */
+ uint8_t igniter_status[AO_PAD_MAX_CHANNELS]; /* status for each igniter */
+};
+
+/* Set current armed pads, report back status
+ */
+
+#define AO_PAD_ARM 2
+
+/* Fire current armed pads for 200ms, no report
+ */
+#define AO_PAD_FIRE 3
+
+#define AO_PAD_FIRE_TIME AO_MS_TO_TICKS(200)
+
+#define AO_PAD_ARM_STATUS_DISARMED 0
+#define AO_PAD_ARM_STATUS_ARMED 1
+#define AO_PAD_ARM_STATUS_UNKNOWN 2
+
+#define AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN 0
+#define AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN 1
+#define AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_CLOSED 2
+#define AO_PAD_IGNITER_STATUS_UNKNOWN 3
+
+void
+ao_pad_init(void);
+
+#endif /* _AO_PAD_H_ */
--- /dev/null
+/*
+ * 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.
+ */
+
+/*
+ * PCA9922 LED driver. This uses SPI to send a single byte to the device to
+ * set the current state of the LEDs using the existing LED interface
+ */
+
+#include <ao.h>
+
+static __xdata uint8_t ao_led_state;
+
+static void
+ao_led_apply(void)
+{
+ /* Don't try the SPI bus during initialization */
+ if (!ao_cur_task)
+ return;
+ ao_spi_get_bit(AO_PCA9922_CS_PORT, AO_PCA9922_CS_PIN, AO_PCA9922_CS, AO_PCA9922_SPI_BUS, AO_SPI_SPEED_FAST);
+ ao_spi_send(&ao_led_state, 1, AO_PCA9922_SPI_BUS);
+ ao_spi_put_bit(AO_PCA9922_CS_PORT, AO_PCA9922_CS_PIN, AO_PCA9922_CS, AO_PCA9922_SPI_BUS);
+}
+
+void
+ao_led_on(uint8_t colors)
+{
+ ao_led_state |= colors;
+ ao_led_apply();
+}
+
+void
+ao_led_off(uint8_t colors)
+{
+ ao_led_state &= ~colors;
+ ao_led_apply();
+}
+
+void
+ao_led_set(uint8_t colors)
+{
+ ao_led_state = colors;
+ ao_led_apply();
+}
+
+void
+ao_led_toggle(uint8_t colors)
+{
+ ao_led_state ^= colors;
+ ao_led_apply();
+}
+
+void
+ao_led_for(uint8_t colors, uint16_t ticks) __reentrant
+{
+ ao_led_on(colors);
+ ao_delay(ticks);
+ ao_led_off(colors);
+}
+
+void
+ao_led_init(uint8_t enable)
+{
+ ao_enable_output(AO_PCA9922_CS_PORT, AO_PCA9922_CS_PIN, AO_PCA9922_CS, 1);
+}
--- /dev/null
+#
+# TeleFire build file
+#
+
+TELEFIRE_VER=0.1
+TELEFIRE_DEF=0_1
+
+vpath %.c ..:../core:../cc1111:../drivers:../product
+vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath ao-make-product.5c ../util
+
+ifndef VERSION
+include ../Version
+endif
+
+INC = \
+ ao.h \
+ ao_pins.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ cc1111.h \
+ ao_product.h
+
+CORE_SRC = \
+ ao_cmd.c \
+ ao_config.c \
+ ao_convert.c \
+ ao_mutex.c \
+ ao_panic.c \
+ ao_stdio.c \
+ ao_storage.c \
+ ao_task.c \
+ ao_freq.c
+
+CC1111_SRC = \
+ ao_adc.c \
+ ao_aes.c \
+ ao_beep.c \
+ ao_dma.c \
+ ao_intflash.c \
+ ao_radio.c \
+ ao_radio_cmac.c \
+ ao_romconfig.c \
+ ao_serial.c \
+ ao_spi.c \
+ ao_string.c \
+ ao_timer.c \
+ ao_usb.c \
+ _bp.c
+
+DRIVER_SRC = \
+ ao_pca9922.c \
+ ao_74hc497.c \
+ ao_pad.c
+
+PRODUCT_SRC = \
+ ao_telefire.c
+
+SRC = \
+ $(CORE_SRC) \
+ $(CC1111_SRC) \
+ $(DRIVER_SRC) \
+ $(PRODUCT_SRC)
+
+PROGNAME = telefire-v$(TELEFIRE_VER)
+PROG = $(PROGNAME)-$(VERSION).ihx
+PRODUCT=TeleFire-v$(TELEFIRE_VER)
+PRODUCT_DEF=-DTELEFIRE_V_$(TELEFIRE_DEF)
+IDPRODUCT=0x000f
+CODESIZE=0x6700
+
+include ../cc1111/Makefile.cc1111
+
+NICKLE=nickle
+CHECK_STACK=sh ../util/check-stack
+
+V=0
+# The user has explicitly enabled quiet compilation.
+ifeq ($(V),0)
+quiet = @printf " $1 $2 $@\n"; $($1)
+endif
+# Otherwise, print the full command line.
+quiet ?= $($1)
+
+all: ../$(PROG)
+
+../$(PROG): $(REL) Makefile
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) ..
+ $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@
+
+ao_product.h: ao-make-product.5c ../Version
+ $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
+
+distclean: clean
+
+clean: clean-cc1111
+
+install:
+
+uninstall:
+
--- /dev/null
+/*
+ * Copyright © 2010 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_RADIO 1
+
+#define HAS_FLIGHT 0
+#define HAS_USB 1
+#define HAS_BEEP 1
+#define HAS_GPS 0
+#define HAS_SERIAL_1 0
+#define HAS_ADC 1
+#define HAS_DBG 0
+#define HAS_EEPROM 1
+#define HAS_LOG 0
+#define USE_INTERNAL_FLASH 1
+#define DBG_ON_P1 0
+#define IGNITE_ON_P2 0
+#define IGNITE_ON_P1 1
+#define IGNITE_ON_P0 0
+#define PACKET_HAS_MASTER 0
+#define PACKET_HAS_SLAVE 0
+#define AO_LED_RED 2
+#define AO_LED_GREEN 1
+#define LEDS_AVAILABLE (0xff)
+#define HAS_EXTERNAL_TEMP 0
+#define HAS_ACCEL_REF 0
+#define SPI_CS_ON_P1 1
+#define HAS_AES 1
+
+#define SPI_CS_PORT P1
+#define SPI_CS_SEL P1SEL
+#define SPI_CS_DIR P1DIR
+
+#define AO_74HC497_CS_PORT P1
+#define AO_74HC497_CS_PIN 4
+#define AO_74HC497_CS P1_4
+
+#define AO_PCA9922_CS_PORT P1
+#define AO_PCA9922_CS_PIN 4
+#define AO_PCA9922_CS P1_4
+
+#define AO_PAD_NUM 4
+#define AO_PAD_PORT P1
+#define AO_PAD_DIR P1DIR
+#define AO_PAD_PIN_0 0
+#define AO_PAD_0 P1_0
+#define AO_PAD_PIN_1 1
+#define AO_PAD_1 P1_1
+#define AO_PAD_PIN_2 2
+#define AO_PAD_2 P1_2
+#define AO_PAD_PIN_3 3
+#define AO_PAD_3 P1_3
+#define AO_PAD_ALL_PINS ((1 << AO_PAD_PIN_0) | (1 << AO_PAD_PIN_1) | (1 << AO_PAD_PIN_2) | (1 << AO_PAD_PIN_3))
+
+/* test these values with real igniters */
+#define AO_PAD_RELAY_CLOSED 3524
+#define AO_PAD_NO_IGNITER 16904
+#define AO_PAD_GOOD_IGNITER 22514
+
+struct ao_adc {
+ int16_t sense[4];
+ int16_t pyro;
+ int16_t batt;
+};
+
+#define AO_ADC_DUMP(p) \
+ printf ("tick: %5u 0: %5d 1: %5d 2: %5d 3: %5d pyro: %5d batt %5d\n", \
+ (p)->adc.sense[0], \
+ (p)->adc.sense[1], \
+ (p)->adc.sense[2], \
+ (p)->adc.sense[3], \
+ (p)->adc.pyro, \
+ (p)->adc.batt)
+
+#define AO_ADC_PINS ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5))
+
+#endif /* _AO_PINS_H_ */
--- /dev/null
+/*
+ * 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_pins.h"
+
+void
+main(void)
+{
+ ao_clock_init();
+
+ ao_led_init(LEDS_AVAILABLE);
+
+ ao_timer_init();
+ ao_adc_init();
+ ao_beep_init();
+ ao_cmd_init();
+ ao_spi_init();
+ ao_storage_init();
+ ao_usb_init();
+ ao_radio_init();
+ ao_aes_init();
+ ao_radio_cmac_init();
+ ao_pad_init();
+ ao_config_init();
+ ao_start_scheduler();
+}