summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-07-15 22:55:20 -0700
committerKeith Packard <keithp@keithp.com>2014-07-15 22:55:20 -0700
commit3cf030fffffd223c3717011e03aac82346295d71 (patch)
treeb6da4fbb1180b75bedb86ce608503a6c0aeb47f3 /src
parent607fbb01710be1cb263625337f5be3d0fb48d5e7 (diff)
parent9ab3a1de95b705783c31a7e16447f52c10b6b480 (diff)
Merge tag '1.4' into fox
tagging 1.4 release Conflicts: src/Makefile
Diffstat (limited to 'src')
-rw-r--r--src/Makefile9
-rw-r--r--src/attiny/ao_async.c89
-rw-r--r--src/avr-demo/Makefile4
-rw-r--r--src/avr/ao_usb_avr.c2
-rw-r--r--src/cc1111/Makefile.cc11112
-rw-r--r--src/cc1111/ao_arch.h2
-rw-r--r--src/cc1111/ao_pins.h49
-rw-r--r--src/cc1111/ao_timer.c40
-rw-r--r--src/cc1111/ao_usb.c14
-rw-r--r--src/core/ao_config.h53
-rw-r--r--src/drivers/ao_aprs.c204
-rw-r--r--src/drivers/ao_cc115l.c37
-rw-r--r--src/drivers/ao_gps_ublox.c13
-rw-r--r--src/drivers/ao_lco_func.c2
-rw-r--r--src/drivers/ao_ms5607.c22
-rw-r--r--src/drivers/ao_ms5607.h4
-rw-r--r--src/drivers/ao_ms5607_convert.c12
-rw-r--r--src/drivers/ao_ms5607_convert_8051.c20
-rw-r--r--src/drivers/ao_pad.c6
-rw-r--r--src/drivers/ao_pca9922.c21
-rw-r--r--src/drivers/ao_quadrature.c103
-rw-r--r--src/easymega-v0.1/.gitignore2
-rw-r--r--src/easymega-v0.1/Makefile144
-rw-r--r--src/easymega-v0.1/ao_easymega.c95
-rw-r--r--src/easymega-v0.1/ao_pins.h352
-rw-r--r--src/easymega-v0.1/flash-loader/Makefile8
-rw-r--r--src/easymega-v0.1/flash-loader/ao_pins.h34
-rw-r--r--src/easymini-v1.0/Makefile1
-rw-r--r--src/easymini-v1.0/ao_pins.h21
-rw-r--r--src/kernel/altitude.h (renamed from src/core/altitude.h)0
-rw-r--r--src/kernel/ao.h (renamed from src/core/ao.h)79
-rw-r--r--src/kernel/ao_adc.h (renamed from src/core/ao_adc.h)0
-rw-r--r--src/kernel/ao_aes.h (renamed from src/core/ao_aes.h)0
-rw-r--r--src/kernel/ao_balloon.c (renamed from src/teleballoon-v1.1/ao_balloon.c)13
-rw-r--r--src/kernel/ao_beep.h (renamed from src/core/ao_beep.h)19
-rw-r--r--src/kernel/ao_boot.h (renamed from src/stm/ao_boot.h)4
-rw-r--r--src/kernel/ao_btm.h (renamed from src/core/ao_btm.h)0
-rw-r--r--src/kernel/ao_cmd.c (renamed from src/core/ao_cmd.c)20
-rw-r--r--src/kernel/ao_companion.h (renamed from src/core/ao_companion.h)0
-rw-r--r--src/kernel/ao_config.c (renamed from src/core/ao_config.c)111
-rw-r--r--src/kernel/ao_config.h146
-rw-r--r--src/kernel/ao_convert.c (renamed from src/core/ao_convert.c)0
-rw-r--r--src/kernel/ao_convert_pa.c (renamed from src/core/ao_convert_pa.c)0
-rw-r--r--src/kernel/ao_convert_pa_test.c (renamed from src/core/ao_convert_pa_test.c)0
-rw-r--r--src/kernel/ao_convert_test.c (renamed from src/core/ao_convert_test.c)0
-rw-r--r--src/kernel/ao_convert_volt.c (renamed from src/core/ao_convert_volt.c)10
-rw-r--r--src/kernel/ao_data.c (renamed from src/core/ao_data.c)0
-rw-r--r--src/kernel/ao_data.h (renamed from src/core/ao_data.h)0
-rw-r--r--src/kernel/ao_dbg.h (renamed from src/core/ao_dbg.h)0
-rw-r--r--src/kernel/ao_debounce.c (renamed from src/core/ao_debounce.c)0
-rw-r--r--src/kernel/ao_debounce.h (renamed from src/core/ao_debounce.h)0
-rw-r--r--src/kernel/ao_distance.c123
-rw-r--r--src/kernel/ao_distance.h25
-rw-r--r--src/kernel/ao_ee_fake.c (renamed from src/core/ao_ee_fake.c)0
-rw-r--r--src/kernel/ao_eeprom.h (renamed from src/core/ao_eeprom.h)0
-rw-r--r--src/kernel/ao_fake_flight.c219
-rw-r--r--src/kernel/ao_fake_flight.h53
-rw-r--r--src/kernel/ao_fec.h (renamed from src/core/ao_fec.h)0
-rw-r--r--src/kernel/ao_fec_rx.c (renamed from src/core/ao_fec_rx.c)0
-rw-r--r--src/kernel/ao_fec_tx.c (renamed from src/core/ao_fec_tx.c)0
-rw-r--r--src/kernel/ao_flight.c (renamed from src/core/ao_flight.c)14
-rw-r--r--src/kernel/ao_flight.h (renamed from src/core/ao_flight.h)0
-rw-r--r--src/kernel/ao_flight_nano.c (renamed from src/core/ao_flight_nano.c)0
-rw-r--r--src/kernel/ao_freq.c (renamed from src/core/ao_freq.c)0
-rw-r--r--src/kernel/ao_gps_print.c (renamed from src/core/ao_gps_print.c)0
-rw-r--r--src/kernel/ao_gps_report.c (renamed from src/core/ao_gps_report.c)0
-rw-r--r--src/kernel/ao_gps_report_mega.c (renamed from src/core/ao_gps_report_mega.c)44
-rw-r--r--src/kernel/ao_gps_report_metrum.c (renamed from src/core/ao_gps_report_metrum.c)0
-rw-r--r--src/kernel/ao_gps_show.c (renamed from src/core/ao_gps_show.c)0
-rw-r--r--src/kernel/ao_host.h (renamed from src/core/ao_host.h)0
-rw-r--r--src/kernel/ao_ignite.c (renamed from src/core/ao_ignite.c)0
-rw-r--r--src/kernel/ao_int64.c (renamed from src/core/ao_int64.c)6
-rw-r--r--src/kernel/ao_int64.h (renamed from src/core/ao_int64.h)0
-rw-r--r--src/kernel/ao_kalman.c (renamed from src/core/ao_kalman.c)0
-rw-r--r--src/kernel/ao_lcd.h (renamed from src/core/ao_lcd.h)0
-rw-r--r--src/kernel/ao_led.h (renamed from src/core/ao_led.h)0
-rw-r--r--src/kernel/ao_list.h (renamed from src/core/ao_list.h)0
-rw-r--r--src/kernel/ao_log.c (renamed from src/core/ao_log.c)62
-rw-r--r--src/kernel/ao_log.h (renamed from src/core/ao_log.h)56
-rw-r--r--src/kernel/ao_log_big.c (renamed from src/core/ao_log_big.c)1
-rw-r--r--src/kernel/ao_log_gps.c137
-rw-r--r--src/kernel/ao_log_gps.h33
-rw-r--r--src/kernel/ao_log_mega.c (renamed from src/core/ao_log_mega.c)7
-rw-r--r--src/kernel/ao_log_metrum.c (renamed from src/core/ao_log_metrum.c)3
-rw-r--r--src/kernel/ao_log_micro.c (renamed from src/core/ao_log_micro.c)0
-rw-r--r--src/kernel/ao_log_micro.h (renamed from src/core/ao_log_micro.h)0
-rw-r--r--src/kernel/ao_log_mini.c (renamed from src/core/ao_log_mini.c)1
-rw-r--r--src/kernel/ao_log_single.c (renamed from src/core/ao_log_single.c)0
-rw-r--r--src/kernel/ao_log_telem.c (renamed from src/core/ao_log_telem.c)0
-rw-r--r--src/kernel/ao_log_telescience.c (renamed from src/core/ao_log_telescience.c)0
-rw-r--r--src/kernel/ao_log_tiny.c (renamed from src/core/ao_log_tiny.c)0
-rw-r--r--src/kernel/ao_microflight.c (renamed from src/core/ao_microflight.c)0
-rw-r--r--src/kernel/ao_microkalman.c (renamed from src/core/ao_microkalman.c)0
-rw-r--r--src/kernel/ao_monitor.c (renamed from src/core/ao_monitor.c)0
-rw-r--r--src/kernel/ao_mutex.c (renamed from src/core/ao_mutex.c)0
-rw-r--r--src/kernel/ao_notask.c (renamed from src/core/ao_notask.c)0
-rw-r--r--src/kernel/ao_notask.h (renamed from src/core/ao_notask.h)0
-rw-r--r--src/kernel/ao_packet.h (renamed from src/core/ao_packet.h)0
-rw-r--r--src/kernel/ao_panic.c (renamed from src/core/ao_panic.c)0
-rw-r--r--src/kernel/ao_product.c (renamed from src/core/ao_product.c)0
-rw-r--r--src/kernel/ao_pyro.c (renamed from src/core/ao_pyro.c)14
-rw-r--r--src/kernel/ao_pyro.h (renamed from src/core/ao_pyro.h)8
-rw-r--r--src/kernel/ao_quaternion.h (renamed from src/core/ao_quaternion.h)0
-rw-r--r--src/kernel/ao_radio_cmac.c (renamed from src/core/ao_radio_cmac.c)0
-rw-r--r--src/kernel/ao_radio_cmac.h (renamed from src/core/ao_radio_cmac.h)0
-rw-r--r--src/kernel/ao_radio_cmac_cmd.c (renamed from src/core/ao_radio_cmac_cmd.c)0
-rw-r--r--src/kernel/ao_radio_cmac_cmd.h (renamed from src/core/ao_radio_cmac_cmd.h)0
-rw-r--r--src/kernel/ao_report.c (renamed from src/core/ao_report.c)103
-rw-r--r--src/kernel/ao_report_micro.c (renamed from src/core/ao_report_micro.c)0
-rw-r--r--src/kernel/ao_rssi.c (renamed from src/core/ao_rssi.c)0
-rw-r--r--src/kernel/ao_sample.c (renamed from src/core/ao_sample.c)0
-rw-r--r--src/kernel/ao_sample.h (renamed from src/core/ao_sample.h)0
-rw-r--r--src/kernel/ao_sample_profile.c (renamed from src/core/ao_sample_profile.c)0
-rw-r--r--src/kernel/ao_sample_profile.h (renamed from src/core/ao_sample_profile.h)0
-rw-r--r--src/kernel/ao_send_packet.c (renamed from src/core/ao_send_packet.c)0
-rw-r--r--src/kernel/ao_send_packet.h (renamed from src/core/ao_send_packet.h)0
-rw-r--r--src/kernel/ao_serial.h (renamed from src/core/ao_serial.h)0
-rw-r--r--src/kernel/ao_sqrt.c (renamed from src/core/ao_sqrt.c)0
-rw-r--r--src/kernel/ao_state.c (renamed from src/core/ao_state.c)0
-rw-r--r--src/kernel/ao_stdio.c (renamed from src/core/ao_stdio.c)3
-rw-r--r--src/kernel/ao_storage.c (renamed from src/core/ao_storage.c)0
-rw-r--r--src/kernel/ao_storage.h (renamed from src/core/ao_storage.h)0
-rw-r--r--src/kernel/ao_task.c (renamed from src/core/ao_task.c)0
-rw-r--r--src/kernel/ao_task.h (renamed from src/core/ao_task.h)0
-rw-r--r--src/kernel/ao_telem.h (renamed from src/core/ao_telem.h)0
-rw-r--r--src/kernel/ao_telemetry.c (renamed from src/core/ao_telemetry.c)14
-rw-r--r--src/kernel/ao_telemetry.h (renamed from src/core/ao_telemetry.h)8
-rw-r--r--src/kernel/ao_tracker.c226
-rw-r--r--src/kernel/ao_tracker.h37
-rw-r--r--src/kernel/ao_usb.h (renamed from src/core/ao_usb.h)2
-rw-r--r--src/lpc/Makefile-lpc.defs4
-rw-r--r--src/lpc/ao_adc_lpc.c2
-rw-r--r--src/lpc/ao_arch.h9
-rw-r--r--src/lpc/ao_boot_chain.c4
-rw-r--r--src/lpc/ao_exti_lpc.c4
-rw-r--r--src/lpc/ao_interrupt.c2
-rw-r--r--src/lpc/ao_led_lpc.c20
-rw-r--r--src/lpc/ao_serial_lpc.c4
-rw-r--r--src/lpc/ao_usb_lpc.c4
-rw-r--r--src/lpcxpresso/ao_pins.h1
-rw-r--r--src/megadongle-v0.1/Makefile1
-rw-r--r--src/micropeak/Makefile17
-rw-r--r--src/microwater/.gitignore2
-rw-r--r--src/microwater/Makefile121
-rw-r--r--src/microwater/ao_pins.h70
-rw-r--r--src/nanopeak-v0.1/Makefile4
-rw-r--r--src/product/Makefile.teledongle4
-rw-r--r--src/product/Makefile.telelaunch4
-rw-r--r--src/product/Makefile.telemetrum4
-rw-r--r--src/product/Makefile.telemini4
-rw-r--r--src/product/Makefile.telenano4
-rw-r--r--src/product/ao_flash_task.c39
-rw-r--r--src/product/ao_micropeak.h2
-rw-r--r--src/spiradio-v0.1/.sdcdbrc2
-rw-r--r--src/spiradio-v0.1/Makefile4
-rw-r--r--src/stm-bringup/Makefile2
-rw-r--r--src/stm-demo/Makefile2
-rw-r--r--src/stm-demo/ao_demo.c41
-rw-r--r--src/stm-demo/ao_pins.h11
-rw-r--r--src/stm-demo/flash-loader/Makefile8
-rw-r--r--src/stm-demo/flash-loader/ao_pins.h35
-rw-r--r--src/stm-flash/Makefile1
-rw-r--r--src/stm/Makefile-flash.defs4
-rw-r--r--src/stm/Makefile.defs4
-rw-r--r--src/stm/ao_arch.h3
-rw-r--r--src/stm/ao_boot_chain.c2
-rw-r--r--src/stm/ao_boot_pin.c2
-rw-r--r--src/stm/ao_fast_timer.c8
-rw-r--r--src/stm/ao_interrupt.c32
-rw-r--r--src/stm/ao_timer.c10
-rw-r--r--src/stm/ao_usb_stm.c5
-rw-r--r--src/stm/registers.ld5
-rw-r--r--src/stm/stm32l.h57
-rw-r--r--src/teleballoon-v1.1/Makefile4
-rw-r--r--src/teleballoon-v1.1/ao_pins.h1
-rw-r--r--src/teleballoon-v2.0/.gitignore3
-rw-r--r--src/teleballoon-v2.0/Makefile130
-rw-r--r--src/teleballoon-v2.0/ao_pins.h328
-rw-r--r--src/teleballoon-v2.0/ao_teleballoon.c92
-rw-r--r--src/telebt-v1.0/.sdcdbrc2
-rw-r--r--src/telebt-v1.0/Makefile4
-rw-r--r--src/telefire-v0.1/.sdcdbrc2
-rw-r--r--src/telefire-v0.1/Makefile4
-rw-r--r--src/telefire-v0.2/.sdcdbrc2
-rw-r--r--src/telefire-v0.2/Makefile4
-rw-r--r--src/telegps-v0.1/Makefile1
-rw-r--r--src/telegps-v0.3/Makefile14
-rw-r--r--src/telegps-v0.3/ao_pins.h10
-rw-r--r--src/telegps-v0.3/ao_telegps.c12
-rw-r--r--src/telegps-v1.0/.gitignore3
-rw-r--r--src/telegps-v1.0/Makefile91
-rw-r--r--src/telegps-v1.0/ao_pins.h149
-rw-r--r--src/telegps-v1.0/ao_telegps.c66
-rw-r--r--src/telegps-v1.0/flash-loader/Makefile8
-rw-r--r--src/telegps-v1.0/flash-loader/ao_pins.h (renamed from src/lpc/ao_boot.h)30
-rw-r--r--src/telelco-v0.1/Makefile1
-rw-r--r--src/telelco-v0.2/Makefile1
-rw-r--r--src/telelco-v0.2/ao_lco.c16
-rw-r--r--src/telelco-v0.2/ao_pins.h2
-rw-r--r--src/telemega-v0.1/ao_pins.h5
-rw-r--r--src/telemega-v1.0/Makefile1
-rw-r--r--src/telemega-v1.0/ao_pins.h5
-rw-r--r--src/telemetrum-v1.0/.sdcdbrc2
-rw-r--r--src/telemetrum-v1.1/.sdcdbrc2
-rw-r--r--src/telemetrum-v1.1/Makefile1
-rw-r--r--src/telemetrum-v1.2/Makefile1
-rw-r--r--src/telemetrum-v2.0/Makefile1
-rw-r--r--src/telemetrum-v2.0/ao_pins.h5
-rw-r--r--src/telemini-v1.0/.sdcdbrc2
-rw-r--r--src/telemini-v2.0/.sdcdbrc2
-rw-r--r--src/telemini-v2.0/Makefile6
-rw-r--r--src/telemini-v2.0/ao_pins.h28
-rw-r--r--src/telepyro-v0.1/Makefile4
-rw-r--r--src/telescience-pwm/Makefile4
-rw-r--r--src/telescience-v0.1/Makefile4
-rw-r--r--src/teleshield-v0.1/Makefile4
-rw-r--r--src/teleterra-v0.2/.sdcdbrc2
-rw-r--r--src/teleterra-v0.2/Makefile4
-rw-r--r--src/test/Makefile8
-rw-r--r--src/test/ao_aprs_test.c39
-rw-r--r--src/test/ao_flight_test.c54
-rw-r--r--src/test/ao_ms5607_convert_test.c2
-rw-r--r--src/tidongle/Makefile4
-rw-r--r--src/usbrelay-v0.1/ao_pins.h79
-rw-r--r--src/usbrelay-v0.1/ao_serial_lpc.h33
-rw-r--r--src/usbrelay-v0.1/ao_usbrelay.c90
-rw-r--r--src/usbrelay-v0.1/flash-loader/ao_pins.h33
-rw-r--r--src/usbtrng/Makefile70
-rw-r--r--src/usbtrng/ao_pins.h73
-rw-r--r--src/usbtrng/ao_usbtrng.c63
-rw-r--r--src/usbtrng/flash-loader/Makefile8
-rw-r--r--src/usbtrng/flash-loader/ao_pins.h33
232 files changed, 4663 insertions, 523 deletions
diff --git a/src/Makefile b/src/Makefile
index 1453720c..a9fe335e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -19,11 +19,10 @@ include Makedefs
SDCCDIRS=\
telemetrum-v1.2 telemetrum-v1.1 telemetrum-v1.0 \
teledongle-v0.2 \
- telemini-v1.0 \
+ telemini-v1.0 telemini-v2.0 \
telebt-v1.0 \
teleterra-v0.2 teleshield-v0.1 \
- telefire-v0.1 telefire-v0.2 \
- telemini-v2.0
+ telefire-v0.1 telefire-v0.2
ARMM3DIRS=\
telemega-v0.1 telemega-v0.1/flash-loader \
@@ -31,9 +30,11 @@ ARMM3DIRS=\
telemetrum-v2.0 telemetrum-v2.0/flash-loader \
megadongle-v0.1 megadongle-v0.1/flash-loader \
telegps-v0.3 telegps-v0.3/flash-loader \
+ telegps-v1.0 telegps-v1.0/flash-loader \
telelco-v0.2 telelco-v0.2/flash-loader \
telescience-v0.2 telescience-v0.2/flash-loader \
- fox1ihu fox1ihu/flash-loader
+ fox1ihu fox1ihu/flash-loader \
+ teleballoon-v2.0
ARMM0DIRS=\
easymini-v1.0 easymini-v1.0/flash-loader
diff --git a/src/attiny/ao_async.c b/src/attiny/ao_async.c
index 3556f54c..f64f7bde 100644
--- a/src/attiny/ao_async.c
+++ b/src/attiny/ao_async.c
@@ -40,11 +40,98 @@ ao_async_byte(uint8_t byte)
{
uint8_t b;
uint16_t w;
+ uint8_t v;
+ uint8_t bit;
+ uint8_t w_hi, w_lo;
/* start data stop */
w = (0x000 << 0) | (byte << 1) | (0x001 << 9);
+ w_hi = w >> 8;
+ w_lo = w;
+
ao_arch_block_interrupts();
+
+ /* Ok, this is a bit painful.
+ * We need this loop to be precisely timed, which
+ * means knowing exactly how many instructions will
+ * be executed for each bit. It's easy to do that by
+ * compiling the C code and looking at the output,
+ * but we need this code to work even if the compiler
+ * changes. So, just hand-code the whole thing
+ */
+
+ asm volatile (
+ " ldi %[b], 10\n" // loop value
+ "loop:\n"
+ " in %[v], %[port]\n" // read current value
+ " andi %[v], %[led_mask]\n" // mask to clear LED bit
+ " mov %[bit], %[w_lo]\n" // get current data byte
+ " andi %[bit], 0x01\n" // get current data bit
+#if AO_LED_SERIAL >= 1
+ " add %[bit],%[bit]\n" // shift by one
+#else
+ " nop\n"
+#endif
+#if AO_LED_SERIAL >= 2
+ " add %[bit],%[bit]\n" // shift by one
+#else
+ " nop\n"
+#endif
+#if AO_LED_SERIAL >= 3
+ " add %[bit],%[bit]\n" // shift by one
+#else
+ " nop\n"
+#endif
+#if AO_LED_SERIAL >= 4
+ " add %[bit],%[bit]\n" // shift by one
+#else
+ " nop\n"
+#endif
+#if AO_LED_SERIAL >= 5
+ " add %[bit],%[bit]\n" // shift by one
+#else
+ " nop\n"
+#endif
+#if AO_LED_SERIAL >= 6
+ " add %[bit],%[bit]\n" // shift by one
+#else
+ " nop\n"
+#endif
+#if AO_LED_SERIAL >= 7
+ " add %[bit],%[bit]\n" // shift by one
+#else
+ " nop\n"
+#endif
+ " or %[v], %[bit]\n" // add to register
+ " out %[port], %[v]\n" // write current value
+ " lsr %[w_hi]\n" // shift data
+ " ror %[w_lo]\n" // ...
+ " nop\n"
+ " nop\n"
+ " nop\n"
+ " nop\n"
+ " nop\n"
+
+ " nop\n"
+ " nop\n"
+ " nop\n"
+ " subi %[b], 1\n" // decrement bit count
+ " brne loop\n" // jump back to top
+ : [v] "=&r" (v),
+ [bit] "=&r" (bit),
+ [b] "=&r" (b),
+ [w_lo] "+r" (w_lo),
+ [w_hi] "+r" (w_hi)
+ : [port] "I" (_SFR_IO_ADDR(LED_PORT)),
+ [led_mask] "M" ((~(1 << AO_LED_SERIAL)) & 0xff)
+ );
+
+#if 0
+ /*
+ * Here's the equivalent C code to document
+ * what the above assembly code does
+ */
for (b = 0; b < 10; b++) {
uint8_t v = LED_PORT & ~(1 << AO_LED_SERIAL);
v |= (w & 1) << AO_LED_SERIAL;
@@ -54,6 +141,7 @@ ao_async_byte(uint8_t byte)
/* Carefully timed to hit around 9600 baud */
asm volatile ("nop");
asm volatile ("nop");
+ asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
@@ -67,5 +155,6 @@ ao_async_byte(uint8_t byte)
asm volatile ("nop");
asm volatile ("nop");
}
+#endif
ao_arch_release_interrupts();
}
diff --git a/src/avr-demo/Makefile b/src/avr-demo/Makefile
index 6d9bfea2..e21ad047 100644
--- a/src/avr-demo/Makefile
+++ b/src/avr-demo/Makefile
@@ -2,7 +2,7 @@
# AltOS build
#
#
-vpath % ..:../core:../product:../drivers:../avr
+vpath % ..:../kernel:../product:../drivers:../avr
vpath make-altitude ..
vpath make-kalman ..
vpath kalman.5c ../kalman
@@ -46,7 +46,7 @@ PRODUCT=AvrDemo-v0.0
MCU=atmega32u4
PRODUCT_DEF=-DAVR_DEMO
IDPRODUCT=0x000a
-CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../core -I..
+CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../kernel -I..
CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -Os -mcall-prologues
NICKLE=nickle
diff --git a/src/avr/ao_usb_avr.c b/src/avr/ao_usb_avr.c
index bd75b17d..cb0455c2 100644
--- a/src/avr/ao_usb_avr.c
+++ b/src/avr/ao_usb_avr.c
@@ -46,7 +46,7 @@ static __xdata uint8_t ao_usb_ep0_out_len;
static __xdata uint8_t *__xdata ao_usb_ep0_out_data;
static __xdata uint8_t ao_usb_in_flushed;
-static __xdata uint8_t ao_usb_running;
+__xdata uint8_t ao_usb_running;
static __xdata uint8_t ao_usb_configuration;
static __xdata uint8_t ueienx_0;
diff --git a/src/cc1111/Makefile.cc1111 b/src/cc1111/Makefile.cc1111
index 78b653b3..0ea30e1d 100644
--- a/src/cc1111/Makefile.cc1111
+++ b/src/cc1111/Makefile.cc1111
@@ -3,7 +3,7 @@ CC=$(SDCC)
CFLAGS=--model-small --debug --opt-code-speed -DCODESIZE=$(CODESIZE)
-CFLAGS += $(PRODUCT_DEF) -I. -I.. -I../core -I../cc1111 -I../drivers -I../product
+CFLAGS += $(PRODUCT_DEF) -I. -I.. -I../kernel -I../cc1111 -I../drivers -I../product
CODESIZE ?= 0x8000
diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h
index 34235b08..fcac331b 100644
--- a/src/cc1111/ao_arch.h
+++ b/src/cc1111/ao_arch.h
@@ -326,4 +326,6 @@ void
ao_p0_isr(void) __interrupt(13);
#endif
+#define AO_ADC_MAX 32767
+
#endif /* _AO_ARCH_H_ */
diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h
index 2f0e2884..2b19f1f6 100644
--- a/src/cc1111/ao_pins.h
+++ b/src/cc1111/ao_pins.h
@@ -18,12 +18,16 @@
#ifndef _AO_PINS_H_
#define _AO_PINS_H_
-#define HAS_RADIO 1
+#define HAS_RADIO 1
+#define DISABLE_LOG_SPACE 1
#if defined(TELEMETRUM_V_1_0)
+ /* Discontinued and was never built with CC1111 chips needing this */
+ #define NEEDS_CC1111_CLOCK_HACK 0
#define HAS_FLIGHT 1
#define HAS_USB 1
#define HAS_BEEP 1
+ #define HAS_BEEP_CONFIG 0
#define HAS_GPS 1
#define HAS_SERIAL_1 1
#define HAS_ADC 1
@@ -55,9 +59,13 @@
#endif
#if defined(TELEMETRUM_V_1_1)
+ /* Discontinued and was never built with CC1111 chips needing this */
+ #define NEEDS_CC1111_CLOCK_HACK 0
#define HAS_FLIGHT 1
#define HAS_USB 1
#define HAS_BEEP 1
+ #define HAS_BEEP_CONFIG 0
+ #define HAS_BATTERY_REPORT 1
#define HAS_GPS 1
#define HAS_SERIAL_1 1
#define HAS_ADC 1
@@ -91,9 +99,13 @@
#endif
#if defined(TELEMETRUM_V_1_2)
+ /* Discontinued and was never built with CC1111 chips needing this */
+ #define NEEDS_CC1111_CLOCK_HACK 0
#define HAS_FLIGHT 1
#define HAS_USB 1
#define HAS_BEEP 1
+ #define HAS_BEEP_CONFIG 0
+ #define HAS_BATTERY_REPORT 1
#define HAS_GPS 1
#define HAS_SERIAL_1 1
#define HAS_ADC 1
@@ -155,6 +167,8 @@
#endif
#if defined(TELEMINI_V_1_0)
+ /* Discontinued and was never built with CC1111 chips needing this */
+ #define NEEDS_CC1111_CLOCK_HACK 0
#define HAS_FLIGHT 1
#define HAS_USB 0
#define HAS_BEEP 0
@@ -182,6 +196,8 @@
#endif
#if defined(TELENANO_V_0_1)
+ /* Discontinued and was never built with CC1111 chips needing this */
+ #define NEEDS_CC1111_CLOCK_HACK 0
#define HAS_FLIGHT 1
#define HAS_USB 0
#define HAS_BEEP 0
@@ -207,9 +223,12 @@
#endif
#if defined(TELEMETRUM_V_0_1)
+ /* Discontinued and was never built with CC1111 chips needing this */
+ #define NEEDS_CC1111_CLOCK_HACK 0
#define HAS_FLIGHT 1
#define HAS_USB 1
#define HAS_BEEP 1
+ #define HAS_BEEP_CONFIG 0
#define HAS_GPS 1
#define HAS_SERIAL_1 1
#define HAS_ADC 1
@@ -237,6 +256,8 @@
#endif
#if defined(TELEDONGLE_V_0_1)
+ /* Discontinued and was never built with CC1111 chips needing this */
+ #define NEEDS_CC1111_CLOCK_HACK 0
#define HAS_FLIGHT 0
#define HAS_USB 1
#define HAS_BEEP 0
@@ -265,6 +286,8 @@
#endif
#if defined(TIDONGLE)
+ /* Discontinued and was never built with CC1111 chips needing this */
+ #define NEEDS_CC1111_CLOCK_HACK 0
#define HAS_FLIGHT 0
#define HAS_USB 1
#define HAS_BEEP 0
@@ -292,6 +315,8 @@
#endif
#if defined(TELEBT_V_0_0)
+ /* Discontinued and was never built with CC1111 chips needing this */
+ #define NEEDS_CC1111_CLOCK_HACK 0
#define HAS_FLIGHT 0
#define HAS_USB 1
#define HAS_BEEP 0
@@ -328,9 +353,12 @@
#endif
#if defined(TELEBT_V_0_1)
+ /* Discontinued and was never built with CC1111 chips needing this */
+ #define NEEDS_CC1111_CLOCK_HACK 0
#define HAS_FLIGHT 0
#define HAS_USB 1
#define HAS_BEEP 1
+ #define HAS_BEEP_CONFIG 0
#define HAS_SERIAL_1 1
#define HAS_SERIAL_1_ALT_1 1
#define HAS_SERIAL_1_ALT_2 0
@@ -371,6 +399,8 @@
#endif
#if defined(TELELAUNCH_V_0_1)
+ /* Discontinued and was never built with CC1111 chips needing this */
+ #define NEEDS_CC1111_CLOCK_HACK 0
#define HAS_FLIGHT 0
#define HAS_USB 1
#define HAS_BEEP 1
@@ -572,4 +602,21 @@ struct ao_adc {
#endif
};
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS 5 /* 5k */
+#define AO_BATTERY_DIV_MINUS 10 /* 10k */
+
+/*
+ * Voltage divider on ADC igniter samplers
+ */
+#define AO_IGNITE_DIV_PLUS 100 /* 100k */
+#define AO_IGNITE_DIV_MINUS 27 /* 27k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV 33
+
#endif /* _AO_PINS_H_ */
diff --git a/src/cc1111/ao_timer.c b/src/cc1111/ao_timer.c
index 75cc4ce8..2fbc6621 100644
--- a/src/cc1111/ao_timer.c
+++ b/src/cc1111/ao_timer.c
@@ -83,25 +83,57 @@ ao_timer_init(void)
T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_8;
}
+#ifndef NEEDS_CC1111_CLOCK_HACK
+#define NEEDS_CC1111_CLOCK_HACK 1
+#endif
+
+#if NEEDS_CC1111_CLOCK_HACK
+static void
+ao_clock_delay(void)
+{
+ uint16_t i = 0;
+
+ while (--i)
+ ao_arch_nop();
+}
+#endif
+
/*
* AltOS always cranks the clock to the max frequency
*/
void
ao_clock_init(void)
{
+#if NEEDS_CC1111_CLOCK_HACK
+ /* Power up both oscillators */
+ SLEEP &= ~(SLEEP_OSC_PD);
+
+ /* Switch to the HFRC oscillator */
+ CLKCON = (CLKCON & ~CLKCON_OSC_MASK) | (CLKCON_OSC_RC);
+
+ /* Wait for the HFRC oscillator to be stable */
+ while (!(SLEEP & SLEEP_HFRC_STB))
+ ;
+
+ /* Delay for 'a while' waiting for the crystal to
+ * stabilize -- the XOSC_STB bit isn't reliable
+ *
+ * http://www.ti.com/lit/er/swrz022c/swrz022c.pdf
+ */
+
+ ao_clock_delay();
+#endif
+
/* Switch system clock to crystal oscilator */
CLKCON = (CLKCON & ~CLKCON_OSC_MASK) | (CLKCON_OSC_XTAL);
+ /* Wait for the HFRC oscillator to be stable */
while (!(SLEEP & SLEEP_XOSC_STB))
;
/* Power down the unused HFRC oscillator */
SLEEP |= SLEEP_OSC_PD;
- /* Wait for HFRC to power down */
- while ((SLEEP & SLEEP_HFRC_STB) != 0)
- ;
-
/* Crank up the timer tick and system clock speed */
CLKCON = ((CLKCON & ~(CLKCON_TICKSPD_MASK | CLKCON_CLKSPD_MASK)) |
(CLKCON_TICKSPD_1 | CLKCON_CLKSPD_1));
diff --git a/src/cc1111/ao_usb.c b/src/cc1111/ao_usb.c
index b0ab409d..d9d255f8 100644
--- a/src/cc1111/ao_usb.c
+++ b/src/cc1111/ao_usb.c
@@ -24,7 +24,7 @@ static __xdata uint16_t ao_usb_in_bytes;
static __pdata uint16_t ao_usb_in_bytes_last;
static __xdata uint16_t ao_usb_out_bytes;
static __pdata uint8_t ao_usb_iif;
-static __pdata uint8_t ao_usb_running;
+__pdata uint8_t ao_usb_running;
static void
ao_usb_set_interrupts(void)
@@ -274,7 +274,7 @@ ao_usb_ep0_setup(void)
ao_usb_ep0_in_len = ao_usb_setup.length;
ao_usb_ep0_flush();
} else if (ao_usb_ep0_out_len) {
-
+
/* Receiving data from the host
*/
ao_usb_ep0_state = AO_USB_EP0_DATA_OUT;
@@ -448,6 +448,9 @@ ao_usb_enable(void)
USBCIF = 0;
USBOIF = 0;
USBIIF = 0;
+#if HAS_USB_PULLUP
+ ao_gpio_set(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 0);
+#endif
}
void
@@ -459,6 +462,10 @@ ao_usb_disable(void)
USBCIE = 0;
IEN2 &= ~IEN2_USBIE;
+#if HAS_USB_PULLUP
+ ao_gpio_set(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 0);
+#endif
+
/* Clear any pending interrupts */
USBCIF = 0;
USBOIF = 0;
@@ -471,6 +478,9 @@ ao_usb_disable(void)
void
ao_usb_init(void)
{
+#if HAS_USB_PULLUP
+ ao_enable_output(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 0);
+#endif
ao_usb_enable();
ao_add_task(&ao_usb_task, ao_usb_ep0, "usb");
diff --git a/src/core/ao_config.h b/src/core/ao_config.h
deleted file mode 100644
index e101af8e..00000000
--- a/src/core/ao_config.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright © 2013 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#ifndef _AO_CONFIG_H_
-#define _AO_CONFIG_H_
-
-#ifndef USE_STORAGE_CONFIG
-#define USE_STORAGE_CONFIG 1
-#endif
-
-#ifndef USE_EEPROM_CONFIG
-#define USE_EEPROM_CONFIG 0
-#endif
-
-#if USE_STORAGE_CONFIG
-
-#include <ao_storage.h>
-
-#define ao_config_setup() ao_storage_setup()
-#define ao_config_erase() ao_storage_erase(ao_storage_config)
-#define ao_config_write(pos,bytes, len) ao_storage_write(ao_storage_config+(pos), bytes, len)
-#define ao_config_read(pos,bytes, len) ao_storage_read(ao_storage_config+(pos), bytes, len)
-#define ao_config_flush() ao_storage_flush()
-
-#endif
-
-#if USE_EEPROM_CONFIG
-
-#include <ao_eeprom.h>
-
-#define ao_config_setup()
-#define ao_config_erase()
-#define ao_config_write(pos,bytes, len) ao_eeprom_write(pos, bytes, len)
-#define ao_config_read(pos,bytes, len) ao_eeprom_read(pos, bytes, len)
-#define ao_config_flush()
-
-#endif
-
-#endif /* _AO_CONFIG_H_ */
diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c
index c327c897..8a1b6a4d 100644
--- a/src/drivers/ao_aprs.c
+++ b/src/drivers/ao_aprs.c
@@ -144,7 +144,6 @@
#endif
#include <ao_aprs.h>
-#include <math.h>
// Public methods, constants, and data structures for each class.
@@ -500,40 +499,205 @@ static int ao_num_sats(void)
return n;
}
+static char ao_gps_locked(void)
+{
+ if (ao_gps_data.flags & AO_GPS_VALID)
+ return 'L';
+ else
+ return 'U';
+}
+
static int tncComment(uint8_t *buf)
{
#if HAS_ADC
struct ao_data packet;
-
+
ao_arch_critical(ao_data_get(&packet););
int16_t battery = ao_battery_decivolt(packet.adc.v_batt);
+#ifdef AO_SENSE_DROGUE
int16_t apogee = ao_ignite_decivolt(AO_SENSE_DROGUE(&packet));
+#endif
+#ifdef AO_SENSE_MAIN
int16_t main = ao_ignite_decivolt(AO_SENSE_MAIN(&packet));
+#endif
return sprintf((char *) buf,
- "S: %d B:%d.%d A:%d.%d M:%d.%d",
+ "%c%d B%d.%d"
+#ifdef AO_SENSE_DROGUE
+ " A%d.%d"
+#endif
+#ifdef AO_SENSE_MAIN
+ " M%d.%d"
+#endif
+ , ao_gps_locked(),
ao_num_sats(),
battery/10,
- battery % 10,
- apogee/10,
- apogee%10,
- main/10,
- main%10);
+ battery % 10
+#ifdef AO_SENSE_DROGUE
+ , apogee/10,
+ apogee%10
+#endif
+#ifdef AO_SENSE_MAIN
+ , main/10,
+ main%10
+#endif
+ );
#else
return sprintf((char *) buf,
- "S: %d", ao_num_sats());
+ "%c%d",
+ ao_gps_locked(),
+ ao_num_sats());
#endif
}
+/*
+ * APRS use a log encoding of altitude with a base of 1.002, such that
+ *
+ * feet = 1.002 ** encoded_altitude
+ *
+ * meters = (1.002 ** encoded_altitude) * 0.3048
+ *
+ * log2(meters) = log2(1.002 ** encoded_altitude) + log2(0.3048)
+ *
+ * log2(meters) = encoded_altitude * log2(1.002) + log2(0.3048)
+ *
+ * encoded_altitude = (log2(meters) - log2(0.3048)) / log2(1.002)
+ *
+ * encoded_altitude = (log2(meters) + log2(1/0.3048)) * (1/log2(1.002))
+ *
+ * We need 9 bits of mantissa to hold 1/log2(1.002) (~ 347), which leaves us
+ * 23 bits of fraction. That turns out to be *just* enough to avoid any
+ * errors in the result (cool, huh?).
+ */
+
+#define fixed23_int(x) ((uint32_t) ((x) << 23))
+#define fixed23_one fixed23_int(1)
+#define fixed23_two fixed23_int(2)
+#define fixed23_half (fixed23_one >> 1)
+#define fixed23_floor(x) ((x) >> 23)
+#define fixed23_real(x) ((uint32_t) ((x) * fixed23_one + 0.5))
+
+static inline uint64_t
+fixed23_mul(uint32_t x, uint32_t y)
+{
+ return ((uint64_t) x * y + fixed23_half) >> 23;
+}
+
+/*
+ * Use 30 fraction bits for the altitude. We need two bits at the
+ * top as we need to handle x, where 0 <= x < 4. We don't
+ * need 30 bits, but it's actually easier this way as we normalize
+ * the incoming value to 1 <= x < 2, and having the integer portion
+ * way up high means we don't have to deal with shifting in both
+ * directions to cover from 0 to 2**30-1.
+ */
+
+#define fixed30_int(x) ((uint32_t) ((x) << 30))
+#define fixed30_one fixed30_int(1)
+#define fixed30_half (fixed30_one >> 1)
+#define fixed30_two fixed30_int(2)
+
+static inline uint32_t
+fixed30_mul(uint32_t x, uint32_t y)
+{
+ return ((uint64_t) x * y + fixed30_half) >> 30;
+}
+
+/*
+ * Fixed point log2. Takes integer argument, returns
+ * fixed point result with 23 bits of fraction
+ */
+
+static uint32_t
+ao_fixed_log2(uint32_t x)
+{
+ uint32_t result;
+ uint32_t frac = fixed23_one;
+
+ /* Bounds check for sanity */
+ if (x <= 0)
+ return 0;
+
+ if (x >= fixed30_one)
+ return 0xffffffff;
+
+ /*
+ * Normalize and compute integer log portion
+ *
+ * This makes 1 <= x < 2, and computes result to be
+ * the integer portion of the log2 of x
+ */
+
+ for (result = fixed23_int(30); x < fixed30_one; result -= fixed23_one, x <<= 1)
+ ;
+
+ /*
+ * Given x, find y and n such that:
+ *
+ * x = y * 2**n 1 <= y < 2
+ *
+ * That means:
+ *
+ * lb(x) = n + lb(y)
+ *
+ * Now, repeatedly square y to find find z and m such that:
+ *
+ * z = y ** (2**m) 2 <= z < 4
+ *
+ * This is possible because 1 <= y < 2
+ *
+ * lb(y) = lb(z) / 2**m
+ *
+ * (1 + lb(z/2))
+ * = -------------
+ * 2**m
+ *
+ * = 2**-m + 2**-m * lb(z/2)
+ *
+ * Note that if 2 <= z < 4, then 1 <= (z/2) < 2, so we can
+ * iterate to find lb(z/2)
+ *
+ * In this implementation, we don't care about the 'm' value,
+ * instead we only care about 2**-m, which we store in 'frac'
+ */
+
+ while (frac != 0 && x != fixed30_one) {
+ /* Repeatedly square x until 2 <= x < 4 */
+ while (x < fixed30_two) {
+ x = fixed30_mul(x, x);
+
+ /* Divide the fractional result bit by 2 */
+ frac >>= 1;
+ }
+
+ /* Add in this result bit */
+ result |= frac;
+
+ /* Make 1 <= x < 2 again and iterate */
+ x >>= 1;
+ }
+ return result;
+}
+
+#define APRS_LOG_CONVERT fixed23_real(1.714065192056127)
+#define APRS_LOG_BASE fixed23_real(346.920048461100941)
+
+static int
+ao_aprs_encode_altitude(int meters)
+{
+ return fixed23_floor(fixed23_mul(ao_fixed_log2(meters) + APRS_LOG_CONVERT, APRS_LOG_BASE) + fixed23_half);
+}
+
/**
* Generate the plain text position packet.
*/
static int tncPositionPacket(void)
{
- int32_t latitude = 0;
- int32_t longitude = 0;
- int32_t altitude = 0;
+ static int32_t latitude;
+ static int32_t longitude;
+ static int32_t altitude;
+ int32_t lat, lon, alt;
uint8_t *buf;
if (ao_gps_data.flags & AO_GPS_VALID) {
@@ -544,30 +708,26 @@ static int tncPositionPacket(void)
altitude = 0;
}
- altitude = (altitude * (int32_t) 10000 + (3048/2)) / (int32_t) 3048;
-
buf = tncBuffer;
*buf++ = '!';
/* Symbol table ID */
*buf++ = '/';
- latitude = ((uint64_t) 380926 * (900000000 - latitude)) / 10000000;
- longitude = ((uint64_t) 190463 * (1800000000 + longitude)) / 10000000;
-
-#define ALTITUDE_LOG_BASE 0.001998002662673f /* log(1.002) */
+ lat = ((uint64_t) 380926 * (900000000 - latitude)) / 10000000;
+ lon = ((uint64_t) 190463 * (1800000000 + longitude)) / 10000000;
- altitude = logf((float) altitude) * (1/ALTITUDE_LOG_BASE);
+ alt = ao_aprs_encode_altitude(altitude);
- tncCompressInt(buf, latitude, 4);
+ tncCompressInt(buf, lat, 4);
buf += 4;
- tncCompressInt(buf, longitude, 4);
+ tncCompressInt(buf, lon, 4);
buf += 4;
/* Symbol code */
*buf++ = '\'';
- tncCompressInt(buf, altitude, 2);
+ tncCompressInt(buf, alt, 2);
buf += 2;
*buf++ = 33 + ((1 << 5) | (2 << 3));
diff --git a/src/drivers/ao_cc115l.c b/src/drivers/ao_cc115l.c
index f0f72d4d..f250e714 100644
--- a/src/drivers/ao_cc115l.c
+++ b/src/drivers/ao_cc115l.c
@@ -52,8 +52,8 @@ struct ao_cc115l_reg {
#if CC115L_TRACE
-const static struct ao_cc115l_reg ao_cc115l_reg[];
-const static char *cc115l_state_name[];
+static const struct ao_cc115l_reg ao_cc115l_reg[];
+static const char *cc115l_state_name[];
enum ao_cc115l_trace_type {
trace_strobe,
@@ -88,6 +88,8 @@ static void trace_add(enum ao_cc115l_trace_type type, int16_t addr, int16_t valu
case trace_strobe:
comment = cc115l_state_name[(value >> 4) & 0x7];
break;
+ default:
+ break;
}
trace[trace_i].type = type;
trace[trace_i].addr = addr;
@@ -197,24 +199,22 @@ ao_radio_tx_fifo_space(void)
return CC115L_FIFO_SIZE - (ao_radio_reg_read(CC115L_TXBYTES) & CC115L_TXBYTES_NUM_TX_BYTES_MASK);
}
-#if UNUSED
+#if CC115L_DEBUG
static uint8_t
ao_radio_status(void)
{
return ao_radio_strobe (CC115L_SNOP);
}
-#endif
-#define ao_radio_rdf_value 0x55
-
-#if UNUSED
static uint8_t
ao_radio_get_marcstate(void)
{
return ao_radio_reg_read(CC115L_MARCSTATE) & CC115L_MARCSTATE_MASK;
}
#endif
-
+
+#define ao_radio_rdf_value 0x55
+
static void
ao_radio_done_isr(void)
{
@@ -612,6 +612,12 @@ ao_radio_rdf_abort(void)
#define POWER_STEP 0x08
+#if HAS_RADIO_POWER
+#define RADIO_POWER ao_config.radio_power
+#else
+#define RADIO_POWER 0xc0
+#endif
+
static void
ao_radio_stx(void)
{
@@ -619,9 +625,10 @@ ao_radio_stx(void)
ao_radio_pa_on();
ao_radio_reg_write(CC115L_PA, 0);
ao_radio_strobe(CC115L_STX);
- for (power = POWER_STEP; power < ao_config.radio_power; power += POWER_STEP)
+ for (power = POWER_STEP; power < RADIO_POWER; power += POWER_STEP)
ao_radio_reg_write(CC115L_PA, power);
- ao_radio_reg_write(CC115L_PA, ao_config.radio_power);
+ if (power != RADIO_POWER)
+ ao_radio_reg_write(CC115L_PA, RADIO_POWER);
}
static void
@@ -668,8 +675,8 @@ ao_radio_test_cmd(void)
static inline int16_t
ao_radio_gpio_bits(void)
{
- return AO_CC115L_DONE_INT_PORT->idr & ((1 << AO_CC115L_FIFO_INT_PIN) |
- (1 << AO_CC115L_DONE_INT_PIN));
+ return ((ao_gpio_get(AO_CC115L_DONE_INT_PORT, AO_CC115L_DONE_INT_PIN, AO_CC115L_DONE_INT) << 1) |
+ ao_gpio_get(AO_CC115L_FIFO_INT_PORT, AO_CC115L_FIFO_INT_PIN, AO_CC115L_FIFO_INT));
}
#endif
@@ -819,7 +826,7 @@ ao_radio_send_aprs(ao_radio_fill_func fill)
}
#if CC115L_DEBUG
-const static char *cc115l_state_name[] = {
+static const char *cc115l_state_name[] = {
[CC115L_STATUS_STATE_IDLE] = "IDLE",
[CC115L_STATUS_STATE_TX] = "TX",
[CC115L_STATUS_STATE_FSTXON] = "FSTXON",
@@ -828,7 +835,7 @@ const static char *cc115l_state_name[] = {
[CC115L_STATUS_STATE_TX_FIFO_UNDERFLOW] = "TX_FIFO_UNDERFLOW",
};
-const static struct ao_cc115l_reg ao_cc115l_reg[] = {
+static const struct ao_cc115l_reg ao_cc115l_reg[] = {
{ .addr = CC115L_IOCFG2, .name = "IOCFG2" },
{ .addr = CC115L_IOCFG1, .name = "IOCFG1" },
{ .addr = CC115L_IOCFG0, .name = "IOCFG0" },
@@ -874,7 +881,7 @@ const static struct ao_cc115l_reg ao_cc115l_reg[] = {
static void ao_radio_show(void) {
uint8_t status = ao_radio_status();
- int i;
+ unsigned int i;
ao_radio_get();
status = ao_radio_status();
diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c
index 01169522..077698a9 100644
--- a/src/drivers/ao_gps_ublox.c
+++ b/src/drivers/ao_gps_ublox.c
@@ -601,6 +601,14 @@ static const uint8_t ublox_enable_nav[] = {
};
void
+ao_gps_set_rate(uint8_t rate)
+{
+ uint8_t i;
+ for (i = 0; i < sizeof (ublox_enable_nav); i++)
+ ao_ublox_set_message_rate(UBLOX_NAV, ublox_enable_nav[i], rate);
+}
+
+void
ao_gps(void) __reentrant
{
uint8_t class, id;
@@ -616,8 +624,7 @@ ao_gps(void) __reentrant
ao_ublox_set_message_rate(UBLOX_NAV, ublox_disable_nav[i], 0);
/* Enable all of the messages we want */
- for (i = 0; i < sizeof (ublox_enable_nav); i++)
- ao_ublox_set_message_rate(UBLOX_NAV, ublox_enable_nav[i], 1);
+ ao_gps_set_rate(1);
ao_ublox_set_navigation_settings((1 << UBLOX_CFG_NAV5_MASK_DYN) | (1 << UBLOX_CFG_NAV5_MASK_FIXMODE),
UBLOX_CFG_NAV5_DYNMODEL_AIRBORNE_4G,
@@ -713,7 +720,7 @@ ao_gps(void) __reentrant
ao_gps_data.flags |= AO_GPS_RUNNING;
if (nav_sol.gps_fix & (1 << NAV_SOL_FLAGS_GPSFIXOK)) {
uint8_t nsat = nav_sol.nsat;
- ao_gps_data.flags |= AO_GPS_VALID;
+ ao_gps_data.flags |= AO_GPS_VALID | AO_GPS_COURSE_VALID;
if (nsat > 15)
nsat = 15;
ao_gps_data.flags |= nsat;
diff --git a/src/drivers/ao_lco_func.c b/src/drivers/ao_lco_func.c
index a5d28e61..9e642836 100644
--- a/src/drivers/ao_lco_func.c
+++ b/src/drivers/ao_lco_func.c
@@ -36,7 +36,7 @@ ao_lco_query(uint16_t box, struct ao_pad_query *query, uint16_t *tick_offset)
command.channels = 0;
ao_radio_cmac_send(&command, sizeof (command));
sent_time = ao_time();
- r = ao_radio_cmac_recv(query, sizeof (*query), AO_MS_TO_TICKS(20));
+ r = ao_radio_cmac_recv(query, sizeof (*query), AO_MS_TO_TICKS(10));
if (r == AO_RADIO_CMAC_OK)
*tick_offset = sent_time - query->tick;
ao_mutex_put(&ao_lco_mutex);
diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c
index 58ab9197..6098699e 100644
--- a/src/drivers/ao_ms5607.c
+++ b/src/drivers/ao_ms5607.c
@@ -21,8 +21,8 @@
#if HAS_MS5607 || HAS_MS5611
-static __xdata struct ao_ms5607_prom ms5607_prom;
-static __xdata uint8_t ms5607_configured;
+__xdata struct ao_ms5607_prom ao_ms5607_prom;
+static __xdata uint8_t ms5607_configured;
static void
ao_ms5607_start(void) {
@@ -111,7 +111,7 @@ ao_ms5607_setup(void)
return;
ms5607_configured = 1;
ao_ms5607_reset();
- ao_ms5607_prom_read(&ms5607_prom);
+ ao_ms5607_prom_read(&ao_ms5607_prom);
}
static __xdata volatile uint8_t ao_ms5607_done;
@@ -208,14 +208,14 @@ __xdata struct ao_task ao_ms5607_task;
void
ao_ms5607_info(void)
{
- printf ("ms5607 reserved: %u\n", ms5607_prom.reserved);
- printf ("ms5607 sens: %u\n", ms5607_prom.sens);
- printf ("ms5607 off: %u\n", ms5607_prom.off);
- printf ("ms5607 tcs: %u\n", ms5607_prom.tcs);
- printf ("ms5607 tco: %u\n", ms5607_prom.tco);
- printf ("ms5607 tref: %u\n", ms5607_prom.tref);
- printf ("ms5607 tempsens: %u\n", ms5607_prom.tempsens);
- printf ("ms5607 crc: %u\n", ms5607_prom.crc);
+ printf ("ms5607 reserved: %u\n", ao_ms5607_prom.reserved);
+ printf ("ms5607 sens: %u\n", ao_ms5607_prom.sens);
+ printf ("ms5607 off: %u\n", ao_ms5607_prom.off);
+ printf ("ms5607 tcs: %u\n", ao_ms5607_prom.tcs);
+ printf ("ms5607 tco: %u\n", ao_ms5607_prom.tco);
+ printf ("ms5607 tref: %u\n", ao_ms5607_prom.tref);
+ printf ("ms5607 tempsens: %u\n", ao_ms5607_prom.tempsens);
+ printf ("ms5607 crc: %u\n", ao_ms5607_prom.crc);
}
static void
diff --git a/src/drivers/ao_ms5607.h b/src/drivers/ao_ms5607.h
index 206efd64..b58178fd 100644
--- a/src/drivers/ao_ms5607.h
+++ b/src/drivers/ao_ms5607.h
@@ -57,6 +57,7 @@ struct ao_ms5607_value {
};
extern __xdata struct ao_ms5607_sample ao_ms5607_current;
+extern __xdata struct ao_ms5607_prom ao_ms5607_prom;
void
ao_ms5607_setup(void);
@@ -74,7 +75,4 @@ void
ao_ms5607_convert(__xdata struct ao_ms5607_sample *sample,
__xdata struct ao_ms5607_value *value);
-void
-ao_ms5607_get_prom(__data struct ao_ms5607_prom *prom);
-
#endif /* _AO_MS5607_H_ */
diff --git a/src/drivers/ao_ms5607_convert.c b/src/drivers/ao_ms5607_convert.c
index bfb952a4..4d412cbe 100644
--- a/src/drivers/ao_ms5607_convert.c
+++ b/src/drivers/ao_ms5607_convert.c
@@ -25,16 +25,16 @@ ao_ms5607_convert(struct ao_ms5607_sample *sample, struct ao_ms5607_value *value
int64_t OFF;
int64_t SENS;
- dT = sample->temp - ((int32_t) ms5607_prom.tref << 8);
+ dT = sample->temp - ((int32_t) ao_ms5607_prom.tref << 8);
- TEMP = 2000 + (((int64_t) dT * ms5607_prom.tempsens) >> 23);
+ TEMP = 2000 + (((int64_t) dT * ao_ms5607_prom.tempsens) >> 23);
#if HAS_MS5611
- OFF = ((int64_t) ms5607_prom.off << 16) + (((int64_t) ms5607_prom.tco * dT) >> 7);
- SENS = ((int64_t) ms5607_prom.sens << 15) + (((int64_t) ms5607_prom.tcs * dT) >> 8);
+ OFF = ((int64_t) ao_ms5607_prom.off << 16) + (((int64_t) ao_ms5607_prom.tco * dT) >> 7);
+ SENS = ((int64_t) ao_ms5607_prom.sens << 15) + (((int64_t) ao_ms5607_prom.tcs * dT) >> 8);
#else
- OFF = ((int64_t) ms5607_prom.off << 17) + (((int64_t) ms5607_prom.tco * dT) >> 6);
- SENS = ((int64_t) ms5607_prom.sens << 16) + (((int64_t) ms5607_prom.tcs * dT) >> 7);
+ OFF = ((int64_t) ao_ms5607_prom.off << 17) + (((int64_t) ao_ms5607_prom.tco * dT) >> 6);
+ SENS = ((int64_t) ao_ms5607_prom.sens << 16) + (((int64_t) ao_ms5607_prom.tcs * dT) >> 7);
#endif
if (TEMP < 2000) {
diff --git a/src/drivers/ao_ms5607_convert_8051.c b/src/drivers/ao_ms5607_convert_8051.c
index f3a48c46..a74086d9 100644
--- a/src/drivers/ao_ms5607_convert_8051.c
+++ b/src/drivers/ao_ms5607_convert_8051.c
@@ -40,30 +40,30 @@ ao_ms5607_convert(__xdata struct ao_ms5607_sample *sample,
__LOCAL ao_int64_t SENS;
__LOCAL ao_int64_t a;
- dT = sample->temp - ((int32_t) ms5607_prom.tref << 8);
+ dT = sample->temp - ((int32_t) ao_ms5607_prom.tref << 8);
- /* TEMP = 2000 + (((int64_t) dT * ms5607_prom.tempsens) >> 23); */
- ao_mul64_32_32(&a, dT, ms5607_prom.tempsens);
+ /* TEMP = 2000 + (((int64_t) dT * ao_ms5607_prom.tempsens) >> 23); */
+ ao_mul64_32_32(&a, dT, ao_ms5607_prom.tempsens);
ao_rshift64(&a, &a, 23);
TEMP = 2000 + a.low;
/* */
- /* OFF = ((int64_t) ms5607_prom.off << SHIFT_OFF) + (((int64_t) ms5607_prom.tco * dT) >> SHIFT_TCO);*/
+ /* OFF = ((int64_t) ao_ms5607_prom.off << SHIFT_OFF) + (((int64_t) ao_ms5607_prom.tco * dT) >> SHIFT_TCO);*/
#if SHIFT_OFF > 16
- OFF.high = ms5607_prom.off >> (32 - SHIFT_OFF);
+ OFF.high = ao_ms5607_prom.off >> (32 - SHIFT_OFF);
#else
OFF.high = 0;
#endif
- OFF.low = (uint32_t) ms5607_prom.off << SHIFT_OFF;
- ao_mul64_32_32(&a, ms5607_prom.tco, dT);
+ OFF.low = (uint32_t) ao_ms5607_prom.off << SHIFT_OFF;
+ ao_mul64_32_32(&a, ao_ms5607_prom.tco, dT);
ao_rshift64(&a, &a, SHIFT_TCO);
ao_plus64(&OFF, &OFF, &a);
/**/
- /* SENS = ((int64_t) ms5607_prom.sens << SHIFT_SENS) + (((int64_t) ms5607_prom.tcs * dT) >> SHIFT_TCS); */
+ /* SENS = ((int64_t) ao_ms5607_prom.sens << SHIFT_SENS) + (((int64_t) ao_ms5607_prom.tcs * dT) >> SHIFT_TCS); */
SENS.high = 0;
- SENS.low = (uint32_t) ms5607_prom.sens << SHIFT_SENS;
- ao_mul64_32_32(&a, ms5607_prom.tcs, dT);
+ SENS.low = (uint32_t) ao_ms5607_prom.sens << SHIFT_SENS;
+ ao_mul64_32_32(&a, ao_ms5607_prom.tcs, dT);
ao_rshift64(&a, &a, SHIFT_TCS);
ao_plus64(&SENS, &SENS, &a);
/**/
diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c
index 62ae68e9..144cbd70 100644
--- a/src/drivers/ao_pad.c
+++ b/src/drivers/ao_pad.c
@@ -153,11 +153,11 @@ ao_pad_monitor(void)
*
* v_pyro \
* 100k igniter
- * output /
+ * output /
* 100k \
* sense relay
- * 27k /
- * gnd ---
+ * 27k /
+ * gnd ---
*
* If the relay is closed, then sense will be 0
* If no igniter is present, then sense will be v_pyro * 27k/227k = pyro * 127 / 227 ~= pyro/2
diff --git a/src/drivers/ao_pca9922.c b/src/drivers/ao_pca9922.c
index d376b968..6d1b5fae 100644
--- a/src/drivers/ao_pca9922.c
+++ b/src/drivers/ao_pca9922.c
@@ -66,6 +66,24 @@ ao_led_set_mask(uint8_t colors, uint8_t mask)
ao_led_apply();
}
+#define LED_TEST 1
+#if LED_TEST
+static void
+ao_led_test(void)
+{
+ ao_cmd_hexbyte();
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ ao_led_set(ao_cmd_lex_i);
+ printf("LEDs set to %02x\n", ao_cmd_lex_i);
+}
+
+static const struct ao_cmds ao_led_cmds[] = {
+ { ao_led_test, "l <value>\0Set LEDs to <value>" },
+ { 0, NULL }
+};
+#endif
+
void
ao_led_toggle(uint8_t colors)
{
@@ -86,4 +104,7 @@ ao_led_init(uint8_t enable)
{
(void) enable;
ao_enable_output(AO_PCA9922_CS_PORT, AO_PCA9922_CS_PIN, AO_PCA9922_CS, 1);
+#if LED_TEST
+ ao_cmd_register(&ao_led_cmds[0]);
+#endif
}
diff --git a/src/drivers/ao_quadrature.c b/src/drivers/ao_quadrature.c
index d07488d0..0cdcc9fb 100644
--- a/src/drivers/ao_quadrature.c
+++ b/src/drivers/ao_quadrature.c
@@ -22,11 +22,14 @@
#include <ao_event.h>
__xdata int32_t ao_quadrature_count[AO_QUADRATURE_COUNT];
-static uint8_t ao_quadrature_state[AO_QUADRATURE_COUNT];
-static int8_t ao_quadrature_raw[AO_QUADRATURE_COUNT];
+static uint8_t ao_quadrature_state[AO_QUADRATURE_COUNT];
-#define BIT(a,b) ((a) | ((b) << 1))
-#define STATE(old_a, old_b, new_a, new_b) (((BIT(old_a, old_b) << 2) | BIT(new_a, new_b)))
+struct ao_debounce {
+ uint8_t state;
+ uint8_t count;
+};
+
+static struct ao_debounce ao_debounce_state[AO_QUADRATURE_COUNT][2];
#define port(q) AO_QUADRATURE_ ## q ## _PORT
#define bita(q) AO_QUADRATURE_ ## q ## _A
@@ -35,14 +38,35 @@ static int8_t ao_quadrature_raw[AO_QUADRATURE_COUNT];
#define pinb(q) AO_QUADRATURE_ ## q ## _B ## _PIN
#define isr(q) ao_quadrature_isr_ ## q
-static inline uint16_t
-ao_quadrature_read(struct stm_gpio *gpio, uint8_t pin_a, uint8_t pin_b) {
- uint16_t v = stm_gpio_get_all(gpio);
+#define DEBOUNCE 10
- return ~((((v >> pin_a) & 1) | (((v >> pin_b) & 1) << 1))) & 3;
+static uint8_t
+ao_debounce(uint8_t cur, struct ao_debounce *debounce)
+{
+ if (cur == debounce->state)
+ debounce->count = 0;
+ else {
+ if (++debounce->count == DEBOUNCE) {
+ debounce->state = cur;
+ debounce->count = 0;
+ }
+ }
+ return debounce->state;
}
-#define _ao_quadrature_get(q) ao_quadrature_read(port(q), bita(q), bitb(q))
+static uint16_t
+ao_quadrature_read(struct stm_gpio *gpio, uint8_t pin_a, uint8_t pin_b, struct ao_debounce debounce_state[2]) {
+ uint16_t v = ~stm_gpio_get_all(gpio);
+ uint8_t a = (v >> pin_a) & 1;
+ uint8_t b = (v >> pin_b) & 1;
+
+ a = ao_debounce(a, &debounce_state[0]);
+ b = ao_debounce(b, &debounce_state[1]);
+
+ return a | (b << 1);
+}
+
+#define _ao_quadrature_get(q) ao_quadrature_read(port(q), bita(q), bitb(q), ao_debounce_state[q])
static void
_ao_quadrature_queue(uint8_t q, int8_t step)
@@ -54,51 +78,28 @@ _ao_quadrature_queue(uint8_t q, int8_t step)
ao_wakeup(&ao_quadrature_count[q]);
}
-static const int8_t step[16] = {
- [STATE(0,0,0,0)] = 0,
- [STATE(0,0,0,1)] = -1,
- [STATE(0,0,1,0)] = 1,
- [STATE(0,0,1,1)] = 0,
- [STATE(0,1,0,0)] = 1,
- [STATE(0,1,1,0)] = 0,
- [STATE(0,1,1,1)] = -1,
- [STATE(1,0,0,0)] = -1,
- [STATE(1,0,0,1)] = 0,
- [STATE(1,0,1,0)] = 0,
- [STATE(1,0,1,1)] = 1,
- [STATE(1,1,0,0)] = 0,
- [STATE(1,1,0,1)] = 1,
- [STATE(1,1,1,0)] = -1,
- [STATE(1,1,1,1)] = 0
-};
-
static void
-_ao_quadrature_set(uint8_t q, uint8_t value) {
- uint8_t v;
-
- v = ao_quadrature_state[q] & 3;
- value = value & 3;
-
- if (v == value)
- return;
-
- ao_quadrature_state[q] = (v << 2) | value;
+_ao_quadrature_set(uint8_t q, uint8_t new) {
+ uint8_t old = ao_quadrature_state[q];
- ao_quadrature_raw[q] += step[ao_quadrature_state[q]];
- if (value == 0) {
- if (ao_quadrature_raw[q] == 4)
+ if (old != new && new == 0) {
+ if (old & 2)
_ao_quadrature_queue(q, 1);
- else if (ao_quadrature_raw[q] == -4)
+ else if (old & 1)
_ao_quadrature_queue(q, -1);
- ao_quadrature_raw[q] = 0;
}
+ ao_quadrature_state[q] = new;
}
static void
ao_quadrature_isr(void)
{
+#if AO_QUADRATURE_COUNT > 0
_ao_quadrature_set(0, _ao_quadrature_get(0));
+#endif
+#if AO_QUADRATURE_COUNT > 1
_ao_quadrature_set(1, _ao_quadrature_get(1));
+#endif
}
int32_t
@@ -120,6 +121,8 @@ static void
ao_quadrature_test(void)
{
uint8_t q;
+ int32_t c;
+ uint8_t s;
ao_cmd_decimal();
q = ao_cmd_lex_i;
@@ -127,10 +130,18 @@ ao_quadrature_test(void)
ao_cmd_status = ao_cmd_syntax_error;
return;
}
- printf ("count %d state %x raw %d\n",
- ao_quadrature_count[q],
- ao_quadrature_state[q],
- ao_quadrature_raw[q]);
+
+ c = -10000;
+ s = 0;
+ while (ao_quadrature_count[q] != 10) {
+ if (ao_quadrature_count[q] != c ||
+ ao_quadrature_state[q] != s) {
+ c = ao_quadrature_count[q];
+ s = ao_quadrature_state[q];
+ printf ("count %3d state %2x\n", c, s);
+ flush();
+ }
+ }
#if 0
for (;;) {
int32_t c;
diff --git a/src/easymega-v0.1/.gitignore b/src/easymega-v0.1/.gitignore
new file mode 100644
index 00000000..410943d5
--- /dev/null
+++ b/src/easymega-v0.1/.gitignore
@@ -0,0 +1,2 @@
+ao_product.h
+easymega-*.elf
diff --git a/src/easymega-v0.1/Makefile b/src/easymega-v0.1/Makefile
new file mode 100644
index 00000000..66619852
--- /dev/null
+++ b/src/easymega-v0.1/Makefile
@@ -0,0 +1,144 @@
+#
+# AltOS build
+#
+#
+
+include ../stm/Makefile.defs
+
+INC = \
+ ao.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_boot.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_hmc5883.h \
+ ao_mpu6000.h \
+ ao_mma655x.h \
+ ao_profile.h \
+ ao_task.h \
+ ao_whiten.h \
+ ao_sample_profile.h \
+ ao_quaternion.h \
+ math.h \
+ ao_mpu.h \
+ stm32l.h \
+ math.h \
+ Makefile
+
+#
+# Common AltOS sources
+#
+# ao_hmc5883.c
+
+#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
+
+MATH_SRC=\
+ ef_acos.c \
+ ef_sqrt.c \
+ ef_rem_pio2.c \
+ kf_cos.c \
+ kf_sin.c \
+ kf_rem_pio2.c \
+ sf_copysign.c \
+ sf_cos.c \
+ sf_fabs.c \
+ sf_floor.c \
+ sf_scalbn.c \
+ sf_sin.c \
+ ef_log.c
+
+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_ignite.c \
+ ao_freq.c \
+ ao_dma_stm.c \
+ ao_spi_stm.c \
+ ao_data.c \
+ ao_ms5607.c \
+ ao_mma655x.c \
+ ao_hmc5883.c \
+ ao_adc_stm.c \
+ ao_beep_stm.c \
+ ao_eeprom_stm.c \
+ ao_storage.c \
+ ao_m25.c \
+ ao_usb_stm.c \
+ ao_exti_stm.c \
+ ao_report.c \
+ ao_i2c_stm.c \
+ ao_mpu6000.c \
+ ao_convert_pa.c \
+ ao_convert_volt.c \
+ ao_log.c \
+ ao_log_mega.c \
+ ao_sample.c \
+ ao_kalman.c \
+ ao_flight.c \
+ ao_companion.c \
+ ao_pyro.c \
+ $(MATH_SRC) \
+ $(PROFILE) \
+ $(SAMPLE_PROFILE) \
+ $(STACK_GUARD)
+
+PRODUCT=EasyMega-v0.1
+PRODUCT_DEF=-DEASYMEGA
+IDPRODUCT=0x0023
+
+CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g
+
+PROGNAME=easymega-v0.1
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_easymega.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+$(PROG): Makefile $(OBJ) altos.ld
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+../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 $(PROGNAME)-*.ihx
+ rm -f ao_product.h
+
+install:
+
+uninstall:
diff --git a/src/easymega-v0.1/ao_easymega.c b/src/easymega-v0.1/ao_easymega.c
new file mode 100644
index 00000000..e217c33c
--- /dev/null
+++ b/src/easymega-v0.1/ao_easymega.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2014 Bdale Garbee <bdale@gag.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_hmc5883.h>
+#include <ao_mpu6000.h>
+#include <ao_mma655x.h>
+#include <ao_log.h>
+#include <ao_exti.h>
+#include <ao_companion.h>
+#include <ao_profile.h>
+#include <ao_eeprom.h>
+#if HAS_SAMPLE_PROFILE
+#include <ao_sample_profile.h>
+#endif
+#include <ao_pyro.h>
+#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_led_init(LEDS_AVAILABLE);
+ ao_led_on(AO_LED_GREEN);
+ ao_timer_init();
+
+ ao_i2c_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_HMC5883
+ ao_hmc5883_init();
+#endif
+#if HAS_MPU6000
+ ao_mpu6000_init();
+#endif
+#if HAS_MMA655X
+ ao_mma655x_init();
+#endif
+
+ ao_eeprom_init();
+ ao_storage_init();
+
+ ao_flight_init();
+ ao_log_init();
+ ao_report_init();
+
+ ao_usb_init();
+ ao_igniter_init();
+ ao_companion_init();
+ ao_pyro_init();
+
+ ao_config_init();
+#if AO_PROFILE
+ ao_profile_init();
+#endif
+#if HAS_SAMPLE_PROFILE
+ ao_sample_profile_init();
+#endif
+
+ ao_start_scheduler();
+ return 0;
+}
diff --git a/src/easymega-v0.1/ao_pins.h b/src/easymega-v0.1/ao_pins.h
new file mode 100644
index 00000000..cb6e3980
--- /dev/null
+++ b/src/easymega-v0.1/ao_pins.h
@@ -0,0 +1,352 @@
+/*
+ * Copyright © 2014 Bdale Garbee <bdale@gag.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 0
+
+#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 0
+#define USE_SERIAL_3_STDIN 0
+#define SERIAL_3_PB10_PB11 0
+#define SERIAL_3_PC10_PC11 0
+#define SERIAL_3_PD8_PD9 0
+
+#define ao_gps_getchar ao_serial1_getchar
+#define ao_gps_putchar ao_serial1_putchar
+#define ao_gps_set_speed ao_serial1_set_speed
+#define ao_gps_fifo (ao_stm_usart1.rx_fifo)
+
+#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1024 * 1024)
+#define HAS_EEPROM 1
+#define USE_INTERNAL_FLASH 0
+#define USE_EEPROM_CONFIG 1
+#define USE_STORAGE_CONFIG 0
+#define HAS_USB 1
+#define HAS_BEEP 1
+#define HAS_BATTERY_REPORT 1
+#define HAS_RADIO 0
+#define HAS_TELEMETRY 0
+#define HAS_APRS 0
+
+#define HAS_SPI_1 1
+#define SPI_1_PA5_PA6_PA7 1 /* Barometer */
+#define SPI_1_PB3_PB4_PB5 1 /* Accelerometer, Gyro */
+#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 */
+#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 1
+#define I2C_1_PB8_PB9 1
+
+#define HAS_I2C_2 0
+#define I2C_2_PB10_PB11 0
+
+#define PACKET_HAS_SLAVE 0
+#define PACKET_HAS_MASTER 0
+
+#define LOW_LEVEL_DEBUG 0
+
+#define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOAEN
+#define LED_PORT (&stm_gpioa)
+#define LED_PIN_RED 9
+#define LED_PIN_GREEN 10
+#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 0
+#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_PYRO(p,n) ((p)->adc.sense[n])
+#define AO_SENSE_DROGUE(p) ((p)->adc.sense[4])
+#define AO_SENSE_MAIN(p) ((p)->adc.sense[5])
+#define AO_IGNITER_CLOSED 400
+#define AO_IGNITER_OPEN 60
+
+/* Pyro A */
+#define AO_PYRO_PORT_0 (&stm_gpioa)
+#define AO_PYRO_PIN_0 15
+
+/* Pyro B */
+#define AO_PYRO_PORT_1 (&stm_gpioc)
+#define AO_PYRO_PIN_1 10
+
+/* Pyro C */
+#define AO_PYRO_PORT_2 (&stm_gpiob)
+#define AO_PYRO_PIN_2 11
+
+/* Pyro D */
+#define AO_PYRO_PORT_3 (&stm_gpiob)
+#define AO_PYRO_PIN_3 10
+
+/* Drogue */
+#define AO_IGNITER_DROGUE_PORT (&stm_gpioa)
+#define AO_IGNITER_DROGUE_PIN 0
+
+/* Main */
+#define AO_IGNITER_MAIN_PORT (&stm_gpioa)
+#define AO_IGNITER_MAIN_PIN 1
+
+/* Number of general purpose pyro channels available */
+#define AO_PYRO_NUM 4
+
+#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 6
+
+struct ao_adc {
+ int16_t sense[AO_ADC_NUM_SENSE];
+ int16_t v_batt;
+ int16_t v_pbatt;
+ int16_t temp;
+};
+
+#define AO_ADC_DUMP(p) \
+ printf("tick: %5u A: %5d B: %5d C: %5d D: %5d drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \
+ (p)->tick, \
+ (p)->adc.sense[0], (p)->adc.sense[1], (p)->adc.sense[2], \
+ (p)->adc.sense[3], (p)->adc.sense[4], (p)->adc.sense[5], \
+ (p)->adc.v_batt, (p)->adc.v_pbatt, (p)->adc.temp)
+
+#define AO_ADC_SENSE_A 14
+#define AO_ADC_SENSE_A_PORT (&stm_gpioc)
+#define AO_ADC_SENSE_A_PIN 4
+
+#define AO_ADC_SENSE_B 15
+#define AO_ADC_SENSE_B_PORT (&stm_gpioc)
+#define AO_ADC_SENSE_B_PIN 5
+
+#define AO_ADC_SENSE_C 13
+#define AO_ADC_SENSE_C_PORT (&stm_gpioc)
+#define AO_ADC_SENSE_C_PIN 3
+
+#define AO_ADC_SENSE_D 12
+#define AO_ADC_SENSE_D_PORT (&stm_gpioc)
+#define AO_ADC_SENSE_D_PIN 2
+
+#define AO_ADC_SENSE_DROGUE 11
+#define AO_ADC_SENSE_DROGUE_PORT (&stm_gpioc)
+#define AO_ADC_SENSE_DROGUE_PIN 1
+
+#define AO_ADC_SENSE_MAIN 10
+#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioc)
+#define AO_ADC_SENSE_MAIN_PIN 0
+
+#define AO_ADC_V_BATT 8
+#define AO_ADC_V_BATT_PORT (&stm_gpiob)
+#define AO_ADC_V_BATT_PIN 0
+
+#define AO_ADC_V_PBATT 9
+#define AO_ADC_V_PBATT_PORT (&stm_gpiob)
+#define AO_ADC_V_PBATT_PIN 1
+
+#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 (AO_ADC_NUM_SENSE + 2)
+
+#define AO_ADC_PIN0_PORT AO_ADC_SENSE_A_PORT
+#define AO_ADC_PIN0_PIN AO_ADC_SENSE_A_PIN
+#define AO_ADC_PIN1_PORT AO_ADC_SENSE_B_PORT
+#define AO_ADC_PIN1_PIN AO_ADC_SENSE_B_PIN
+#define AO_ADC_PIN2_PORT AO_ADC_SENSE_C_PORT
+#define AO_ADC_PIN2_PIN AO_ADC_SENSE_C_PIN
+#define AO_ADC_PIN3_PORT AO_ADC_SENSE_D_PORT
+#define AO_ADC_PIN3_PIN AO_ADC_SENSE_D_PIN
+#define AO_ADC_PIN4_PORT AO_ADC_SENSE_DROGUE_PORT
+#define AO_ADC_PIN4_PIN AO_ADC_SENSE_DROGUE_PIN
+#define AO_ADC_PIN5_PORT AO_ADC_SENSE_MAIN_PORT
+#define AO_ADC_PIN5_PIN AO_ADC_SENSE_MAIN_PIN
+#define AO_ADC_PIN6_PORT AO_ADC_V_BATT_PORT
+#define AO_ADC_PIN6_PIN AO_ADC_V_BATT_PIN
+#define AO_ADC_PIN7_PORT AO_ADC_V_PBATT_PORT
+#define AO_ADC_PIN7_PIN AO_ADC_V_PBATT_PIN
+
+#define AO_NUM_ADC (AO_ADC_NUM_SENSE + 3)
+
+#define AO_ADC_SQ1 AO_ADC_SENSE_A
+#define AO_ADC_SQ2 AO_ADC_SENSE_B
+#define AO_ADC_SQ3 AO_ADC_SENSE_C
+#define AO_ADC_SQ4 AO_ADC_SENSE_D
+#define AO_ADC_SQ5 AO_ADC_SENSE_DROGUE
+#define AO_ADC_SQ6 AO_ADC_SENSE_MAIN
+#define AO_ADC_SQ7 AO_ADC_V_BATT
+#define AO_ADC_SQ8 AO_ADC_V_PBATT
+#define AO_ADC_SQ9 AO_ADC_TEMP
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS 56 /* 5.6k */
+#define AO_BATTERY_DIV_MINUS 100 /* 10k */
+
+/*
+ * Voltage divider on ADC igniter samplers
+ */
+#define AO_IGNITE_DIV_PLUS 100 /* 100k */
+#define AO_IGNITE_DIV_MINUS 27 /* 27k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV 33
+
+/*
+ * Pressure sensor settings
+ */
+#define HAS_MS5607 1
+#define HAS_MS5611 0
+#define AO_MS5607_PRIVATE_PINS 1
+#define AO_MS5607_CS_PORT (&stm_gpioa)
+#define AO_MS5607_CS_PIN 3
+#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS_PIN)
+#define AO_MS5607_MISO_PORT (&stm_gpioa)
+#define AO_MS5607_MISO_PIN 6
+#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO_PIN)
+#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_PIN 12
+#define AO_M25_SPI_CS_MASK (1 << AO_M25_SPI_CS_PIN)
+#define AO_M25_SPI_BUS AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Mag sensor (hmc5883)
+ */
+
+#define HAS_HMC5883 1
+#define AO_HMC5883_INT_PORT (&stm_gpioc)
+#define AO_HMC5883_INT_PIN 14
+#define AO_HMC5883_I2C_INDEX STM_I2C_INDEX(1)
+
+/*
+ * mpu6000
+ */
+
+#define HAS_MPU6000 1
+#define AO_MPU6000_INT_PORT (&stm_gpioc)
+#define AO_MPU6000_INT_PIN 15
+#define AO_MPU6000_SPI_BUS AO_SPI_1_PB3_PB4_PB5
+#define AO_MPU6000_SPI_CS_PORT (&stm_gpioc)
+#define AO_MPU6000_SPI_CS_PIN 13
+#define HAS_IMU 1
+
+/*
+ * mma655x
+ */
+
+#define HAS_MMA655X 1
+#define AO_MMA655X_SPI_INDEX AO_SPI_1_PB3_PB4_PB5
+#define AO_MMA655X_CS_PORT (&stm_gpioc)
+#define AO_MMA655X_CS_PIN 12
+
+#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 0
+#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/easymega-v0.1/flash-loader/Makefile b/src/easymega-v0.1/flash-loader/Makefile
new file mode 100644
index 00000000..35312fd6
--- /dev/null
+++ b/src/easymega-v0.1/flash-loader/Makefile
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=easymega-v0.1
+include $(TOPDIR)/stm/Makefile-flash.defs
diff --git a/src/easymega-v0.1/flash-loader/ao_pins.h b/src/easymega-v0.1/flash-loader/ao_pins.h
new file mode 100644
index 00000000..445289bf
--- /dev/null
+++ b/src/easymega-v0.1/flash-loader/ao_pins.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+/* External crystal at 8MHz */
+#define AO_HSE 8000000
+
+#include <ao_flash_stm_pins.h>
+
+/* Companion port cs_companion0 PD0 */
+
+#define AO_BOOT_PIN 1
+#define AO_BOOT_APPLICATION_GPIO stm_gpiob
+#define AO_BOOT_APPLICATION_PIN 6
+#define AO_BOOT_APPLICATION_VALUE 1
+#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/easymini-v1.0/Makefile b/src/easymini-v1.0/Makefile
index 7dae2692..654be22b 100644
--- a/src/easymini-v1.0/Makefile
+++ b/src/easymini-v1.0/Makefile
@@ -32,6 +32,7 @@ ALTOS_SRC = \
ao_sample.c \
ao_data.c \
ao_convert_pa.c \
+ ao_convert_volt.c \
ao_task.c \
ao_log.c \
ao_log_mini.c \
diff --git a/src/easymini-v1.0/ao_pins.h b/src/easymini-v1.0/ao_pins.h
index e721030d..0edde5a2 100644
--- a/src/easymini-v1.0/ao_pins.h
+++ b/src/easymini-v1.0/ao_pins.h
@@ -15,8 +15,8 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#define HAS_BEEP 1
-#define HAS_LED 0
+#define HAS_BEEP 1
+#define HAS_BATTERY_REPORT 1
#define AO_STACK_SIZE 384
@@ -134,3 +134,20 @@ struct ao_adc {
#define AO_ADC_DUMP(p) \
printf("tick: %5u apogee: %5d main: %5d batt: %5d\n", \
(p)->tick, (p)->adc.sense_a, (p)->adc.sense_m, (p)->adc.v_batt)
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS 100 /* 100k */
+#define AO_BATTERY_DIV_MINUS 27 /* 27k */
+
+/*
+ * Voltage divider on ADC igniter samplers
+ */
+#define AO_IGNITE_DIV_PLUS 100 /* 100k */
+#define AO_IGNITE_DIV_MINUS 27 /* 27k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV 33
diff --git a/src/core/altitude.h b/src/kernel/altitude.h
index a278bbc6..a278bbc6 100644
--- a/src/core/altitude.h
+++ b/src/kernel/altitude.h
diff --git a/src/core/ao.h b/src/kernel/ao.h
index 29ad2603..5ff9b518 100644
--- a/src/core/ao.h
+++ b/src/kernel/ao.h
@@ -394,6 +394,9 @@ struct ao_gps_tracking_orig {
};
void
+ao_gps_set_rate(uint8_t rate);
+
+void
ao_gps(void);
void
@@ -737,6 +740,7 @@ ao_igniter_init(void);
/*
* ao_config.c
*/
+#include <ao_config.h>
#if AO_PYRO_NUM
#include <ao_pyro.h>
@@ -749,81 +753,6 @@ ao_igniter_init(void);
extern __xdata uint8_t ao_force_freq;
#endif
-#define AO_CONFIG_MAJOR 1
-#define AO_CONFIG_MINOR 15
-
-#define AO_AES_LEN 16
-
-extern __xdata uint8_t ao_config_aes_seq;
-
-struct ao_config {
- uint8_t major;
- uint8_t minor;
- uint16_t main_deploy;
- int16_t accel_plus_g; /* changed for minor version 2 */
- uint8_t _legacy_radio_channel;
- char callsign[AO_MAX_CALLSIGN + 1];
- uint8_t apogee_delay; /* minor version 1 */
- int16_t accel_minus_g; /* minor version 2 */
- uint32_t radio_cal; /* minor version 3 */
- uint32_t flight_log_max; /* minor version 4 */
- uint8_t ignite_mode; /* minor version 5 */
- uint8_t pad_orientation; /* minor version 6 */
- uint32_t radio_setting; /* minor version 7 */
- uint8_t radio_enable; /* minor version 8 */
- uint8_t aes_key[AO_AES_LEN]; /* minor version 9 */
- uint32_t frequency; /* minor version 10 */
- uint16_t apogee_lockout; /* minor version 11 */
-#if AO_PYRO_NUM
- struct ao_pyro pyro[AO_PYRO_NUM]; /* minor version 12 */
-#endif
- uint16_t aprs_interval; /* minor version 13 */
-#if HAS_RADIO_POWER
- uint8_t radio_power; /* minor version 14 */
-#endif
-#if HAS_RADIO_AMP
- uint8_t radio_amp; /* minor version 14 */
-#endif
-#if HAS_GYRO
- int16_t accel_zero_along; /* minor version 15 */
- int16_t accel_zero_across; /* minor version 15 */
- int16_t accel_zero_through; /* minor version 15 */
-#endif
-};
-
-#define AO_IGNITE_MODE_DUAL 0
-#define AO_IGNITE_MODE_APOGEE 1
-#define AO_IGNITE_MODE_MAIN 2
-
-#define AO_RADIO_ENABLE_CORE 1
-#define AO_RADIO_DISABLE_TELEMETRY 2
-#define AO_RADIO_DISABLE_RDF 4
-
-#define AO_PAD_ORIENTATION_ANTENNA_UP 0
-#define AO_PAD_ORIENTATION_ANTENNA_DOWN 1
-
-extern __xdata struct ao_config ao_config;
-
-#define AO_CONFIG_MAX_SIZE 128
-
-void
-_ao_config_edit_start(void);
-
-void
-_ao_config_edit_finish(void);
-
-void
-ao_config_get(void);
-
-void
-ao_config_put(void);
-
-void
-ao_config_set_radio(void);
-
-void
-ao_config_init(void);
-
/*
* ao_rssi.c
*/
diff --git a/src/core/ao_adc.h b/src/kernel/ao_adc.h
index 373db1c4..373db1c4 100644
--- a/src/core/ao_adc.h
+++ b/src/kernel/ao_adc.h
diff --git a/src/core/ao_aes.h b/src/kernel/ao_aes.h
index c47bc2db..c47bc2db 100644
--- a/src/core/ao_aes.h
+++ b/src/kernel/ao_aes.h
diff --git a/src/teleballoon-v1.1/ao_balloon.c b/src/kernel/ao_balloon.c
index 12752d1f..904a9c08 100644
--- a/src/teleballoon-v1.1/ao_balloon.c
+++ b/src/kernel/ao_balloon.c
@@ -31,6 +31,13 @@
#error Please define HAS_USB
#endif
+#if HAS_SENSOR_ERRORS
+/* Any sensor can set this to mark the flight computer as 'broken' */
+__xdata uint8_t ao_sensor_errors;
+#endif
+
+__pdata uint16_t ao_motor_number; /* number of motors burned so far */
+
/* Main flight thread. */
__pdata enum ao_flight_state ao_flight_state; /* current flight state */
@@ -67,7 +74,8 @@ ao_flight(void)
/* Disable the USB controller in flight mode
* to save power
*/
- ao_usb_disable();
+ if (!ao_usb_running)
+ ao_usb_disable();
#endif
/* Disable packet mode in pad state */
@@ -112,9 +120,8 @@ ao_flight(void)
ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
}
break;
- case ao_flight_drogue:
+ default:
break;
-
}
}
}
diff --git a/src/core/ao_beep.h b/src/kernel/ao_beep.h
index 55f61171..9d6ecf27 100644
--- a/src/core/ao_beep.h
+++ b/src/kernel/ao_beep.h
@@ -18,6 +18,12 @@
#ifndef _AO_BEEP_H_
#define _AO_BEEP_H_
+#ifndef HAS_BEEP_CONFIG
+#if defined(USE_EEPROM_CONFIG) && USE_EEPROM_CONFIG || HAS_EEPROM
+#define HAS_BEEP_CONFIG 1
+#endif
+#endif
+
/*
* ao_beep.c
*/
@@ -28,9 +34,16 @@
* 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_MID_DEFAULT 94 /* 3989Hz */
+
+#if HAS_BEEP_CONFIG
+#define AO_BEEP_MID ao_config.mid_beep
+#else
+#define AO_BEEP_MID AO_BEEP_MID_DEFAULT
+#endif
+#define AO_BEEP_LOW AO_BEEP_MID * 150 / 94 /* 2500Hz */
+#define AO_BEEP_HIGH AO_BEEP_MID * 75 / 94 /* 5000Hz */
+
#define AO_BEEP_OFF 0 /* off */
#define AO_BEEP_g 240 /* 1562.5Hz */
diff --git a/src/stm/ao_boot.h b/src/kernel/ao_boot.h
index e0ed4de7..62392d25 100644
--- a/src/stm/ao_boot.h
+++ b/src/kernel/ao_boot.h
@@ -31,9 +31,11 @@ ao_boot_check_chain(void);
void
ao_boot_reboot(uint32_t *base);
+#define AO_BOOT_FORCE_LOADER ((uint32_t *) 0)
+
static inline void
ao_boot_loader(void) {
- ao_boot_reboot(AO_BOOT_LOADER_BASE);
+ ao_boot_reboot(AO_BOOT_FORCE_LOADER);
}
#endif /* _AO_BOOT_H_ */
diff --git a/src/core/ao_btm.h b/src/kernel/ao_btm.h
index 484e5d7f..484e5d7f 100644
--- a/src/core/ao_btm.h
+++ b/src/kernel/ao_btm.h
diff --git a/src/core/ao_cmd.c b/src/kernel/ao_cmd.c
index 4ebaa607..0052bdce 100644
--- a/src/core/ao_cmd.c
+++ b/src/kernel/ao_cmd.c
@@ -23,7 +23,11 @@ __pdata uint32_t ao_cmd_lex_u32;
__pdata char ao_cmd_lex_c;
__pdata enum ao_cmd_status ao_cmd_status;
+#if AO_PYRO_NUM
+#define CMD_LEN 128
+#else
#define CMD_LEN 48
+#endif
static __xdata char cmd_line[CMD_LEN];
static __pdata uint8_t cmd_len;
@@ -274,20 +278,32 @@ version(void)
printf("manufacturer %s\n"
"product %s\n"
"serial-number %u\n"
-#if HAS_FLIGHT
+#if HAS_FLIGHT || HAS_TRACKER
"current-flight %u\n"
#endif
#if HAS_LOG
"log-format %u\n"
+#if !DISABLE_LOG_SPACE
+ "log-space %lu\n"
+#endif
+#endif
+#if defined(AO_BOOT_APPLICATION_BASE) && defined(AO_BOOT_APPLICATION_BOUND)
+ "program-space %u\n"
#endif
, ao_manufacturer
, ao_product
, ao_serial_number
-#if HAS_FLIGHT
+#if HAS_FLIGHT || HAS_TRACKER
, ao_flight_number
#endif
#if HAS_LOG
, ao_log_format
+#if !DISABLE_LOG_SPACE
+ , (unsigned long) ao_storage_log_max
+#endif
+#endif
+#if defined(AO_BOOT_APPLICATION_BASE) && defined(AO_BOOT_APPLICATION_BOUND)
+ , (uint32_t) AO_BOOT_APPLICATION_BOUND - (uint32_t) AO_BOOT_APPLICATION_BASE
#endif
);
printf("software-version %s\n", ao_version);
diff --git a/src/core/ao_companion.h b/src/kernel/ao_companion.h
index 035325a3..035325a3 100644
--- a/src/core/ao_companion.h
+++ b/src/kernel/ao_companion.h
diff --git a/src/core/ao_config.c b/src/kernel/ao_config.c
index 4482f673..71445335 100644
--- a/src/core/ao_config.c
+++ b/src/kernel/ao_config.c
@@ -22,6 +22,12 @@
#include <ao_sample.h>
#include <ao_data.h>
#endif
+#if HAS_BEEP
+#include <ao_beep.h>
+#endif
+#if HAS_TRACKER
+#include <ao_tracker.h>
+#endif
__xdata struct ao_config ao_config;
__pdata uint8_t ao_config_loaded;
@@ -38,6 +44,7 @@ __xdata uint8_t ao_config_mutex;
#define AO_CONFIG_DEFAULT_APOGEE_DELAY 0
#define AO_CONFIG_DEFAULT_IGNITE_MODE AO_IGNITE_MODE_DUAL
#define AO_CONFIG_DEFAULT_PAD_ORIENTATION AO_PAD_ORIENTATION_ANTENNA_UP
+#define AO_CONFIG_DEFAULT_PYRO_TIME AO_MS_TO_TICKS(50)
#if HAS_EEPROM
#ifndef USE_INTERNAL_FLASH
#error Please define USE_INTERNAL_FLASH
@@ -127,7 +134,7 @@ _ao_config_get(void)
ao_config.radio_cal = ao_radio_cal;
#endif
/* Fixups for minor version 4 */
-#if HAS_FLIGHT
+#if HAS_LOG
if (minor < 4)
ao_config.flight_log_max = AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX;
#endif
@@ -171,6 +178,20 @@ _ao_config_get(void)
ao_config.accel_minus_g = 0;
}
#endif
+#if HAS_BEEP_CONFIG
+ if (minor < 16)
+ ao_config.mid_beep = AO_BEEP_MID_DEFAULT;
+#endif
+#if HAS_TRACKER
+ if (minor < 17) {
+ ao_config.tracker_motion = AO_TRACKER_MOTION_DEFAULT;
+ ao_config.tracker_interval = AO_TRACKER_INTERVAL_DEFAULT;
+ }
+#endif
+#if AO_PYRO_NUM
+ if (minor < 18)
+ ao_config.pyro_time = AO_CONFIG_DEFAULT_PYRO_TIME;
+#endif
ao_config.minor = AO_CONFIG_MINOR;
ao_config_dirty = 1;
}
@@ -357,7 +378,7 @@ ao_config_accel_calibrate_set(void) __reentrant
int16_t accel_across_up = 0, accel_across_down = 0;
int16_t accel_through_up = 0, accel_through_down = 0;
#endif
-
+
ao_cmd_decimal();
if (ao_cmd_status != ao_cmd_success)
return;
@@ -555,7 +576,7 @@ ao_config_radio_enable_set(void) __reentrant
_ao_config_edit_finish();
}
#endif /* HAS_RADIO */
-
+
#if HAS_AES
__xdata uint8_t ao_config_aes_seq = 1;
@@ -650,6 +671,72 @@ ao_config_radio_power_set(void)
#endif
+#if HAS_BEEP_CONFIG
+void
+ao_config_beep_show(void)
+{
+ printf ("Beeper setting: %d\n", ao_config.mid_beep);
+}
+
+void
+ao_config_beep_set(void)
+{
+ ao_cmd_decimal();
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ _ao_config_edit_start();
+ ao_config.mid_beep = ao_cmd_lex_i;
+ _ao_config_edit_finish();
+}
+#endif
+
+#if HAS_TRACKER
+void
+ao_config_tracker_show(void)
+{
+ printf ("Tracker setting: %d %d\n",
+ ao_config.tracker_motion,
+ ao_config.tracker_interval);
+}
+
+void
+ao_config_tracker_set(void)
+{
+ uint16_t m, i;
+ ao_cmd_decimal();
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ m = ao_cmd_lex_i;
+ ao_cmd_decimal();
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ i = ao_cmd_lex_i;
+ _ao_config_edit_start();
+ ao_config.tracker_motion = m;
+ ao_config.tracker_interval = i;
+ _ao_config_edit_finish();
+}
+#endif /* HAS_TRACKER */
+
+#if AO_PYRO_NUM
+void
+ao_config_pyro_time_show(void)
+{
+ printf ("Pyro time: %d\n", ao_config.pyro_time);
+}
+
+void
+ao_config_pyro_time_set(void)
+{
+ ao_cmd_decimal();
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ _ao_config_edit_start();
+ ao_config.pyro_time = ao_cmd_lex_i;
+ _ao_config_edit_finish();
+}
+#endif
+
struct ao_config_var {
__code char *str;
void (*set)(void) __reentrant;
@@ -697,7 +784,7 @@ __code struct ao_config_var ao_config_vars[] = {
#if HAS_ACCEL
{ "a <+g> <-g>\0Accel calib (0 for auto)",
ao_config_accel_calibrate_set,ao_config_accel_calibrate_show },
- { "o <0 antenna up, 1 antenna down>\0Set pad orientation",
+ { "o <0 antenna up, 1 antenna down>\0Pad orientation",
ao_config_pad_orientation_set,ao_config_pad_orientation_show },
#endif /* HAS_ACCEL */
#if HAS_LOG
@@ -705,21 +792,31 @@ __code struct ao_config_var ao_config_vars[] = {
ao_config_log_set, ao_config_log_show },
#endif
#if HAS_IGNITE
- { "i <0 dual, 1 apogee, 2 main>\0Set igniter mode",
+ { "i <0 dual, 1 apogee, 2 main>\0Igniter mode",
ao_config_ignite_mode_set, ao_config_ignite_mode_show },
#endif
#if HAS_AES
- { "k <32 hex digits>\0Set AES encryption key",
+ { "k <32 hex digits>\0AES encryption key",
ao_config_key_set, ao_config_key_show },
#endif
#if AO_PYRO_NUM
- { "P <n,?>\0Configure pyro channels",
+ { "P <n,?>\0Pyro channels",
ao_pyro_set, ao_pyro_show },
+ { "I <ticks>\0Pyro firing time",
+ ao_config_pyro_time_set, ao_config_pyro_time_show },
#endif
#if HAS_APRS
{ "A <secs>\0APRS packet interval (0 disable)",
ao_config_aprs_set, ao_config_aprs_show },
#endif
+#if HAS_BEEP_CONFIG
+ { "b <val>\0Beeper tone (freq = 1/2 (24e6/32) / beep",
+ ao_config_beep_set, ao_config_beep_show },
+#endif
+#if HAS_TRACKER
+ { "t <motion> <interval>\0Tracker configuration",
+ ao_config_tracker_set, ao_config_tracker_show },
+#endif
{ "s\0Show",
ao_config_show, 0 },
#if HAS_EEPROM
diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h
new file mode 100644
index 00000000..2b5cd352
--- /dev/null
+++ b/src/kernel/ao_config.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_CONFIG_H_
+#define _AO_CONFIG_H_
+
+#include <ao_pyro.h>
+
+#ifndef USE_STORAGE_CONFIG
+#define USE_STORAGE_CONFIG 1
+#endif
+
+#ifndef USE_EEPROM_CONFIG
+#define USE_EEPROM_CONFIG 0
+#endif
+
+#if USE_STORAGE_CONFIG
+
+#include <ao_storage.h>
+
+#define ao_config_setup() ao_storage_setup()
+#define ao_config_erase() ao_storage_erase(ao_storage_config)
+#define ao_config_write(pos,bytes, len) ao_storage_write(ao_storage_config+(pos), bytes, len)
+#define ao_config_read(pos,bytes, len) ao_storage_read(ao_storage_config+(pos), bytes, len)
+#define ao_config_flush() ao_storage_flush()
+
+#endif
+
+#if USE_EEPROM_CONFIG
+
+#include <ao_eeprom.h>
+
+#define ao_config_setup()
+#define ao_config_erase()
+#define ao_config_write(pos,bytes, len) ao_eeprom_write(pos, bytes, len)
+#define ao_config_read(pos,bytes, len) ao_eeprom_read(pos, bytes, len)
+#define ao_config_flush()
+
+#endif
+
+#define AO_CONFIG_MAJOR 1
+#define AO_CONFIG_MINOR 18
+
+#define AO_AES_LEN 16
+
+extern __xdata uint8_t ao_config_aes_seq;
+
+struct ao_config {
+ uint8_t major;
+ uint8_t minor;
+ uint16_t main_deploy;
+ int16_t accel_plus_g; /* changed for minor version 2 */
+ uint8_t _legacy_radio_channel;
+ char callsign[AO_MAX_CALLSIGN + 1];
+ uint8_t apogee_delay; /* minor version 1 */
+ int16_t accel_minus_g; /* minor version 2 */
+ uint32_t radio_cal; /* minor version 3 */
+ uint32_t flight_log_max; /* minor version 4 */
+ uint8_t ignite_mode; /* minor version 5 */
+ uint8_t pad_orientation; /* minor version 6 */
+ uint32_t radio_setting; /* minor version 7 */
+ uint8_t radio_enable; /* minor version 8 */
+ uint8_t aes_key[AO_AES_LEN]; /* minor version 9 */
+ uint32_t frequency; /* minor version 10 */
+ uint16_t apogee_lockout; /* minor version 11 */
+#if AO_PYRO_NUM
+ struct ao_pyro pyro[AO_PYRO_NUM]; /* minor version 12 */
+#endif
+ uint16_t aprs_interval; /* minor version 13 */
+#if HAS_RADIO_POWER
+ uint8_t radio_power; /* minor version 14 */
+#endif
+#if HAS_RADIO_AMP
+ uint8_t radio_amp; /* minor version 14 */
+#endif
+#if HAS_GYRO
+ int16_t accel_zero_along; /* minor version 15 */
+ int16_t accel_zero_across; /* minor version 15 */
+ int16_t accel_zero_through; /* minor version 15 */
+#endif
+#if HAS_BEEP
+ uint8_t mid_beep; /* minor version 16 */
+#endif
+#if HAS_TRACKER
+ uint16_t tracker_motion; /* minor version 17 */
+ uint8_t tracker_interval; /* minor version 17 */
+#endif
+#if AO_PYRO_NUM
+ uint16_t pyro_time; /* minor version 18 */
+#endif
+};
+
+#define AO_IGNITE_MODE_DUAL 0
+#define AO_IGNITE_MODE_APOGEE 1
+#define AO_IGNITE_MODE_MAIN 2
+
+#define AO_RADIO_ENABLE_CORE 1
+#define AO_RADIO_DISABLE_TELEMETRY 2
+#define AO_RADIO_DISABLE_RDF 4
+
+#define AO_PAD_ORIENTATION_ANTENNA_UP 0
+#define AO_PAD_ORIENTATION_ANTENNA_DOWN 1
+
+#ifndef AO_CONFIG_MAX_SIZE
+#define AO_CONFIG_MAX_SIZE 128
+#endif
+
+/* Make sure AO_CONFIG_MAX_SIZE is big enough */
+typedef uint8_t config_check_space[(int) (AO_CONFIG_MAX_SIZE - sizeof (struct ao_config))];
+
+extern __xdata struct ao_config ao_config;
+extern __pdata uint8_t ao_config_loaded;
+
+void
+_ao_config_edit_start(void);
+
+void
+_ao_config_edit_finish(void);
+
+void
+ao_config_get(void);
+
+void
+ao_config_put(void);
+
+void
+ao_config_set_radio(void);
+
+void
+ao_config_init(void);
+
+#endif /* _AO_CONFIG_H_ */
diff --git a/src/core/ao_convert.c b/src/kernel/ao_convert.c
index aa9b5f48..aa9b5f48 100644
--- a/src/core/ao_convert.c
+++ b/src/kernel/ao_convert.c
diff --git a/src/core/ao_convert_pa.c b/src/kernel/ao_convert_pa.c
index fe6e0ef6..fe6e0ef6 100644
--- a/src/core/ao_convert_pa.c
+++ b/src/kernel/ao_convert_pa.c
diff --git a/src/core/ao_convert_pa_test.c b/src/kernel/ao_convert_pa_test.c
index 7d5b1922..7d5b1922 100644
--- a/src/core/ao_convert_pa_test.c
+++ b/src/kernel/ao_convert_pa_test.c
diff --git a/src/core/ao_convert_test.c b/src/kernel/ao_convert_test.c
index 87e76841..87e76841 100644
--- a/src/core/ao_convert_test.c
+++ b/src/kernel/ao_convert_test.c
diff --git a/src/core/ao_convert_volt.c b/src/kernel/ao_convert_volt.c
index 8556d423..f697e748 100644
--- a/src/core/ao_convert_volt.c
+++ b/src/kernel/ao_convert_volt.c
@@ -17,17 +17,23 @@
#include "ao.h"
-#define scale(v,p,m) ((int32_t) (v) * (AO_ADC_REFERENCE_DV * ((p) + (m))) / (AO_ADC_MAX * (m)))
+#define MUL(p,m) ((int32_t) AO_ADC_REFERENCE_DV * ((p) + (m)))
+#define ADD(p,m) (MUL(p,m)/2)
+#define DIV(p,m) ((int32_t) AO_ADC_MAX * (m))
+#define scale(v,p,m) (((int32_t) (v) * MUL(p,m) + ADD(p,m)) / DIV(p,m))
+#if HAS_APRS || HAS_BATTERY_REPORT
int16_t
ao_battery_decivolt(int16_t adc)
{
return scale(adc, AO_BATTERY_DIV_PLUS, AO_BATTERY_DIV_MINUS);
}
+#endif
+#if HAS_APRS && defined(AO_IGNITE_DIV_PLUS)
int16_t
ao_ignite_decivolt(int16_t adc)
{
return scale(adc, AO_IGNITE_DIV_PLUS, AO_IGNITE_DIV_MINUS);
}
-
+#endif
diff --git a/src/core/ao_data.c b/src/kernel/ao_data.c
index 6a3d02a1..6a3d02a1 100644
--- a/src/core/ao_data.c
+++ b/src/kernel/ao_data.c
diff --git a/src/core/ao_data.h b/src/kernel/ao_data.h
index c4b062fd..c4b062fd 100644
--- a/src/core/ao_data.h
+++ b/src/kernel/ao_data.h
diff --git a/src/core/ao_dbg.h b/src/kernel/ao_dbg.h
index 181e6ec2..181e6ec2 100644
--- a/src/core/ao_dbg.h
+++ b/src/kernel/ao_dbg.h
diff --git a/src/core/ao_debounce.c b/src/kernel/ao_debounce.c
index b9d67729..b9d67729 100644
--- a/src/core/ao_debounce.c
+++ b/src/kernel/ao_debounce.c
diff --git a/src/core/ao_debounce.h b/src/kernel/ao_debounce.h
index 19c620f5..19c620f5 100644
--- a/src/core/ao_debounce.h
+++ b/src/kernel/ao_debounce.h
diff --git a/src/kernel/ao_distance.c b/src/kernel/ao_distance.c
new file mode 100644
index 00000000..5654182a
--- /dev/null
+++ b/src/kernel/ao_distance.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2014 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_distance.h>
+
+static uint32_t
+ao_dist(int32_t a, int32_t b)
+{
+ int32_t d = a - b;
+ if (d < 0)
+ d = -d;
+
+ return (uint32_t) ((int64_t) d * 111198 / 10000000);
+}
+
+static uint32_t
+ao_lat_dist(int32_t lat_a, int32_t lat_b)
+{
+ return ao_dist(lat_a, lat_b);
+}
+
+static const uint8_t cos_table[] = {
+ 0, /* 0 */
+ 0, /* 1 */
+ 0, /* 2 */
+ 255, /* 3 */
+ 254, /* 4 */
+ 253, /* 5 */
+ 252, /* 6 */
+ 251, /* 7 */
+ 249, /* 8 */
+ 247, /* 9 */
+ 245, /* 10 */
+ 243, /* 11 */
+ 240, /* 12 */
+ 238, /* 13 */
+ 235, /* 14 */
+ 232, /* 15 */
+ 228, /* 16 */
+ 225, /* 17 */
+ 221, /* 18 */
+ 217, /* 19 */
+ 213, /* 20 */
+ 209, /* 21 */
+ 205, /* 22 */
+ 200, /* 23 */
+ 195, /* 24 */
+ 190, /* 25 */
+ 185, /* 26 */
+ 180, /* 27 */
+ 175, /* 28 */
+ 169, /* 29 */
+ 163, /* 30 */
+ 158, /* 31 */
+ 152, /* 32 */
+ 145, /* 33 */
+ 139, /* 34 */
+ 133, /* 35 */
+ 126, /* 36 */
+ 120, /* 37 */
+ 113, /* 38 */
+ 106, /* 39 */
+ 100, /* 40 */
+ 93, /* 41 */
+ 86, /* 42 */
+ 79, /* 43 */
+ 71, /* 44 */
+ 64, /* 45 */
+ 57, /* 46 */
+ 49, /* 47 */
+ 42, /* 48 */
+ 35, /* 49 */
+ 27, /* 50 */
+ 20, /* 51 */
+ 12, /* 52 */
+ 5, /* 53 */
+ 1, /* 54 */
+};
+
+static uint32_t
+ao_lon_dist(int32_t lon_a, int32_t lon_b)
+{
+ uint8_t c = cos_table[lon_a >> 24];
+ uint32_t lon_dist;
+
+ /* check if it's shorter to go the other way around */
+ if ((lon_a >> 1) < (lon_b >> 1) - (1800000000 >> 1))
+ lon_a += 3600000000;
+ lon_dist = ao_dist(lon_a, lon_b);
+ if (c) {
+ if (lon_dist & 0x7f800000)
+ lon_dist = (lon_dist >> 8) * c;
+ else
+ lon_dist = (lon_dist * (int16_t) c) >> 8;
+ }
+ return lon_dist;
+}
+
+static uint32_t sqr(uint32_t x) { return x * x; }
+
+uint32_t
+ao_distance(int32_t lat_a, int32_t lon_a, int32_t lat_b, int32_t lon_b)
+{
+ uint32_t lat_dist = ao_lat_dist(lat_a, lat_b);
+ uint32_t lon_dist = ao_lon_dist(lon_a, lon_b);
+
+ return ao_sqrt (sqr(lat_dist) + sqr(lon_dist));
+}
diff --git a/src/kernel/ao_distance.h b/src/kernel/ao_distance.h
new file mode 100644
index 00000000..6762434e
--- /dev/null
+++ b/src/kernel/ao_distance.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright © 2014 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_DISTANCE_H_
+#define _AO_DISTANCE_H_
+#include <stdint.h>
+
+uint32_t
+ao_distance(int32_t lat_a, int32_t lon_a, int32_t lat_b, int32_t lon_b);
+
+#endif /* _AO_DISTANCE_H_ */
diff --git a/src/core/ao_ee_fake.c b/src/kernel/ao_ee_fake.c
index 7fcfcab0..7fcfcab0 100644
--- a/src/core/ao_ee_fake.c
+++ b/src/kernel/ao_ee_fake.c
diff --git a/src/core/ao_eeprom.h b/src/kernel/ao_eeprom.h
index 915522bf..915522bf 100644
--- a/src/core/ao_eeprom.h
+++ b/src/kernel/ao_eeprom.h
diff --git a/src/kernel/ao_fake_flight.c b/src/kernel/ao_fake_flight.c
new file mode 100644
index 00000000..11329bb9
--- /dev/null
+++ b/src/kernel/ao_fake_flight.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright © 2014 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_fake_flight.h>
+#if HAS_MS5607 || HAS_MS5611
+#include <ao_ms5607.h>
+#endif
+
+uint8_t ao_fake_flight_active;
+
+static uint8_t ao_fake_has_cur;
+static volatile uint8_t ao_fake_has_next;
+static uint8_t ao_fake_has_offset;
+static uint16_t ao_fake_tick_offset;
+static struct ao_data ao_fake_cur, ao_fake_next;
+
+void
+ao_fake_flight_poll(void)
+{
+ if (ao_fake_has_next && (ao_tick_count - ao_fake_next.tick) >= 0) {
+ ao_fake_cur = ao_fake_next;
+ ao_fake_has_next = 0;
+ ao_wakeup((void *) &ao_fake_has_next);
+ ao_fake_has_cur = 1;
+ }
+ if (!ao_fake_has_cur)
+ return;
+ ao_data_ring[ao_data_head] = ao_fake_cur;
+ ao_data_ring[ao_data_head].tick = ao_tick_count;
+ ao_data_head = ao_data_ring_next(ao_data_head);
+ ao_wakeup((void *) &ao_data_head);
+}
+
+static uint8_t
+ao_fake_data_read(void)
+{
+ uint8_t i;
+ uint8_t *d = (void *) &ao_fake_next;
+
+ if (getchar() == 0)
+ return FALSE;
+ for (i = 0; i < sizeof (struct ao_data); i++)
+ *d++ = getchar();
+ if (!ao_fake_has_offset) {
+ ao_fake_tick_offset = (ao_tick_count + 1000) - ao_fake_next.tick;
+ ao_fake_next.tick = ao_tick_count;
+ ao_fake_has_offset = 1;
+ } else
+ ao_fake_next.tick += ao_fake_tick_offset;
+ ao_fake_has_next = 1;
+ return TRUE;
+}
+
+static void
+ao_fake_calib_get(struct ao_fake_calib *calib)
+{
+#if HAS_ACCEL
+ calib->accel_plus_g = ao_config.accel_plus_g;
+ calib->accel_minus_g = ao_config.accel_minus_g;
+#endif
+#if HAS_GYRO
+ calib->accel_zero_along = ao_config.accel_zero_along;
+ calib->accel_zero_across = ao_config.accel_zero_across;
+ calib->accel_zero_through = ao_config.accel_zero_through;
+#endif
+#if HAS_MS5607 || HAS_MS5611
+ calib->ms5607_prom = ao_ms5607_prom;
+#endif
+}
+
+static void
+ao_fake_calib_set(struct ao_fake_calib *calib)
+{
+#if HAS_ACCEL
+ ao_config.accel_plus_g = calib->accel_plus_g;
+ ao_config.accel_minus_g = calib->accel_minus_g;
+#endif
+#if HAS_GYRO
+ ao_config.accel_zero_along = calib->accel_zero_along;
+ ao_config.accel_zero_across = calib->accel_zero_across;
+ ao_config.accel_zero_through = calib->accel_zero_through;
+#endif
+#if HAS_MS5607 || HAS_MS5611
+ ao_ms5607_prom = calib->ms5607_prom;
+#endif
+}
+
+static uint8_t
+ao_fake_calib_read(void)
+{
+ struct ao_fake_calib ao_calib;
+ uint8_t *d = (void *) &ao_calib;
+ uint16_t i;
+
+ /* Read calibration data */
+ for (i = 0; i < sizeof (struct ao_fake_calib); i++)
+ *d++ = getchar();
+ if (ao_calib.major != AO_FAKE_CALIB_MAJOR
+#if AO_FAKE_CALIB_MINOR != 0
+ || ao_calib.minor < AO_FAKE_CALIB_MINOR
+#endif
+ ) {
+ printf ("Calibration data major version mismatch %d.%d <= %d.%d\n",
+ ao_calib.major, ao_calib.minor, AO_FAKE_CALIB_MAJOR, AO_FAKE_CALIB_MINOR);
+ return FALSE;
+ }
+ ao_fake_calib_set(&ao_calib);
+ return TRUE;
+}
+
+static void
+ao_fake_flight(void)
+{
+ int16_t calib_size, data_size;
+ struct ao_fake_calib save_calib;
+ uint16_t my_pyro_fired = 0;
+ enum ao_flight_state my_state = ao_flight_invalid;
+ int i;
+
+ ao_cmd_hex();
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ calib_size = ao_cmd_lex_i;
+ ao_cmd_hex();
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ data_size = ao_cmd_lex_i;
+ if ((unsigned) calib_size != sizeof (struct ao_fake_calib)) {
+ printf ("calib size %d larger than actual size %d\n",
+ calib_size, sizeof (struct ao_fake_calib));
+ ao_cmd_status = ao_cmd_syntax_error;
+ return;
+ }
+ if (data_size != sizeof (struct ao_data)) {
+ printf ("data size %d doesn't match actual size %d\n",
+ data_size, sizeof (struct ao_data));
+ ao_cmd_status = ao_cmd_syntax_error;
+ return;
+ }
+ ao_fake_calib_get(&save_calib);
+ if (!ao_fake_calib_read())
+ return;
+
+ ao_fake_has_next = 0;
+ ao_fake_has_cur = 0;
+ ao_fake_flight_active = 1;
+ ao_sample_init();
+#if PACKET_HAS_SLAVE
+ ao_packet_slave_stop();
+#endif
+#if AO_LED_RED
+ /* Turn on the LED to indicate startup */
+ ao_led_on(AO_LED_RED);
+#endif
+ ao_flight_state = ao_flight_startup;
+ for (;;) {
+ if (my_state != ao_flight_state) {
+ printf("state %d\n", ao_flight_state);
+ my_state = ao_flight_state;
+ flush();
+ }
+ if (my_pyro_fired != ao_pyro_fired) {
+ int pyro;
+
+ for (pyro = 0; pyro < AO_PYRO_NUM; pyro++) {
+ uint16_t bit = (1 << pyro);
+ if (!(my_pyro_fired & bit) && (ao_pyro_fired & bit))
+ printf ("fire %d\n", pyro);
+ }
+ my_pyro_fired = ao_pyro_fired;
+ }
+ while (ao_fake_has_next)
+ ao_sleep((void *) &ao_fake_has_next);
+ if (!ao_fake_data_read())
+ break;
+ }
+
+ /* Wait 20 seconds to see if we enter landed state */
+ for (i = 0; i < 200; i++)
+ {
+ if (ao_flight_state == ao_flight_landed)
+ break;
+ ao_delay(AO_MS_TO_TICKS(100));
+ }
+#if AO_LED_RED
+ /* Turn on the LED to indicate startup */
+ ao_led_on(AO_LED_RED);
+#endif
+ ao_fake_flight_active = 0;
+ ao_flight_state = ao_flight_startup;
+ ao_sample_init();
+ ao_fake_calib_set(&save_calib);
+}
+
+static const struct ao_cmds ao_fake_flight_cmds[] = {
+ { ao_fake_flight, "F <calib-size> <data-size>\0Start fake flight" },
+ { 0, NULL }
+};
+
+void
+ao_fake_flight_init(void)
+{
+ ao_cmd_register(&ao_fake_flight_cmds[0]);
+}
diff --git a/src/kernel/ao_fake_flight.h b/src/kernel/ao_fake_flight.h
new file mode 100644
index 00000000..172fc589
--- /dev/null
+++ b/src/kernel/ao_fake_flight.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2014 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_FAKE_FLIGHT_H_
+#define _AO_FAKE_FLIGHT_H_
+#if HAS_MS5607 || HAS_MS5611
+#include <ao_ms5607.h>
+#endif
+
+extern uint8_t ao_fake_flight_active;
+
+#define AO_FAKE_CALIB_MAJOR 1
+#define AO_FAKE_CALIB_MINOR 0
+
+struct ao_fake_calib {
+ uint16_t major;
+ uint16_t minor;
+#if HAS_ACCEL
+ int16_t accel_plus_g;
+ int16_t accel_minus_g;
+#endif
+#if HAS_GYRO
+ int16_t accel_zero_along;
+ int16_t accel_zero_across;
+ int16_t accel_zero_through;
+ uint16_t pad30;
+#endif
+#if HAS_MS5607 || HAS_MS5611
+ struct ao_ms5607_prom ms5607_prom;
+#endif
+};
+
+void
+ao_fake_flight_poll(void);
+
+void
+ao_fake_flight_init(void);
+
+#endif /* _AO_FAKE_FLIGHT_H_ */
diff --git a/src/core/ao_fec.h b/src/kernel/ao_fec.h
index 618756c1..618756c1 100644
--- a/src/core/ao_fec.h
+++ b/src/kernel/ao_fec.h
diff --git a/src/core/ao_fec_rx.c b/src/kernel/ao_fec_rx.c
index c4f5559a..c4f5559a 100644
--- a/src/core/ao_fec_rx.c
+++ b/src/kernel/ao_fec_rx.c
diff --git a/src/core/ao_fec_tx.c b/src/kernel/ao_fec_tx.c
index 4941d745..4941d745 100644
--- a/src/core/ao_fec_tx.c
+++ b/src/kernel/ao_fec_tx.c
diff --git a/src/core/ao_flight.c b/src/kernel/ao_flight.c
index 702c3403..2b433ee9 100644
--- a/src/core/ao_flight.c
+++ b/src/kernel/ao_flight.c
@@ -36,6 +36,10 @@
#error Please define HAS_USB
#endif
+#if HAS_FAKE_FLIGHT
+#include <ao_fake_flight.h>
+#endif
+
#ifndef HAS_TELEMETRY
#define HAS_TELEMETRY HAS_RADIO
#endif
@@ -130,7 +134,10 @@ ao_flight(void)
/* Disable the USB controller in flight mode
* to save power
*/
- ao_usb_disable();
+#if HAS_FAKE_FLIGHT
+ if (!ao_fake_flight_active)
+#endif
+ ao_usb_disable();
#endif
#if !HAS_ACCEL && PACKET_HAS_SLAVE
@@ -143,7 +150,7 @@ ao_flight(void)
ao_rdf_set(1);
ao_telemetry_set_interval(AO_TELEMETRY_INTERVAL_PAD);
#endif
-#if HAS_LED
+#if AO_LED_RED
/* signal successful initialization by turning off the LED */
ao_led_off(AO_LED_RED);
#endif
@@ -160,7 +167,7 @@ ao_flight(void)
ao_packet_slave_start();
#endif
-#if HAS_LED
+#if AO_LED_RED
/* signal successful initialization by turning off the LED */
ao_led_off(AO_LED_RED);
#endif
@@ -170,7 +177,6 @@ ao_flight(void)
break;
case ao_flight_pad:
-
/* pad to boost:
*
* barometer: > 20m vertical motion
diff --git a/src/core/ao_flight.h b/src/kernel/ao_flight.h
index 01d21c11..01d21c11 100644
--- a/src/core/ao_flight.h
+++ b/src/kernel/ao_flight.h
diff --git a/src/core/ao_flight_nano.c b/src/kernel/ao_flight_nano.c
index 406d81ad..406d81ad 100644
--- a/src/core/ao_flight_nano.c
+++ b/src/kernel/ao_flight_nano.c
diff --git a/src/core/ao_freq.c b/src/kernel/ao_freq.c
index 12496f6f..12496f6f 100644
--- a/src/core/ao_freq.c
+++ b/src/kernel/ao_freq.c
diff --git a/src/core/ao_gps_print.c b/src/kernel/ao_gps_print.c
index 47c945d7..47c945d7 100644
--- a/src/core/ao_gps_print.c
+++ b/src/kernel/ao_gps_print.c
diff --git a/src/core/ao_gps_report.c b/src/kernel/ao_gps_report.c
index 07201ac2..07201ac2 100644
--- a/src/core/ao_gps_report.c
+++ b/src/kernel/ao_gps_report.c
diff --git a/src/core/ao_gps_report_mega.c b/src/kernel/ao_gps_report_mega.c
index 5e3c71bf..cb0c0fd9 100644
--- a/src/core/ao_gps_report_mega.c
+++ b/src/kernel/ao_gps_report_mega.c
@@ -18,6 +18,43 @@
#include "ao.h"
#include "ao_log.h"
+#ifndef GPS_SPARSE_LOG
+#define GPS_SPARSE_LOG 0
+#endif
+
+#if GPS_SPARSE_LOG
+static int32_t prev_lat, prev_lon, int16_t prev_alt;
+static uint8_t has_prev, unmoving;
+
+#define GPS_SPARSE_UNMOVING_REPORTS 10
+#define GPS_SPARSE_UNMOVING_GROUND 10
+#define GPS_SPARSE_UNMOVING_AIR 10
+
+static uint8_t
+ao_gps_sparse_should_log(int32_t lat, int32_t lon, int16_t alt)
+{
+ uint8_t ret = 1;
+
+ if (has_prev && ao_log_running) {
+ uint32_t h = ao_distance(prev_lat, prev_lon, lat, lon);
+ uint16_t v = alt > prev_alt ? (alt - prev_alt) : (prev_alt - alt);
+
+ if (h < GPS_SPARSE_UNMOVING_GROUND && v < GPS_SPARSE_UNMOVING_AIR) {
+ if (unmoving < GPS_SPARSE_UNMOVING_REPORTS)
+ ++unmoving;
+ } else
+ unmoving = 0;
+ } else
+ unmoving = 0;
+
+ prev_lat = lat;
+ prev_lon = lon;
+ prev_alt = alt;
+ has_prev = 1;
+ return unmoving >= GPS_SPARSE_UNMOVING_REPORTS;
+}
+#endif
+
void
ao_gps_report_mega(void)
{
@@ -38,7 +75,14 @@ ao_gps_report_mega(void)
ao_gps_new = 0;
ao_mutex_put(&ao_gps_mutex);
+#if GPS_SPARSE_LOG
+ /* Don't log data if GPS has a fix and hasn't moved for a while */
+ if ((gps_data.flags & AO_GPS_VALID) &&
+ !ao_gps_sparse_should_log(gps_data.latitude, gps_data.longitude, gps_data.altitude))
+ continue;
+#endif
if ((new & AO_GPS_NEW_DATA) && (gps_data.flags & AO_GPS_VALID)) {
+
gps_log.tick = ao_gps_tick;
gps_log.type = AO_LOG_GPS_TIME;
gps_log.u.gps.latitude = gps_data.latitude;
diff --git a/src/core/ao_gps_report_metrum.c b/src/kernel/ao_gps_report_metrum.c
index 696a833b..696a833b 100644
--- a/src/core/ao_gps_report_metrum.c
+++ b/src/kernel/ao_gps_report_metrum.c
diff --git a/src/core/ao_gps_show.c b/src/kernel/ao_gps_show.c
index 3a05e35a..3a05e35a 100644
--- a/src/core/ao_gps_show.c
+++ b/src/kernel/ao_gps_show.c
diff --git a/src/core/ao_host.h b/src/kernel/ao_host.h
index 6eb752c9..6eb752c9 100644
--- a/src/core/ao_host.h
+++ b/src/kernel/ao_host.h
diff --git a/src/core/ao_ignite.c b/src/kernel/ao_ignite.c
index 823d003c..823d003c 100644
--- a/src/core/ao_ignite.c
+++ b/src/kernel/ao_ignite.c
diff --git a/src/core/ao_int64.c b/src/kernel/ao_int64.c
index aa23dbe0..ca75751b 100644
--- a/src/core/ao_int64.c
+++ b/src/kernel/ao_int64.c
@@ -17,8 +17,6 @@
#include <ao_int64.h>
-__pdata ao_int64_t *__data ao_64r, *__data ao_64a, *__data ao_64b;
-
void ao_plus64(__pdata ao_int64_t *r, __pdata ao_int64_t *a, __pdata ao_int64_t *b) __FATTR {
__LOCAL uint32_t t;
@@ -151,8 +149,8 @@ void ao_mul64_64_16(__ARG ao_int64_t *r, __ARG ao_int64_t *a, __ARG uint16_t b)
ao_neg64(&ap, a);
a = &ap;
negative++;
- } else
- ao_umul64_64_16(r, a, b);
+ }
+ ao_umul64_64_16(r, a, b);
if (negative)
ao_neg64(r, r);
}
diff --git a/src/core/ao_int64.h b/src/kernel/ao_int64.h
index b16db58c..b16db58c 100644
--- a/src/core/ao_int64.h
+++ b/src/kernel/ao_int64.h
diff --git a/src/core/ao_kalman.c b/src/kernel/ao_kalman.c
index 9aea1f14..9aea1f14 100644
--- a/src/core/ao_kalman.c
+++ b/src/kernel/ao_kalman.c
diff --git a/src/core/ao_lcd.h b/src/kernel/ao_lcd.h
index f7e1391a..f7e1391a 100644
--- a/src/core/ao_lcd.h
+++ b/src/kernel/ao_lcd.h
diff --git a/src/core/ao_led.h b/src/kernel/ao_led.h
index d9a0914a..d9a0914a 100644
--- a/src/core/ao_led.h
+++ b/src/kernel/ao_led.h
diff --git a/src/core/ao_list.h b/src/kernel/ao_list.h
index 8a6fa4d9..8a6fa4d9 100644
--- a/src/core/ao_list.h
+++ b/src/kernel/ao_list.h
diff --git a/src/core/ao_log.c b/src/kernel/ao_log.c
index 20febefe..91617d93 100644
--- a/src/core/ao_log.c
+++ b/src/kernel/ao_log.c
@@ -18,7 +18,11 @@
#include "ao.h"
#include <ao_log.h>
#include <ao_config.h>
+#if HAS_TRACKER
+#include <ao_tracker.h>
+#endif
+__xdata uint8_t ao_log_mutex;
__pdata uint32_t ao_log_current_pos;
__pdata uint32_t ao_log_end_pos;
__pdata uint32_t ao_log_start_pos;
@@ -38,13 +42,22 @@ ao_log_flush(void)
*/
struct ao_log_erase {
- uint8_t unused;
+ uint8_t mark;
uint16_t flight;
};
static __xdata struct ao_log_erase erase;
+#ifndef LOG_MAX_ERASE
#define LOG_MAX_ERASE 16
+#endif
+
+#ifndef LOG_ERASE_MARK
+#if USE_EEPROM_CONFIG
+#error "Must define LOG_ERASE_MARK with USE_EEPROM_CONFIG"
+#endif
+#define LOG_ERASE_MARK 0x00
+#endif
static uint32_t
ao_log_erase_pos(uint8_t i)
@@ -55,9 +68,21 @@ ao_log_erase_pos(uint8_t i)
void
ao_log_write_erase(uint8_t pos)
{
- erase.unused = 0x00;
+ erase.mark = LOG_ERASE_MARK;
erase.flight = ao_flight_number;
ao_config_write(ao_log_erase_pos(pos), &erase, sizeof (erase));
+
+#if USE_EEPROM_CONFIG
+ if (pos == 0) {
+ uint8_t i;
+ for (i = 1; i < LOG_MAX_ERASE; i++) {
+ erase.mark = ~LOG_ERASE_MARK;
+ erase.flight = 0;
+ ao_config_write(ao_log_erase_pos(i), &erase, sizeof (erase));
+ }
+ }
+#endif
+
ao_config_flush();
}
@@ -75,9 +100,9 @@ ao_log_erase_mark(void)
for (i = 0; i < LOG_MAX_ERASE; i++) {
ao_log_read_erase(i);
- if (erase.unused == 0 && erase.flight == ao_flight_number)
+ if (erase.mark == LOG_ERASE_MARK && erase.flight == ao_flight_number)
return;
- if (erase.unused == 0xff) {
+ if (erase.mark != LOG_ERASE_MARK) {
ao_log_write_erase(i);
return;
}
@@ -136,7 +161,7 @@ ao_log_scan(void) __reentrant
*/
for (log_slot = LOG_MAX_ERASE; log_slot-- > 0;) {
ao_log_read_erase(log_slot);
- if (erase.unused == 0) {
+ if (erase.mark == LOG_ERASE_MARK) {
if (ao_flight_number == 0 ||
(int16_t) (erase.flight - ao_flight_number) > 0)
ao_flight_number = erase.flight;
@@ -196,7 +221,11 @@ ao_log_full(void)
return ao_log_current_pos == ao_log_end_pos;
}
-#if HAS_ADC
+#ifndef LOG_ADC
+#define LOG_ADC HAS_ADC
+#endif
+
+#if LOG_ADC
static __xdata struct ao_task ao_log_task;
#endif
@@ -225,6 +254,7 @@ ao_log_delete(void) __reentrant
{
uint8_t slot;
uint8_t slots;
+ uint32_t log_current_pos, log_end_pos;
ao_cmd_decimal();
if (ao_cmd_status != ao_cmd_success)
@@ -235,10 +265,13 @@ ao_log_delete(void) __reentrant
if (ao_cmd_lex_i) {
for (slot = 0; slot < slots; slot++) {
if (ao_log_flight(slot) == ao_cmd_lex_i) {
+#if HAS_TRACKER
+ ao_tracker_erase_start(ao_cmd_lex_i);
+#endif
ao_log_erase_mark();
- ao_log_current_pos = ao_log_pos(slot);
- ao_log_end_pos = ao_log_current_pos + ao_config.flight_log_max;
- while (ao_log_current_pos < ao_log_end_pos) {
+ log_current_pos = ao_log_pos(slot);
+ log_end_pos = log_current_pos + ao_config.flight_log_max;
+ while (log_current_pos < log_end_pos) {
uint8_t i;
static __xdata uint8_t b;
@@ -248,15 +281,18 @@ ao_log_delete(void) __reentrant
* memory over and over again
*/
for (i = 0; i < 16; i++) {
- if (ao_storage_read(ao_log_current_pos + i, &b, 1))
+ if (ao_storage_read(log_current_pos + i, &b, 1))
if (b != 0xff)
break;
}
if (i == 16)
break;
- ao_storage_erase(ao_log_current_pos);
- ao_log_current_pos += ao_storage_block;
+ ao_storage_erase(log_current_pos);
+ log_current_pos += ao_storage_block;
}
+#if HAS_TRACKER
+ ao_tracker_erase_end();
+#endif
puts("Erased");
return;
}
@@ -284,7 +320,7 @@ ao_log_init(void)
#ifndef HAS_ADC
#error Define HAS_ADC for ao_log.c
#endif
-#if HAS_ADC
+#if LOG_ADC
/* Create a task to log events to eeprom */
ao_add_task(&ao_log_task, ao_log, "log");
#endif
diff --git a/src/core/ao_log.h b/src/kernel/ao_log.h
index 09f31188..33cda3eb 100644
--- a/src/core/ao_log.h
+++ b/src/kernel/ao_log.h
@@ -29,7 +29,7 @@
* by sleeping on this variable.
*/
extern __xdata uint16_t ao_flight_number;
-
+extern __xdata uint8_t ao_log_mutex;
extern __pdata uint32_t ao_log_current_pos;
extern __pdata uint32_t ao_log_end_pos;
extern __pdata uint32_t ao_log_start_pos;
@@ -47,6 +47,7 @@ extern __pdata enum ao_flight_state ao_log_state;
#define AO_LOG_FORMAT_EASYMINI 6 /* 16-byte MS5607 baro only, 3.0V supply */
#define AO_LOG_FORMAT_TELEMETRUM 7 /* 16-byte typed telemetrum records */
#define AO_LOG_FORMAT_TELEMINI 8 /* 16-byte MS5607 baro only, 3.3V supply */
+#define AO_LOG_FORMAT_TELEGPS 9 /* 32 byte telegps records */
#define AO_LOG_FORMAT_NONE 127 /* No log at all */
extern __code uint8_t ao_log_format;
@@ -206,9 +207,9 @@ struct ao_log_mega {
uint16_t flight; /* 4 */
int16_t ground_accel; /* 6 */
uint32_t ground_pres; /* 8 */
- int16_t ground_accel_along; /* 16 */
- int16_t ground_accel_across; /* 12 */
- int16_t ground_accel_through; /* 14 */
+ int16_t ground_accel_along; /* 12 */
+ int16_t ground_accel_across; /* 14 */
+ int16_t ground_accel_through; /* 16 */
int16_t ground_roll; /* 18 */
int16_t ground_pitch; /* 20 */
int16_t ground_yaw; /* 22 */
@@ -364,6 +365,50 @@ struct ao_log_mini {
(dst)[2] = (value) >> 16; \
} while (0)
+struct ao_log_gps {
+ char type; /* 0 */
+ uint8_t csum; /* 1 */
+ uint16_t tick; /* 2 */
+ union { /* 4 */
+ /* AO_LOG_FLIGHT */
+ struct {
+ uint16_t flight; /* 4 */
+ int16_t start_altitude; /* 6 */
+ int32_t start_latitude; /* 8 */
+ int32_t start_longitude; /* 12 */
+ } flight; /* 16 */
+ /* AO_LOG_GPS_TIME */
+ struct {
+ int32_t latitude; /* 4 */
+ int32_t longitude; /* 8 */
+ int16_t altitude; /* 12 */
+ uint8_t hour; /* 14 */
+ uint8_t minute; /* 15 */
+ uint8_t second; /* 16 */
+ uint8_t flags; /* 17 */
+ uint8_t year; /* 18 */
+ uint8_t month; /* 19 */
+ uint8_t day; /* 20 */
+ uint8_t course; /* 21 */
+ uint16_t ground_speed; /* 22 */
+ int16_t climb_rate; /* 24 */
+ uint8_t pdop; /* 26 */
+ uint8_t hdop; /* 27 */
+ uint8_t vdop; /* 28 */
+ uint8_t mode; /* 29 */
+ uint8_t state; /* 30 */
+ } gps; /* 31 */
+ /* AO_LOG_GPS_SAT */
+ struct {
+ uint16_t channels; /* 4 */
+ struct {
+ uint8_t svid;
+ uint8_t c_n;
+ } sats[12]; /* 6 */
+ } gps_sat; /* 30 */
+ } u;
+};
+
/* Write a record to the eeprom log */
uint8_t
ao_log_data(__xdata struct ao_log_record *log) __reentrant;
@@ -377,6 +422,9 @@ ao_log_metrum(__xdata struct ao_log_metrum *log) __reentrant;
uint8_t
ao_log_mini(__xdata struct ao_log_mini *log) __reentrant;
+uint8_t
+ao_log_gps(__xdata struct ao_log_gps *log) __reentrant;
+
void
ao_log_flush(void);
diff --git a/src/core/ao_log_big.c b/src/kernel/ao_log_big.c
index db01f46c..8f57bf75 100644
--- a/src/core/ao_log_big.c
+++ b/src/kernel/ao_log_big.c
@@ -17,7 +17,6 @@
#include "ao.h"
-static __xdata uint8_t ao_log_mutex;
static __xdata struct ao_log_record log;
__code uint8_t ao_log_format = AO_LOG_FORMAT_FULL;
diff --git a/src/kernel/ao_log_gps.c b/src/kernel/ao_log_gps.c
new file mode 100644
index 00000000..3b728c25
--- /dev/null
+++ b/src/kernel/ao_log_gps.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright © 2014 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_log_gps.h>
+#include <ao_data.h>
+#include <ao_flight.h>
+#include <ao_distance.h>
+#include <ao_tracker.h>
+
+static __xdata struct ao_log_gps log;
+
+__code uint8_t ao_log_format = AO_LOG_FORMAT_TELEGPS;
+
+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_gps); i++)
+ sum += *b++;
+ return -sum;
+}
+
+uint8_t
+ao_log_gps(__xdata struct ao_log_gps *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_gps));
+ ao_log_current_pos += sizeof (struct ao_log_gps);
+ }
+ } ao_mutex_put(&ao_log_mutex);
+ return wrote;
+}
+
+void
+ao_log_gps_flight(void)
+{
+ log.type = AO_LOG_FLIGHT;
+ log.tick = ao_time();
+ log.u.flight.flight = ao_flight_number;
+ ao_log_gps(&log);
+}
+
+void
+ao_log_gps_data(uint16_t tick, struct ao_telemetry_location *gps_data)
+{
+ log.tick = tick;
+ log.type = AO_LOG_GPS_TIME;
+ log.u.gps.latitude = gps_data->latitude;
+ log.u.gps.longitude = gps_data->longitude;
+ log.u.gps.altitude = gps_data->altitude;
+
+ log.u.gps.hour = gps_data->hour;
+ log.u.gps.minute = gps_data->minute;
+ log.u.gps.second = gps_data->second;
+ log.u.gps.flags = gps_data->flags;
+ log.u.gps.year = gps_data->year;
+ log.u.gps.month = gps_data->month;
+ log.u.gps.day = gps_data->day;
+ log.u.gps.course = gps_data->course;
+ log.u.gps.ground_speed = gps_data->ground_speed;
+ log.u.gps.climb_rate = gps_data->climb_rate;
+ log.u.gps.pdop = gps_data->pdop;
+ log.u.gps.hdop = gps_data->hdop;
+ log.u.gps.vdop = gps_data->vdop;
+ log.u.gps.mode = gps_data->mode;
+ ao_log_gps(&log);
+}
+
+void
+ao_log_gps_tracking(uint16_t tick, struct ao_telemetry_satellite *gps_tracking_data)
+{
+ uint8_t c, n, i;
+
+ log.tick = tick;
+ log.type = AO_LOG_GPS_SAT;
+ i = 0;
+ n = gps_tracking_data->channels;
+ for (c = 0; c < n; c++)
+ if ((log.u.gps_sat.sats[i].svid = gps_tracking_data->sats[c].svid))
+ {
+ log.u.gps_sat.sats[i].c_n = gps_tracking_data->sats[c].c_n_1;
+ i++;
+ if (i >= 12)
+ break;
+ }
+ log.u.gps_sat.channels = i;
+ ao_log_gps(&log);
+}
+
+static uint8_t
+ao_log_dump_check_data(void)
+{
+ if (ao_log_csum((uint8_t *) &log) != 0)
+ return 0;
+ return 1;
+}
+
+uint16_t
+ao_log_flight(uint8_t slot)
+{
+ if (!ao_storage_read(ao_log_pos(slot),
+ &log,
+ sizeof (struct ao_log_gps)))
+ return 0;
+
+ if (ao_log_dump_check_data() && log.type == AO_LOG_FLIGHT)
+ return log.u.flight.flight;
+ return 0;
+}
diff --git a/src/kernel/ao_log_gps.h b/src/kernel/ao_log_gps.h
new file mode 100644
index 00000000..5851f4d1
--- /dev/null
+++ b/src/kernel/ao_log_gps.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2014 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_telemetry.h"
+
+#ifndef _AO_LOG_GPS_H_
+#define _AO_LOG_GPS_H_
+
+uint8_t
+ao_log_gps_should_log(int32_t lat, int32_t lon, int16_t alt);
+
+void
+ao_log_gps_flight(void);
+
+void
+ao_log_gps_data(uint16_t tick, struct ao_telemetry_location *gps_data);
+
+#endif /* _AO_LOG_GPS_H_ */
diff --git a/src/core/ao_log_mega.c b/src/kernel/ao_log_mega.c
index 768947d5..cb83be4b 100644
--- a/src/core/ao_log_mega.c
+++ b/src/kernel/ao_log_mega.c
@@ -20,7 +20,6 @@
#include <ao_data.h>
#include <ao_flight.h>
-static __xdata uint8_t ao_log_mutex;
static __xdata struct ao_log_mega log;
__code uint8_t ao_log_format = AO_LOG_FORMAT_TELEMEGA;
@@ -65,7 +64,7 @@ ao_log_dump_check_data(void)
return 1;
}
-#if HAS_ADC
+#if HAS_FLIGHT
static __data uint8_t ao_log_data_pos;
/* a hack to make sure that ao_log_megas fill the eeprom block in even units */
@@ -100,9 +99,9 @@ ao_log(void)
log.u.flight.ground_accel_along = ao_ground_accel_along;
log.u.flight.ground_accel_across = ao_ground_accel_across;
log.u.flight.ground_accel_through = ao_ground_accel_through;
+ log.u.flight.ground_roll = ao_ground_roll;
log.u.flight.ground_pitch = ao_ground_pitch;
log.u.flight.ground_yaw = ao_ground_yaw;
- log.u.flight.ground_roll = ao_ground_roll;
#endif
log.u.flight.ground_pres = ao_ground_pres;
log.u.flight.flight = ao_flight_number;
@@ -183,7 +182,7 @@ ao_log(void)
ao_sleep(&ao_log_running);
}
}
-#endif
+#endif /* HAS_FLIGHT */
uint16_t
ao_log_flight(uint8_t slot)
diff --git a/src/core/ao_log_metrum.c b/src/kernel/ao_log_metrum.c
index 91624d98..08e7b8c4 100644
--- a/src/core/ao_log_metrum.c
+++ b/src/kernel/ao_log_metrum.c
@@ -20,7 +20,6 @@
#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;
@@ -116,7 +115,9 @@ ao_log(void)
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
+#if HAS_ACCEL
log.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]);
+#endif
ao_log_metrum(&log);
if (ao_log_state <= ao_flight_coast)
next_sensor = log.tick + AO_SENSOR_INTERVAL_ASCENT;
diff --git a/src/core/ao_log_micro.c b/src/kernel/ao_log_micro.c
index d665efb5..d665efb5 100644
--- a/src/core/ao_log_micro.c
+++ b/src/kernel/ao_log_micro.c
diff --git a/src/core/ao_log_micro.h b/src/kernel/ao_log_micro.h
index 976852ee..976852ee 100644
--- a/src/core/ao_log_micro.h
+++ b/src/kernel/ao_log_micro.h
diff --git a/src/core/ao_log_mini.c b/src/kernel/ao_log_mini.c
index 29e3bd9f..0ca3ed06 100644
--- a/src/core/ao_log_mini.c
+++ b/src/kernel/ao_log_mini.c
@@ -20,7 +20,6 @@
#include <ao_data.h>
#include <ao_flight.h>
-static __xdata uint8_t ao_log_mutex;
static __xdata struct ao_log_mini log;
__code uint8_t ao_log_format = AO_LOG_FORMAT;
diff --git a/src/core/ao_log_single.c b/src/kernel/ao_log_single.c
index 3f6235a6..3f6235a6 100644
--- a/src/core/ao_log_single.c
+++ b/src/kernel/ao_log_single.c
diff --git a/src/core/ao_log_telem.c b/src/kernel/ao_log_telem.c
index 095aca37..095aca37 100644
--- a/src/core/ao_log_telem.c
+++ b/src/kernel/ao_log_telem.c
diff --git a/src/core/ao_log_telescience.c b/src/kernel/ao_log_telescience.c
index 002a10bd..002a10bd 100644
--- a/src/core/ao_log_telescience.c
+++ b/src/kernel/ao_log_telescience.c
diff --git a/src/core/ao_log_tiny.c b/src/kernel/ao_log_tiny.c
index 67767dc9..67767dc9 100644
--- a/src/core/ao_log_tiny.c
+++ b/src/kernel/ao_log_tiny.c
diff --git a/src/core/ao_microflight.c b/src/kernel/ao_microflight.c
index f680e400..f680e400 100644
--- a/src/core/ao_microflight.c
+++ b/src/kernel/ao_microflight.c
diff --git a/src/core/ao_microkalman.c b/src/kernel/ao_microkalman.c
index 0684ea2b..0684ea2b 100644
--- a/src/core/ao_microkalman.c
+++ b/src/kernel/ao_microkalman.c
diff --git a/src/core/ao_monitor.c b/src/kernel/ao_monitor.c
index 18f170b4..18f170b4 100644
--- a/src/core/ao_monitor.c
+++ b/src/kernel/ao_monitor.c
diff --git a/src/core/ao_mutex.c b/src/kernel/ao_mutex.c
index 952ff462..952ff462 100644
--- a/src/core/ao_mutex.c
+++ b/src/kernel/ao_mutex.c
diff --git a/src/core/ao_notask.c b/src/kernel/ao_notask.c
index 6f967e6d..6f967e6d 100644
--- a/src/core/ao_notask.c
+++ b/src/kernel/ao_notask.c
diff --git a/src/core/ao_notask.h b/src/kernel/ao_notask.h
index 6b6b5bb8..6b6b5bb8 100644
--- a/src/core/ao_notask.h
+++ b/src/kernel/ao_notask.h
diff --git a/src/core/ao_packet.h b/src/kernel/ao_packet.h
index b8426cf9..b8426cf9 100644
--- a/src/core/ao_packet.h
+++ b/src/kernel/ao_packet.h
diff --git a/src/core/ao_panic.c b/src/kernel/ao_panic.c
index c29cd8fe..c29cd8fe 100644
--- a/src/core/ao_panic.c
+++ b/src/kernel/ao_panic.c
diff --git a/src/core/ao_product.c b/src/kernel/ao_product.c
index b9327bac..b9327bac 100644
--- a/src/core/ao_product.c
+++ b/src/kernel/ao_product.c
diff --git a/src/core/ao_pyro.c b/src/kernel/ao_pyro.c
index e59f5bc4..85d88d98 100644
--- a/src/core/ao_pyro.c
+++ b/src/kernel/ao_pyro.c
@@ -213,7 +213,7 @@ ao_pyro_pins_fire(uint16_t fire)
if (fire & (1 << p))
ao_pyro_pin_set(p, 1);
}
- ao_delay(AO_MS_TO_TICKS(50));
+ ao_delay(ao_config.pyro_time);
for (p = 0; p < AO_PYRO_NUM; p++) {
if (fire & (1 << p)) {
ao_pyro_pin_set(p, 0);
@@ -281,7 +281,7 @@ ao_pyro_check(void)
#define NO_VALUE 0xff
-#define AO_PYRO_NAME_LEN 3
+#define AO_PYRO_NAME_LEN 4
#if !DISABLE_HELP
#define ENABLE_HELP 1
@@ -403,7 +403,10 @@ ao_pyro_show(void)
if (ao_pyro_values[v].offset != NO_VALUE) {
int16_t value;
- value = *((int16_t *) ((char *) pyro + ao_pyro_values[v].offset));
+ if (ao_pyro_values[v].flag & AO_PYRO_8_BIT_VALUE)
+ value = *((uint8_t *) ((char *) pyro + ao_pyro_values[v].offset));
+ else
+ value = *((int16_t *) ((char *) pyro + ao_pyro_values[v].offset));
printf ("%6d ", value);
} else {
printf (" ");
@@ -467,7 +470,10 @@ ao_pyro_set(void)
ao_cmd_decimal();
if (ao_cmd_status != ao_cmd_success)
return;
- *((int16_t *) ((char *) &pyro_tmp + ao_pyro_values[v].offset)) = ao_cmd_lex_i;
+ if (ao_pyro_values[v].flag & AO_PYRO_8_BIT_VALUE)
+ *((uint8_t *) ((char *) &pyro_tmp + ao_pyro_values[v].offset)) = ao_cmd_lex_i;
+ else
+ *((int16_t *) ((char *) &pyro_tmp + ao_pyro_values[v].offset)) = ao_cmd_lex_i;
}
}
_ao_config_edit_start();
diff --git a/src/core/ao_pyro.h b/src/kernel/ao_pyro.h
index 0c5642d6..b37aaeb1 100644
--- a/src/core/ao_pyro.h
+++ b/src/kernel/ao_pyro.h
@@ -45,7 +45,11 @@ enum ao_pyro_flag {
ao_pyro_state_less = 0x00004000,
ao_pyro_state_greater_or_equal = 0x00008000,
-};
+}
+#ifdef __GNUC__
+ __attribute__ ((packed))
+#endif
+ ;
struct ao_pyro {
enum ao_pyro_flag flags;
@@ -61,6 +65,8 @@ struct ao_pyro {
uint8_t fired;
};
+#define AO_PYRO_8_BIT_VALUE (ao_pyro_state_less|ao_pyro_state_greater_or_equal)
+
extern uint8_t ao_pyro_wakeup;
extern uint16_t ao_pyro_fired;
diff --git a/src/core/ao_quaternion.h b/src/kernel/ao_quaternion.h
index 044f1607..044f1607 100644
--- a/src/core/ao_quaternion.h
+++ b/src/kernel/ao_quaternion.h
diff --git a/src/core/ao_radio_cmac.c b/src/kernel/ao_radio_cmac.c
index bff848f6..bff848f6 100644
--- a/src/core/ao_radio_cmac.c
+++ b/src/kernel/ao_radio_cmac.c
diff --git a/src/core/ao_radio_cmac.h b/src/kernel/ao_radio_cmac.h
index e86f31e9..e86f31e9 100644
--- a/src/core/ao_radio_cmac.h
+++ b/src/kernel/ao_radio_cmac.h
diff --git a/src/core/ao_radio_cmac_cmd.c b/src/kernel/ao_radio_cmac_cmd.c
index 64410921..64410921 100644
--- a/src/core/ao_radio_cmac_cmd.c
+++ b/src/kernel/ao_radio_cmac_cmd.c
diff --git a/src/core/ao_radio_cmac_cmd.h b/src/kernel/ao_radio_cmac_cmd.h
index 6b8782de..6b8782de 100644
--- a/src/core/ao_radio_cmac_cmd.h
+++ b/src/kernel/ao_radio_cmac_cmd.h
diff --git a/src/core/ao_report.c b/src/kernel/ao_report.c
index 1104cd82..f2263154 100644
--- a/src/core/ao_report.c
+++ b/src/kernel/ao_report.c
@@ -52,6 +52,60 @@ static const uint8_t flight_reports[] = {
static __pdata enum ao_flight_state ao_report_state;
+/*
+ * Farnsworth spacing
+ *
+ * From: http://www.arrl.org/files/file/Technology/x9004008.pdf
+ *
+ * c: character rate in wpm
+ * s: overall rate in wpm
+ * u: unit rate (dit speed)
+ *
+ * dit: u
+ * dah: 3u
+ * intra-character-time: u
+ *
+ * u = 1.2/c
+ *
+ * Because our clock runs at 10ms, we'll round up to 70ms for u, which
+ * is about 17wpm
+ *
+ * Farnsworth adds space between characters and
+ * words:
+ * 60 c - 37.2 s
+ * Ta = -------------
+ * sc
+ *
+ * 3 Ta
+ * Tc = ----
+ * 19
+ *
+ * 7 Ta
+ * Tw = ----
+ * 19
+ *
+ * Ta = total delay to add to the characters (31 units)
+ * of a standard 50-unit "word", in seconds
+ *
+ * Tc = period between characters, in seconds
+ *
+ * Tw = period between words, in seconds
+ *
+ * We'll use Farnsworth spacing with c=18 and s=12:
+ *
+ * u = 1.2/18 = 0.0667
+ *
+ * Ta = (60 * 17 - 37.2 * 12) / (17 * 12) = 2.812
+ *
+ * Tc = 3 * Ta / 19 = .444
+ *
+ * Tw = 1.036
+ *
+ * Note that the values below are all reduced by 10ms; that's because
+ * the timer always adds a tick to make sure the task actually sleeps
+ * at least as long as the argument.
+ */
+
static void
ao_report_beep(void) __reentrant
{
@@ -62,13 +116,13 @@ ao_report_beep(void) __reentrant
return;
while (l--) {
if (r & 8)
- mid(AO_MS_TO_TICKS(600));
- else
mid(AO_MS_TO_TICKS(200));
- pause(AO_MS_TO_TICKS(200));
+ else
+ mid(AO_MS_TO_TICKS(60));
+ pause(AO_MS_TO_TICKS(60));
r >>= 1;
}
- pause(AO_MS_TO_TICKS(400));
+ pause(AO_MS_TO_TICKS(360));
}
static void
@@ -87,19 +141,18 @@ ao_report_digit(uint8_t digit) __reentrant
}
static void
-ao_report_altitude(void)
+ao_report_number(int16_t n)
{
- __pdata int16_t agl = ao_max_height;
__xdata uint8_t digits[10];
__pdata uint8_t ndigits, i;
- if (agl < 0)
- agl = 0;
+ if (n < 0)
+ n = 0;
ndigits = 0;
do {
- digits[ndigits++] = agl % 10;
- agl /= 10;
- } while (agl);
+ digits[ndigits++] = n % 10;
+ n /= 10;
+ } while (n);
i = ndigits;
do
@@ -107,6 +160,27 @@ ao_report_altitude(void)
while (i != 0);
}
+static void
+ao_report_altitude(void)
+{
+ ao_report_number(ao_max_height);
+}
+
+#if HAS_BATTERY_REPORT
+static void
+ao_report_battery(void)
+{
+ __xdata struct ao_data packet;
+ for (;;) {
+ ao_data_get(&packet);
+ if (packet.adc.v_batt != 0)
+ break;
+ ao_sleep(DATA_TO_XDATA(&ao_sample_data));
+ }
+ ao_report_number(ao_battery_decivolt(packet.adc.v_batt));
+}
+#endif
+
#if HAS_IGNITE_REPORT
static uint8_t
ao_report_igniter_ready(enum ao_igniter igniter)
@@ -163,7 +237,12 @@ ao_report(void)
{
ao_report_state = ao_flight_state;
for(;;) {
- ao_report_beep();
+#if HAS_BATTERY_REPORT
+ if (ao_flight_state == ao_flight_startup)
+ ao_report_battery();
+ else
+#endif
+ ao_report_beep();
if (ao_flight_state == ao_flight_landed) {
ao_report_altitude();
#if HAS_FLIGHT
diff --git a/src/core/ao_report_micro.c b/src/kernel/ao_report_micro.c
index 0e8e287f..0e8e287f 100644
--- a/src/core/ao_report_micro.c
+++ b/src/kernel/ao_report_micro.c
diff --git a/src/core/ao_rssi.c b/src/kernel/ao_rssi.c
index 244a84fe..244a84fe 100644
--- a/src/core/ao_rssi.c
+++ b/src/kernel/ao_rssi.c
diff --git a/src/core/ao_sample.c b/src/kernel/ao_sample.c
index 34658951..34658951 100644
--- a/src/core/ao_sample.c
+++ b/src/kernel/ao_sample.c
diff --git a/src/core/ao_sample.h b/src/kernel/ao_sample.h
index 16d4c507..16d4c507 100644
--- a/src/core/ao_sample.h
+++ b/src/kernel/ao_sample.h
diff --git a/src/core/ao_sample_profile.c b/src/kernel/ao_sample_profile.c
index d3743d12..d3743d12 100644
--- a/src/core/ao_sample_profile.c
+++ b/src/kernel/ao_sample_profile.c
diff --git a/src/core/ao_sample_profile.h b/src/kernel/ao_sample_profile.h
index dbc29d3d..dbc29d3d 100644
--- a/src/core/ao_sample_profile.h
+++ b/src/kernel/ao_sample_profile.h
diff --git a/src/core/ao_send_packet.c b/src/kernel/ao_send_packet.c
index 66315d22..66315d22 100644
--- a/src/core/ao_send_packet.c
+++ b/src/kernel/ao_send_packet.c
diff --git a/src/core/ao_send_packet.h b/src/kernel/ao_send_packet.h
index 526f7b55..526f7b55 100644
--- a/src/core/ao_send_packet.h
+++ b/src/kernel/ao_send_packet.h
diff --git a/src/core/ao_serial.h b/src/kernel/ao_serial.h
index baf213c0..baf213c0 100644
--- a/src/core/ao_serial.h
+++ b/src/kernel/ao_serial.h
diff --git a/src/core/ao_sqrt.c b/src/kernel/ao_sqrt.c
index 3a550eaa..3a550eaa 100644
--- a/src/core/ao_sqrt.c
+++ b/src/kernel/ao_sqrt.c
diff --git a/src/core/ao_state.c b/src/kernel/ao_state.c
index ed197aa5..ed197aa5 100644
--- a/src/core/ao_state.c
+++ b/src/kernel/ao_state.c
diff --git a/src/core/ao_stdio.c b/src/kernel/ao_stdio.c
index cd144d6b..99118137 100644
--- a/src/core/ao_stdio.c
+++ b/src/kernel/ao_stdio.c
@@ -51,6 +51,9 @@
#ifndef USE_SERIAL_9_STDIN
#define USE_SERIAL_9_STDIN 0
#endif
+#ifndef PACKET_HAS_SLAVE
+#define PACKET_HAS_SLAVE 0
+#endif
#define USE_SERIAL_STDIN (USE_SERIAL_0_STDIN + \
USE_SERIAL_1_STDIN + \
diff --git a/src/core/ao_storage.c b/src/kernel/ao_storage.c
index 6eddae7f..6eddae7f 100644
--- a/src/core/ao_storage.c
+++ b/src/kernel/ao_storage.c
diff --git a/src/core/ao_storage.h b/src/kernel/ao_storage.h
index 6cc6fcb7..6cc6fcb7 100644
--- a/src/core/ao_storage.h
+++ b/src/kernel/ao_storage.h
diff --git a/src/core/ao_task.c b/src/kernel/ao_task.c
index bafb4943..bafb4943 100644
--- a/src/core/ao_task.c
+++ b/src/kernel/ao_task.c
diff --git a/src/core/ao_task.h b/src/kernel/ao_task.h
index 9c56b480..9c56b480 100644
--- a/src/core/ao_task.h
+++ b/src/kernel/ao_task.h
diff --git a/src/core/ao_telem.h b/src/kernel/ao_telem.h
index 1a8da291..1a8da291 100644
--- a/src/core/ao_telem.h
+++ b/src/kernel/ao_telem.h
diff --git a/src/core/ao_telemetry.c b/src/kernel/ao_telemetry.c
index 5a00d825..9f778b09 100644
--- a/src/core/ao_telemetry.c
+++ b/src/kernel/ao_telemetry.c
@@ -187,7 +187,9 @@ ao_send_metrum_sensor(void)
telemetry.generic.type = AO_TELEMETRY_METRUM_SENSOR;
telemetry.metrum_sensor.state = ao_flight_state;
+#if HAS_ACCEL
telemetry.metrum_sensor.accel = ao_data_accel(packet);
+#endif
telemetry.metrum_sensor.pres = ao_data_pres(packet);
telemetry.metrum_sensor.temp = ao_data_temp(packet);
@@ -216,9 +218,15 @@ ao_send_metrum_data(void)
telemetry.generic.type = AO_TELEMETRY_METRUM_DATA;
telemetry.metrum_data.ground_pres = ao_ground_pres;
+#if HAS_ACCEL
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;
+#else
+ telemetry.metrum_data.ground_accel = 1;
+ telemetry.metrum_data.accel_plus_g = 0;
+ telemetry.metrum_data.accel_minus_g = 2;
+#endif
ao_radio_send(&telemetry, sizeof (telemetry));
ao_telemetry_metrum_data_cur = ao_telemetry_metrum_data_max;
@@ -297,8 +305,14 @@ ao_send_configuration(void)
#endif
telemetry.configuration.config_major = AO_CONFIG_MAJOR;
telemetry.configuration.config_minor = AO_CONFIG_MINOR;
+#if AO_idProduct_NUMBER == 0x25 && HAS_ADC
+ /* TeleGPS gets battery voltage instead of apogee delay */
+ telemetry.configuration.apogee_delay = ao_data_ring[ao_data_ring_prev(ao_data_head)].adc.v_batt;
+#else
telemetry.configuration.apogee_delay = ao_config.apogee_delay;
telemetry.configuration.main_deploy = ao_config.main_deploy;
+#endif
+
telemetry.configuration.flight_log_max = ao_config.flight_log_max >> 10;
ao_xmemcpy (telemetry.configuration.callsign,
ao_config.callsign,
diff --git a/src/core/ao_telemetry.h b/src/kernel/ao_telemetry.h
index 237a35ab..be7d0340 100644
--- a/src/core/ao_telemetry.h
+++ b/src/kernel/ao_telemetry.h
@@ -115,7 +115,7 @@ struct ao_telemetry_location {
uint16_t ground_speed; /* 26 cm/s */
int16_t climb_rate; /* 28 cm/s */
uint8_t course; /* 30 degrees / 2 */
- uint8_t unused[1]; /* 31 */
+ uint8_t unused; /* 31 unused */
/* 32 */
};
@@ -154,7 +154,7 @@ struct ao_telemetry_companion {
uint16_t companion_data[AO_COMPANION_MAX_CHANNELS]; /* 8 */
/* 32 */
};
-
+
#define AO_TELEMETRY_MEGA_SENSOR 0x08
struct ao_telemetry_mega_sensor {
@@ -181,7 +181,7 @@ struct ao_telemetry_mega_sensor {
int16_t mag_z; /* 30 */
/* 32 */
};
-
+
#define AO_TELEMETRY_MEGA_DATA 0x09
struct ao_telemetry_mega_data {
@@ -231,7 +231,7 @@ struct ao_telemetry_metrum_sensor {
uint8_t pad[6]; /* 26 */
/* 32 */
};
-
+
#define AO_TELEMETRY_METRUM_DATA 0x0B
struct ao_telemetry_metrum_data {
diff --git a/src/kernel/ao_tracker.c b/src/kernel/ao_tracker.c
new file mode 100644
index 00000000..9febc7f0
--- /dev/null
+++ b/src/kernel/ao_tracker.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright © 2014 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_flight.h>
+#include <ao_log.h>
+#include <ao_log_gps.h>
+#include <ao_distance.h>
+#include <ao_tracker.h>
+#include <ao_exti.h>
+
+static uint8_t ao_tracker_force_telem;
+
+#if HAS_USB_CONNECT
+static inline uint8_t
+ao_usb_connected(void)
+{
+ return ao_gpio_get(AO_USB_CONNECT_PORT, AO_USB_CONNECT_PIN, AO_USB_CONNECT) != 0;
+}
+#else
+#define ao_usb_connected() 1
+#endif
+
+struct gps_position {
+ int32_t latitude;
+ int32_t longitude;
+ int16_t altitude;
+};
+
+#define GPS_RING 16
+
+struct gps_position gps_position[GPS_RING];
+
+#define ao_gps_ring_next(n) (((n) + 1) & (GPS_RING - 1))
+#define ao_gps_ring_prev(n) (((n) - 1) & (GPS_RING - 1))
+
+static uint8_t gps_head;
+
+static uint8_t tracker_mutex;
+static uint8_t log_started;
+static struct ao_telemetry_location gps_data;
+static uint8_t tracker_running;
+static uint16_t tracker_interval;
+
+static void
+ao_tracker(void)
+{
+ uint8_t new;
+ int32_t ground_distance;
+ int16_t height;
+ uint16_t gps_tick;
+ uint8_t new_tracker_running;
+
+#if HAS_ADC
+ ao_timer_set_adc_interval(100);
+#endif
+
+#if !HAS_USB_CONNECT
+ ao_tracker_force_telem = 1;
+#endif
+ ao_log_scan();
+
+ ao_rdf_set(1);
+
+ tracker_interval = ao_config.tracker_interval;
+ ao_gps_set_rate(tracker_interval);
+
+ for (;;) {
+
+ /** Wait for new GPS data
+ */
+ while (!(new = ao_gps_new))
+ ao_sleep(&ao_gps_new);
+ ao_mutex_get(&ao_gps_mutex);
+ gps_data = ao_gps_data;
+ gps_tick = ao_gps_tick;
+ ao_gps_new = 0;
+ ao_mutex_put(&ao_gps_mutex);
+
+ new_tracker_running = ao_tracker_force_telem || !ao_usb_connected();
+
+ if (ao_config.tracker_interval != tracker_interval) {
+ tracker_interval = ao_config.tracker_interval;
+ ao_gps_set_rate(tracker_interval);
+
+ /* force telemetry interval to be reset */
+ tracker_running = 0;
+ }
+
+ if (new_tracker_running && !tracker_running)
+ ao_telemetry_set_interval(AO_SEC_TO_TICKS(tracker_interval));
+ else if (!new_tracker_running && tracker_running)
+ ao_telemetry_set_interval(0);
+
+ tracker_running = new_tracker_running;
+
+ if (new_tracker_running && !ao_log_running)
+ ao_log_start();
+ else if (!new_tracker_running && ao_log_running)
+ ao_log_stop();
+
+ if (!ao_log_running)
+ continue;
+
+ if (new & AO_GPS_NEW_DATA) {
+ if ((gps_data.flags & (AO_GPS_VALID|AO_GPS_COURSE_VALID)) ==
+ (AO_GPS_VALID|AO_GPS_COURSE_VALID))
+ {
+ uint8_t ring;
+ uint8_t moving = 0;
+
+ for (ring = ao_gps_ring_next(gps_head); ring != gps_head; ring = ao_gps_ring_next(ring)) {
+ ground_distance = ao_distance(gps_data.latitude, gps_data.longitude,
+ gps_position[ring].latitude,
+ gps_position[ring].longitude);
+ height = gps_position[ring].altitude - gps_data.altitude;
+ if (height < 0)
+ height = -height;
+
+ if (ao_tracker_force_telem)
+ printf("head %d ring %d ground_distance %d height %d\n", gps_head, ring, ground_distance, height);
+ if (ground_distance > ao_config.tracker_motion ||
+ height > (ao_config.tracker_motion << 1))
+ {
+ moving = 1;
+ break;
+ }
+ }
+ if (ao_tracker_force_telem) {
+ printf ("moving %d started %d\n", moving, log_started);
+ flush();
+ }
+ if (moving) {
+ ao_mutex_get(&tracker_mutex);
+ if (!log_started) {
+ ao_log_gps_flight();
+ log_started = 1;
+ }
+ ao_log_gps_data(gps_tick, &gps_data);
+ gps_position[gps_head].latitude = gps_data.latitude;
+ gps_position[gps_head].longitude = gps_data.longitude;
+ gps_position[gps_head].altitude = gps_data.altitude;
+ gps_head = ao_gps_ring_next(gps_head);
+ ao_mutex_put(&tracker_mutex);
+ }
+ }
+ }
+ }
+}
+
+static uint8_t erasing_current;
+
+void
+ao_tracker_erase_start(uint16_t flight)
+{
+ erasing_current = flight == ao_flight_number;
+ if (erasing_current) {
+ ao_mutex_get(&tracker_mutex);
+ ao_log_stop();
+ if (++ao_flight_number == 0)
+ ao_flight_number = 1;
+ }
+}
+
+void
+ao_tracker_erase_end(void)
+{
+ if (erasing_current) {
+ ao_log_scan();
+ log_started = 0;
+ ao_mutex_put(&tracker_mutex);
+ }
+}
+
+static struct ao_task ao_tracker_task;
+
+static void
+ao_tracker_set_telem(void)
+{
+ uint8_t telem;
+ ao_cmd_hex();
+ telem = ao_cmd_lex_i;
+ if (ao_cmd_status == ao_cmd_success)
+ ao_tracker_force_telem = telem;
+ ao_cmd_status = ao_cmd_success;
+ printf ("flight: %d\n", ao_flight_number);
+ printf ("force_telem: %d\n", ao_tracker_force_telem);
+ printf ("tracker_running: %d\n", tracker_running);
+ printf ("log_started: %d\n", log_started);
+ printf ("latitude: %ld\n", (long) gps_data.latitude);
+ printf ("longitude: %ld\n", (long) gps_data.longitude);
+ printf ("altitude: %d\n", gps_data.altitude);
+ printf ("log_running: %d\n", ao_log_running);
+ printf ("log_start_pos: %ld\n", (long) ao_log_start_pos);
+ printf ("log_cur_pos: %ld\n", (long) ao_log_current_pos);
+ printf ("log_end_pos: %ld\n", (long) ao_log_end_pos);
+}
+
+static const struct ao_cmds ao_tracker_cmds[] = {
+ { ao_tracker_set_telem, "t <d>\0Set telem on USB" },
+ { 0, NULL },
+};
+
+void
+ao_tracker_init(void)
+{
+#if HAS_USB_CONNECT
+ ao_enable_input(AO_USB_CONNECT_PORT, AO_USB_CONNECT_PIN, 0);
+#endif
+ ao_cmd_register(&ao_tracker_cmds[0]);
+ ao_add_task(&ao_tracker_task, ao_tracker, "tracker");
+}
diff --git a/src/kernel/ao_tracker.h b/src/kernel/ao_tracker.h
new file mode 100644
index 00000000..78c40cb4
--- /dev/null
+++ b/src/kernel/ao_tracker.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2014 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_TRACKER_H_
+#define _AO_TRACKER_H_
+
+/* Any motion more than this will result in a log entry */
+
+#define AO_TRACKER_MOTION_DEFAULT 10
+#define AO_TRACKER_INTERVAL_DEFAULT 1
+
+#define AO_TRACKER_MOTION_COUNT 10
+
+void
+ao_tracker_init(void);
+
+void
+ao_tracker_erase_start(uint16_t flight);
+
+void
+ao_tracker_erase_end(void);
+
+#endif /* _AO_TRACKER_H_ */
diff --git a/src/core/ao_usb.h b/src/kernel/ao_usb.h
index 35e64e65..1ce4f82f 100644
--- a/src/core/ao_usb.h
+++ b/src/kernel/ao_usb.h
@@ -137,4 +137,6 @@ struct ao_usb_line_coding {
uint8_t data_bits;
} ;
+extern __pdata uint8_t ao_usb_running;
+
#endif /* _AO_USB_H_ */
diff --git a/src/lpc/Makefile-lpc.defs b/src/lpc/Makefile-lpc.defs
index fecb9135..bccea5bc 100644
--- a/src/lpc/Makefile-lpc.defs
+++ b/src/lpc/Makefile-lpc.defs
@@ -4,7 +4,7 @@ endif
include $(TOPDIR)/Makedefs
-vpath % $(TOPDIR)/lpc:$(TOPDIR)/product:$(TOPDIR)/drivers:$(TOPDIR)/core:$(TOPDIR)/util:$(TOPDIR)/kalman:$(TOPDIR/aes):$(TOPDIR):$(TOPDIR)/math
+vpath % $(TOPDIR)/lpc:$(TOPDIR)/product:$(TOPDIR)/drivers:$(TOPDIR)/kernel:$(TOPDIR)/util:$(TOPDIR)/kalman:$(TOPDIR/aes):$(TOPDIR):$(TOPDIR)/math
vpath make-altitude $(TOPDIR)/util
vpath make-kalman $(TOPDIR)/util
vpath kalman.5c $(TOPDIR)/kalman
@@ -28,7 +28,7 @@ CC=$(ARM_CC)
WARN_FLAGS=-Wall -Wextra -Werror
-AO_CFLAGS=-I. -I$(TOPDIR)/lpc -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) -I$(TOPDIR)/math -I$(TOPDIR) $(PDCLIB_INCLUDES)
+AO_CFLAGS=-I. -I$(TOPDIR)/lpc -I$(TOPDIR)/kernel -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) -I$(TOPDIR)/math -I$(TOPDIR) $(PDCLIB_INCLUDES)
LPC_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m0 -mthumb\
-ffreestanding -nostdlib $(AO_CFLAGS) $(WARN_FLAGS)
diff --git a/src/lpc/ao_adc_lpc.c b/src/lpc/ao_adc_lpc.c
index e1aae0e4..b24163ee 100644
--- a/src/lpc/ao_adc_lpc.c
+++ b/src/lpc/ao_adc_lpc.c
@@ -160,7 +160,7 @@ ao_adc_dump(void) __reentrant
#else
printf("tick: %5u", packet.tick);
d = (int16_t *) (&packet.adc);
- for (i = 0; i < AO_NUM_ADC; i++)
+ for (i = 0; i < AO_ADC_NUM; i++)
printf (" %2d: %5d", i, d[i]);
printf("\n");
#endif
diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h
index d04bf2c8..5fbb8dfa 100644
--- a/src/lpc/ao_arch.h
+++ b/src/lpc/ao_arch.h
@@ -28,10 +28,10 @@
#define AO_STACK_SIZE 512
#endif
-#define AO_LED_TYPE uint16_t
-
#define AO_PORT_TYPE uint32_t
+#define AO_LED_TYPE AO_PORT_TYPE
+
#ifndef AO_TICK_TYPE
#define AO_TICK_TYPE uint16_t
#define AO_TICK_SIGNED int16_t
@@ -140,7 +140,12 @@ ao_serial_init(void);
#define AO_SPI_SPEED_FAST AO_SPI_SPEED_12MHz
#define AO_BOOT_APPLICATION_BASE ((uint32_t *) 0x00001000)
+#define AO_BOOT_APPLICATION_BOUND ((uint32_t *) (0x00000000 + 32 * 1024))
#define AO_BOOT_LOADER_BASE ((uint32_t *) 0x00000000)
#define HAS_BOOT_LOADER 1
+/* ADC definitions */
+
+#define AO_ADC_MAX 32767
+
#endif /* _AO_ARCH_H_ */
diff --git a/src/lpc/ao_boot_chain.c b/src/lpc/ao_boot_chain.c
index a08d1f2c..9e45ba27 100644
--- a/src/lpc/ao_boot_chain.c
+++ b/src/lpc/ao_boot_chain.c
@@ -43,14 +43,14 @@ struct ao_boot {
};
static struct ao_boot __attribute__ ((section(".boot"))) ao_boot;
-
+
int
ao_boot_check_chain(void)
{
if (ao_boot.signal == AO_BOOT_SIGNAL && ao_boot.check == AO_BOOT_CHECK) {
ao_boot.signal = 0;
ao_boot.check = 0;
- if (ao_boot.base == 0)
+ if (ao_boot.base == AO_BOOT_FORCE_LOADER)
return 0;
ao_boot_chain(ao_boot.base);
}
diff --git a/src/lpc/ao_exti_lpc.c b/src/lpc/ao_exti_lpc.c
index 941aa965..fdb6a1ca 100644
--- a/src/lpc/ao_exti_lpc.c
+++ b/src/lpc/ao_exti_lpc.c
@@ -69,7 +69,7 @@ _ao_exti_set_enable(uint8_t pint)
lpc_gpio_pin.sienr = mask;
else
lpc_gpio_pin.cienr = mask;
-
+
if (mode & AO_EXTI_MODE_FALLING)
lpc_gpio_pin.sienf = mask;
else
@@ -98,7 +98,7 @@ ao_exti_setup (uint8_t port, uint8_t pin, uint8_t mode, void (*callback)(void))
mask = (1 << pint);
ao_pint_inuse |= mask;
ao_pint_enabled &= ~mask;
-
+
ao_pint_map[id] = pint;
ao_exti_callback[pint] = callback;
diff --git a/src/lpc/ao_interrupt.c b/src/lpc/ao_interrupt.c
index c4dc7867..3318db2b 100644
--- a/src/lpc/ao_interrupt.c
+++ b/src/lpc/ao_interrupt.c
@@ -172,5 +172,5 @@ const void *lpc_interrupt_vector[] = {
i(0xb0, hardfault), /* IRQ28 */
i(0xb4, hardfault),
i(0xb8, usb_wakeup),
- i(0xbc, hardfault),
+ i(0xbc, hardfault),
};
diff --git a/src/lpc/ao_led_lpc.c b/src/lpc/ao_led_lpc.c
index 7bef51ba..d983437c 100644
--- a/src/lpc/ao_led_lpc.c
+++ b/src/lpc/ao_led_lpc.c
@@ -17,38 +17,38 @@
#include <ao.h>
-__pdata uint16_t ao_led_enable;
+__pdata AO_PORT_TYPE ao_led_enable;
void
-ao_led_on(uint16_t colors)
+ao_led_on(AO_PORT_TYPE colors)
{
lpc_gpio.pin[LED_PORT] |= colors;
}
void
-ao_led_off(uint16_t colors)
+ao_led_off(AO_PORT_TYPE colors)
{
lpc_gpio.pin[LED_PORT] &= ~colors;
}
void
-ao_led_set(uint16_t colors)
+ao_led_set(AO_PORT_TYPE colors)
{
- uint16_t on = colors & ao_led_enable;
- uint16_t off = ~colors & ao_led_enable;
+ AO_PORT_TYPE on = colors & ao_led_enable;
+ AO_PORT_TYPE off = ~colors & ao_led_enable;
ao_led_off(off);
ao_led_on(on);
}
void
-ao_led_toggle(uint16_t colors)
+ao_led_toggle(AO_PORT_TYPE colors)
{
lpc_gpio.pin[LED_PORT] ^= colors;
}
void
-ao_led_for(uint16_t colors, uint16_t ticks) __reentrant
+ao_led_for(AO_PORT_TYPE colors, uint16_t ticks) __reentrant
{
ao_led_on(colors);
ao_delay(ticks);
@@ -56,10 +56,8 @@ ao_led_for(uint16_t colors, uint16_t ticks) __reentrant
}
void
-ao_led_init(uint16_t enable)
+ao_led_init(AO_PORT_TYPE enable)
{
- int bit;
-
ao_led_enable = enable;
lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_GPIO);
lpc_gpio.dir[LED_PORT] |= enable;
diff --git a/src/lpc/ao_serial_lpc.c b/src/lpc/ao_serial_lpc.c
index 431ae98a..b0d5fcbc 100644
--- a/src/lpc/ao_serial_lpc.c
+++ b/src/lpc/ao_serial_lpc.c
@@ -206,8 +206,8 @@ ao_serial_init(void)
lpc_nvic_set_enable(LPC_ISR_USART_POS);
lpc_nvic_set_priority(LPC_ISR_USART_POS, 0);
#if USE_SERIAL_0_STDIN
- ao_add_stdio(_ao_serial_pollchar,
- ao_serial_putchar,
+ ao_add_stdio(_ao_serial0_pollchar,
+ ao_serial0_putchar,
NULL);
#endif
}
diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c
index d02ccdd6..12f5d8e6 100644
--- a/src/lpc/ao_usb_lpc.c
+++ b/src/lpc/ao_usb_lpc.c
@@ -109,7 +109,7 @@ static uint8_t ao_usb_in_pending;
* but not pulled to the shadow buffer.
*/
static uint8_t ao_usb_out_avail;
-static uint8_t ao_usb_running;
+uint8_t ao_usb_running;
static uint8_t ao_usb_configuration;
#define AO_USB_EP0_GOT_RESET 1
@@ -875,7 +875,7 @@ ao_usb_enable(void)
int t;
/* Enable USB pins */
-#if HAS_USB_CONNECT
+#if HAS_LPC_USB_CONNECT
lpc_ioconf.pio0_6 = ((LPC_IOCONF_FUNC_USB_CONNECT << LPC_IOCONF_FUNC) |
(LPC_IOCONF_MODE_INACTIVE << LPC_IOCONF_MODE) |
(0 << LPC_IOCONF_HYS) |
diff --git a/src/lpcxpresso/ao_pins.h b/src/lpcxpresso/ao_pins.h
index c0074ce2..0ffc2fad 100644
--- a/src/lpcxpresso/ao_pins.h
+++ b/src/lpcxpresso/ao_pins.h
@@ -16,7 +16,6 @@
*/
#define HAS_BEEP 0
-#define HAS_LED 1
/* Crystal on the board */
#define AO_LPC_CLKIN 12000000
diff --git a/src/megadongle-v0.1/Makefile b/src/megadongle-v0.1/Makefile
index 6035c348..ade8e496 100644
--- a/src/megadongle-v0.1/Makefile
+++ b/src/megadongle-v0.1/Makefile
@@ -9,6 +9,7 @@ INC = \
ao.h \
ao_arch.h \
ao_arch_funcs.h \
+ ao_boot.h \
ao_pins.h \
ao_product.h \
ao_cc1120_CC1120.h \
diff --git a/src/micropeak/Makefile b/src/micropeak/Makefile
index dcc32874..6ae3d0be 100644
--- a/src/micropeak/Makefile
+++ b/src/micropeak/Makefile
@@ -2,12 +2,15 @@
# Tiny AltOS build
#
#
-vpath % ../attiny:../drivers:../core:../product:..
+vpath % ../attiny:../drivers:../kernel:../product:..
vpath ao-make-product.5c ../util
vpath make-altitude-pa ../util
include ../avr/Makefile.defs
+PUBLISH_DIR=$(HOME)/altusmetrumllc/Binaries
+PUBLISH_FILE=$(PUBLISH_DIR)/$(PROG)-$(VERSION).hex
+
MCU=attiny85
DUDECPUTYPE=t85
#PROGRAMMER=stk500v2 -P usb
@@ -47,7 +50,7 @@ INC=\
IDPRODUCT=0
PRODUCT=MicroPeak-v0.1
PRODUCT_DEF=-DMICROPEAK
-CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../core -I.. -I../drivers -I../product
+CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../kernel -I.. -I../drivers -I../product
CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTINY
NICKLE=nickle
@@ -98,6 +101,16 @@ clean:
rm -f *.o $(PROG) $(PROG).hex
rm -f ao_product.h
+
+publish: $(PROG).hex
+ cp -a $(PROG).hex $(PUBLISH_FILE)
+
+load-product:
+ $(LOADCMD) $(LOADARG)$(PUBLISH_FILE)
+
+load-product-slow:
+ $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PUBLISH_FILE)
+
../altitude-pa.h: make-altitude-pa
nickle $< > $@
diff --git a/src/microwater/.gitignore b/src/microwater/.gitignore
new file mode 100644
index 00000000..0573d989
--- /dev/null
+++ b/src/microwater/.gitignore
@@ -0,0 +1,2 @@
+ao_product.h
+microwater-*
diff --git a/src/microwater/Makefile b/src/microwater/Makefile
new file mode 100644
index 00000000..a49cda4b
--- /dev/null
+++ b/src/microwater/Makefile
@@ -0,0 +1,121 @@
+#
+# Tiny AltOS build
+#
+#
+vpath % ../attiny:../drivers:../kernel:../product:..
+vpath ao-make-product.5c ../util
+vpath make-altitude-pa ../util
+
+include ../avr/Makefile.defs
+
+PUBLISH_DIR=$(HOME)/altusmetrumllc/Binaries
+PUBLISH_FILE=$(PUBLISH_DIR)/$(PROG)-$(VERSION).hex
+
+MCU=attiny85
+DUDECPUTYPE=t85
+#PROGRAMMER=stk500v2 -P usb
+LOADSLOW=-i 32 -B 32
+LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w:
+
+#LDFLAGS=-L$(LDSCRIPTS) -Tavr25.x
+
+ALTOS_SRC = \
+ ao_micropeak.c \
+ ao_spi_attiny.c \
+ ao_led.c \
+ ao_clock.c \
+ ao_ms5607.c \
+ ao_exti.c \
+ ao_convert_pa.c \
+ ao_report_micro.c \
+ ao_notask.c \
+ ao_eeprom_tiny.c \
+ ao_panic.c \
+ ao_log_micro.c \
+ ao_async.c \
+ ao_microflight.c \
+ ao_microkalman.c
+
+INC=\
+ ao.h \
+ ao_pins.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_exti.h \
+ ao_ms5607.h \
+ ao_log_micro.h \
+ ao_micropeak.h \
+ altitude-pa.h
+
+IDPRODUCT=0
+PRODUCT=MicroWater-v0.1
+PRODUCT_DEF=-DMICROPEAK
+CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../kernel -I.. -I../drivers -I../product
+CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTINY
+
+NICKLE=nickle
+
+PROG=microwater-v0.1
+
+SRC=$(ALTOS_SRC)
+OBJ=$(SRC:.c=.o)
+
+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).hex
+
+CHECK=sh ../util/check-avr-mem
+
+$(PROG): Makefile $(OBJ)
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ)
+ $(call quiet,CHECK) $(PROG) || ($(RM) -f $(PROG); exit 1)
+
+$(PROG).hex: $(PROG)
+ avr-size $(PROG)
+ $(OBJCOPY) -R .eeprom -O ihex $(PROG) $@
+
+
+load: $(PROG).hex
+ $(LOADCMD) $(LOADARG)$(PROG).hex
+
+load-slow: $(PROG).hex
+ $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PROG).hex
+
+ao_product.h: ao-make-product.5c ../Version
+ $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
+
+ao_product.o: ao_product.c ao_product.h
+
+%.o : %.c $(INC)
+ $(call quiet,CC) -c $(CFLAGS) $<
+
+distclean: clean
+
+clean:
+ rm -f *.o $(PROG) $(PROG).hex
+ rm -f ao_product.h
+
+
+publish: $(PROG).hex
+ cp -a $(PROG).hex $(PUBLISH_FILE)
+
+load-product:
+ $(LOADCMD) $(LOADARG)$(PUBLISH_FILE)
+
+load-product-slow:
+ $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PUBLISH_FILE)
+
+../altitude-pa.h: make-altitude-pa
+ nickle $< > $@
+
+install:
+
+uninstall:
+
+$(OBJ): ao_product.h $(INC)
diff --git a/src/microwater/ao_pins.h b/src/microwater/ao_pins.h
new file mode 100644
index 00000000..37885ec2
--- /dev/null
+++ b/src/microwater/ao_pins.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+#include <avr/pgmspace.h>
+
+#define AO_LED_ORANGE (1<<4)
+#define AO_LED_SERIAL 4
+#define AO_LED_PANIC AO_LED_ORANGE
+#define AO_LED_REPORT AO_LED_ORANGE
+#define LEDS_AVAILABLE (AO_LED_ORANGE)
+#define USE_SERIAL_1_STDIN 0
+#define HAS_USB 0
+#define PACKET_HAS_SLAVE 0
+#define HAS_SERIAL_1 0
+#define HAS_TASK 0
+#define HAS_MS5607 1
+#define HAS_MS5611 0
+#define HAS_EEPROM 0
+#define HAS_BEEP 0
+#define AVR_CLOCK 250000UL
+
+/* SPI */
+#define SPI_PORT PORTB
+#define SPI_PIN PINB
+#define SPI_DIR DDRB
+#define AO_MS5607_CS_PORT PORTB
+#define AO_MS5607_CS_PIN 3
+
+/* MS5607 */
+#define AO_MS5607_SPI_INDEX 0
+#define AO_MS5607_MISO_PORT PORTB
+#define AO_MS5607_MISO_PIN 0
+#define AO_MS5607_BARO_OVERSAMPLE 4096
+#define AO_MS5607_TEMP_OVERSAMPLE 1024
+
+/* I2C */
+#define I2C_PORT PORTB
+#define I2C_PIN PINB
+#define I2C_DIR DDRB
+#define I2C_PIN_SCL PINB2
+#define I2C_PIN_SDA PINB0
+
+#define AO_CONST_ATTRIB PROGMEM
+typedef int32_t alt_t;
+#define FETCH_ALT(o) ((alt_t) pgm_read_dword(&altitude_table[o]))
+
+#define AO_ALT_VALUE(x) ((x) * (alt_t) 10)
+
+/* Pressure change (in Pa) to detect boost */
+#ifndef BOOST_DETECT
+#define BOOST_DETECT 120 /* 10m at sea level, 12m at 2000m */
+#endif
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/nanopeak-v0.1/Makefile b/src/nanopeak-v0.1/Makefile
index 04eea902..d3779594 100644
--- a/src/nanopeak-v0.1/Makefile
+++ b/src/nanopeak-v0.1/Makefile
@@ -2,7 +2,7 @@
# Tiny AltOS build
#
#
-vpath % ../attiny:../drivers:../core:../product:..
+vpath % ../attiny:../drivers:../kernel:../product:..
vpath ao-make-product.5c ../util
vpath make-altitude-pa ../util
@@ -47,7 +47,7 @@ INC=\
IDPRODUCT=0
PRODUCT=NanoPeak-v0.1
PRODUCT_DEF=-DNANOPEAK
-CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../core -I.. -I../drivers -I../product
+CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../kernel -I.. -I../drivers -I../product
CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTINY
NICKLE=nickle
diff --git a/src/product/Makefile.teledongle b/src/product/Makefile.teledongle
index da9bcba0..81151364 100644
--- a/src/product/Makefile.teledongle
+++ b/src/product/Makefile.teledongle
@@ -7,8 +7,8 @@
# TD_VER, TD_DEF and include
# this file
-vpath %.c ..:../core:../cc1111:../drivers:../product
-vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath %.c ..:../kernel:../cc1111:../drivers:../product
+vpath %.h ..:../kernel:../cc1111:../drivers:../product
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/product/Makefile.telelaunch b/src/product/Makefile.telelaunch
index a5e2eb7f..90fe7833 100644
--- a/src/product/Makefile.telelaunch
+++ b/src/product/Makefile.telelaunch
@@ -4,8 +4,8 @@
# define TELELAUNCH_VER, TELELAUNCH_DEF
# this file
-vpath %.c ..:../core:../cc1111:../drivers:../product
-vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath %.c ..:../kernel:../cc1111:../drivers:../product
+vpath %.h ..:../kernel:../cc1111:../drivers:../product
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/product/Makefile.telemetrum b/src/product/Makefile.telemetrum
index c740a483..dbbf57d8 100644
--- a/src/product/Makefile.telemetrum
+++ b/src/product/Makefile.telemetrum
@@ -7,8 +7,8 @@
# TM_VER, TM_DEF, TM_INC and TM_SRC and include
# this file
-vpath %.c .:..:../core:../cc1111:../drivers:../product
-vpath %.h .:..:../core:../cc1111:../drivers:../product
+vpath %.c .:..:../kernel:../cc1111:../drivers:../product
+vpath %.h .:..:../kernel:../cc1111:../drivers:../product
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/product/Makefile.telemini b/src/product/Makefile.telemini
index 0884079e..ff8b9d56 100644
--- a/src/product/Makefile.telemini
+++ b/src/product/Makefile.telemini
@@ -4,8 +4,8 @@
# Define TELEMINI_VER and TELEMINI_DEF and then
# include this file
-vpath %.c ..:../core:../cc1111:../drivers:../product
-vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath %.c ..:../kernel:../cc1111:../drivers:../product
+vpath %.h ..:../kernel:../cc1111:../drivers:../product
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/product/Makefile.telenano b/src/product/Makefile.telenano
index c31989ee..d2fcb6d8 100644
--- a/src/product/Makefile.telenano
+++ b/src/product/Makefile.telenano
@@ -4,8 +4,8 @@
# Define TELENANO_VER and TELENANO_DEF and then
# include this file
-vpath %.c ..:../core:../cc1111:../drivers:../product
-vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath %.c ..:../kernel:../cc1111:../drivers:../product
+vpath %.h ..:../kernel:../cc1111:../drivers:../product
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/product/ao_flash_task.c b/src/product/ao_flash_task.c
index 6cb308e1..9a12add6 100644
--- a/src/product/ao_flash_task.c
+++ b/src/product/ao_flash_task.c
@@ -79,6 +79,14 @@ ao_block_erase(void)
ao_flash_erase_page(p);
}
+static int
+ao_block_valid_address(uint32_t addr)
+{
+ if ((uint32_t) AO_BOOT_APPLICATION_BASE <= addr && addr <= (uint32_t) AO_BOOT_APPLICATION_BOUND - 256)
+ return 1;
+ return 0;
+}
+
static void
ao_block_write(void)
{
@@ -87,12 +95,10 @@ ao_block_write(void)
uint8_t data[256];
uint16_t i;
- if (addr < (uint32_t) AO_BOOT_APPLICATION_BASE) {
- ao_put_string("Invalid address\n");
- return;
- }
for (i = 0; i < 256; i++)
data[i] = ao_usb_getchar();
+ if (!ao_block_valid_address(addr))
+ return;
ao_flash_page(p, (void *) data);
}
@@ -104,18 +110,43 @@ ao_block_read(void)
uint16_t i;
uint8_t c;
+ if (!ao_block_valid_address(addr)) {
+ for (i = 0; i < 256; i++)
+ ao_usb_putchar(0xff);
+ return;
+ }
for (i = 0; i < 256; i++) {
c = *p++;
ao_usb_putchar(c);
}
}
+static inline void
+hexchar(uint8_t c)
+{
+ if (c > 10)
+ c += 'a' - ('9' + 1);
+ ao_usb_putchar(c + '0');
+}
+
+static void
+ao_put_hex(uint32_t u)
+{
+ int8_t i;
+ for (i = 28; i >= 0; i -= 4)
+ hexchar((u >> i) & 0xf);
+}
+
static void
ao_show_version(void)
{
ao_put_string("altos-loader");
ao_put_string("\nmanufacturer "); ao_put_string(ao_manufacturer);
ao_put_string("\nproduct "); ao_put_string(ao_product);
+ ao_put_string("\nflash-range ");
+ ao_put_hex((uint32_t) AO_BOOT_APPLICATION_BASE);
+ ao_usb_putchar(' ');
+ ao_put_hex((uint32_t) AO_BOOT_APPLICATION_BOUND);
ao_put_string("\nsoftware-version "); ao_put_string(ao_version);
ao_put_string("\n");
}
diff --git a/src/product/ao_micropeak.h b/src/product/ao_micropeak.h
index 0cefca6f..0ec407d7 100644
--- a/src/product/ao_micropeak.h
+++ b/src/product/ao_micropeak.h
@@ -25,7 +25,9 @@
#define GROUND_AVG (1 << GROUND_AVG_SHIFT)
/* Pressure change (in Pa) to detect boost */
+#ifndef BOOST_DETECT
#define BOOST_DETECT 360 /* 30m at sea level, 36m at 2000m */
+#endif
/* Wait after power on before doing anything to give the user time to assemble the rocket */
#define BOOST_DELAY AO_SEC_TO_TICKS(60)
diff --git a/src/spiradio-v0.1/.sdcdbrc b/src/spiradio-v0.1/.sdcdbrc
index b9f6129c..2c77e32b 100644
--- a/src/spiradio-v0.1/.sdcdbrc
+++ b/src/spiradio-v0.1/.sdcdbrc
@@ -1,2 +1,2 @@
---directory=../cc1111:../product:../core:../drivers:.
+--directory=../cc1111:../product:../kernel:../drivers:.
diff --git a/src/spiradio-v0.1/Makefile b/src/spiradio-v0.1/Makefile
index e644bc49..cd7a9cde 100644
--- a/src/spiradio-v0.1/Makefile
+++ b/src/spiradio-v0.1/Makefile
@@ -5,8 +5,8 @@
SPIRADIO_VER=0.1
SPIRADIO_DEF=0_1
-vpath %.c ..:../core:../cc1111:../drivers:../product
-vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath %.c ..:../kernel:../cc1111:../drivers:../product
+vpath %.h ..:../kernel:../cc1111:../drivers:../product
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/stm-bringup/Makefile b/src/stm-bringup/Makefile
index 797df2d6..b0943e56 100644
--- a/src/stm-bringup/Makefile
+++ b/src/stm-bringup/Makefile
@@ -1,4 +1,4 @@
-vpath % ..:../core:../product:../drivers:../stm
+vpath % ..:../kernel:../product:../drivers:../stm
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/stm-demo/Makefile b/src/stm-demo/Makefile
index 98fcd9e5..869fb32f 100644
--- a/src/stm-demo/Makefile
+++ b/src/stm-demo/Makefile
@@ -9,6 +9,7 @@ INC = \
ao.h \
ao_arch.h \
ao_arch_funcs.h \
+ ao_boot.h \
ao_pins.h \
ao_product.h
@@ -26,7 +27,6 @@ ALTOS_SRC = \
ao_stdio.c \
ao_panic.c \
ao_timer.c \
- ao_serial_stm.c \
ao_lcd_stm.c \
ao_lcd_font.c \
ao_mutex.c \
diff --git a/src/stm-demo/ao_demo.c b/src/stm-demo/ao_demo.c
index 58cf651b..ffc5d2d8 100644
--- a/src/stm-demo/ao_demo.c
+++ b/src/stm-demo/ao_demo.c
@@ -171,12 +171,38 @@ ao_event(void)
}
#endif
+static uint8_t ao_blinking = 0;
+
+static void
+ao_blink(void)
+{
+ for (;;) {
+ while (!ao_blinking)
+ ao_sleep(&ao_blinking);
+ while (ao_blinking) {
+ ao_led_toggle(AO_LED_BLUE|AO_LED_GREEN);
+ ao_delay(AO_MS_TO_TICKS(500));
+ }
+ }
+}
+
+static struct ao_task ao_blink_task;
+
+static void
+ao_blink_toggle(void)
+{
+ ao_blinking = !ao_blinking;
+ ao_wakeup(&ao_blinking);
+}
+
+
__code struct ao_cmds ao_demo_cmds[] = {
{ ao_dma_test, "D\0DMA test" },
{ ao_spi_write, "W\0SPI write" },
{ ao_spi_read, "R\0SPI read" },
{ ao_i2c_write, "i\0I2C write" },
{ ao_temp, "t\0Show temp" },
+ { ao_blink_toggle, "b\0Toggle LED blinking" },
/* { ao_event, "e\0Monitor event queue" }, */
{ 0, NULL }
};
@@ -188,23 +214,26 @@ main(void)
ao_task_init();
- ao_serial_init();
+ ao_led_init(LEDS_AVAILABLE);
+ ao_led_on(AO_LED_GREEN);
+ ao_led_off(AO_LED_BLUE);
ao_timer_init();
ao_dma_init();
ao_cmd_init();
// ao_lcd_stm_init();
// ao_lcd_font_init();
- ao_spi_init();
- ao_i2c_init();
- ao_exti_init();
+// ao_spi_init();
+// ao_i2c_init();
+// ao_exti_init();
// ao_quadrature_init();
// ao_button_init();
- ao_timer_set_adc_interval(100);
+// ao_timer_set_adc_interval(100);
- ao_adc_init();
+// ao_adc_init();
ao_usb_init();
+ ao_add_task(&ao_blink_task, ao_blink, "blink");
ao_cmd_register(&ao_demo_cmds[0]);
ao_start_scheduler();
diff --git a/src/stm-demo/ao_pins.h b/src/stm-demo/ao_pins.h
index 40e48a36..885b9db6 100644
--- a/src/stm-demo/ao_pins.h
+++ b/src/stm-demo/ao_pins.h
@@ -42,13 +42,13 @@
#define AO_APB2_PRESCALER 1
#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_1
-#define HAS_SERIAL_1 1
-#define USE_SERIAL_1_STDIN 1
+#define HAS_SERIAL_1 0
+#define USE_SERIAL_1_STDIN 0
#define SERIAL_1_PB6_PB7 1
#define SERIAL_1_PA9_PA10 0
#define HAS_SERIAL_2 0
-#define USE_SERIAL_2_STDIN 1
+#define USE_SERIAL_2_STDIN 0
#define SERIAL_2_PA2_PA3 0
#define SERIAL_2_PD5_PD6 1
@@ -70,7 +70,7 @@
#define AO_BOOT_CHAIN 1
-#define LOW_LEVEL_DEBUG 1
+#define LOW_LEVEL_DEBUG 0
#define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOBEN
#define LED_PORT (&stm_gpiob)
@@ -78,8 +78,7 @@
#define LED_PIN_BLUE 6
#define AO_LED_GREEN (1 << LED_PIN_GREEN)
#define AO_LED_BLUE (1 << LED_PIN_BLUE)
-
-#define AO_LED_RED AO_LED_BLUE /* a patent lie */
+#define AO_LED_PANIC AO_LED_BLUE
#define LEDS_AVAILABLE (AO_LED_BLUE | AO_LED_GREEN)
diff --git a/src/stm-demo/flash-loader/Makefile b/src/stm-demo/flash-loader/Makefile
new file mode 100644
index 00000000..27e54278
--- /dev/null
+++ b/src/stm-demo/flash-loader/Makefile
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=stm-demo
+include $(TOPDIR)/stm/Makefile-flash.defs
diff --git a/src/stm-demo/flash-loader/ao_pins.h b/src/stm-demo/flash-loader/ao_pins.h
new file mode 100644
index 00000000..4c59101a
--- /dev/null
+++ b/src/stm-demo/flash-loader/ao_pins.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+/* Bridge SB17 on the board and use the MCO from the other chip */
+#define AO_HSE 8000000
+#define AO_HSE_BYPASS 1
+
+#include <ao_flash_stm_pins.h>
+
+/* Use the 'user switch' to force boot loader on power on */
+
+#define AO_BOOT_PIN 1
+#define AO_BOOT_APPLICATION_GPIO stm_gpioa
+#define AO_BOOT_APPLICATION_PIN 0
+#define AO_BOOT_APPLICATION_VALUE 0
+#define AO_BOOT_APPLICATION_MODE 0
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/stm-flash/Makefile b/src/stm-flash/Makefile
index 5c0699e1..568ab85a 100644
--- a/src/stm-flash/Makefile
+++ b/src/stm-flash/Makefile
@@ -9,6 +9,7 @@ INC = \
ao.h \
ao_arch.h \
ao_arch_funcs.h \
+ ao_boot.h \
ao_pins.h \
ao_product.h
diff --git a/src/stm/Makefile-flash.defs b/src/stm/Makefile-flash.defs
index 3890eff1..dde51a68 100644
--- a/src/stm/Makefile-flash.defs
+++ b/src/stm/Makefile-flash.defs
@@ -1,4 +1,4 @@
-vpath % $(TOPDIR)/stm:$(TOPDIR)/product:$(TOPDIR)/drivers:$(TOPDIR)/core:$(TOPDIR)/util:$(TOPDIR)
+vpath % $(TOPDIR)/stm:$(TOPDIR)/product:$(TOPDIR)/drivers:$(TOPDIR)/kernel:$(TOPDIR)/util:$(TOPDIR)
vpath ao-make-product.5c $(TOPDIR)/util
.SUFFIXES: .elf .ihx
@@ -14,7 +14,7 @@ include $(TOPDIR)/Makedefs
CC=$(ARM_CC)
LIBS=$(PDCLIB_LIBS_M3) -lgcc
-AO_CFLAGS=-I. -I$(TOPDIR)/stm -I$(TOPDIR)/core -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) $(PDCLIB_INCLUDES)
+AO_CFLAGS=-I. -I$(TOPDIR)/stm -I$(TOPDIR)/kernel -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) $(PDCLIB_INCLUDES)
STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS)
LDFLAGS=-L$(TOPDIR)/stm -Wl,-Taltos-loader.ld
diff --git a/src/stm/Makefile.defs b/src/stm/Makefile.defs
index 42adfd09..c3d2707f 100644
--- a/src/stm/Makefile.defs
+++ b/src/stm/Makefile.defs
@@ -1,4 +1,4 @@
-vpath % ../stm:../product:../drivers:../core:../util:../kalman:../aes:../math:..
+vpath % ../stm:../product:../drivers:../kernel:../util:../kalman:../aes:../math:..
vpath make-altitude ../util
vpath make-kalman ../util
vpath kalman.5c ../kalman
@@ -26,7 +26,7 @@ LIBS=$(PDCLIB_LIBS_M3) -lgcc
WARN_FLAGS=-Wall -Wextra -Werror
-AO_CFLAGS=-I. -I../stm -I../core -I../drivers -I../math -I.. $(PDCLIB_INCLUDES)
+AO_CFLAGS=-I. -I../stm -I../kernel -I../drivers -I../math -I.. $(PDCLIB_INCLUDES)
STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb \
-ffreestanding -nostdlib $(AO_CFLAGS) $(WARN_FLAGS)
diff --git a/src/stm/ao_arch.h b/src/stm/ao_arch.h
index 76fa9194..a6276c5a 100644
--- a/src/stm/ao_arch.h
+++ b/src/stm/ao_arch.h
@@ -139,7 +139,8 @@ ao_adc_init();
#define AO_ADC_MAX 4095
#define AO_BOOT_APPLICATION_BASE ((uint32_t *) 0x08001000)
-#define AO_BOOT_LOADER_BASE ((uint32_t *) 0x0)
+#define AO_BOOT_APPLICATION_BOUND ((uint32_t *) (0x08000000 + stm_flash_size()))
+#define AO_BOOT_LOADER_BASE ((uint32_t *) 0x08000000)
#define HAS_BOOT_LOADER 1
#endif /* _AO_ARCH_H_ */
diff --git a/src/stm/ao_boot_chain.c b/src/stm/ao_boot_chain.c
index 6a3864a7..bcebf033 100644
--- a/src/stm/ao_boot_chain.c
+++ b/src/stm/ao_boot_chain.c
@@ -50,7 +50,7 @@ ao_boot_check_chain(void)
if (ao_boot.signal == AO_BOOT_SIGNAL && ao_boot.check == AO_BOOT_CHECK) {
ao_boot.signal = 0;
ao_boot.check = 0;
- if (ao_boot.base == 0)
+ if (ao_boot.base == AO_BOOT_FORCE_LOADER)
return 0;
ao_boot_chain(ao_boot.base);
}
diff --git a/src/stm/ao_boot_pin.c b/src/stm/ao_boot_pin.c
index 1000a65a..e825b618 100644
--- a/src/stm/ao_boot_pin.c
+++ b/src/stm/ao_boot_pin.c
@@ -26,7 +26,7 @@ ao_boot_check_pin(void)
/* Enable power interface clock */
stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN);
-
+
/* Enable the input pin */
ao_enable_input(&AO_BOOT_APPLICATION_GPIO, AO_BOOT_APPLICATION_PIN,
AO_BOOT_APPLICATION_MODE);
diff --git a/src/stm/ao_fast_timer.c b/src/stm/ao_fast_timer.c
index d61b40c9..9a73eb51 100644
--- a/src/stm/ao_fast_timer.c
+++ b/src/stm/ao_fast_timer.c
@@ -88,7 +88,11 @@ void stm_tim6_isr(void)
#define TIMER_23467_SCALER 1
#endif
-#define TIMER_10kHz ((AO_PCLK1 * TIMER_23467_SCALER) / 10000)
+#ifndef FAST_TIMER_FREQ
+#define FAST_TIMER_FREQ 10000
+#endif
+
+#define TIMER_FAST ((AO_PCLK1 * TIMER_23467_SCALER) / FAST_TIMER_FREQ)
void
ao_fast_timer_init(void)
@@ -100,7 +104,7 @@ ao_fast_timer_init(void)
/* Turn on timer 6 */
stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_TIM6EN);
- stm_tim6.psc = TIMER_10kHz;
+ stm_tim6.psc = TIMER_FAST;
stm_tim6.arr = 9;
stm_tim6.cnt = 0;
diff --git a/src/stm/ao_interrupt.c b/src/stm/ao_interrupt.c
index 969e6a0f..56cce0c0 100644
--- a/src/stm/ao_interrupt.c
+++ b/src/stm/ao_interrupt.c
@@ -39,6 +39,38 @@ void stm_ignore_isr(void)
const void *stm_interrupt_vector[];
+uint32_t
+stm_flash_size(void) {
+ uint16_t dev_id = stm_dev_id();
+ uint16_t kbytes = 0;
+
+ switch (dev_id) {
+ case 0x416: /* cat 1 */
+ kbytes = stm_flash_size_medium.f_size;
+ break;
+ case 0x429: /* cat 2 */
+ kbytes = stm_flash_size_medium.f_size & 0xff;
+ break;
+ case 0x427: /* cat 3 */
+ kbytes = stm_flash_size_large.f_size;
+ break;
+ case 0x436: /* cat 4 */
+ switch (stm_flash_size_large.f_size) {
+ case 0:
+ kbytes = 256;
+ break;
+ case 1:
+ kbytes = 384;
+ break;
+ }
+ break;
+ case 0x437: /* cat 5 */
+ kbytes = stm_flash_size_large.f_size;
+ break;
+ }
+ return (uint32_t) kbytes * 1024;
+}
+
void start(void)
{
#ifdef AO_BOOT_CHAIN
diff --git a/src/stm/ao_timer.c b/src/stm/ao_timer.c
index d93531fc..8db62e76 100644
--- a/src/stm/ao_timer.c
+++ b/src/stm/ao_timer.c
@@ -17,6 +17,9 @@
#include "ao.h"
#include <ao_task.h>
+#if HAS_FAKE_FLIGHT
+#include <ao_fake_flight.h>
+#endif
#ifndef HAS_TICK
#define HAS_TICK 1
@@ -47,7 +50,12 @@ void stm_systick_isr(void)
#if AO_DATA_ALL
if (++ao_data_count == ao_data_interval) {
ao_data_count = 0;
- ao_adc_poll();
+#if HAS_FAKE_FLIGHT
+ if (ao_fake_flight_active)
+ ao_fake_flight_poll();
+ else
+#endif
+ ao_adc_poll();
#if (AO_DATA_ALL & ~(AO_DATA_ADC))
ao_wakeup((void *) &ao_data_count);
#endif
diff --git a/src/stm/ao_usb_stm.c b/src/stm/ao_usb_stm.c
index 27b82357..4e9d1f14 100644
--- a/src/stm/ao_usb_stm.c
+++ b/src/stm/ao_usb_stm.c
@@ -117,7 +117,7 @@ static uint8_t ao_usb_in_pending;
* but not pulled to the shadow buffer.
*/
static uint8_t ao_usb_out_avail;
-static uint8_t ao_usb_running;
+uint8_t ao_usb_running;
static uint8_t ao_usb_configuration;
#define AO_USB_EP0_GOT_RESET 1
@@ -727,6 +727,9 @@ ao_usb_ep0_handle(uint8_t receive)
if (receive & AO_USB_EP0_GOT_TX_ACK) {
debug ("\tgot tx ack\n");
+#if HAS_FLIGHT && AO_USB_FORCE_IDLE
+ ao_flight_force_idle = 1;
+#endif
/* Wait until the IN packet is received from addr 0
* before assigning our local address
*/
diff --git a/src/stm/registers.ld b/src/stm/registers.ld
index 8318c75a..d40fd90f 100644
--- a/src/stm/registers.ld
+++ b/src/stm/registers.ld
@@ -52,5 +52,10 @@ stm_scb = 0xe000ed00;
stm_mpu = 0xe000ed90;
+stm_dbg_mcu = 0xe0042000;
+
/* calibration data in system memory */
stm_temp_cal = 0x1ff80078;
+stm_flash_size_medium = 0x1ff8004c;
+stm_flash_size_large = 0x1ff800cc;
+stm_device_id = 0x1ff80050;
diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h
index 302f4d24..799cccbd 100644
--- a/src/stm/stm32l.h
+++ b/src/stm/stm32l.h
@@ -176,12 +176,27 @@ stm_gpio_get_all(struct stm_gpio *gpio) {
return gpio->idr;
}
-extern struct stm_gpio stm_gpioa;
-extern struct stm_gpio stm_gpiob;
-extern struct stm_gpio stm_gpioc;
-extern struct stm_gpio stm_gpiod;
-extern struct stm_gpio stm_gpioe;
-extern struct stm_gpio stm_gpioh;
+/*
+ * We can't define these in registers.ld or our fancy
+ * ao_enable_gpio macro will expand into a huge pile of code
+ * as the compiler won't do correct constant folding and
+ * dead-code elimination
+
+ extern struct stm_gpio stm_gpioa;
+ extern struct stm_gpio stm_gpiob;
+ extern struct stm_gpio stm_gpioc;
+ extern struct stm_gpio stm_gpiod;
+ extern struct stm_gpio stm_gpioe;
+ extern struct stm_gpio stm_gpioh;
+
+*/
+
+#define stm_gpioh (*((struct stm_gpio *) 0x40021400))
+#define stm_gpioe (*((struct stm_gpio *) 0x40021000))
+#define stm_gpiod (*((struct stm_gpio *) 0x40020c00))
+#define stm_gpioc (*((struct stm_gpio *) 0x40020800))
+#define stm_gpiob (*((struct stm_gpio *) 0x40020400))
+#define stm_gpioa (*((struct stm_gpio *) 0x40020000))
struct stm_usart {
vuint32_t sr; /* status register */
@@ -1492,6 +1507,36 @@ extern struct stm_temp_cal stm_temp_cal;
#define stm_temp_cal_cold 25
#define stm_temp_cal_hot 110
+struct stm_dbg_mcu {
+ uint32_t idcode;
+};
+
+extern struct stm_dbg_mcu stm_dbg_mcu;
+
+static inline uint16_t
+stm_dev_id(void) {
+ return stm_dbg_mcu.idcode & 0xfff;
+}
+
+struct stm_flash_size {
+ uint16_t f_size;
+};
+
+extern struct stm_flash_size stm_flash_size_medium;
+extern struct stm_flash_size stm_flash_size_large;
+
+/* Returns flash size in bytes */
+extern uint32_t
+stm_flash_size(void);
+
+struct stm_device_id {
+ uint32_t u_id0;
+ uint32_t u_id1;
+ uint32_t u_id2;
+};
+
+extern struct stm_device_id stm_device_id;
+
#define STM_NUM_I2C 2
#define STM_I2C_INDEX(channel) ((channel) - 1)
diff --git a/src/teleballoon-v1.1/Makefile b/src/teleballoon-v1.1/Makefile
index 6ff076a9..c6f6345a 100644
--- a/src/teleballoon-v1.1/Makefile
+++ b/src/teleballoon-v1.1/Makefile
@@ -17,8 +17,8 @@ TELEBALLOON_SRC = \
ao_gps_skytraq.c \
ao_m25.c
-vpath %.c ..:../core:../cc1111:../drivers:../product:.
-vpath %.h ..:../core:../cc1111:../drivers:../product:.
+vpath %.c ..:../kernel:../cc1111:../drivers:../product:.
+vpath %.h ..:../kernel:../cc1111:../drivers:../product:.
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/teleballoon-v1.1/ao_pins.h b/src/teleballoon-v1.1/ao_pins.h
index 7ba48c96..4c23ca88 100644
--- a/src/teleballoon-v1.1/ao_pins.h
+++ b/src/teleballoon-v1.1/ao_pins.h
@@ -28,6 +28,7 @@
#define HAS_FLIGHT 1
#define HAS_USB 1
#define HAS_BEEP 1
+ #define HAS_BATTERY_REPORT 1
#define HAS_GPS 1
#define HAS_SERIAL_1 1
#define HAS_ADC 1
diff --git a/src/teleballoon-v2.0/.gitignore b/src/teleballoon-v2.0/.gitignore
new file mode 100644
index 00000000..85f12553
--- /dev/null
+++ b/src/teleballoon-v2.0/.gitignore
@@ -0,0 +1,3 @@
+ao_product.h
+teleballoon-*.elf
+
diff --git a/src/teleballoon-v2.0/Makefile b/src/teleballoon-v2.0/Makefile
new file mode 100644
index 00000000..28588778
--- /dev/null
+++ b/src/teleballoon-v2.0/Makefile
@@ -0,0 +1,130 @@
+#
+# AltOS build
+#
+#
+
+include ../stm/Makefile.defs
+
+INC = \
+ ao.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_boot.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
+
+MATH_SRC=\
+ ef_log.c
+
+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_eeprom_stm.c \
+ ao_report.c \
+ ao_convert_pa.c \
+ ao_convert_volt.c \
+ ao_log.c \
+ ao_log_metrum.c \
+ ao_sample.c \
+ ao_kalman.c \
+ ao_balloon.c \
+ ao_telemetry.c \
+ ao_packet_slave.c \
+ ao_packet.c \
+ ao_companion.c \
+ ao_aprs.c \
+ $(MATH_SRC) \
+ $(PROFILE) \
+ $(SAMPLE_PROFILE) \
+ $(STACK_GUARD)
+
+PRODUCT=TeleBalloon-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=teleballoon-v2.0
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_teleballoon.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+$(PROG): Makefile $(OBJ) altos.ld
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+../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 $(PROGNAME)-*.ihx
+ rm -f ao_product.h
+
+install:
+
+uninstall:
diff --git a/src/teleballoon-v2.0/ao_pins.h b/src/teleballoon-v2.0/ao_pins.h
new file mode 100644
index 00000000..a369070f
--- /dev/null
+++ b/src/teleballoon-v2.0/ao_pins.h
@@ -0,0 +1,328 @@
+/*
+ * 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_CONFIG_DEFAULT_FLIGHT_LOG_MAX (512 * 1024)
+#define AO_CONFIG_MAX_SIZE 1024
+#define LOG_ERASE_MARK 0x55
+#define LOG_MAX_ERASE 128
+
+#define HAS_EEPROM 1
+#define USE_INTERNAL_FLASH 0
+#define USE_EEPROM_CONFIG 1
+#define USE_STORAGE_CONFIG 0
+#define HAS_USB 1
+#define HAS_BEEP 1
+#define HAS_BATTERY_REPORT 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
+#define AO_USB_FORCE_IDLE 0
+
+/*
+ * Igniter
+ */
+
+#define HAS_IGNITE 0
+#define HAS_IGNITE_REPORT 0
+
+#define AO_SENSE_DROGUE(p) ((p)->adc.sense_a)
+#define AO_SENSE_MAIN(p) ((p)->adc.sense_m)
+#define AO_IGNITER_CLOSED 400
+#define AO_IGNITER_OPEN 60
+
+/* Drogue */
+#define AO_IGNITER_DROGUE_PORT (&stm_gpioa)
+#define AO_IGNITER_DROGUE_PIN 8
+
+/* Main */
+#define AO_IGNITER_MAIN_PORT (&stm_gpioa)
+#define AO_IGNITER_MAIN_PIN 9
+
+#define AO_IGNITER_SET_DROGUE(v) stm_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, v)
+#define AO_IGNITER_SET_MAIN(v) stm_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, v)
+
+/*
+ * ADC
+ */
+#define AO_DATA_RING 32
+#define AO_ADC_NUM_SENSE 2
+
+struct ao_adc {
+ int16_t sense_a;
+ int16_t sense_m;
+ int16_t v_batt;
+ int16_t temp;
+};
+
+#define AO_ADC_DUMP(p) \
+ printf("tick: %5u drogue: %5d main: %5d batt: %5d\n", \
+ (p)->tick, \
+ (p)->adc.sense_a, (p)->adc.sense_m, \
+ (p)->adc.v_batt);
+
+#define AO_ADC_SENSE_DROGUE 0
+#define AO_ADC_SENSE_DROGUE_PORT (&stm_gpioa)
+#define AO_ADC_SENSE_DROGUE_PIN 0
+
+#define AO_ADC_SENSE_MAIN 1
+#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioa)
+#define AO_ADC_SENSE_MAIN_PIN 1
+
+#define AO_ADC_V_BATT 8
+#define AO_ADC_V_BATT_PORT (&stm_gpiob)
+#define AO_ADC_V_BATT_PIN 0
+
+#define AO_ADC_TEMP 16
+
+#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_GPIOAEN) | \
+ (1 << STM_RCC_AHBENR_GPIOEEN) | \
+ (1 << STM_RCC_AHBENR_GPIOBEN))
+
+#define AO_NUM_ADC_PIN 3
+
+#define AO_ADC_PIN0_PORT AO_ADC_SENSE_DROGUE_PORT
+#define AO_ADC_PIN0_PIN AO_ADC_SENSE_DROGUE_PIN
+#define AO_ADC_PIN1_PORT AO_ADC_SENSE_MAIN_PORT
+#define AO_ADC_PIN1_PIN AO_ADC_SENSE_MAIN_PIN
+#define AO_ADC_PIN2_PORT AO_ADC_V_BATT_PORT
+#define AO_ADC_PIN2_PIN AO_ADC_V_BATT_PIN
+
+#define AO_NUM_ADC (AO_NUM_ADC_PIN + 1)
+
+#define AO_ADC_SQ1 AO_ADC_SENSE_DROGUE
+#define AO_ADC_SQ2 AO_ADC_SENSE_MAIN
+#define AO_ADC_SQ3 AO_ADC_V_BATT
+#define AO_ADC_SQ4 AO_ADC_TEMP
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS 56 /* 5.6k */
+#define AO_BATTERY_DIV_MINUS 100 /* 10k */
+
+/*
+ * Voltage divider on ADC igniter samplers
+ */
+#define AO_IGNITE_DIV_PLUS 100 /* 100k */
+#define AO_IGNITE_DIV_MINUS 27 /* 27k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV 33
+
+/*
+ * GPS
+ */
+
+#define AO_SERIAL_SPEED_UBLOX AO_SERIAL_SPEED_9600
+
+#define ao_gps_getchar ao_serial3_getchar
+#define ao_gps_putchar ao_serial3_putchar
+#define ao_gps_set_speed ao_serial3_set_speed
+#define ao_gps_fifo (ao_stm_usart3.rx_fifo)
+
+/*
+ * Pressure sensor settings
+ */
+#define HAS_MS5607 1
+#define HAS_MS5611 0
+#define AO_MS5607_PRIVATE_PINS 1
+#define AO_MS5607_CS_PORT (&stm_gpiob)
+#define AO_MS5607_CS_PIN 12
+#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS)
+#define AO_MS5607_MISO_PORT (&stm_gpioa)
+#define AO_MS5607_MISO_PIN 6
+#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO)
+#define AO_MS5607_SPI_INDEX AO_SPI_1_PA5_PA6_PA7
+
+/*
+ * SPI Flash memory
+ */
+
+#define M25_MAX_CHIPS 1
+#define AO_M25_SPI_CS_PORT (&stm_gpiob)
+#define AO_M25_SPI_CS_MASK (1 << 8)
+#define AO_M25_SPI_BUS AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Radio (cc1120)
+ */
+
+/* gets pretty close to 434.550 */
+
+#define AO_RADIO_CAL_DEFAULT 0x6ca333
+
+#define AO_FEC_DEBUG 0
+#define AO_CC1120_SPI_CS_PORT (&stm_gpioa)
+#define AO_CC1120_SPI_CS_PIN 2
+#define AO_CC1120_SPI_BUS AO_SPI_2_PB13_PB14_PB15
+#define AO_CC1120_SPI stm_spi2
+
+#define AO_CC1120_INT_PORT (&stm_gpioa)
+#define AO_CC1120_INT_PIN (3)
+#define AO_CC1120_MCU_WAKEUP_PORT (&stm_gpioa)
+#define AO_CC1120_MCU_WAKEUP_PIN (4)
+
+#define AO_CC1120_INT_GPIO 2
+#define AO_CC1120_INT_GPIO_IOCFG CC1120_IOCFG2
+
+#define AO_CC1120_MARC_GPIO 3
+#define AO_CC1120_MARC_GPIO_IOCFG CC1120_IOCFG3
+
+#define HAS_BOOT_RADIO 0
+
+#define HAS_HIGHG_ACCEL 0
+
+/* Disable accelerometer for balloon mode */
+
+#define HAS_ACCEL 0
+
+/*
+ * mma655x
+ */
+
+#define HAS_MMA655X 0
+#define AO_MMA655X_SPI_INDEX AO_SPI_1_PB3_PB4_PB5
+#define AO_MMA655X_CS_PORT (&stm_gpiob)
+#define AO_MMA655X_CS_PIN 9
+#define AO_MMA655X_INVERT 1
+
+#define NUM_CMDS 16
+
+/*
+ * Companion
+ */
+
+#define AO_COMPANION_CS_PORT (&stm_gpiob)
+#define AO_COMPANION_CS_PIN (6)
+#define AO_COMPANION_SPI_BUS AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Monitor
+ */
+
+#define HAS_MONITOR 0
+#define LEGACY_MONITOR 0
+#define HAS_MONITOR_PUT 1
+#define AO_MONITOR_LED 0
+#define HAS_RSSI 0
+
+/*
+ * Profiling Viterbi decoding
+ */
+
+#ifndef AO_PROFILE
+#define AO_PROFILE 0
+#endif
+
+/*
+ * Teleballoon-specific bits
+ */
+
+#define AO_TELEMETRY_INTERVAL_BALLOON AO_MS_TO_TICKS(1000)
+
+#define AO_SEND_METRUM 1
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/teleballoon-v2.0/ao_teleballoon.c b/src/teleballoon-v2.0/ao_teleballoon.c
new file mode 100644
index 00000000..9b506814
--- /dev/null
+++ b/src/teleballoon-v2.0/ao_teleballoon.c
@@ -0,0 +1,92 @@
+/*
+ * 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_eeprom.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_RED);
+ 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_eeprom_init();
+
+ 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_companion_init();
+
+ ao_config_init();
+#if AO_PROFILE
+ ao_profile_init();
+#endif
+#if HAS_SAMPLE_PROFILE
+ ao_sample_profile_init();
+#endif
+
+ ao_start_scheduler();
+ return 0;
+}
diff --git a/src/telebt-v1.0/.sdcdbrc b/src/telebt-v1.0/.sdcdbrc
index b9f6129c..2c77e32b 100644
--- a/src/telebt-v1.0/.sdcdbrc
+++ b/src/telebt-v1.0/.sdcdbrc
@@ -1,2 +1,2 @@
---directory=../cc1111:../product:../core:../drivers:.
+--directory=../cc1111:../product:../kernel:../drivers:.
diff --git a/src/telebt-v1.0/Makefile b/src/telebt-v1.0/Makefile
index 40853fc3..a7797499 100644
--- a/src/telebt-v1.0/Makefile
+++ b/src/telebt-v1.0/Makefile
@@ -5,8 +5,8 @@
TELEBT_VER=1.0
TELEBT_DEF=1_0
-vpath %.c ..:../core:../cc1111:../drivers:../product
-vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath %.c ..:../kernel:../cc1111:../drivers:../product
+vpath %.h ..:../kernel:../cc1111:../drivers:../product
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/telefire-v0.1/.sdcdbrc b/src/telefire-v0.1/.sdcdbrc
index b9f6129c..2c77e32b 100644
--- a/src/telefire-v0.1/.sdcdbrc
+++ b/src/telefire-v0.1/.sdcdbrc
@@ -1,2 +1,2 @@
---directory=../cc1111:../product:../core:../drivers:.
+--directory=../cc1111:../product:../kernel:../drivers:.
diff --git a/src/telefire-v0.1/Makefile b/src/telefire-v0.1/Makefile
index f9e11698..25267268 100644
--- a/src/telefire-v0.1/Makefile
+++ b/src/telefire-v0.1/Makefile
@@ -5,8 +5,8 @@
TELEFIRE_VER=0.1
TELEFIRE_DEF=0_1
-vpath %.c ..:../core:../cc1111:../drivers:../product
-vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath %.c ..:../kernel:../cc1111:../drivers:../product
+vpath %.h ..:../kernel:../cc1111:../drivers:../product
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/telefire-v0.2/.sdcdbrc b/src/telefire-v0.2/.sdcdbrc
index b9f6129c..2c77e32b 100644
--- a/src/telefire-v0.2/.sdcdbrc
+++ b/src/telefire-v0.2/.sdcdbrc
@@ -1,2 +1,2 @@
---directory=../cc1111:../product:../core:../drivers:.
+--directory=../cc1111:../product:../kernel:../drivers:.
diff --git a/src/telefire-v0.2/Makefile b/src/telefire-v0.2/Makefile
index a820990a..ad5065c1 100644
--- a/src/telefire-v0.2/Makefile
+++ b/src/telefire-v0.2/Makefile
@@ -5,8 +5,8 @@
TELEFIRE_VER=0.2
TELEFIRE_DEF=0_2
-vpath %.c ..:../core:../cc1111:../drivers:../product
-vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath %.c ..:../kernel:../cc1111:../drivers:../product
+vpath %.h ..:../kernel:../cc1111:../drivers:../product
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/telegps-v0.1/Makefile b/src/telegps-v0.1/Makefile
index 77ef9c4a..46eb0ac5 100644
--- a/src/telegps-v0.1/Makefile
+++ b/src/telegps-v0.1/Makefile
@@ -9,6 +9,7 @@ INC = \
ao.h \
ao_arch.h \
ao_arch_funcs.h \
+ ao_boot.h \
ao_pins.h \
ao_product.h \
ao_task.h \
diff --git a/src/telegps-v0.3/Makefile b/src/telegps-v0.3/Makefile
index 5aad32b5..1eaf7c47 100644
--- a/src/telegps-v0.3/Makefile
+++ b/src/telegps-v0.3/Makefile
@@ -11,6 +11,7 @@ INC = \
ao_arch_funcs.h \
ao_pins.h \
ao_product.h \
+ ao_tracker.h \
ao_task.h \
ao_whiten.h \
ao_cc115l.h \
@@ -19,9 +20,6 @@ INC = \
Makefile
-MATH_SRC=\
- ef_log.c
-
ALTOS_SRC = \
ao_interrupt.c \
ao_boot_chain.c \
@@ -44,13 +42,14 @@ ALTOS_SRC = \
ao_cc115l.c \
ao_fec_tx.c \
ao_aprs.c \
+ ao_tracker.c \
ao_telemetry.c \
ao_storage.c \
ao_m25.c \
ao_log.c \
- ao_log_mega.c \
- ao_gps_report_mega.c \
- $(MATH_SRC) \
+ ao_log_gps.c \
+ ao_distance.c \
+ ao_sqrt.c \
$(SAMPLE_PROFILE)
PRODUCT=TeleGPS-v0.3
@@ -61,11 +60,12 @@ CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) $(PROFILE_DEF) -Os -g
PROGNAME=telegps-v0.3
PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
SRC=$(ALTOS_SRC) ao_telegps.c
OBJ=$(SRC:.c=.o)
-all: $(PROG)
+all: $(PROG) $(HEX)
LDFLAGS=-L../lpc -Wl,-Taltos.ld
diff --git a/src/telegps-v0.3/ao_pins.h b/src/telegps-v0.3/ao_pins.h
index a4afaa54..d0e4d835 100644
--- a/src/telegps-v0.3/ao_pins.h
+++ b/src/telegps-v0.3/ao_pins.h
@@ -46,7 +46,7 @@
#define HAS_BEEP 0
#define HAS_RADIO 1
#define HAS_TELEMETRY 1
-#define HAS_RDF 0
+#define HAS_RDF 1
#define HAS_APRS 1
#define HAS_RADIO_RECV 0
@@ -69,9 +69,11 @@
#define HAS_FLIGHT 0
#define HAS_ADC 0
#define HAS_LOG 1
+#define HAS_TRACKER 1
-#define AO_CONFIG_DEFAULT_APRS_INTERVAL 5
+#define AO_CONFIG_DEFAULT_APRS_INTERVAL 0
#define AO_CONFIG_DEFAULT_RADIO_POWER 0xc0
+#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX 496 * 1024
/*
* GPS
@@ -85,9 +87,9 @@
/* gets pretty close to 434.550 */
-#define AO_RADIO_CAL_DEFAULT 0x10b6a5
+#define AO_RADIO_CAL_DEFAULT 1095378
-#define HAS_RADIO_POWER 1
+#define HAS_RADIO_POWER 0
#define AO_FEC_DEBUG 0
#define AO_CC115L_SPI_CS_PORT 0
#define AO_CC115L_SPI_CS_PIN 3
diff --git a/src/telegps-v0.3/ao_telegps.c b/src/telegps-v0.3/ao_telegps.c
index 608817e7..dd699ecf 100644
--- a/src/telegps-v0.3/ao_telegps.c
+++ b/src/telegps-v0.3/ao_telegps.c
@@ -17,15 +17,13 @@
#include <ao.h>
#include <ao_exti.h>
-#include <ao_fat.h>
-
-uint16_t ao_flight_number = 1;
+#include <ao_tracker.h>
int
main(void)
{
ao_clock_init();
-
+
#if HAS_STACK_GUARD
ao_mpu_init();
#endif
@@ -48,18 +46,18 @@ main(void)
ao_gps_init();
#if HAS_LOG
- ao_gps_report_mega_init();
ao_log_init();
#endif
+ ao_tracker_init();
+
ao_telemetry_init();
- ao_telemetry_set_interval(AO_SEC_TO_TICKS(1));
#if HAS_SAMPLE_PROFILE
ao_sample_profile_init();
#endif
ao_config_init();
-
+
ao_start_scheduler();
return 0;
}
diff --git a/src/telegps-v1.0/.gitignore b/src/telegps-v1.0/.gitignore
new file mode 100644
index 00000000..892c3acc
--- /dev/null
+++ b/src/telegps-v1.0/.gitignore
@@ -0,0 +1,3 @@
+ao_product.h
+ao_serial_lpc.h
+*.elf
diff --git a/src/telegps-v1.0/Makefile b/src/telegps-v1.0/Makefile
new file mode 100644
index 00000000..bd13cfe7
--- /dev/null
+++ b/src/telegps-v1.0/Makefile
@@ -0,0 +1,91 @@
+#
+# AltOS build
+#
+#
+
+include ../lpc/Makefile.defs
+
+INC = \
+ ao.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_pins.h \
+ ao_product.h \
+ ao_tracker.h \
+ ao_task.h \
+ ao_whiten.h \
+ ao_cc115l.h \
+ ao_fec.h \
+ lpc.h \
+ Makefile
+
+
+ALTOS_SRC = \
+ ao_interrupt.c \
+ ao_boot_chain.c \
+ ao_product.c \
+ ao_romconfig.c \
+ ao_cmd.c \
+ ao_config.c \
+ ao_task.c \
+ ao_stdio.c \
+ ao_panic.c \
+ ao_timer_lpc.c \
+ ao_mutex.c \
+ ao_freq.c \
+ ao_spi_lpc.c \
+ ao_usb_lpc.c \
+ ao_exti_lpc.c \
+ ao_serial_lpc.c \
+ ao_gps_ublox.c \
+ ao_gps_show.c \
+ ao_cc115l.c \
+ ao_fec_tx.c \
+ ao_aprs.c \
+ ao_tracker.c \
+ ao_telemetry.c \
+ ao_storage.c \
+ ao_m25.c \
+ ao_log.c \
+ ao_log_gps.c \
+ ao_distance.c \
+ ao_sqrt.c \
+ ao_data.c \
+ ao_adc_lpc.c \
+ ao_convert_volt.c \
+ $(SAMPLE_PROFILE)
+
+PRODUCT=TeleGPS-v1.0
+PRODUCT_DEF=-DTELEGPS
+IDPRODUCT=0x0025
+
+CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) $(PROFILE_DEF) -Os -g
+
+PROGNAME=telegps-v1.0
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_telegps.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+LDFLAGS=-L../lpc -Wl,-Taltos.ld
+
+$(PROG): Makefile $(OBJ) altos.ld
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+$(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 ao_serial_lpc.h $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f ao_product.h
+
+install:
+
+uninstall:
diff --git a/src/telegps-v1.0/ao_pins.h b/src/telegps-v1.0/ao_pins.h
new file mode 100644
index 00000000..5f53dd9d
--- /dev/null
+++ b/src/telegps-v1.0/ao_pins.h
@@ -0,0 +1,149 @@
+/*
+ * 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 AO_STACK_SIZE 448
+
+#define IS_FLASH_LOADER 0
+
+/* Crystal on the board */
+#define AO_LPC_CLKIN 12000000
+
+/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */
+#define AO_LPC_CLKOUT 48000000
+
+/* System clock frequency */
+#define AO_LPC_SYSCLK 24000000
+
+#define HAS_SERIAL_0 1
+#define SERIAL_0_18_19 1
+#define USE_SERIAL_0_STDIN 0
+
+#define ao_gps_getchar ao_serial0_getchar
+#define ao_gps_putchar ao_serial0_putchar
+#define ao_gps_set_speed ao_serial0_set_speed
+#define ao_gps_fifo (ao_usart_rx_fifo)
+
+#define HAS_EEPROM 1
+#define USE_INTERNAL_FLASH 0
+#define HAS_USB 1
+#define HAS_BEEP 0
+#define HAS_RADIO 1
+#define HAS_TELEMETRY 1
+#define HAS_RDF 1
+#define HAS_APRS 1
+#define HAS_RADIO_RECV 0
+
+#define HAS_USB_PULLUP 1
+#define AO_USB_PULLUP_PORT 0
+#define AO_USB_PULLUP_PIN 7
+#define HAS_USB_CONNECT 1
+#define AO_USB_CONNECT_PORT 1
+#define AO_USB_CONNECT_PIN 19
+
+/* Flash part */
+#define HAS_SPI_0 1
+#define SPI_SCK0_P0_6 1
+#define SPI_0_OSPEEDR AO_SPI_OSPEED_12MHz
+
+/* Radio */
+#define HAS_SPI_1 1
+#define SPI_SCK1_P1_15 1
+#define SPI_MISO1_P0_22 1
+#define SPI_MOSI1_P0_21 1
+
+#define HAS_GPS 1
+#define HAS_FLIGHT 0
+#define HAS_LOG 1
+#define HAS_TRACKER 1
+
+#define AO_CONFIG_DEFAULT_APRS_INTERVAL 0
+#define AO_CONFIG_DEFAULT_RADIO_POWER 0xc0
+#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX 496 * 1024
+
+/*
+ * GPS
+ */
+
+#define AO_SERIAL_SPEED_UBLOX AO_SERIAL_SPEED_9600
+
+/*
+ * Radio (cc115l)
+ */
+
+/* gets pretty close to 434.550 */
+
+#define AO_RADIO_CAL_DEFAULT 1095378
+
+#define HAS_RADIO_POWER 0
+#define AO_FEC_DEBUG 0
+#define AO_CC115L_SPI_CS_PORT 0
+#define AO_CC115L_SPI_CS_PIN 3
+#define AO_CC115L_SPI_BUS 0
+
+#define AO_CC115L_FIFO_INT_GPIO_IOCFG CC115L_IOCFG2
+#define AO_CC115L_FIFO_INT_PORT 0
+#define AO_CC115L_FIFO_INT_PIN 20
+
+#define AO_CC115L_DONE_INT_GPIO_IOCFG CC115L_IOCFG0
+#define AO_CC115L_DONE_INT_PORT 0
+#define AO_CC115L_DONE_INT_PIN 2
+
+/*
+ * Flash (M25)
+ */
+#define M25_MAX_CHIPS 1
+#define AO_M25_SPI_CS_PORT 0
+#define AO_M25_SPI_CS_MASK (1 << 23)
+#define AO_M25_SPI_BUS 1
+
+#define PACKET_HAS_SLAVE 0
+
+/*
+ * ADC
+ */
+
+#define HAS_ADC 1
+#define LOG_ADC 0
+
+#define AO_DATA_RING 4
+
+#define AO_ADC_3 1
+
+struct ao_adc {
+ int16_t v_batt;
+};
+
+#define AO_ADC_DUMP(p) \
+ printf("tick: %5u batt: %5d\n", \
+ (p)->tick, \
+ (p)->adc.v_batt)
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS 56 /* 5.6k */
+#define AO_BATTERY_DIV_MINUS 100 /* 10k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV 33
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telegps-v1.0/ao_telegps.c b/src/telegps-v1.0/ao_telegps.c
new file mode 100644
index 00000000..7a71699b
--- /dev/null
+++ b/src/telegps-v1.0/ao_telegps.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <ao.h>
+#include <ao_exti.h>
+#include <ao_tracker.h>
+
+int
+main(void)
+{
+ ao_clock_init();
+
+#if HAS_STACK_GUARD
+ ao_mpu_init();
+#endif
+
+ ao_task_init();
+ ao_timer_init();
+
+ ao_spi_init();
+ ao_exti_init();
+
+ ao_storage_init();
+
+ ao_serial_init();
+
+ ao_cmd_init();
+
+ ao_usb_init();
+ ao_radio_init();
+
+#if HAS_ADC
+ ao_adc_init();
+#endif
+
+ ao_gps_init();
+#if HAS_LOG
+ ao_log_init();
+#endif
+
+ ao_tracker_init();
+
+ ao_telemetry_init();
+
+#if HAS_SAMPLE_PROFILE
+ ao_sample_profile_init();
+#endif
+ ao_config_init();
+
+ ao_start_scheduler();
+ return 0;
+}
diff --git a/src/telegps-v1.0/flash-loader/Makefile b/src/telegps-v1.0/flash-loader/Makefile
new file mode 100644
index 00000000..5283f554
--- /dev/null
+++ b/src/telegps-v1.0/flash-loader/Makefile
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=telegps-v1.0
+include $(TOPDIR)/lpc/Makefile-flash.defs
diff --git a/src/lpc/ao_boot.h b/src/telegps-v1.0/flash-loader/ao_pins.h
index e0ed4de7..91097a25 100644
--- a/src/lpc/ao_boot.h
+++ b/src/telegps-v1.0/flash-loader/ao_pins.h
@@ -15,25 +15,19 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#ifndef _AO_BOOT_H_
-#define _AO_BOOT_H_
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
-void
-ao_boot_chain(uint32_t *base);
+#include <ao_flash_lpc_pins.h>
-void
-ao_boot_check_pin(void);
+#define AO_BOOT_PIN 1
+#define AO_BOOT_APPLICATION_GPIO 0
+#define AO_BOOT_APPLICATION_PIN 19
+#define AO_BOOT_APPLICATION_VALUE 1
+#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP
-/* Return true to switch to application (if present) */
-int
-ao_boot_check_chain(void);
+#define HAS_USB_PULLUP 1
+#define AO_USB_PULLUP_PORT 0
+#define AO_USB_PULLUP_PIN 7
-void
-ao_boot_reboot(uint32_t *base);
-
-static inline void
-ao_boot_loader(void) {
- ao_boot_reboot(AO_BOOT_LOADER_BASE);
-}
-
-#endif /* _AO_BOOT_H_ */
+#endif /* _AO_PINS_H_ */
diff --git a/src/telelco-v0.1/Makefile b/src/telelco-v0.1/Makefile
index 44d9237f..f7628c30 100644
--- a/src/telelco-v0.1/Makefile
+++ b/src/telelco-v0.1/Makefile
@@ -9,6 +9,7 @@ INC = \
ao.h \
ao_arch.h \
ao_arch_funcs.h \
+ ao_boot.h \
ao_companion.h \
ao_data.h \
ao_sample.h \
diff --git a/src/telelco-v0.2/Makefile b/src/telelco-v0.2/Makefile
index f28bdd32..7a21f099 100644
--- a/src/telelco-v0.2/Makefile
+++ b/src/telelco-v0.2/Makefile
@@ -9,6 +9,7 @@ INC = \
ao.h \
ao_arch.h \
ao_arch_funcs.h \
+ ao_boot.h \
ao_companion.h \
ao_data.h \
ao_sample.h \
diff --git a/src/telelco-v0.2/ao_lco.c b/src/telelco-v0.2/ao_lco.c
index 0bbb76f1..b3f5bb16 100644
--- a/src/telelco-v0.2/ao_lco.c
+++ b/src/telelco-v0.2/ao_lco.c
@@ -251,18 +251,22 @@ ao_lco_search(void)
{
uint16_t tick_offset;
int8_t r;
+ int8_t try;
uint8_t box;
ao_lco_box_reset_present();
for (box = 0; box < AO_PAD_MAX_BOXES; box++) {
if ((box % 10) == 0)
ao_lco_set_box(box);
- tick_offset = 0;
- r = ao_lco_query(box, &ao_pad_query, &tick_offset);
- PRINTD("box %d result %d\n", box, r);
- if (r == AO_RADIO_CMAC_OK) {
- ao_lco_box_set_present(box);
- ao_delay(AO_MS_TO_TICKS(30));
+ for (try = 0; try < 5; try++) {
+ tick_offset = 0;
+ r = ao_lco_query(box, &ao_pad_query, &tick_offset);
+ PRINTD("box %d result %d\n", box, r);
+ if (r == AO_RADIO_CMAC_OK) {
+ ao_lco_box_set_present(box);
+ ao_delay(AO_MS_TO_TICKS(30));
+ break;
+ }
}
}
if (ao_lco_min_box <= ao_lco_max_box)
diff --git a/src/telelco-v0.2/ao_pins.h b/src/telelco-v0.2/ao_pins.h
index 62f221a1..a6fd4ff8 100644
--- a/src/telelco-v0.2/ao_pins.h
+++ b/src/telelco-v0.2/ao_pins.h
@@ -72,6 +72,8 @@
#define PACKET_HAS_SLAVE 0
#define PACKET_HAS_MASTER 0
+#define FAST_TIMER_FREQ 10000 /* .1ms for debouncing */
+
/*
* Radio is a cc1120 connected via SPI
*/
diff --git a/src/telemega-v0.1/ao_pins.h b/src/telemega-v0.1/ao_pins.h
index db397c66..2616e906 100644
--- a/src/telemega-v0.1/ao_pins.h
+++ b/src/telemega-v0.1/ao_pins.h
@@ -65,12 +65,17 @@
#define ao_gps_fifo (ao_stm_usart3.rx_fifo)
#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1024 * 1024)
+#define AO_CONFIG_MAX_SIZE 1024
+#define LOG_ERASE_MARK 0x55
+#define LOG_MAX_ERASE 128
+
#define HAS_EEPROM 1
#define USE_INTERNAL_FLASH 0
#define USE_EEPROM_CONFIG 1
#define USE_STORAGE_CONFIG 0
#define HAS_USB 1
#define HAS_BEEP 1
+#define HAS_BATTERY_REPORT 1
#define HAS_RADIO 1
#define HAS_TELEMETRY 1
#define HAS_APRS 1
diff --git a/src/telemega-v1.0/Makefile b/src/telemega-v1.0/Makefile
index 7a0c1195..46c768e4 100644
--- a/src/telemega-v1.0/Makefile
+++ b/src/telemega-v1.0/Makefile
@@ -9,6 +9,7 @@ INC = \
ao.h \
ao_arch.h \
ao_arch_funcs.h \
+ ao_boot.h \
ao_companion.h \
ao_data.h \
ao_sample.h \
diff --git a/src/telemega-v1.0/ao_pins.h b/src/telemega-v1.0/ao_pins.h
index fe97c684..77b753d1 100644
--- a/src/telemega-v1.0/ao_pins.h
+++ b/src/telemega-v1.0/ao_pins.h
@@ -65,12 +65,17 @@
#define ao_gps_fifo (ao_stm_usart3.rx_fifo)
#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1024 * 1024)
+#define AO_CONFIG_MAX_SIZE 1024
+#define LOG_ERASE_MARK 0x55
+#define LOG_MAX_ERASE 128
+
#define HAS_EEPROM 1
#define USE_INTERNAL_FLASH 0
#define USE_EEPROM_CONFIG 1
#define USE_STORAGE_CONFIG 0
#define HAS_USB 1
#define HAS_BEEP 1
+#define HAS_BATTERY_REPORT 1
#define HAS_RADIO 1
#define HAS_TELEMETRY 1
#define HAS_APRS 1
diff --git a/src/telemetrum-v1.0/.sdcdbrc b/src/telemetrum-v1.0/.sdcdbrc
index fbe9a599..e9a51ea6 100644
--- a/src/telemetrum-v1.0/.sdcdbrc
+++ b/src/telemetrum-v1.0/.sdcdbrc
@@ -1 +1 @@
---directory=../cc1111:../product:../core:../drivers:.
+--directory=../cc1111:../product:../kernel:../drivers:.
diff --git a/src/telemetrum-v1.1/.sdcdbrc b/src/telemetrum-v1.1/.sdcdbrc
index fbe9a599..e9a51ea6 100644
--- a/src/telemetrum-v1.1/.sdcdbrc
+++ b/src/telemetrum-v1.1/.sdcdbrc
@@ -1 +1 @@
---directory=../cc1111:../product:../core:../drivers:.
+--directory=../cc1111:../product:../kernel:../drivers:.
diff --git a/src/telemetrum-v1.1/Makefile b/src/telemetrum-v1.1/Makefile
index e44be7f9..61e9273b 100644
--- a/src/telemetrum-v1.1/Makefile
+++ b/src/telemetrum-v1.1/Makefile
@@ -12,6 +12,7 @@ TM_SRC = \
ao_companion.c \
ao_gps_skytraq.c \
ao_gps_show.c \
+ ao_convert_volt.c \
ao_m25.c
include ../product/Makefile.telemetrum
diff --git a/src/telemetrum-v1.2/Makefile b/src/telemetrum-v1.2/Makefile
index f2285fbe..38ba6d49 100644
--- a/src/telemetrum-v1.2/Makefile
+++ b/src/telemetrum-v1.2/Makefile
@@ -12,6 +12,7 @@ TM_SRC = \
ao_companion.c \
ao_gps_skytraq.c \
ao_gps_show.c \
+ ao_convert_volt.c \
ao_m25.c
include ../product/Makefile.telemetrum
diff --git a/src/telemetrum-v2.0/Makefile b/src/telemetrum-v2.0/Makefile
index 83a364dc..d77e9585 100644
--- a/src/telemetrum-v2.0/Makefile
+++ b/src/telemetrum-v2.0/Makefile
@@ -9,6 +9,7 @@ INC = \
ao.h \
ao_arch.h \
ao_arch_funcs.h \
+ ao_boot.h \
ao_companion.h \
ao_data.h \
ao_sample.h \
diff --git a/src/telemetrum-v2.0/ao_pins.h b/src/telemetrum-v2.0/ao_pins.h
index 1b5cedc7..a9a4b243 100644
--- a/src/telemetrum-v2.0/ao_pins.h
+++ b/src/telemetrum-v2.0/ao_pins.h
@@ -60,12 +60,17 @@
#define SERIAL_3_PD8_PD9 0
#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (512 * 1024)
+#define AO_CONFIG_MAX_SIZE 1024
+#define LOG_ERASE_MARK 0x55
+#define LOG_MAX_ERASE 128
+
#define HAS_EEPROM 1
#define USE_INTERNAL_FLASH 0
#define USE_EEPROM_CONFIG 1
#define USE_STORAGE_CONFIG 0
#define HAS_USB 1
#define HAS_BEEP 1
+#define HAS_BATTERY_REPORT 1
#define BEEPER_CHANNEL 4
#define HAS_RADIO 1
#define HAS_TELEMETRY 1
diff --git a/src/telemini-v1.0/.sdcdbrc b/src/telemini-v1.0/.sdcdbrc
index b9f6129c..2c77e32b 100644
--- a/src/telemini-v1.0/.sdcdbrc
+++ b/src/telemini-v1.0/.sdcdbrc
@@ -1,2 +1,2 @@
---directory=../cc1111:../product:../core:../drivers:.
+--directory=../cc1111:../product:../kernel:../drivers:.
diff --git a/src/telemini-v2.0/.sdcdbrc b/src/telemini-v2.0/.sdcdbrc
index b9f6129c..2c77e32b 100644
--- a/src/telemini-v2.0/.sdcdbrc
+++ b/src/telemini-v2.0/.sdcdbrc
@@ -1,2 +1,2 @@
---directory=../cc1111:../product:../core:../drivers:.
+--directory=../cc1111:../product:../kernel:../drivers:.
diff --git a/src/telemini-v2.0/Makefile b/src/telemini-v2.0/Makefile
index fcac2c48..ca69dc41 100644
--- a/src/telemini-v2.0/Makefile
+++ b/src/telemini-v2.0/Makefile
@@ -5,8 +5,8 @@
TELEMINI_VER=2.0
TELEMINI_DEF=2_0
-vpath %.c ..:../core:../cc1111:../drivers:../product
-vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath %.c ..:../kernel:../cc1111:../drivers:../product
+vpath %.h ..:../kernel:../cc1111:../drivers:../product
vpath ao-make-product.5c ../util
ifndef VERSION
@@ -30,7 +30,6 @@ INC = \
CORE_SRC = \
ao_cmd.c \
ao_config.c \
- ao_convert.c \
ao_flight.c \
ao_kalman.c \
ao_log.c \
@@ -59,6 +58,7 @@ CC1111_SRC = \
ao_spi.c \
ao_usb.c \
ao_convert_pa.c \
+ ao_convert_volt.c \
ao_beep.c \
ao_timer.c \
ao_exti.c \
diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h
index c4681ee2..f202ccd1 100644
--- a/src/telemini-v2.0/ao_pins.h
+++ b/src/telemini-v2.0/ao_pins.h
@@ -22,8 +22,16 @@
#define HAS_FLIGHT 1
#define HAS_USB 1
+
+#define HAS_USB_PULLUP 1
+#define AO_USB_PULLUP_PORT P1
+#define AO_USB_PULLUP_PIN 0
+#define AO_USB_PULLUP P1_0
+
#define USB_FORCE_FLIGHT_IDLE 1
#define HAS_BEEP 1
+#define HAS_BEEP_CONFIG 0
+#define HAS_BATTERY_REPORT 1
#define HAS_GPS 0
#define HAS_SERIAL_1 0
#define HAS_EEPROM 1
@@ -32,9 +40,8 @@
#define HAS_DBG 0
#define PACKET_HAS_SLAVE 1
-#define AO_LED_GREEN 1
#define AO_LED_RED 2
-#define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN)
+#define LEDS_AVAILABLE AO_LED_RED
#define HAS_EXTERNAL_TEMP 0
#define HAS_ACCEL 0
#define HAS_IGNITE 1
@@ -158,4 +165,21 @@ struct ao_adc {
ao_data_ring[ao_data_head].ms5607_raw.temp = ao_ms5607_current.temp; \
} while (0)
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS 100 /* 100k */
+#define AO_BATTERY_DIV_MINUS 27 /* 27k */
+
+/*
+ * Voltage divider on ADC igniter samplers
+ */
+#define AO_IGNITE_DIV_PLUS 100 /* 100k */
+#define AO_IGNITE_DIV_MINUS 27 /* 27k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV 33
+
#endif /* _AO_PINS_H_ */
diff --git a/src/telepyro-v0.1/Makefile b/src/telepyro-v0.1/Makefile
index 025b324a..dcac03dc 100644
--- a/src/telepyro-v0.1/Makefile
+++ b/src/telepyro-v0.1/Makefile
@@ -2,7 +2,7 @@
# AltOS build
#
#
-vpath % .:..:../core:../product:../drivers:../avr
+vpath % .:..:../kernel:../product:../drivers:../avr
vpath ao-make-product.5c ../util
include ../avr/Makefile.defs
@@ -45,7 +45,7 @@ PRODUCT=TelePyro-v0.1
MCU=atmega32u4
PRODUCT_DEF=-DTELEPYRO
IDPRODUCT=0x0011
-CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../core -I..
+CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../kernel -I..
CFLAGS += -mmcu=$(MCU) -Wall -Wstrict-prototypes -O3 -mcall-prologues -DAVR
NICKLE=nickle
diff --git a/src/telescience-pwm/Makefile b/src/telescience-pwm/Makefile
index de81b8d7..493bd480 100644
--- a/src/telescience-pwm/Makefile
+++ b/src/telescience-pwm/Makefile
@@ -2,7 +2,7 @@
# AltOS build
#
#
-vpath % ..:../core:../product:../drivers:../avr
+vpath % ..:../kernel:../product:../drivers:../avr
vpath ao-make-product.5c ../util
include ../avr/Makefile.defs
@@ -57,7 +57,7 @@ PRODUCT=TeleScience-PWM
MCU=atmega32u4
PRODUCT_DEF=-DTELESCIENCE -DTELESCIENCE_PWM
IDPRODUCT=0x0011
-CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../core -I..
+CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../kernel -I..
CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O3 -mcall-prologues -DAVR
NICKLE=nickle
diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile
index 6e4eb6de..c55c48e2 100644
--- a/src/telescience-v0.1/Makefile
+++ b/src/telescience-v0.1/Makefile
@@ -2,7 +2,7 @@
# AltOS build
#
#
-vpath % ..:../core:../product:../drivers:../avr
+vpath % ..:../kernel:../product:../drivers:../avr
vpath ao-make-product.5c ../util
include ../avr/Makefile.defs
@@ -56,7 +56,7 @@ PRODUCT=TeleScience-v0.1
MCU=atmega32u4
PRODUCT_DEF=-DTELESCIENCE
IDPRODUCT=0x0011
-CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../core -I..
+CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../kernel -I..
CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O3 -mcall-prologues -DAVR
NICKLE=nickle
diff --git a/src/teleshield-v0.1/Makefile b/src/teleshield-v0.1/Makefile
index e8b262ef..f54488a2 100644
--- a/src/teleshield-v0.1/Makefile
+++ b/src/teleshield-v0.1/Makefile
@@ -17,8 +17,8 @@ TELESHIELD_SRC = \
ao_btm.c \
ao_spi.c
-vpath %.c ..:../core:../cc1111:../drivers:../product:.
-vpath %.h ..:../core:../cc1111:../drivers:../product:.
+vpath %.c ..:../kernel:../cc1111:../drivers:../product:.
+vpath %.h ..:../kernel:../cc1111:../drivers:../product:.
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/teleterra-v0.2/.sdcdbrc b/src/teleterra-v0.2/.sdcdbrc
index fbe9a599..e9a51ea6 100644
--- a/src/teleterra-v0.2/.sdcdbrc
+++ b/src/teleterra-v0.2/.sdcdbrc
@@ -1 +1 @@
---directory=../cc1111:../product:../core:../drivers:.
+--directory=../cc1111:../product:../kernel:../drivers:.
diff --git a/src/teleterra-v0.2/Makefile b/src/teleterra-v0.2/Makefile
index 88637360..826c52e5 100644
--- a/src/teleterra-v0.2/Makefile
+++ b/src/teleterra-v0.2/Makefile
@@ -2,8 +2,8 @@
# TeleTerra build file
#
-vpath %.c ..:../core:../cc1111:../drivers:../product
-vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath %.c ..:../kernel:../cc1111:../drivers:../product
+vpath %.h ..:../kernel:../cc1111:../drivers:../product
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/test/Makefile b/src/test/Makefile
index c6025219..017f7f71 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -1,4 +1,4 @@
-vpath % ..:../core:../drivers:../util:../micropeak:../aes:../product
+vpath % ..:../kernel:../drivers:../util:../micropeak:../aes:../product
PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noisy_accel ao_flight_test_mm \
ao_gps_test ao_gps_test_skytraq ao_gps_test_ublox ao_convert_test ao_convert_pa_test ao_fec_test \
@@ -9,7 +9,7 @@ INCS=ao_kalman.h ao_ms5607.h ao_log.h ao_data.h altitude-pa.h altitude.h ao_quat
KALMAN=make-kalman
-CFLAGS=-I.. -I. -I../core -I../drivers -I../micropeak -I../product -O0 -g -Wall
+CFLAGS=-I.. -I. -I../kernel -I../drivers -I../micropeak -I../product -O0 -g -Wall
all: $(PROGS) ao_aprs_data.wav
@@ -52,10 +52,10 @@ ao_kalman.h: $(KALMAN)
(cd .. && make ao_kalman.h)
ao_fec_test: ao_fec_test.c ao_fec_tx.c ao_fec_rx.c
- cc $(CFLAGS) -DAO_FEC_DEBUG=1 -o $@ ao_fec_test.c ../core/ao_fec_tx.c ../core/ao_fec_rx.c -lm
+ cc $(CFLAGS) -DAO_FEC_DEBUG=1 -o $@ ao_fec_test.c ../kernel/ao_fec_tx.c ../kernel/ao_fec_rx.c -lm
ao_aprs_test: ao_aprs_test.c ao_aprs.c
- cc $(CFLAGS) -o $@ ao_aprs_test.c
+ cc $(CFLAGS) -o $@ ao_aprs_test.c -lm
SOX_INPUT_ARGS=--type raw --encoding unsigned-integer -b 8 -c 1 -r 9600
SOX_OUTPUT_ARGS=--type wav
diff --git a/src/test/ao_aprs_test.c b/src/test/ao_aprs_test.c
index 69147786..86cf527a 100644
--- a/src/test/ao_aprs_test.c
+++ b/src/test/ao_aprs_test.c
@@ -23,7 +23,16 @@
#include <ao_telemetry.h>
+#define AO_GPS_NUM_SAT_MASK (0xf << 0)
+#define AO_GPS_NUM_SAT_SHIFT (0)
+
+#define AO_GPS_VALID (1 << 4)
+#define AO_GPS_RUNNING (1 << 5)
+#define AO_GPS_DATE_VALID (1 << 6)
+#define AO_GPS_COURSE_VALID (1 << 7)
+
struct ao_telemetry_location ao_gps_data;
+struct ao_telemetry_satellite ao_gps_tracking_data;
#define AO_APRS_TEST
@@ -73,7 +82,7 @@ ao_radio_send_aprs(ao_radio_fill_func fill);
* 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
- *
+ *
*/
@@ -88,14 +97,42 @@ audio_gap(int secs)
#endif
}
+#include <math.h>
+
+int
+ao_aprs_encode_altitude_expensive(int meters)
+{
+ double feet = meters / 0.3048;
+
+ double encode = log(feet) / log(1.002);
+ return floor(encode + 0.5);
+}
+
// This is where we go after reset.
int main(int argc, char **argv)
{
+ int e, x;
+ int a;
+
+ for (a = 1; a < 100000; a++) {
+ e = ao_aprs_encode_altitude(a);
+ x = ao_aprs_encode_altitude_expensive(a);
+
+ if (e != x) {
+ double back_feet, back_meters;
+ back_feet = pow(1.002, e);
+ back_meters = back_feet * 0.3048;
+ fprintf (stderr, "APRS altitude encoding failure: altitude %d actual %d expected %d actual meters %f\n",
+ a, e, x, back_meters);
+ }
+ }
+
audio_gap(1);
ao_gps_data.latitude = (45.0 + 28.25 / 60.0) * 10000000;
ao_gps_data.longitude = (-(122 + 44.2649 / 60.0)) * 10000000;
ao_gps_data.altitude = 84;
+ ao_gps_data.flags = (AO_GPS_VALID|AO_GPS_RUNNING);
/* Transmit one packet */
ao_aprs_send();
diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c
index 0abb4090..0647fc6c 100644
--- a/src/test/ao_flight_test.c
+++ b/src/test/ao_flight_test.c
@@ -49,13 +49,12 @@ int ao_gps_new;
#define HAS_MPU6000 1
#define HAS_MMA655X 1
#define HAS_HMC5883 1
+#define HAS_BEEP 1
struct ao_adc {
int16_t sense[AO_ADC_NUM_SENSE];
int16_t v_batt;
int16_t v_pbatt;
- int16_t accel_ref;
- int16_t accel;
int16_t temp;
};
#else
@@ -309,7 +308,7 @@ struct ao_cmds {
#if TELEMEGA
#include "ao_convert_pa.c"
#include <ao_ms5607.h>
-struct ao_ms5607_prom ms5607_prom;
+struct ao_ms5607_prom ao_ms5607_prom;
#include "ao_ms5607_convert.c"
#define AO_PYRO_NUM 4
#include <ao_pyro.h>
@@ -317,22 +316,8 @@ struct ao_ms5607_prom ms5607_prom;
#include "ao_convert.c"
#endif
-struct ao_config {
- uint16_t main_deploy;
- int16_t accel_plus_g;
- int16_t accel_minus_g;
- uint8_t pad_orientation;
- uint16_t apogee_lockout;
-#if TELEMEGA
- struct ao_pyro pyro[AO_PYRO_NUM]; /* minor version 12 */
- int16_t accel_zero_along;
- int16_t accel_zero_across;
- int16_t accel_zero_through;
-#endif
-};
-
-#define AO_PAD_ORIENTATION_ANTENNA_UP 0
-#define AO_PAD_ORIENTATION_ANTENNA_DOWN 1
+#include <ao_config.h>
+#include <ao_fake_flight.h>
#define ao_config_get()
@@ -732,6 +717,18 @@ ao_sleep(void *wchan)
ao_flight_started = 1;
ao_ground_pres = int32(bytes, 4);
ao_ground_height = ao_pa_to_altitude(ao_ground_pres);
+ ao_ground_accel_along = int16(bytes, 8);
+ ao_ground_accel_across = int16(bytes, 10);
+ ao_ground_accel_through = int16(bytes, 12);
+ ao_ground_roll = int16(bytes, 14);
+ ao_ground_pitch = int16(bytes, 16);
+ ao_ground_yaw = int16(bytes, 18);
+ ao_ground_mpu6000.accel_x = ao_ground_accel_across;
+ ao_ground_mpu6000.accel_y = ao_ground_accel_along;
+ ao_ground_mpu6000.accel_z = ao_ground_accel_through;
+ ao_ground_mpu6000.gyro_x = ao_ground_pitch >> 9;
+ ao_ground_mpu6000.gyro_y = ao_ground_roll >> 9;
+ ao_ground_mpu6000.gyro_z = ao_ground_yaw >> 9;
break;
case 'A':
ao_data_static.tick = tick;
@@ -768,21 +765,21 @@ ao_sleep(void *wchan)
continue;
} else if (nword == 3 && strcmp(words[0], "ms5607") == 0) {
if (strcmp(words[1], "reserved:") == 0)
- ms5607_prom.reserved = strtoul(words[2], NULL, 10);
+ ao_ms5607_prom.reserved = strtoul(words[2], NULL, 10);
else if (strcmp(words[1], "sens:") == 0)
- ms5607_prom.sens = strtoul(words[2], NULL, 10);
+ ao_ms5607_prom.sens = strtoul(words[2], NULL, 10);
else if (strcmp(words[1], "off:") == 0)
- ms5607_prom.off = strtoul(words[2], NULL, 10);
+ ao_ms5607_prom.off = strtoul(words[2], NULL, 10);
else if (strcmp(words[1], "tcs:") == 0)
- ms5607_prom.tcs = strtoul(words[2], NULL, 10);
+ ao_ms5607_prom.tcs = strtoul(words[2], NULL, 10);
else if (strcmp(words[1], "tco:") == 0)
- ms5607_prom.tco = strtoul(words[2], NULL, 10);
+ ao_ms5607_prom.tco = strtoul(words[2], NULL, 10);
else if (strcmp(words[1], "tref:") == 0)
- ms5607_prom.tref = strtoul(words[2], NULL, 10);
+ ao_ms5607_prom.tref = strtoul(words[2], NULL, 10);
else if (strcmp(words[1], "tempsens:") == 0)
- ms5607_prom.tempsens = strtoul(words[2], NULL, 10);
+ ao_ms5607_prom.tempsens = strtoul(words[2], NULL, 10);
else if (strcmp(words[1], "crc:") == 0)
- ms5607_prom.crc = strtoul(words[2], NULL, 10);
+ ao_ms5607_prom.crc = strtoul(words[2], NULL, 10);
continue;
} else if (nword >= 3 && strcmp(words[0], "Pyro") == 0) {
int p = strtoul(words[1], NULL, 10);
@@ -791,7 +788,7 @@ ao_sleep(void *wchan)
for (i = 2; i < nword; i++) {
for (j = 0; j < NUM_PYRO_VALUES; j++)
- if (!strcmp (words[2], ao_pyro_values[j].name))
+ if (!strcmp (words[i], ao_pyro_values[j].name))
break;
if (j == NUM_PYRO_VALUES)
continue;
@@ -991,6 +988,7 @@ void run_flight_fixed(char *name, FILE *f, int summary, char *info)
emulator_in = f;
emulator_info = info;
ao_summary = summary;
+
ao_flight_init();
ao_flight();
}
diff --git a/src/test/ao_ms5607_convert_test.c b/src/test/ao_ms5607_convert_test.c
index ad593204..1c571f1c 100644
--- a/src/test/ao_ms5607_convert_test.c
+++ b/src/test/ao_ms5607_convert_test.c
@@ -23,7 +23,7 @@
#include <stdint.h>
#include <ao_ms5607.h>
-struct ao_ms5607_prom ms5607_prom = {
+struct ao_ms5607_prom ao_ms5607_prom = {
0x002c,
0xa6e0,
0x988e,
diff --git a/src/tidongle/Makefile b/src/tidongle/Makefile
index b2ba537b..0e90d744 100644
--- a/src/tidongle/Makefile
+++ b/src/tidongle/Makefile
@@ -2,8 +2,8 @@
# TIDongle build file
#
-vpath %.c ..:../core:../cc1111:../drivers:../product
-vpath %.h ..:../core:../cc1111:../drivers:../product
+vpath %.c ..:../kernel:../cc1111:../drivers:../product
+vpath %.h ..:../kernel:../cc1111:../drivers:../product
vpath ao-make-product.5c ../util
ifndef VERSION
diff --git a/src/usbrelay-v0.1/ao_pins.h b/src/usbrelay-v0.1/ao_pins.h
new file mode 100644
index 00000000..a72f6cc8
--- /dev/null
+++ b/src/usbrelay-v0.1/ao_pins.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2014 Bdale Garbee <bdale@gag.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.
+ */
+
+#define HAS_BEEP 0
+
+#define AO_STACK_SIZE 384
+
+#define IS_FLASH_LOADER 0
+
+/* Crystal on the board */
+#define AO_LPC_CLKIN 12000000
+
+/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */
+#define AO_LPC_CLKOUT 48000000
+
+/* System clock frequency */
+#define AO_LPC_SYSCLK 24000000
+
+#define HAS_USB 1
+
+#define HAS_USB_CONNECT 0
+#define HAS_USB_VBUS 0
+#define HAS_USB_PULLUP 1
+#define AO_USB_PULLUP_PORT 0
+#define AO_USB_PULLUP_PIN 6
+
+/* USART */
+
+#define HAS_SERIAL 1
+#define USE_SERIAL_0_STDIN 0
+#define SERIAL_0_18_19 1
+#define SERIAL_0_14_15 0
+#define SERIAL_0_17_18 0
+#define SERIAL_0_26_27 0
+
+/* SPI */
+
+#define HAS_SPI_0 0
+#define SPI_SCK0_P0_6 0
+#define HAS_SPI_1 0
+#define SPI_SCK1_P1_15 0
+#define SPI_MISO1_P0_22 0
+#define SPI_MOSI1_P0_21 0
+
+/* LED */
+
+#define LED_PORT 0
+#define LED_PIN_RED 23
+#define LED_PIN_GREEN 7
+#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)
+
+/* RELAY */
+
+#define RELAY_PORT 0
+#define RELAY_PIN 3
+#define RELAY_BIT (1 << RELAY_PIN)
+
+/* Kludge the SPI driver to not configure any
+ * pin for SCK or MOSI
+ */
+#define HAS_SCK1 0
+#define HAS_MOSI1 0
diff --git a/src/usbrelay-v0.1/ao_serial_lpc.h b/src/usbrelay-v0.1/ao_serial_lpc.h
new file mode 100644
index 00000000..a95b6af1
--- /dev/null
+++ b/src/usbrelay-v0.1/ao_serial_lpc.h
@@ -0,0 +1,33 @@
+#define AO_LPC_USARTCLK 12000000
+
+static const struct {
+ uint16_t dl;
+ uint8_t divaddval;
+ uint8_t mulval;
+} ao_usart_speeds[] = {
+ [AO_SERIAL_SPEED_4800] = { /* actual = 4800.00 */
+ .dl = 125,
+ .divaddval = 1,
+ .mulval = 4
+ },
+ [AO_SERIAL_SPEED_9600] = { /* actual = 9603.07 */
+ .dl = 71,
+ .divaddval = 1,
+ .mulval = 10
+ },
+ [AO_SERIAL_SPEED_19200] = { /* actual = 19181.59 */
+ .dl = 23,
+ .divaddval = 7,
+ .mulval = 10
+ },
+ [AO_SERIAL_SPEED_57600] = { /* actual = 57692.31 */
+ .dl = 7,
+ .divaddval = 6,
+ .mulval = 7
+ },
+ [AO_SERIAL_SPEED_115200] = { /* actual = 115384.6 */
+ .dl = 4,
+ .divaddval = 5,
+ .mulval = 8
+ },
+};
diff --git a/src/usbrelay-v0.1/ao_usbrelay.c b/src/usbrelay-v0.1/ao_usbrelay.c
new file mode 100644
index 00000000..879094b5
--- /dev/null
+++ b/src/usbrelay-v0.1/ao_usbrelay.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2014 Bdale Garbee <bdale@gag.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>
+
+uint8_t relay_output;
+
+void
+ao_relay_init(void)
+{
+ lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_GPIO);
+ lpc_gpio.dir[RELAY_PORT] |= RELAY_BIT;
+}
+
+// switch relay to selected output, turn correct LED on as a side effect
+static void
+ao_relay_control(uint8_t output)
+{
+ switch (output) {
+ case 1:
+ lpc_gpio.pin[RELAY_PORT] |= RELAY_BIT;
+ ao_led_on(AO_LED_RED);
+ ao_led_off(AO_LED_GREEN);
+ break;
+ default:
+ lpc_gpio.pin[RELAY_PORT] &= ~RELAY_BIT;
+ ao_led_off(AO_LED_RED);
+ ao_led_on(AO_LED_GREEN);
+ }
+}
+
+static void
+ao_relay_select(void) __reentrant
+{
+ uint8_t output;
+
+ ao_cmd_decimal();
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ output = ao_cmd_lex_i;
+ if (output > 1)
+ printf ("Invalid relay position %u\n", output);
+ else
+ ao_relay_control(output);
+}
+
+static __code struct ao_cmds ao_relay_cmds[] = {
+ { ao_relay_select, "R <output>\0Select relay output" },
+ { 0, NULL }
+};
+
+void
+main(void)
+{
+ ao_clock_init();
+ ao_task_init();
+ ao_timer_init();
+
+ ao_usb_init();
+
+ ao_serial_init();
+
+ ao_led_init(LEDS_AVAILABLE);
+
+ ao_relay_init();
+
+ // initialize to default output
+ relay_output = 0;
+ ao_relay_control(relay_output);
+
+ ao_cmd_init();
+
+ ao_cmd_register(ao_relay_cmds);
+
+ ao_start_scheduler();
+}
diff --git a/src/usbrelay-v0.1/flash-loader/ao_pins.h b/src/usbrelay-v0.1/flash-loader/ao_pins.h
new file mode 100644
index 00000000..a8046009
--- /dev/null
+++ b/src/usbrelay-v0.1/flash-loader/ao_pins.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+#include <ao_flash_lpc_pins.h>
+
+#define AO_BOOT_PIN 1
+#define AO_BOOT_APPLICATION_GPIO 0
+#define AO_BOOT_APPLICATION_PIN 19
+#define AO_BOOT_APPLICATION_VALUE 1
+#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP
+
+#define HAS_USB_PULLUP 1
+#define AO_USB_PULLUP_PORT 0
+#define AO_USB_PULLUP_PIN 6
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/usbtrng/Makefile b/src/usbtrng/Makefile
new file mode 100644
index 00000000..80e137e7
--- /dev/null
+++ b/src/usbtrng/Makefile
@@ -0,0 +1,70 @@
+#
+# AltOS build
+#
+#
+
+include ../lpc/Makefile.defs
+
+INC = \
+ ao.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_pins.h \
+ ao_product.h \
+ lpc.h
+
+#
+# Common AltOS sources
+#
+ALTOS_SRC = \
+ ao_interrupt.c \
+ ao_boot_chain.c \
+ ao_romconfig.c \
+ ao_product.c \
+ ao_mutex.c \
+ ao_panic.c \
+ ao_stdio.c \
+ ao_task.c \
+ ao_cmd.c \
+ ao_timer_lpc.c \
+ ao_exti_lpc.c \
+ ao_usb_lpc.c \
+ ao_serial_lpc.c \
+ ao_spi_lpc.c \
+ ao_led_lpc.c
+
+PRODUCT=usbtrng-v0.1
+PRODUCT_DEF=-DUSBTRNG_V_0_1
+IDPRODUCT=0x0028
+
+CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS) -g -Os
+
+PROGNAME=usbtrng-v0.1
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_usbtrng.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+$(PROG): Makefile $(OBJ) altos.ld
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+ao_product.h: ao-make-product.5c ../Version
+ $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
+
+$(OBJ): $(INC)
+
+load: $(PROG)
+ lpc-load $(PROG)
+
+distclean: clean
+
+clean:
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f ao_product.h
+
+install:
+
+uninstall:
diff --git a/src/usbtrng/ao_pins.h b/src/usbtrng/ao_pins.h
new file mode 100644
index 00000000..b1fa6eb9
--- /dev/null
+++ b/src/usbtrng/ao_pins.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#define HAS_BEEP 0
+
+#define AO_STACK_SIZE 384
+
+#define IS_FLASH_LOADER 0
+
+/* Crystal on the board */
+#define AO_LPC_CLKIN 12000000
+
+/* Main clock frequency. 48MHz for USB so we don't use the USB PLL */
+#define AO_LPC_CLKOUT 48000000
+
+/* System clock frequency */
+#define AO_LPC_SYSCLK 24000000
+
+#define HAS_USB 1
+
+#define HAS_USB_CONNECT 0
+#define HAS_USB_VBUS 0
+#define HAS_USB_PULLUP 1
+#define AO_USB_PULLUP_PORT 0
+#define AO_USB_PULLUP_PIN 6
+
+/* USART */
+
+#define HAS_SERIAL 1
+#define USE_SERIAL_0_STDIN 0
+#define SERIAL_0_18_19 1
+#define SERIAL_0_14_15 0
+#define SERIAL_0_17_18 0
+#define SERIAL_0_26_27 0
+
+/* SPI */
+
+#define HAS_SPI_0 0
+#define SPI_SCK0_P0_6 0
+#define HAS_SPI_1 1
+#define SPI_SCK1_P1_15 0
+#define SPI_MISO1_P0_22 1
+#define SPI_MOSI1_P0_21 0
+
+/* LED */
+
+#define LED_PORT 0
+#define LED_PIN_RED 3
+#define LED_PIN_GREEN 21
+#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)
+
+/* Kludge the SPI driver to not configure any
+ * pin for SCK or MOSI
+ */
+#define HAS_SCK1 0
+#define HAS_MOSI1 0
diff --git a/src/usbtrng/ao_usbtrng.c b/src/usbtrng/ao_usbtrng.c
new file mode 100644
index 00000000..6b4d20fe
--- /dev/null
+++ b/src/usbtrng/ao_usbtrng.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2014 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>
+
+#define AO_TRNG_SPI_BUS 1
+#define AO_TRNG_SPI_SPEED AO_SPI_SPEED_250kHz
+
+static void
+ao_trng_test(void)
+{
+ static uint8_t random[32];
+ uint8_t i;
+
+ ao_spi_get(AO_TRNG_SPI_BUS, AO_TRNG_SPI_SPEED);
+ ao_spi_recv(random, sizeof (random), AO_TRNG_SPI_BUS);
+ ao_spi_put(AO_TRNG_SPI_BUS);
+ for (i = 0; i < sizeof (random); i++)
+ printf (" %02x", random[i]);
+ printf ("\n");
+}
+
+static const struct ao_cmds ao_trng_cmds[] = {
+ { ao_trng_test, "R\0Dump some random numbers" },
+ { 0, NULL }
+};
+
+void
+main(void)
+{
+ ao_clock_init();
+ ao_task_init();
+ ao_timer_init();
+
+ ao_spi_init();
+ ao_usb_init();
+
+ ao_serial_init();
+
+ ao_led_init(LEDS_AVAILABLE);
+
+ ao_led_on(AO_LED_GREEN);
+
+ ao_cmd_init();
+
+ ao_cmd_register(ao_trng_cmds);
+
+ ao_start_scheduler();
+}
diff --git a/src/usbtrng/flash-loader/Makefile b/src/usbtrng/flash-loader/Makefile
new file mode 100644
index 00000000..e34f1089
--- /dev/null
+++ b/src/usbtrng/flash-loader/Makefile
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=usbtrng-v0.1
+include $(TOPDIR)/lpc/Makefile-flash.defs
diff --git a/src/usbtrng/flash-loader/ao_pins.h b/src/usbtrng/flash-loader/ao_pins.h
new file mode 100644
index 00000000..a8046009
--- /dev/null
+++ b/src/usbtrng/flash-loader/ao_pins.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+#include <ao_flash_lpc_pins.h>
+
+#define AO_BOOT_PIN 1
+#define AO_BOOT_APPLICATION_GPIO 0
+#define AO_BOOT_APPLICATION_PIN 19
+#define AO_BOOT_APPLICATION_VALUE 1
+#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP
+
+#define HAS_USB_PULLUP 1
+#define AO_USB_PULLUP_PORT 0
+#define AO_USB_PULLUP_PIN 6
+
+#endif /* _AO_PINS_H_ */