summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBdale Garbee <bdale@gag.com>2014-09-09 23:28:39 -0600
committerBdale Garbee <bdale@gag.com>2014-09-09 23:28:39 -0600
commit16405fd3eb6f82ef3a709e3ed30fc48faef7b547 (patch)
treec111819b3ba0c9357af41c81b798326b9df7adad /src
parent5a2f6ed6210844f7284fbf9f7ecba68c8a14fa52 (diff)
parent28bd5057252e61bc5b1a35a00bc1f9fdfde097f7 (diff)
Merge branch 'branch-1.5' into debian
Conflicts: ChangeLog Releasing altosui/Instdrv/NSIS/Includes/java.nsh altosui/altos-windows.nsi.in configure.ac doc/Makefile doc/altusmetrum.xsl micropeak/micropeak-windows.nsi.in telegps/telegps-windows.nsi.in
Diffstat (limited to 'src')
-rw-r--r--src/Makefile13
-rw-r--r--src/cc1111/ao_intflash.c2
-rw-r--r--src/cc1111/ao_pins.h26
-rw-r--r--src/cc1111/ao_radio.c176
-rw-r--r--src/cc1111/cc1111.h61
-rw-r--r--src/drivers/ao_aprs.c104
-rw-r--r--src/drivers/ao_cc1120.c338
-rw-r--r--src/drivers/ao_cc1120.h8
-rw-r--r--src/drivers/ao_cc1120_CC1120.h56
-rw-r--r--src/drivers/ao_cc115l.c78
-rw-r--r--src/drivers/ao_gps_skytraq.c9
-rw-r--r--src/drivers/ao_gps_ublox.c12
-rw-r--r--src/drivers/ao_lco_func.c16
-rw-r--r--src/drivers/ao_packet_master.c8
-rw-r--r--src/drivers/ao_pad.c16
-rw-r--r--src/easymega-v1.0/.gitignore (renamed from src/easymega-v0.1/.gitignore)0
-rw-r--r--src/easymega-v1.0/Makefile (renamed from src/easymega-v0.1/Makefile)6
-rw-r--r--src/easymega-v1.0/ao_easymega.c (renamed from src/easymega-v0.1/ao_easymega.c)0
-rw-r--r--src/easymega-v1.0/ao_pins.h (renamed from src/easymega-v0.1/ao_pins.h)3
-rw-r--r--src/easymega-v1.0/flash-loader/Makefile (renamed from src/easymega-v0.1/flash-loader/Makefile)2
-rw-r--r--src/easymega-v1.0/flash-loader/ao_pins.h (renamed from src/easymega-v0.1/flash-loader/ao_pins.h)0
-rwxr-xr-xsrc/kalman/kalman.5c2
-rw-r--r--src/kalman/kalman_micro.5c2
-rw-r--r--src/kernel/ao.h35
-rw-r--r--src/kernel/ao_cmd.c3
-rw-r--r--src/kernel/ao_config.c156
-rw-r--r--src/kernel/ao_config.h22
-rw-r--r--src/kernel/ao_convert.c10
-rw-r--r--src/kernel/ao_convert_pa.c20
-rw-r--r--src/kernel/ao_convert_pa_test.c1
-rw-r--r--src/kernel/ao_data.h6
-rw-r--r--src/kernel/ao_flight.c12
-rw-r--r--src/kernel/ao_forward.c48
-rw-r--r--src/kernel/ao_forward.h24
-rw-r--r--src/kernel/ao_gps_print.c6
-rw-r--r--src/kernel/ao_gps_report.c8
-rw-r--r--src/kernel/ao_gps_report_mega.c7
-rw-r--r--src/kernel/ao_gps_report_metrum.c4
-rw-r--r--src/kernel/ao_gps_show.c8
-rw-r--r--src/kernel/ao_kalman.c147
-rw-r--r--src/kernel/ao_log.c141
-rw-r--r--src/kernel/ao_log.h32
-rw-r--r--src/kernel/ao_log_gps.c17
-rw-r--r--src/kernel/ao_log_gps.h3
-rw-r--r--src/kernel/ao_log_micro.c11
-rw-r--r--src/kernel/ao_microflight.c24
-rw-r--r--src/kernel/ao_microkalman.c12
-rw-r--r--src/kernel/ao_monitor.c4
-rw-r--r--src/kernel/ao_mutex.c23
-rw-r--r--src/kernel/ao_pyro.c59
-rw-r--r--src/kernel/ao_pyro.h3
-rw-r--r--src/kernel/ao_report.c13
-rw-r--r--src/kernel/ao_rssi.c10
-rw-r--r--src/kernel/ao_sample.c2
-rw-r--r--src/kernel/ao_sample.h56
-rw-r--r--src/kernel/ao_telemetry.c40
-rw-r--r--src/kernel/ao_telemetry.h34
-rw-r--r--src/kernel/ao_tracker.c18
-rw-r--r--src/lpc/ao_arch_funcs.h17
-rw-r--r--src/megadongle-v0.1/Makefile1
-rw-r--r--src/megadongle-v0.1/ao_megadongle.c4
-rw-r--r--src/megadongle-v0.1/ao_pins.h49
-rw-r--r--src/microkite/.gitignore2
-rw-r--r--src/microkite/Makefile134
-rw-r--r--src/microkite/ao_pins.h71
-rw-r--r--src/microkite/microkite-load.tmpl20
-rw-r--r--src/micropeak/Makefile41
-rw-r--r--src/micropeak/micropeak-load.tmpl20
-rw-r--r--src/product/Makefile.teledongle2
-rw-r--r--src/product/Makefile.telelaunch2
-rw-r--r--src/product/Makefile.telemetrum1
-rw-r--r--src/product/Makefile.telenano2
-rw-r--r--src/product/ao_micropeak.c3
-rw-r--r--src/product/ao_micropeak.h13
-rw-r--r--src/stm/ao_arch_funcs.h25
-rw-r--r--src/stm/ao_spi_stm.c51
-rw-r--r--src/telebt-v1.0/ao_pins.h2
-rw-r--r--src/telefire-v0.1/Makefile1
-rw-r--r--src/telefire-v0.1/ao_pins.h3
-rw-r--r--src/telefire-v0.2/Makefile1
-rw-r--r--src/telefire-v0.2/ao_pins.h6
-rw-r--r--src/telegps-v1.0/ao_pins.h2
-rw-r--r--src/telelco-v0.2/ao_lco.c2
-rw-r--r--src/telelco-v0.2/ao_pins.h1
-rw-r--r--src/telemega-v1.0/Makefile1
-rw-r--r--src/telemini-v2.0/Makefile3
-rw-r--r--src/telemini-v2.0/ao_pins.h7
-rw-r--r--src/telerepeat-v1.0/Makefile100
-rw-r--r--src/telerepeat-v1.0/ao_pins.h111
-rw-r--r--src/telerepeat-v1.0/ao_telerepeat.c47
-rw-r--r--src/teleshield-v0.1/ao_pins.h1
-rw-r--r--src/teleterra-v0.2/ao_pins.h4
-rw-r--r--src/test/Makefile4
-rw-r--r--src/test/ao_aprs_test.c31
-rw-r--r--src/test/ao_flight_test.c122
-rw-r--r--src/test/ao_gps_test.c5
-rw-r--r--src/test/ao_gps_test_skytraq.c4
-rw-r--r--src/test/ao_gps_test_ublox.c9
-rw-r--r--src/test/ao_micropeak_test.c1
-rwxr-xr-xsrc/test/plottest6
-rw-r--r--src/util/make-altitude-pa184
101 files changed, 2395 insertions, 678 deletions
diff --git a/src/Makefile b/src/Makefile
index 4e8b3c20..20126de6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -22,9 +22,11 @@ SDCCDIRS=\
telemini-v1.0 telemini-v2.0 \
telebt-v1.0 \
teleterra-v0.2 teleshield-v0.1 \
- telefire-v0.1 telefire-v0.2
+ telefire-v0.1 telefire-v0.2 \
+ telerepeat-v1.0
ARMM3DIRS=\
+ easymega-v1.0 easymega-v1.0/flash-loader \
telemega-v0.1 telemega-v0.1/flash-loader \
telemega-v1.0 telemega-v1.0/flash-loader \
telemetrum-v2.0 telemetrum-v2.0/flash-loader \
@@ -39,7 +41,7 @@ ARMM0DIRS=\
easymini-v1.0 easymini-v1.0/flash-loader
AVRDIRS=\
- telescience-v0.1 telescience-pwm micropeak nanopeak-v0.1
+ telescience-v0.1 telescience-pwm micropeak nanopeak-v0.1 microkite
SUBDIRS=
@@ -98,7 +100,7 @@ uninstall:
all-recursive: all-local
-all-local: altitude.h altitude-pa.h ao_kalman.h ao_whiten.h $(PDCLIB)
+all-local: altitude.h altitude-pa.h altitude-pa-small.h ao_kalman.h ao_whiten.h $(PDCLIB)
altitude.h: make-altitude
nickle $< > $@
@@ -106,7 +108,10 @@ altitude.h: make-altitude
altitude-pa.h: make-altitude-pa
nickle $< > $@
-ao_kalman.h: make-kalman kalman.5c kalman_filter.5c load_csv.5c matrix.5c
+altitude-pa-small.h: make-altitude-pa
+ nickle $< --sample 3 > $@
+
+ao_kalman.h: make-kalman kalman.5c kalman_micro.5c kalman_filter.5c load_csv.5c matrix.5c
bash $< kalman > $@
ao_whiten.h: make-whiten
diff --git a/src/cc1111/ao_intflash.c b/src/cc1111/ao_intflash.c
index 632e2a85..eb3535c6 100644
--- a/src/cc1111/ao_intflash.c
+++ b/src/cc1111/ao_intflash.c
@@ -129,6 +129,8 @@ ao_intflash_write_aligned(uint16_t pos, __xdata void *d, uint16_t len) __reentra
nop
_endasm;
}
+ __critical while (!ao_intflash_dma_done)
+ ao_sleep(&ao_intflash_dma_done);
}
static void
diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h
index 2b19f1f6..e12f813f 100644
--- a/src/cc1111/ao_pins.h
+++ b/src/cc1111/ao_pins.h
@@ -20,6 +20,8 @@
#define HAS_RADIO 1
#define DISABLE_LOG_SPACE 1
+#define AO_VALUE_32 0
+#define HAS_WIDE_GPS 0
#if defined(TELEMETRUM_V_1_0)
/* Discontinued and was never built with CC1111 chips needing this */
@@ -56,6 +58,9 @@
#define HAS_ACCEL 1
#define HAS_IGNITE 1
#define HAS_MONITOR 0
+ #define HAS_TELEMETRY 1
+ #define HAS_RADIO_RATE 0 /* not enough space for this */
+ #define HAS_MUTEX_TRY 0
#endif
#if defined(TELEMETRUM_V_1_1)
@@ -96,6 +101,9 @@
#define HAS_ACCEL 1
#define HAS_IGNITE 1
#define HAS_MONITOR 0
+ #define HAS_TELEMETRY 1
+ #define HAS_RADIO_RATE 0 /* not enough space for this */
+ #define HAS_MUTEX_TRY 0
#endif
#if defined(TELEMETRUM_V_1_2)
@@ -136,6 +144,9 @@
#define HAS_ACCEL 1
#define HAS_IGNITE 1
#define HAS_MONITOR 0
+ #define HAS_TELEMETRY 1
+ #define HAS_RADIO_RATE 0 /* not enough space for this */
+ #define HAS_MUTEX_TRY 0
#endif
#if defined(TELEDONGLE_V_0_2)
@@ -164,6 +175,8 @@
#define LEGACY_MONITOR 1
#define HAS_RSSI 1
#define HAS_AES 0
+ #define HAS_TELEMETRY 0
+ #define AO_RADIO_REG_TEST 1
#endif
#if defined(TELEMINI_V_1_0)
@@ -193,6 +206,8 @@
#define HAS_ACCEL 0
#define HAS_IGNITE 1
#define HAS_MONITOR 0
+ #define HAS_TELEMETRY 1
+ #define HAS_RADIO_RATE 0 /* not enough space for this */
#endif
#if defined(TELENANO_V_0_1)
@@ -220,6 +235,8 @@
#define HAS_ACCEL 0
#define HAS_IGNITE 0
#define HAS_MONITOR 0
+ #define HAS_TELEMETRY 1
+ #define HAS_RADIO_RATE 0 /* not enough space for this */
#endif
#if defined(TELEMETRUM_V_0_1)
@@ -252,6 +269,8 @@
#define HAS_ACCEL 1
#define HAS_IGNITE 1
#define HAS_MONITOR 0
+ #define HAS_TELEMETRY 1
+ #define HAS_RADIO_RATE 0 /* not enough space for this */
#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX ((uint32_t) 127 * (uint32_t) 1024)
#endif
@@ -283,6 +302,7 @@
#define LEGACY_MONITOR 1
#define HAS_RSSI 1
#define HAS_AES 0
+ #define HAS_TELEMETRY 0
#endif
#if defined(TIDONGLE)
@@ -312,6 +332,7 @@
#define LEGACY_MONITOR 1
#define HAS_RSSI 1
#define HAS_AES 0
+ #define HAS_TELEMETRY 0
#endif
#if defined(TELEBT_V_0_0)
@@ -350,6 +371,8 @@
#define LEGACY_MONITOR 1
#define HAS_RSSI 0
#define HAS_AES 0
+ #define HAS_TELEMETRY 0
+ #define AO_RADIO_REG_TEST 1
#endif
#if defined(TELEBT_V_0_1)
@@ -396,6 +419,8 @@
#define LEGACY_MONITOR 1
#define HAS_RSSI 0
#define HAS_AES 0
+ #define HAS_TELEMETRY 0
+ #define AO_RADIO_REG_TEST 1
#endif
#if defined(TELELAUNCH_V_0_1)
@@ -428,6 +453,7 @@
#define HAS_IGNITE 1
#define HAS_MONITOR 0
#define HAS_AES 1
+ #define HAS_TELEMETRY 0
#endif
#if DBG_ON_P1
diff --git a/src/cc1111/ao_radio.c b/src/cc1111/ao_radio.c
index 190647ce..b9821a42 100644
--- a/src/cc1111/ao_radio.c
+++ b/src/cc1111/ao_radio.c
@@ -40,6 +40,42 @@
#define IF_FREQ_CONTROL 6
/*
+ * http://www.ntia.doc.gov/files/ntia/publications/84-168.pdf
+ *
+ * Necessary bandwidth for a FSK modulated signal:
+ *
+ * bw = 2.6d + 0.55b 1.5 < m < 5.5
+ * bw = 2.1d + 1.9b 5.5 < m < 20
+ *
+ * b is the modulation rate in bps
+ * d is the peak deviation (from the center)
+ *
+ * m = 2d / b
+ *
+ * 20.5 kHz deviation 38.4kbps signal:
+ *
+ * m = 41 / 38.4, which is < 5.5:
+ *
+ * bw = 2.6 * 20.5 + 0.55 * 38.4 = 74.42kHz
+ *
+ * M = 1, E = 3, bw = 75kHz
+ *
+ * 5.125 kHz deviation, 9.6kbps signal
+ *
+ * m = 10.25 / 9.6, which is < 5.5:
+ *
+ * bw = 2.6 * 5.125 + 0.55 * 9.6 = 18.6kHz
+ *
+ * M = 2, E = 3, bw = 53.6kHz
+ *
+ * 1.28125kHz deviation, 2.4kbps signal
+ *
+ * m = 2.565 / 2.4, which is < 5.5:
+ *
+ * bw = 2.6 * 20.5 + 1.9 * 2.4 = 47.61kHz
+ *
+ * M = 3, E = 3, bw = 53.6kHz
+ *
* For channel bandwidth of 93.75 kHz, the CHANBW_E and CHANBW_M values are
*
* BW = 24e6 / (8 * (4 + M) * 2 ** E)
@@ -47,7 +83,9 @@
* So, M = 0 and E = 3
*/
-#define CHANBW_M 0
+#define CHANBW_M_384 1
+#define CHANBW_M_96 3
+#define CHANBW_M_24 3
#define CHANBW_E 3
/*
@@ -55,22 +93,41 @@
*
* R = (256 + M) * 2** E * 24e6 / 2**28
*
- * So M is 163 and E is 10
+ * So for 38360kBaud, M is 163 and E is 10
*/
-#define DRATE_E 10
#define DRATE_M 163
+#define DRATE_E_384 10
+
+/* For 9600 baud, M is 163 and E is 8
+ */
+
+#define DRATE_E_96 8
+
+/* For 2400 baud, M is 163 and E is 6
+ */
+
+#define DRATE_E_24 6
+
/*
* For a channel deviation of 20.5kHz, the DEVIATION_E and DEVIATION_M values are:
*
* F = 24e6/2**17 * (8 + DEVIATION_M) * 2**DEVIATION_E
*
- * So M is 6 and E is 3
+ * For 20.5kHz deviation, M is 6 and E is 3
+ * For 5.125kHz deviation, M is 6 and E is 1
+ * For 1.28125kHz deviation, M is 0 and E is 0
*/
-#define DEVIATION_M 6
-#define DEVIATION_E 3
+#define DEVIATION_M_384 6
+#define DEVIATION_E_384 3
+
+#define DEVIATION_M_96 6
+#define DEVIATION_E_96 1
+
+#define DEVIATION_M_24 0
+#define DEVIATION_E_24 0
/*
* For our RDF beacon, set the symbol rate to 2kBaud (for a 1kHz tone),
@@ -122,13 +179,10 @@ static __code uint8_t radio_setup[] = {
RF_FSCTRL1_OFF, (IF_FREQ_CONTROL << RF_FSCTRL1_FREQ_IF_SHIFT),
RF_FSCTRL0_OFF, (0 << RF_FSCTRL0_FREQOFF_SHIFT),
- RF_MDMCFG4_OFF, ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
- (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) |
- (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)),
RF_MDMCFG3_OFF, (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
- RF_MDMCFG2_OFF, (RF_MDMCFG2_DEM_DCFILT_OFF |
+ RF_MDMCFG2_OFF, (RF_MDMCFG2_DEM_DCFILT_ON |
RF_MDMCFG2_MOD_FORMAT_GFSK |
- RF_MDMCFG2_SYNC_MODE_15_16_THRES),
+ RF_MDMCFG2_SYNC_MODE_15_16),
RF_MDMCFG1_OFF, (RF_MDMCFG1_FEC_EN |
RF_MDMCFG1_NUM_PREAMBLE_4 |
(2 << RF_MDMCFG1_CHANSPC_E_SHIFT)),
@@ -136,9 +190,6 @@ static __code uint8_t radio_setup[] = {
RF_CHANNR_OFF, 0,
- RF_DEVIATN_OFF, ((DEVIATION_E << RF_DEVIATN_DEVIATION_E_SHIFT) |
- (DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)),
-
/* SmartRF says set LODIV_BUF_CURRENT_TX to 0
* And, we're not using power ramping, so use PA_POWER 0
*/
@@ -155,8 +206,8 @@ static __code uint8_t radio_setup[] = {
RF_FSCAL1_OFF, 0x00,
RF_FSCAL0_OFF, 0x1F,
- RF_TEST2_OFF, 0x88,
- RF_TEST1_OFF, 0x31,
+ RF_TEST2_OFF, RF_TEST2_RX_LOW_DATA_RATE_MAGIC,
+ RF_TEST1_OFF, RF_TEST1_RX_LOW_DATA_RATE_MAGIC,
RF_TEST0_OFF, 0x09,
/* default sync values */
@@ -187,10 +238,16 @@ static __code uint8_t radio_setup[] = {
RF_BSCFG_BS_POST_KI_PRE_KI|
RF_BSCFG_BS_POST_KP_PRE_KP|
RF_BSCFG_BS_LIMIT_0),
- RF_AGCCTRL2_OFF, 0x03,
- RF_AGCCTRL1_OFF, 0x40,
- RF_AGCCTRL0_OFF, 0x91,
-
+ RF_AGCCTRL2_OFF, (RF_AGCCTRL2_MAX_DVGA_GAIN_ALL|
+ RF_AGCCTRL2_MAX_LNA_GAIN_0|
+ RF_AGCCTRL2_MAGN_TARGET_33dB),
+ RF_AGCCTRL1_OFF, (RF_AGCCTRL1_AGC_LNA_PRIORITY_0 |
+ RF_AGCCTRL1_CARRIER_SENSE_REL_THR_DISABLE |
+ RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_0DB),
+ RF_AGCCTRL0_OFF, (RF_AGCCTRL0_HYST_LEVEL_NONE |
+ RF_AGCCTRL0_WAIT_TIME_8 |
+ RF_AGCCTRL0_AGC_FREEZE_NORMAL |
+ RF_AGCCTRL0_FILTER_LENGTH_8),
RF_IOCFG2_OFF, 0x00,
RF_IOCFG1_OFF, 0x00,
RF_IOCFG0_OFF, 0x00,
@@ -198,7 +255,7 @@ static __code uint8_t radio_setup[] = {
static __code uint8_t rdf_setup[] = {
RF_MDMCFG4_OFF, ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
- (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) |
+ (CHANBW_M_384 << RF_MDMCFG4_CHANBW_M_SHIFT) |
(RDF_DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)),
RF_MDMCFG3_OFF, (RDF_DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
RF_MDMCFG2_OFF, (RF_MDMCFG2_DEM_DCFILT_OFF |
@@ -212,26 +269,30 @@ static __code uint8_t rdf_setup[] = {
(RDF_DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)),
/* packet length is set in-line */
- RF_PKTCTRL1_OFF, ((1 << PKTCTRL1_PQT_SHIFT)|
+ RF_PKTCTRL1_OFF, ((0 << PKTCTRL1_PQT_SHIFT)|
PKTCTRL1_ADR_CHK_NONE),
RF_PKTCTRL0_OFF, (RF_PKTCTRL0_PKT_FORMAT_NORMAL|
RF_PKTCTRL0_LENGTH_CONFIG_FIXED),
};
static __code uint8_t fixed_pkt_setup[] = {
+#if !HAS_RADIO_RATE
RF_MDMCFG4_OFF, ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
- (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) |
- (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)),
+ (CHANBW_M_384 << RF_MDMCFG4_CHANBW_M_SHIFT) |
+ (DRATE_E_384 << RF_MDMCFG4_DRATE_E_SHIFT)),
+#endif
RF_MDMCFG3_OFF, (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
- RF_MDMCFG2_OFF, (RF_MDMCFG2_DEM_DCFILT_OFF |
+ RF_MDMCFG2_OFF, (RF_MDMCFG2_DEM_DCFILT_ON |
RF_MDMCFG2_MOD_FORMAT_GFSK |
- RF_MDMCFG2_SYNC_MODE_15_16_THRES),
+ RF_MDMCFG2_SYNC_MODE_15_16),
RF_MDMCFG1_OFF, (RF_MDMCFG1_FEC_EN |
RF_MDMCFG1_NUM_PREAMBLE_4 |
(2 << RF_MDMCFG1_CHANSPC_E_SHIFT)),
- RF_DEVIATN_OFF, ((DEVIATION_E << RF_DEVIATN_DEVIATION_E_SHIFT) |
- (DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)),
+#if !HAS_RADIO_RATE
+ RF_DEVIATN_OFF, ((DEVIATION_E_384 << RF_DEVIATN_DEVIATION_E_SHIFT) |
+ (DEVIATION_M_384 << RF_DEVIATN_DEVIATION_M_SHIFT)),
+#endif
/* max packet length -- now set inline */
RF_PKTCTRL1_OFF, ((1 << PKTCTRL1_PQT_SHIFT)|
@@ -243,6 +304,38 @@ static __code uint8_t fixed_pkt_setup[] = {
RF_PKTCTRL0_LENGTH_CONFIG_FIXED),
};
+#if HAS_RADIO_RATE
+static __code struct {
+ uint8_t mdmcfg4;
+ uint8_t deviatn;
+} packet_rate_setup[] = {
+ /* 38400 */
+ {
+ ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
+ (CHANBW_M_384 << RF_MDMCFG4_CHANBW_M_SHIFT) |
+ (DRATE_E_384 << RF_MDMCFG4_DRATE_E_SHIFT)),
+ ((DEVIATION_E_384 << RF_DEVIATN_DEVIATION_E_SHIFT) |
+ (DEVIATION_M_384 << RF_DEVIATN_DEVIATION_M_SHIFT)),
+ },
+ /* 9600 */
+ {
+ ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
+ (CHANBW_M_96 << RF_MDMCFG4_CHANBW_M_SHIFT) |
+ (DRATE_E_96 << RF_MDMCFG4_DRATE_E_SHIFT)),
+ ((DEVIATION_E_96 << RF_DEVIATN_DEVIATION_E_SHIFT) |
+ (DEVIATION_M_96 << RF_DEVIATN_DEVIATION_M_SHIFT)),
+ },
+ /* 2400 */
+ {
+ ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
+ (CHANBW_M_24 << RF_MDMCFG4_CHANBW_M_SHIFT) |
+ (DRATE_E_24 << RF_MDMCFG4_DRATE_E_SHIFT)),
+ ((DEVIATION_E_24 << RF_DEVIATN_DEVIATION_E_SHIFT) |
+ (DEVIATION_M_24 << RF_DEVIATN_DEVIATION_M_SHIFT)),
+ },
+};
+#endif
+
__xdata uint8_t ao_radio_dma;
__xdata uint8_t ao_radio_dma_done;
__xdata uint8_t ao_radio_done;
@@ -308,6 +401,10 @@ ao_radio_get(uint8_t len)
RF_FREQ1 = (uint8_t) (ao_config.radio_setting >> 8);
RF_FREQ0 = (uint8_t) (ao_config.radio_setting);
RF_PKTLEN = len;
+#if HAS_RADIO_RATE
+ RF_MDMCFG4 = packet_rate_setup[ao_config.radio_rate].mdmcfg4;
+ RF_DEVIATN = packet_rate_setup[ao_config.radio_rate].deviatn;
+#endif
}
@@ -551,8 +648,31 @@ ao_radio_test_cmd(void)
ao_radio_test(0);
}
+#if AO_RADIO_REG_TEST
+static void
+ao_radio_set_reg(void)
+{
+ uint8_t offset;
+ ao_cmd_hex();
+ offset = ao_cmd_lex_i;
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ ao_cmd_hex();
+ printf("RF[%x] %x", offset, RF[offset]);
+ if (ao_cmd_status == ao_cmd_success) {
+ RF[offset] = ao_cmd_lex_i;
+ printf (" -> %x", RF[offset]);
+ }
+ ao_cmd_status = ao_cmd_success;
+ printf("\n");
+}
+#endif
+
__code struct ao_cmds ao_radio_cmds[] = {
{ ao_radio_test_cmd, "C <1 start, 0 stop, none both>\0Radio carrier test" },
+#if AO_RADIO_REG_TEST
+ { ao_radio_set_reg, "V <offset> <value>\0Set radio register" },
+#endif
{ 0, NULL },
};
diff --git a/src/cc1111/cc1111.h b/src/cc1111/cc1111.h
index 80d3fb70..ac1e71c9 100644
--- a/src/cc1111/cc1111.h
+++ b/src/cc1111/cc1111.h
@@ -1165,12 +1165,73 @@ __xdata __at (0xdf16) uint8_t RF_BSCFG;
__xdata __at (0xdf17) uint8_t RF_AGCCTRL2;
#define RF_AGCCTRL2_OFF 0x17
+#define RF_AGCCTRL2_MAX_DVGA_GAIN_ALL (0 << 6)
+#define RF_AGCCTRL2_MAX_DVGA_GAIN_BUT_1 (1 << 6)
+#define RF_AGCCTRL2_MAX_DVGA_GAIN_BUT_2 (2 << 6)
+#define RF_AGCCTRL2_MAX_DVGA_GAIN_BUT_3 (3 << 6)
+#define RF_AGCCTRL2_MAX_LNA_GAIN_0 (0 << 3)
+#define RF_AGCCTRL2_MAX_LNA_GAIN_2_6 (1 << 3)
+#define RF_AGCCTRL2_MAX_LNA_GAIN_6_1 (2 << 3)
+#define RF_AGCCTRL2_MAX_LNA_GAIN_7_4 (3 << 3)
+#define RF_AGCCTRL2_MAX_LNA_GAIN_9_2 (4 << 3)
+#define RF_AGCCTRL2_MAX_LNA_GAIN_11_5 (5 << 3)
+#define RF_AGCCTRL2_MAX_LNA_GAIN_14_6 (6 << 3)
+#define RF_AGCCTRL2_MAX_LNA_GAIN_17_1 (7 << 3)
+#define RF_AGCCTRL2_MAGN_TARGET_24dB (0 << 0)
+#define RF_AGCCTRL2_MAGN_TARGET_27dB (1 << 0)
+#define RF_AGCCTRL2_MAGN_TARGET_30dB (2 << 0)
+#define RF_AGCCTRL2_MAGN_TARGET_33dB (3 << 0)
+#define RF_AGCCTRL2_MAGN_TARGET_36dB (4 << 0)
+#define RF_AGCCTRL2_MAGN_TARGET_38dB (5 << 0)
+#define RF_AGCCTRL2_MAGN_TARGET_40dB (6 << 0)
+#define RF_AGCCTRL2_MAGN_TARGET_42dB (7 << 0)
+
__xdata __at (0xdf18) uint8_t RF_AGCCTRL1;
#define RF_AGCCTRL1_OFF 0x18
+#define RF_AGCCTRL1_AGC_LNA_PRIORITY_0 (0 << 6)
+#define RF_AGCCTRL1_AGC_LNA_PRIORITY_1 (1 << 6)
+#define RF_AGCCTRL1_CARRIER_SENSE_REL_THR_DISABLE (0 << 4)
+#define RF_AGCCTRL1_CARRIER_SENSE_REL_THR_6DB (1 << 4)
+#define RF_AGCCTRL1_CARRIER_SENSE_REL_THR_10DB (2 << 4)
+#define RF_AGCCTRL1_CARRIER_SENSE_REL_THR_14DB (3 << 4)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_DISABLE (0x8 << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_7DB_BELOW (0x9 << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_6DB_BELOW (0xa << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_5DB_BELOW (0xb << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_4DB_BELOW (0xc << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_3DB_BELOW (0xd << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_2DB_BELOW (0xe << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_1DB_BELOW (0xf << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_0DB (0x0 << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_1DB_ABOVE (0x1 << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_2DB_ABOVE (0x2 << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_3DB_ABOVE (0x3 << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_4DB_ABOVE (0x4 << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_5DB_ABOVE (0x5 << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_6DB_ABOVE (0x6 << 0)
+#define RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_7DB_ABOVE (0x7 << 0)
+
__xdata __at (0xdf19) uint8_t RF_AGCCTRL0;
#define RF_AGCCTRL0_OFF 0x19
+#define RF_AGCCTRL0_HYST_LEVEL_NONE (0 << 6)
+#define RF_AGCCTRL0_HYST_LEVEL_LOW (1 << 6)
+#define RF_AGCCTRL0_HYST_LEVEL_MEDIUM (2 << 6)
+#define RF_AGCCTRL0_HYST_LEVEL_HIGH (3 << 6)
+#define RF_AGCCTRL0_WAIT_TIME_8 (0 << 4)
+#define RF_AGCCTRL0_WAIT_TIME_16 (1 << 4)
+#define RF_AGCCTRL0_WAIT_TIME_24 (2 << 4)
+#define RF_AGCCTRL0_WAIT_TIME_32 (3 << 4)
+#define RF_AGCCTRL0_AGC_FREEZE_NORMAL (0 << 2)
+#define RF_AGCCTRL0_AGC_FREEZE_SYNC (1 << 2)
+#define RF_AGCCTRL0_AGC_FREEZE_MANUAL_ANALOG (2 << 2)
+#define RF_AGCCTRL0_AGC_FREEZE_MANUAL_BOTH (3 << 2)
+#define RF_AGCCTRL0_FILTER_LENGTH_8 (0 << 0)
+#define RF_AGCCTRL0_FILTER_LENGTH_16 (1 << 0)
+#define RF_AGCCTRL0_FILTER_LENGTH_32 (2 << 0)
+#define RF_AGCCTRL0_FILTER_LENGTH_64 (3 << 0)
+
__xdata __at (0xdf1a) uint8_t RF_FREND1;
#define RF_FREND1_OFF 0x1a
diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c
index 8a1b6a4d..19beb78f 100644
--- a/src/drivers/ao_aprs.c
+++ b/src/drivers/ao_aprs.c
@@ -1,11 +1,11 @@
-/**
+/**
* http://ad7zj.net/kd7lmo/aprsbeacon_code.html
*
* @mainpage Pico Beacon
*
* @section overview_sec Overview
*
- * The Pico Beacon is an APRS based tracking beacon that operates in the UHF 420-450MHz band. The device utilizes a
+ * The Pico Beacon is an APRS based tracking beacon that operates in the UHF 420-450MHz band. The device utilizes a
* Microchip PIC 18F2525 embedded controller, Motorola M12+ GPS engine, and Analog Devices AD9954 DDS. The device is capable
* of generating a 1200bps A-FSK and 9600 bps FSK AX.25 compliant APRS (Automatic Position Reporting System) message.
@@ -24,7 +24,7 @@
* (4) corrected size of LOG_COORD block when searching for end of log.
*
* @subsection v303 V3.03
- * 15 Sep 2005, Change include; (1) removed AD9954 setting SDIO as input pin,
+ * 15 Sep 2005, Change include; (1) removed AD9954 setting SDIO as input pin,
* (2) additional comments and Doxygen tags,
* (3) integration and test code calculates DDS FTW,
* (4) swapped bus and reference analog input ports (hardware change),
@@ -38,7 +38,7 @@
* (2) Doxygen documentation clean up and additions, and
* (3) added integration and test code to baseline.
*
- *
+ *
* @subsection v301 V3.01
* 13 Jan 2005, Renamed project and files to Pico Beacon.
*
@@ -54,28 +54,28 @@
* (8) added flight data recorder, and
* (9) added diagnostics terminal mode.
*
- *
+ *
* @subsection v201 V2.01
- * 30 Jan 2004, Change include; (1) General clean up of in-line documentation, and
+ * 30 Jan 2004, Change include; (1) General clean up of in-line documentation, and
* (2) changed temperature resolution to 0.1 degrees F.
*
- *
+ *
* @subsection v200 V2.00
* 26 Oct 2002, Change include; (1) Micro Beacon II hardware changes including PIC18F252 processor,
- * (2) serial EEPROM,
- * (3) GPS power control,
- * (4) additional ADC input, and
- * (5) LM60 temperature sensor.
+ * (2) serial EEPROM,
+ * (3) GPS power control,
+ * (4) additional ADC input, and
+ * (5) LM60 temperature sensor.
*
*
* @subsection v101 V1.01
- * 5 Dec 2001, Change include; (1) Changed startup message, and
+ * 5 Dec 2001, Change include; (1) Changed startup message, and
* (2) applied SEPARATE pragma to several methods for memory usage.
*
*
* @subsection v100 V1.00
* 25 Sep 2001, Initial release. Flew ANSR-3 and ANSR-4.
- *
+ *
*
@@ -102,11 +102,11 @@
* 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
- *
+ *
- *
- *
+ *
+ *
* @section design Design Details
*
* Provides design details on a variety of the components that make up the Pico Beacon.
@@ -118,29 +118,33 @@
* @page power Power Consumption
*
* Measured DC power consumption.
- *
- * 3VDC prime power current
+ *
+ * 3VDC prime power current
*
- * 7mA Held in reset
+ * 7mA Held in reset
- * 18mA Processor running, all I/O off
+ * 18mA Processor running, all I/O off
- * 110mA GPS running
+ * 110mA GPS running
- * 120mA GPS running w/antenna
+ * 120mA GPS running w/antenna
- * 250mA DDS running and GPS w/antenna
+ * 250mA DDS running and GPS w/antenna
- * 420mA DDS running, GPS w/antenna, and PA chain on with no RF
+ * 420mA DDS running, GPS w/antenna, and PA chain on with no RF
- * 900mA Transmit
+ * 900mA Transmit
*
*/
#ifndef AO_APRS_TEST
#include <ao.h>
+
+#if !HAS_APRS
+#error HAS_APRS not set
+#endif
#endif
#include <ao_aprs.h>
@@ -176,11 +180,11 @@ static uint16_t sysCRC16(const uint8_t *buffer, uint8_t length, uint16_t crc)
{
uint8_t i, bit, value;
- for (i = 0; i < length; ++i)
+ for (i = 0; i < length; ++i)
{
value = buffer[i];
- for (bit = 0; bit < 8; ++bit)
+ for (bit = 0; bit < 8; ++bit)
{
crc ^= (value & 0x01);
crc = ( crc & 0x01 ) ? ( crc >> 1 ) ^ 0x8408 : ( crc >> 1 );
@@ -253,7 +257,7 @@ typedef enum
/// AX.25 compliant packet header that contains destination, station call sign, and path.
/// 0x76 for SSID-11, 0x78 for SSID-12
-static uint8_t TNC_AX25_HEADER[] = {
+static uint8_t TNC_AX25_HEADER[] = {
'A' << 1, 'P' << 1, 'A' << 1, 'M' << 1, ' ' << 1, ' ' << 1, 0x60,
'N' << 1, '0' << 1, 'C' << 1, 'A' << 1, 'L' << 1, 'L' << 1, 0x78,
'W' << 1, 'I' << 1, 'D' << 1, 'E' << 1, '2' << 1, ' ' << 1, 0x65,
@@ -261,6 +265,7 @@ static uint8_t TNC_AX25_HEADER[] = {
#define TNC_CALLSIGN_OFF 7
#define TNC_CALLSIGN_LEN 6
+#define TNC_SSID_OFF 13
static void
tncSetCallsign(void)
@@ -275,6 +280,9 @@ tncSetCallsign(void)
}
for (; i < TNC_CALLSIGN_LEN; i++)
TNC_AX25_HEADER[TNC_CALLSIGN_OFF + i] = ' ' << 1;
+
+ /* Fill in the SSID with the low digit of the serial number */
+ TNC_AX25_HEADER[TNC_SSID_OFF] = 0x60 | ((ao_config.aprs_ssid & 0xf) << 1);
#endif
}
@@ -302,7 +310,7 @@ static uint8_t tncBitStuff;
/// Buffer to hold the message portion of the AX.25 packet as we prepare it.
static uint8_t tncBuffer[TNC_BUFFER_SIZE];
-/**
+/**
* Initialize the TNC internal variables.
*/
static void tncInit()
@@ -323,7 +331,7 @@ static void tnc1200TimerTick()
else
timeNCOFreq = 0x3aab;
- switch (tncMode)
+ switch (tncMode)
{
case TNC_TX_READY:
// Generate a test signal alteranting between high and low tones.
@@ -339,16 +347,16 @@ static void tnc1200TimerTick()
else
tncTxBit = 0;
}
-
+
// When the flag is done, determine if we need to send more or data.
- if (++tncBitCount == 8)
+ if (++tncBitCount == 8)
{
tncBitCount = 0;
tncShift = 0x7e;
// Once we transmit x mS of flags, send the data.
// txDelay bytes * 8 bits/byte * 833uS/bit = x mS
- if (++tncIndex == TNC_TX_DELAY)
+ if (++tncIndex == TNC_TX_DELAY)
{
tncIndex = 0;
tncShift = TNC_AX25_HEADER[0];
@@ -361,7 +369,7 @@ static void tnc1200TimerTick()
case TNC_TX_HEADER:
// Determine if we have sent 5 ones in a row, if we have send a zero.
- if (tncBitStuff == 0x1f)
+ if (tncBitStuff == 0x1f)
{
if (tncTxBit == 0)
tncTxBit = 1;
@@ -381,17 +389,17 @@ static void tnc1200TimerTick()
tncTxBit = 0;
}
- // Save the data stream so we can determine if bit stuffing is
+ // Save the data stream so we can determine if bit stuffing is
// required on the next bit time.
tncBitStuff = ((tncBitStuff << 1) | (tncShift & 0x01)) & 0x1f;
// If all the bits were shifted, get the next byte.
- if (++tncBitCount == 8)
+ if (++tncBitCount == 8)
{
tncBitCount = 0;
// After the header is sent, then send the data.
- if (++tncIndex == sizeof(TNC_AX25_HEADER))
+ if (++tncIndex == sizeof(TNC_AX25_HEADER))
{
tncIndex = 0;
tncShift = tncBuffer[0];
@@ -406,7 +414,7 @@ static void tnc1200TimerTick()
case TNC_TX_DATA:
// Determine if we have sent 5 ones in a row, if we have send a zero.
- if (tncBitStuff == 0x1f)
+ if (tncBitStuff == 0x1f)
{
if (tncTxBit == 0)
tncTxBit = 1;
@@ -426,17 +434,17 @@ static void tnc1200TimerTick()
tncTxBit = 0;
}
- // Save the data stream so we can determine if bit stuffing is
+ // Save the data stream so we can determine if bit stuffing is
// required on the next bit time.
tncBitStuff = ((tncBitStuff << 1) | (tncShift & 0x01)) & 0x1f;
// If all the bits were shifted, get the next byte.
- if (++tncBitCount == 8)
+ if (++tncBitCount == 8)
{
tncBitCount = 0;
// If everything was sent, transmit closing flags.
- if (++tncIndex == tncLength)
+ if (++tncIndex == tncLength)
{
tncIndex = 0;
tncShift = 0x7e;
@@ -451,7 +459,7 @@ static void tnc1200TimerTick()
case TNC_TX_END:
// The variable tncShift contains the lastest data byte.
- // NRZI enocde the data stream.
+ // NRZI enocde the data stream.
if ((tncShift & 0x01) == 0x00) {
if (tncTxBit == 0)
tncTxBit = 1;
@@ -460,13 +468,13 @@ static void tnc1200TimerTick()
}
// If all the bits were shifted, get the next one.
- if (++tncBitCount == 8)
+ if (++tncBitCount == 8)
{
tncBitCount = 0;
tncShift = 0x7e;
-
+
// Transmit two closing flags.
- if (++tncIndex == 2)
+ if (++tncIndex == 2)
{
tncMode = TNC_TX_READY;
@@ -530,6 +538,7 @@ static int tncComment(uint8_t *buf)
#ifdef AO_SENSE_MAIN
" M%d.%d"
#endif
+ " %d"
, ao_gps_locked(),
ao_num_sats(),
battery/10,
@@ -542,6 +551,7 @@ static int tncComment(uint8_t *buf)
, main/10,
main%10
#endif
+ , ao_serial_number
);
#else
return sprintf((char *) buf,
@@ -703,7 +713,7 @@ static int tncPositionPacket(void)
if (ao_gps_data.flags & AO_GPS_VALID) {
latitude = ao_gps_data.latitude;
longitude = ao_gps_data.longitude;
- altitude = ao_gps_data.altitude;
+ altitude = AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data);
if (altitude < 0)
altitude = 0;
}
@@ -759,7 +769,7 @@ tncFill(uint8_t *buf, int16_t len)
return l;
}
-/**
+/**
* Prepare an AX.25 data packet. Each time this method is called, it automatically
* rotates through 1 of 3 messages.
*
diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c
index 31225939..3ea8b704 100644
--- a/src/drivers/ao_cc1120.c
+++ b/src/drivers/ao_cc1120.c
@@ -41,8 +41,10 @@ extern const uint32_t ao_radio_cal;
#define FOSC 32000000
+#define ao_radio_try_select(task_id) ao_spi_try_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_4MHz, task_id)
#define ao_radio_select() ao_spi_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_4MHz)
#define ao_radio_deselect() ao_spi_put_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS)
+#define ao_radio_spi_send_sync(d,l) ao_spi_send_sync((d), (l), AO_CC1120_SPI_BUS)
#define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1120_SPI_BUS)
#define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1120_SPI_BUS)
#define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC1120_SPI_BUS)
@@ -107,7 +109,7 @@ ao_radio_reg_write(uint16_t addr, uint8_t value)
}
static void
-ao_radio_burst_read_start (uint16_t addr)
+_ao_radio_burst_read_start (uint16_t addr)
{
uint8_t data[2];
uint8_t d;
@@ -124,8 +126,8 @@ ao_radio_burst_read_start (uint16_t addr)
addr);
d = 1;
}
- ao_radio_select();
- ao_radio_spi_send(data, d);
+
+ ao_radio_spi_send_sync(data, d);
}
static void
@@ -209,7 +211,7 @@ ao_radio_tx_fifo_space(void)
return CC1120_FIFO_SIZE - ao_radio_reg_read(CC1120_NUM_TXBYTES);
}
-#if 0
+#if CC1120_DEBUG
static uint8_t
ao_radio_status(void)
{
@@ -245,7 +247,7 @@ ao_radio_check_marc_status(void)
{
ao_radio_mcu_wake = 0;
ao_radio_marc_status = ao_radio_get_marc_status();
-
+
/* Anyt other than 'tx/rx finished' means an error occurred */
if (ao_radio_marc_status & ~(CC1120_MARC_STATUS1_TX_FINISHED|CC1120_MARC_STATUS1_RX_FINISHED))
ao_radio_abort = 1;
@@ -275,48 +277,102 @@ static void
ao_radio_idle(void)
{
for (;;) {
- uint8_t state = ao_radio_strobe(CC1120_SIDLE);
- if ((state >> CC1120_STATUS_STATE) == CC1120_STATUS_STATE_IDLE)
+ uint8_t state = (ao_radio_strobe(CC1120_SIDLE) >> CC1120_STATUS_STATE) & CC1120_STATUS_STATE_MASK;
+ if (state == CC1120_STATUS_STATE_IDLE)
break;
- if ((state >> CC1120_STATUS_STATE) == CC1120_STATUS_STATE_TX_FIFO_ERROR)
+ if (state == CC1120_STATUS_STATE_TX_FIFO_ERROR)
ao_radio_strobe(CC1120_SFTX);
+ if (state == CC1120_STATUS_STATE_RX_FIFO_ERROR)
+ ao_radio_strobe(CC1120_SFRX);
}
/* Flush any pending TX bytes */
ao_radio_strobe(CC1120_SFTX);
}
/*
- * Packet deviation is 20.5kHz
+ * Packet deviation
*
* fdev = fosc >> 24 * (256 + dev_m) << dev_e
*
+ * Deviation for 38400 baud should be 20.5kHz:
+ *
* 32e6Hz / (2 ** 24) * (256 + 80) * (2 ** 5) = 20508Hz
+ *
+ * Deviation for 9600 baud should be 5.125kHz:
+ *
+ * 32e6Hz / (2 ** 24) * (256 + 80) * (2 ** 3) = 5127Hz
+ *
+ * Deviation for 2400 baud should be 1.28125kHz, but cc1111 and
+ * cc115l can't do that, so we'll use 1.5kHz instead:
+ *
+ * 32e6Hz / (2 ** 24) * (256 + 137) * (2 ** 1) = 1499Hz
*/
-#define PACKET_DEV_E 5
-#define PACKET_DEV_M 80
+#define PACKET_DEV_M_384 80
+#define PACKET_DEV_E_384 5
+
+#define PACKET_DEV_M_96 80
+#define PACKET_DEV_E_96 3
+
+#define PACKET_DEV_M_24 137
+#define PACKET_DEV_E_24 1
/*
- * For our packet data, set the symbol rate to 38400 Baud
+ * For our packet data
*
* (2**20 + DATARATE_M) * 2 ** DATARATE_E
* Rdata = -------------------------------------- * fosc
* 2 ** 39
*
+ * Given the bit period of the baseband, T, the bandwidth of the
+ * baseband signal is B = 1/(2T). The overall bandwidth of the
+ * modulated signal is then Channel bandwidth = 2Δf + 2B.
+ *
+ * 38400 -- 2 * 20500 + 38400 = 79.4 kHz
+ * 9600 -- 2 * 5.125 + 9600 = 19.9 kHz
+ * 2400 -- 2 * 1.5 + 2400 = 5.4 khz
+ *
+ * Symbol rate 38400 Baud:
*
* DATARATE_M = 239914
* DATARATE_E = 9
+ * CHANBW = 79.4 (round to 100)
+ *
+ * Symbol rate 9600 Baud:
+ *
+ * DATARATE_M = 239914
+ * DATARATE_E = 7
+ * CHANBW = 19.9 (round to 20)
+ *
+ * Symbol rate 2400 Baud:
+ *
+ * DATARATE_M = 239914
+ * DATARATE_E = 5
+ * CHANBW = 5.0 (round to 8.0)
*/
-#define PACKET_DRATE_E 9
+
#define PACKET_DRATE_M 239914
+#define PACKET_DRATE_E_384 9
+
+/* 200 / 2 = 100 */
+#define PACKET_CHAN_BW_384 ((0 << CC1120_CHAN_BW_CHFILT_BYPASS) | \
+ (CC1120_CHAN_BW_ADC_CIC_DECFACT_20 << CC1120_CHAN_BW_ADC_CIC_DECFACT) | \
+ (2 << CC1120_CHAN_BW_BB_CIC_DECFACT))
+
+#define PACKET_DRATE_E_96 7
+/* 200 / 10 = 20 */
+#define PACKET_CHAN_BW_96 ((0 << CC1120_CHAN_BW_CHFILT_BYPASS) | \
+ (CC1120_CHAN_BW_ADC_CIC_DECFACT_20 << CC1120_CHAN_BW_ADC_CIC_DECFACT) | \
+ (10 << CC1120_CHAN_BW_BB_CIC_DECFACT))
+
+#define PACKET_DRATE_E_24 5
+/* 200 / 25 = 8 */
+#define PACKET_CHAN_BW_24 ((0 << CC1120_CHAN_BW_CHFILT_BYPASS) | \
+ (CC1120_CHAN_BW_ADC_CIC_DECFACT_20 << CC1120_CHAN_BW_ADC_CIC_DECFACT) | \
+ (25 << CC1120_CHAN_BW_BB_CIC_DECFACT))
+
static const uint16_t packet_setup[] = {
- CC1120_DEVIATION_M, PACKET_DEV_M,
- CC1120_MODCFG_DEV_E, ((CC1120_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1120_MODCFG_DEV_E_MODEM_MODE) |
- (CC1120_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1120_MODCFG_DEV_E_MOD_FORMAT) |
- (PACKET_DEV_E << CC1120_MODCFG_DEV_E_DEV_E)),
- CC1120_DRATE2, ((PACKET_DRATE_E << CC1120_DRATE2_DATARATE_E) |
- (((PACKET_DRATE_M >> 16) & CC1120_DRATE2_DATARATE_M_19_16_MASK) << CC1120_DRATE2_DATARATE_M_19_16)),
CC1120_DRATE1, ((PACKET_DRATE_M >> 8) & 0xff),
CC1120_DRATE0, ((PACKET_DRATE_M >> 0) & 0xff),
CC1120_PKT_CFG2, ((CC1120_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1120_PKT_CFG2_CCA_MODE) |
@@ -335,6 +391,39 @@ static const uint16_t packet_setup[] = {
AO_CC1120_MARC_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_MARC_MCU_WAKEUP,
};
+static const uint16_t packet_setup_384[] = {
+ CC1120_DEVIATION_M, PACKET_DEV_M_384,
+ CC1120_MODCFG_DEV_E, ((CC1120_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1120_MODCFG_DEV_E_MODEM_MODE) |
+ (CC1120_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1120_MODCFG_DEV_E_MOD_FORMAT) |
+ (PACKET_DEV_E_384 << CC1120_MODCFG_DEV_E_DEV_E)),
+ CC1120_DRATE2, ((PACKET_DRATE_E_384 << CC1120_DRATE2_DATARATE_E) |
+ (((PACKET_DRATE_M >> 16) & CC1120_DRATE2_DATARATE_M_19_16_MASK) << CC1120_DRATE2_DATARATE_M_19_16)),
+ CC1120_CHAN_BW, PACKET_CHAN_BW_384,
+ CC1120_PA_CFG0, 0x7b,
+};
+
+static const uint16_t packet_setup_96[] = {
+ CC1120_DEVIATION_M, PACKET_DEV_M_96,
+ CC1120_MODCFG_DEV_E, ((CC1120_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1120_MODCFG_DEV_E_MODEM_MODE) |
+ (CC1120_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1120_MODCFG_DEV_E_MOD_FORMAT) |
+ (PACKET_DEV_E_96 << CC1120_MODCFG_DEV_E_DEV_E)),
+ CC1120_DRATE2, ((PACKET_DRATE_E_96 << CC1120_DRATE2_DATARATE_E) |
+ (((PACKET_DRATE_M >> 16) & CC1120_DRATE2_DATARATE_M_19_16_MASK) << CC1120_DRATE2_DATARATE_M_19_16)),
+ CC1120_CHAN_BW, PACKET_CHAN_BW_96,
+ CC1120_PA_CFG0, 0x7d,
+};
+
+static const uint16_t packet_setup_24[] = {
+ CC1120_DEVIATION_M, PACKET_DEV_M_24,
+ CC1120_MODCFG_DEV_E, ((CC1120_MODCFG_DEV_E_MODEM_MODE_NORMAL << CC1120_MODCFG_DEV_E_MODEM_MODE) |
+ (CC1120_MODCFG_DEV_E_MOD_FORMAT_2_GFSK << CC1120_MODCFG_DEV_E_MOD_FORMAT) |
+ (PACKET_DEV_E_24 << CC1120_MODCFG_DEV_E_DEV_E)),
+ CC1120_DRATE2, ((PACKET_DRATE_E_24 << CC1120_DRATE2_DATARATE_E) |
+ (((PACKET_DRATE_M >> 16) & CC1120_DRATE2_DATARATE_M_19_16_MASK) << CC1120_DRATE2_DATARATE_M_19_16)),
+ CC1120_CHAN_BW, PACKET_CHAN_BW_24,
+ CC1120_PA_CFG0, 0x7e,
+};
+
static const uint16_t packet_tx_setup[] = {
CC1120_PKT_CFG2, ((CC1120_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1120_PKT_CFG2_CCA_MODE) |
(CC1120_PKT_CFG2_PKT_FORMAT_NORMAL << CC1120_PKT_CFG2_PKT_FORMAT)),
@@ -397,6 +486,7 @@ static const uint16_t rdf_setup[] = {
(0 << CC1120_PKT_CFG0_UART_SWAP_EN)),
CC1120_PREAMBLE_CFG1, ((CC1120_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1120_PREAMBLE_CFG1_NUM_PREAMBLE) |
(CC1120_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1120_PREAMBLE_CFG1_PREAMBLE_WORD)),
+ CC1120_PA_CFG0, 0x7e,
};
/*
@@ -443,6 +533,7 @@ static const uint16_t aprs_setup[] = {
(0 << CC1120_PKT_CFG1_APPEND_STATUS)),
CC1120_PREAMBLE_CFG1, ((CC1120_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1120_PREAMBLE_CFG1_NUM_PREAMBLE) |
(CC1120_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1120_PREAMBLE_CFG1_PREAMBLE_WORD)),
+ CC1120_PA_CFG0, 0x7d,
};
/*
@@ -506,23 +597,48 @@ static uint16_t ao_radio_mode;
#define AO_RADIO_MODE_TEST (AO_RADIO_MODE_BITS_TEST | AO_RADIO_MODE_BITS_INFINITE | AO_RADIO_MODE_BITS_TX_BUF)
static void
+_ao_radio_set_regs(const uint16_t *regs, int nreg)
+{
+ int i;
+
+ for (i = 0; i < nreg; i++) {
+ ao_radio_reg_write(regs[0], regs[1]);
+ regs += 2;
+ }
+}
+
+#define ao_radio_set_regs(setup) _ao_radio_set_regs(setup, (sizeof (setup) / sizeof(setup[0])) >> 1)
+
+static void
ao_radio_set_mode(uint16_t new_mode)
{
uint16_t changes;
- unsigned int i;
if (new_mode == ao_radio_mode)
return;
changes = new_mode & (~ao_radio_mode);
- if (changes & AO_RADIO_MODE_BITS_PACKET)
- for (i = 0; i < sizeof (packet_setup) / sizeof (packet_setup[0]); i += 2)
- ao_radio_reg_write(packet_setup[i], packet_setup[i+1]);
+
+ if (changes & AO_RADIO_MODE_BITS_PACKET) {
+ ao_radio_set_regs(packet_setup);
+
+ switch (ao_config.radio_rate) {
+ default:
+ case AO_RADIO_RATE_38400:
+ ao_radio_set_regs(packet_setup_384);
+ break;
+ case AO_RADIO_RATE_9600:
+ ao_radio_set_regs(packet_setup_96);
+ break;
+ case AO_RADIO_RATE_2400:
+ ao_radio_set_regs(packet_setup_24);
+ break;
+ }
+ }
if (changes & AO_RADIO_MODE_BITS_PACKET_TX)
- for (i = 0; i < sizeof (packet_tx_setup) / sizeof (packet_tx_setup[0]); i += 2)
- ao_radio_reg_write(packet_tx_setup[i], packet_tx_setup[i+1]);
-
+ ao_radio_set_regs(packet_tx_setup);
+
if (changes & AO_RADIO_MODE_BITS_TX_BUF)
ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_TXFIFO_THR);
@@ -530,20 +646,16 @@ ao_radio_set_mode(uint16_t new_mode)
ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_RX0TX1_CFG);
if (changes & AO_RADIO_MODE_BITS_PACKET_RX)
- for (i = 0; i < sizeof (packet_rx_setup) / sizeof (packet_rx_setup[0]); i += 2)
- ao_radio_reg_write(packet_rx_setup[i], packet_rx_setup[i+1]);
-
+ ao_radio_set_regs(packet_rx_setup);
+
if (changes & AO_RADIO_MODE_BITS_RDF)
- for (i = 0; i < sizeof (rdf_setup) / sizeof (rdf_setup[0]); i += 2)
- ao_radio_reg_write(rdf_setup[i], rdf_setup[i+1]);
+ ao_radio_set_regs(rdf_setup);
if (changes & AO_RADIO_MODE_BITS_APRS)
- for (i = 0; i < sizeof (aprs_setup) / sizeof (aprs_setup[0]); i += 2)
- ao_radio_reg_write(aprs_setup[i], aprs_setup[i+1]);
+ ao_radio_set_regs(aprs_setup);
if (changes & AO_RADIO_MODE_BITS_TEST)
- for (i = 0; i < sizeof (test_setup) / sizeof (test_setup[0]); i += 2)
- ao_radio_reg_write(test_setup[i], test_setup[i+1]);
+ ao_radio_set_regs(test_setup);
if (changes & AO_RADIO_MODE_BITS_INFINITE)
ao_radio_reg_write(CC1120_PKT_CFG0, AO_PKT_CFG0_INFINITE);
@@ -563,12 +675,9 @@ static uint8_t ao_radio_configured = 0;
static void
ao_radio_setup(void)
{
- unsigned int i;
-
ao_radio_strobe(CC1120_SRES);
- for (i = 0; i < sizeof (radio_setup) / sizeof (radio_setup[0]); i += 2)
- ao_radio_reg_write(radio_setup[i], radio_setup[i+1]);
+ ao_radio_set_regs(radio_setup);
ao_radio_mode = 0;
@@ -592,6 +701,7 @@ static void
ao_radio_get(uint8_t len)
{
static uint32_t last_radio_setting;
+ static uint8_t last_radio_rate;
ao_mutex_get(&ao_radio_mutex);
@@ -603,6 +713,10 @@ ao_radio_get(uint8_t len)
ao_radio_reg_write(CC1120_FREQ0, ao_config.radio_setting);
last_radio_setting = ao_config.radio_setting;
}
+ if (ao_config.radio_rate != last_radio_rate) {
+ ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET;
+ last_radio_rate = ao_config.radio_rate;
+ }
ao_radio_set_len(len);
}
@@ -696,7 +810,7 @@ ao_radio_test_cmd(void)
ao_radio_set_mode(AO_RADIO_MODE_TEST);
ao_radio_strobe(CC1120_STX);
#if CC1120_TRACE
- { int t;
+ { int t;
for (t = 0; t < 10; t++) {
printf ("status: %02x\n", ao_radio_status());
ao_delay(AO_MS_TO_TICKS(100));
@@ -793,7 +907,7 @@ ao_radio_send(const void *d, uint8_t size)
} else {
ao_exti_enable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
}
-
+
fifo_space = ao_radio_wait_tx(encode_len != 0);
if (ao_radio_abort) {
ao_radio_idle();
@@ -881,6 +995,11 @@ static uint16_t rx_data_consumed;
static uint16_t rx_data_cur;
static uint8_t rx_ignore;
static uint8_t rx_waiting;
+static uint8_t rx_starting;
+static uint8_t rx_task_id;
+static uint32_t rx_fast_start;
+static uint32_t rx_slow_start;
+static uint32_t rx_missed;
#if AO_PROFILE
static uint32_t rx_start_tick, rx_packet_tick, rx_done_tick, rx_last_done_tick;
@@ -895,13 +1014,34 @@ ao_radio_rx_isr(void)
{
uint8_t d;
+ if (rx_task_id) {
+ if (ao_radio_try_select(rx_task_id)) {
+ ++rx_fast_start;
+ rx_task_id = 0;
+ _ao_radio_burst_read_start(CC1120_SOFT_RX_DATA_OUT);
+ } else {
+ if (rx_ignore)
+ --rx_ignore;
+ else {
+ ao_radio_abort = 1;
+ rx_missed++;
+ }
+ return;
+ }
+ }
+ if (rx_starting) {
+ rx_starting = 0;
+ ao_wakeup(&ao_radio_wake);
+ }
d = AO_CC1120_SPI.dr;
AO_CC1120_SPI.dr = 0;
if (rx_ignore == 0) {
- if (rx_data_cur >= rx_data_count)
- ao_exti_disable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
- else
+ if (rx_data_cur < rx_data_count)
rx_data[rx_data_cur++] = d;
+ if (rx_data_cur >= rx_data_count) {
+ ao_spi_clr_cs(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN));
+ ao_exti_disable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
+ }
if (rx_waiting && rx_data_cur - rx_data_consumed >= AO_FEC_DECODE_BLOCK) {
#if AO_PROFILE
if (!rx_packet_tick)
@@ -920,24 +1060,20 @@ ao_radio_rx_isr(void)
static uint16_t
ao_radio_rx_wait(void)
{
- do {
- if (ao_radio_mcu_wake)
- ao_radio_check_marc_status();
- ao_alarm(AO_MS_TO_TICKS(100));
- ao_arch_block_interrupts();
- rx_waiting = 1;
- while (rx_data_cur - rx_data_consumed < AO_FEC_DECODE_BLOCK &&
- !ao_radio_abort &&
- !ao_radio_mcu_wake)
- {
- if (ao_sleep(&ao_radio_wake))
- ao_radio_abort = 1;
- }
- rx_waiting = 0;
- ao_arch_release_interrupts();
- ao_clear_alarm();
- } while (ao_radio_mcu_wake);
- if (ao_radio_abort)
+ ao_alarm(AO_MS_TO_TICKS(100));
+ ao_arch_block_interrupts();
+ rx_waiting = 1;
+ while (rx_data_cur - rx_data_consumed < AO_FEC_DECODE_BLOCK &&
+ !ao_radio_abort &&
+ !ao_radio_mcu_wake)
+ {
+ if (ao_sleep(&ao_radio_wake))
+ ao_radio_abort = 1;
+ }
+ rx_waiting = 0;
+ ao_arch_release_interrupts();
+ ao_clear_alarm();
+ if (ao_radio_abort || ao_radio_mcu_wake)
return 0;
rx_data_consumed += AO_FEC_DECODE_BLOCK;
#if AO_PROFILE
@@ -977,48 +1113,67 @@ ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout)
*/
ao_radio_abort = 0;
- /* configure interrupt pin */
ao_radio_get(len);
- ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX);
ao_radio_wake = 0;
ao_radio_mcu_wake = 0;
- AO_CC1120_SPI.cr2 = 0;
-
- /* clear any RXNE */
- (void) AO_CC1120_SPI.dr;
+ ao_radio_set_mode(AO_RADIO_MODE_PACKET_RX);
- /* Have the radio signal when the preamble quality goes high */
- ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_PQT_REACHED);
+ /* configure interrupt pin */
+ ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_CLKEN_SOFT);
ao_exti_set_mode(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN,
- AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_HIGH);
- ao_exti_set_callback(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, ao_radio_isr);
+ AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH);
+
+ ao_exti_set_callback(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, ao_radio_rx_isr);
ao_exti_enable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
- ao_exti_enable(AO_CC1120_MCU_WAKEUP_PORT, AO_CC1120_MCU_WAKEUP_PIN);
+
+ rx_starting = 1;
+ rx_task_id = ao_cur_task->task_id;
ao_radio_strobe(CC1120_SRX);
- /* Wait for the preamble to appear */
- ao_radio_wait_isr(timeout);
+ if (timeout)
+ ao_alarm(timeout);
+ ao_arch_block_interrupts();
+ while (rx_starting && !ao_radio_abort) {
+ if (ao_sleep(&ao_radio_wake))
+ ao_radio_abort = 1;
+ }
+ uint8_t rx_task_id_save = rx_task_id;
+ rx_task_id = 0;
+ rx_starting = 0;
+ ao_arch_release_interrupts();
+ if (timeout)
+ ao_clear_alarm();
+
if (ao_radio_abort) {
ret = 0;
+ rx_task_id = 0;
goto abort;
}
- ao_radio_reg_write(AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_CLKEN_SOFT);
- ao_exti_set_mode(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN,
- AO_EXTI_MODE_FALLING|AO_EXTI_PRIORITY_HIGH);
-
- ao_exti_set_callback(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, ao_radio_rx_isr);
- ao_exti_enable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
-
- ao_radio_burst_read_start(CC1120_SOFT_RX_DATA_OUT);
+ if (rx_task_id_save) {
+ ++rx_slow_start;
+ ao_radio_select();
+ _ao_radio_burst_read_start(CC1120_SOFT_RX_DATA_OUT);
+ if (rx_ignore) {
+ uint8_t ignore = AO_CC1120_SPI.dr;
+ (void) ignore;
+ AO_CC1120_SPI.dr = 0;
+ --rx_ignore;
+ }
+ }
ret = ao_fec_decode(rx_data, rx_data_count, d, size + 2, ao_radio_rx_wait);
ao_radio_burst_read_stop();
+ if (ao_radio_mcu_wake)
+ ao_radio_check_marc_status();
+ if (ao_radio_abort)
+ ret = 0;
+
abort:
/* Convert from 'real' rssi to cc1111-style values */
@@ -1033,7 +1188,7 @@ abort:
radio_rssi = AO_RADIO_FROM_RSSI (rssi);
}
- ao_radio_strobe(CC1120_SIDLE);
+ ao_radio_idle();
ao_radio_put();
@@ -1072,7 +1227,7 @@ struct ao_cc1120_reg {
char *name;
};
-const static struct ao_cc1120_reg ao_cc1120_reg[] = {
+static const struct ao_cc1120_reg ao_cc1120_reg[] = {
{ .addr = CC1120_IOCFG3, .name = "IOCFG3" },
{ .addr = CC1120_IOCFG2, .name = "IOCFG2" },
{ .addr = CC1120_IOCFG1, .name = "IOCFG1" },
@@ -1253,7 +1408,7 @@ const static struct ao_cc1120_reg ao_cc1120_reg[] = {
static void ao_radio_show(void) {
uint8_t status = ao_radio_status();
- int i;
+ unsigned int i;
ao_radio_get(0xff);
status = ao_radio_status();
@@ -1264,6 +1419,10 @@ static void ao_radio_show(void) {
for (i = 0; i < AO_NUM_CC1120_REG; i++)
printf ("\t%02x %-20.20s\n", ao_radio_reg_read(ao_cc1120_reg[i].addr), ao_cc1120_reg[i].name);
+
+ printf("RX fast start: %u\n", rx_fast_start);
+ printf("RX slow start: %u\n", rx_slow_start);
+ printf("RX missed: %u\n", rx_missed);
ao_radio_put();
}
@@ -1287,12 +1446,12 @@ static void ao_radio_packet(void) {
}
void
-ao_radio_test_recv()
+ao_radio_test_recv(void)
{
uint8_t bytes[34];
uint8_t b;
- if (ao_radio_recv(bytes, 34)) {
+ if (ao_radio_recv(bytes, 34, 0)) {
if (bytes[33] & 0x80)
printf ("CRC OK");
else
@@ -1308,13 +1467,12 @@ ao_radio_test_recv()
#include <ao_aprs.h>
static void
-ao_radio_aprs()
+ao_radio_aprs(void)
{
ao_packet_slave_stop();
ao_aprs_send();
}
#endif
-
#endif
static const struct ao_cmds ao_radio_cmds[] = {
diff --git a/src/drivers/ao_cc1120.h b/src/drivers/ao_cc1120.h
index a1d78c01..943f3449 100644
--- a/src/drivers/ao_cc1120.h
+++ b/src/drivers/ao_cc1120.h
@@ -189,6 +189,12 @@
#define CC1120_FREQ_IF_CFG 0x0f
#define CC1120_IQIC 0x10
#define CC1120_CHAN_BW 0x11
+#define CC1120_CHAN_BW_CHFILT_BYPASS 7
+#define CC1120_CHAN_BW_ADC_CIC_DECFACT 6
+#define CC1120_CHAN_BW_ADC_CIC_DECFACT_20 0
+#define CC1120_CHAN_BW_ADC_CIC_DECFACT_32 1
+#define CC1120_CHAN_BW_BB_CIC_DECFACT 0
+
#define CC1120_MDMCFG1 0x12
#define CC1120_MDMCFG1_CARRIER_SENSE_GATE 7
#define CC1120_MDMCFG1_FIFO_EN 6
@@ -294,7 +300,7 @@
#define CC1120_SETTLING_CFG_FS_AUTOCAL_MASK 3
#define CC1120_SETTLING_CFG_LOCK_TIME 1
#define CC1120_SETTLING_CFG_LOCK_TIME_50_20 0
-#define CC1120_SETTLING_CFG_LOCK_TIME_70_30 1
+#define CC1120_SETTLING_CFG_LOCK_TIME_75_30 1
#define CC1120_SETTLING_CFG_LOCK_TIME_100_40 2
#define CC1120_SETTLING_CFG_LOCK_TIME_150_60 3
#define CC1120_SETTLING_CFG_LOCK_TIME_MASK 3
diff --git a/src/drivers/ao_cc1120_CC1120.h b/src/drivers/ao_cc1120_CC1120.h
index 399abc4d..21a31a89 100644
--- a/src/drivers/ao_cc1120_CC1120.h
+++ b/src/drivers/ao_cc1120_CC1120.h
@@ -31,20 +31,23 @@
CC1120_SYNC0, 0x91, /* Sync Word Configuration [7:0] */
CC1120_SYNC_CFG1, /* Sync Word Detection Configuration */
- (CC1120_SYNC_CFG1_DEM_CFG_PQT_GATING_ENABLED << CC1120_SYNC_CFG1_DEM_CFG) |
- (0x07 << CC1120_SYNC_CFG1_SYNC_THR),
+ (CC1120_SYNC_CFG1_DEM_CFG_PQT_GATING_DISABLED << CC1120_SYNC_CFG1_DEM_CFG) |
+ (0xc << CC1120_SYNC_CFG1_SYNC_THR),
CC1120_SYNC_CFG0,
(CC1120_SYNC_CFG0_SYNC_MODE_16_BITS << CC1120_SYNC_CFG0_SYNC_MODE) |
- (CC1120_SYNC_CFG0_SYNC_NUM_ERROR_2 << CC1120_SYNC_CFG0_SYNC_NUM_ERROR),
- CC1120_DCFILT_CFG, 0x1c, /* Digital DC Removal Configuration */
+ (CC1120_SYNC_CFG0_SYNC_NUM_ERROR_DISABLED << CC1120_SYNC_CFG0_SYNC_NUM_ERROR),
+ CC1120_DCFILT_CFG, 0x15, /* Digital DC Removal Configuration */
CC1120_PREAMBLE_CFG1, /* Preamble Length Configuration */
(CC1120_PREAMBLE_CFG1_NUM_PREAMBLE_4_BYTES << CC1120_PREAMBLE_CFG1_NUM_PREAMBLE) |
(CC1120_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1120_PREAMBLE_CFG1_PREAMBLE_WORD),
CC1120_PREAMBLE_CFG0,
- (1 << CC1120_PREAMBLE_CFG0_PQT_EN) |
- (0x6 << CC1120_PREAMBLE_CFG0_PQT),
- CC1120_FREQ_IF_CFG, 0x40, /* RX Mixer Frequency Configuration */
- CC1120_IQIC, 0x46, /* Digital Image Channel Compensation Configuration */
+ (0 << CC1120_PREAMBLE_CFG0_PQT_EN) |
+ (0xe << CC1120_PREAMBLE_CFG0_PQT),
+
+ /* Adjust PQT lower to accept fewer packets */
+
+ CC1120_FREQ_IF_CFG, 0x3a, /* RX Mixer Frequency Configuration */
+ CC1120_IQIC, 0x00, /* Digital Image Channel Compensation Configuration */
CC1120_CHAN_BW, 0x02, /* Channel Filter Configuration */
CC1120_MDMCFG1, /* General Modem Parameter Configuration */
@@ -53,12 +56,12 @@
(0 << CC1120_MDMCFG1_MANCHESTER_EN) |
(0 << CC1120_MDMCFG1_INVERT_DATA_EN) |
(0 << CC1120_MDMCFG1_COLLISION_DETECT_EN) |
- (CC1120_MDMCFG1_DVGA_GAIN_9 << CC1120_MDMCFG1_DVGA_GAIN) |
+ (CC1120_MDMCFG1_DVGA_GAIN_0 << CC1120_MDMCFG1_DVGA_GAIN) |
(0 << CC1120_MDMCFG1_SINGLE_ADC_EN),
- CC1120_MDMCFG0, 0x05, /* General Modem Parameter Configuration */
+ CC1120_MDMCFG0, 0x0d, /* General Modem Parameter Configuration */
/* AGC reference = 10 * log10(receive BW) - 4 = 10 * log10(100e3) - 4 = 46 */
- CC1120_AGC_REF, 46, /* AGC Reference Level Configuration */
+ CC1120_AGC_REF, 0x36, /* AGC Reference Level Configuration */
/* Carrier sense threshold - 25dB above the noise */
CC1120_AGC_CS_THR, 25, /* Carrier Sense Threshold Configuration */
@@ -93,7 +96,7 @@
CC1120_SETTLING_CFG, /* Frequency Synthesizer Calibration and Settling Configuration */
(CC1120_SETTLING_CFG_FS_AUTOCAL_IDLE_TO_ON << CC1120_SETTLING_CFG_FS_AUTOCAL) |
- (CC1120_SETTLING_CFG_LOCK_TIME_50_20 << CC1120_SETTLING_CFG_LOCK_TIME) |
+ (CC1120_SETTLING_CFG_LOCK_TIME_75_30 << CC1120_SETTLING_CFG_LOCK_TIME) |
(CC1120_SETTLING_CFG_FSREG_TIME_60 << CC1120_SETTLING_CFG_FSREG_TIME),
CC1120_FS_CFG, /* Frequency Synthesizer Configuration */
@@ -109,7 +112,7 @@
CC1120_PKT_CFG1, 0x45, /* Packet Configuration, Reg 1 */
CC1120_PKT_CFG0, 0x00, /* Packet Configuration, Reg 0 */
#endif
- CC1120_RFEND_CFG1, 0x0f, /* RFEND Configuration, Reg 1 */
+ CC1120_RFEND_CFG1, 0x0e, /* RFEND Configuration, Reg 1 */
CC1120_RFEND_CFG0, 0x00, /* RFEND Configuration, Reg 0 */
// CC1120_PA_CFG2, 0x3f, /* Power Amplifier Configuration, Reg 2 */
CC1120_PA_CFG2, 0x3f, /* Power Amplifier Configuration, Reg 2 */
@@ -117,8 +120,8 @@
CC1120_PA_CFG0, 0x7b, /* Power Amplifier Configuration, Reg 0 */
CC1120_PKT_LEN, 0xff, /* Packet Length Configuration */
CC1120_IF_MIX_CFG, 0x00, /* IF Mix Configuration */
- CC1120_FREQOFF_CFG, 0x22, /* Frequency Offset Correction Configuration */
- CC1120_TOC_CFG, 0x0b, /* Timing Offset Correction Configuration */
+ CC1120_FREQOFF_CFG, 0x20, /* Frequency Offset Correction Configuration */
+ CC1120_TOC_CFG, 0x0a, /* Timing Offset Correction Configuration */
CC1120_MARC_SPARE, 0x00, /* MARC Spare */
CC1120_ECG_CFG, 0x00, /* External Clock Frequency Configuration */
CC1120_SOFT_TX_DATA_CFG, 0x00, /* Soft TX Data Configuration */
@@ -167,7 +170,7 @@
CC1120_XOSC4, 0xa0, /* Crystal Oscillator Configuration, Reg 4 */
CC1120_XOSC3, 0x03, /* Crystal Oscillator Configuration, Reg 3 */
CC1120_XOSC2, 0x04, /* Crystal Oscillator Configuration, Reg 2 */
- CC1120_XOSC1, 0x01, /* Crystal Oscillator Configuration, Reg 1 */
+ CC1120_XOSC1, 0x03, /* Crystal Oscillator Configuration, Reg 1 */
CC1120_XOSC0, 0x00, /* Crystal Oscillator Configuration, Reg 0 */
CC1120_ANALOG_SPARE, 0x00, /* */
CC1120_PA_CFG3, 0x00, /* Power Amplifier Configuration, Reg 3 */
@@ -196,31 +199,10 @@
CC1120_AGC_GAIN2, 0xd1, /* AGC Gain, Reg 2 */
CC1120_AGC_GAIN1, 0x00, /* AGC Gain, Reg 1 */
CC1120_AGC_GAIN0, 0x3f, /* AGC Gain, Reg 0 */
- CC1120_SOFT_RX_DATA_OUT, 0x00, /* Soft Decision Symbol Data */
- CC1120_SOFT_TX_DATA_IN, 0x00, /* Soft TX Data Input Register */
- CC1120_ASK_SOFT_RX_DATA, 0x30, /* AGC ASK Soft Decision Output */
CC1120_RNDGEN, 0x7f, /* Random Number Value */
- CC1120_MAGN2, 0x00, /* Signal Magnitude after CORDIC [16] */
- CC1120_MAGN1, 0x00, /* Signal Magnitude after CORDIC [15:8] */
- CC1120_MAGN0, 0x00, /* Signal Magnitude after CORDIC [7:0] */
- CC1120_ANG1, 0x00, /* Signal Angular after CORDIC [9:8] */
- CC1120_ANG0, 0x00, /* Signal Angular after CORDIC [7:0] */
- CC1120_CHFILT_I2, 0x08, /* Channel Filter Data Real Part [18:16] */
- CC1120_CHFILT_I1, 0x00, /* Channel Filter Data Real Part [15:8] */
- CC1120_CHFILT_I0, 0x00, /* Channel Filter Data Real Part [7:0] */
- CC1120_CHFILT_Q2, 0x00, /* Channel Filter Data Imaginary Part [18:16] */
- CC1120_CHFILT_Q1, 0x00, /* Channel Filter Data Imaginary Part [15:8] */
- CC1120_CHFILT_Q0, 0x00, /* Channel Filter Data Imaginary Part [7:0] */
- CC1120_GPIO_STATUS, 0x00, /* GPIO Status */
CC1120_FSCAL_CTRL, 0x01, /* */
CC1120_PHASE_ADJUST, 0x00, /* */
- CC1120_PARTNUMBER, 0x00, /* Part Number */
- CC1120_PARTVERSION, 0x00, /* Part Revision */
CC1120_SERIAL_STATUS, 0x00, /* Serial Status */
- CC1120_RX_STATUS, 0x01, /* RX Status */
- CC1120_TX_STATUS, 0x00, /* TX Status */
- CC1120_MARC_STATUS1, 0x00, /* MARC Status, Reg 1 */
- CC1120_MARC_STATUS0, 0x00, /* MARC Status, Reg 0 */
CC1120_PA_IFAMP_TEST, 0x00, /* */
CC1120_FSRF_TEST, 0x00, /* */
CC1120_PRE_TEST, 0x00, /* */
diff --git a/src/drivers/ao_cc115l.c b/src/drivers/ao_cc115l.c
index f250e714..cf61acfe 100644
--- a/src/drivers/ao_cc115l.c
+++ b/src/drivers/ao_cc115l.c
@@ -249,36 +249,81 @@ ao_radio_idle(void)
}
/*
- * Packet deviation is 20.5kHz
+ * Packet deviation
*
* fdev = fosc >> 17 * (8 + dev_m) << dev_e
*
+ * For 38400 baud, use 20.5kHz:
+ *
* 26e6 / (2 ** 17) * (8 + 5) * (2 ** 3) = 20630Hz
+ *
+ * For 9600 baud, use 5.125kHz:
+ *
+ * 26e6 / (2 ** 17) * (8 + 5) * (2 ** 1) = 5157Hz
+ *
+ * For 2400 baud, use 1.5kHz:
+ *
+ * 26e6 / (2 ** 17) * (8 + 0) * (2 ** 0) = 1587Hz
*/
-#define PACKET_DEV_E 3
-#define PACKET_DEV_M 5
+#define PACKET_DEV_E_384 3
+#define PACKET_DEV_M_384 5
+
+#define PACKET_DEV_E_96 1
+#define PACKET_DEV_M_96 5
+
+#define PACKET_DEV_E_24 0
+#define PACKET_DEV_M_24 0
/*
- * For our packet data, set the symbol rate to 38400 Baud
+ * For our packet data:
*
* (256 + DATARATE_M) * 2 ** DATARATE_E
* Rdata = -------------------------------------- * fosc
* 2 ** 28
*
+ * For 38400 baud:
+ *
* (256 + 131) * (2 ** 10) / (2**28) * 26e6 = 38383
*
* DATARATE_M = 131
- * DATARATE_E = 10
+ * DATARATE_E_384 = 10
+ * DATARATE_E_96 = 8
+ * DATARATE_E_24 = 6
*/
-#define PACKET_DRATE_E 10
-#define PACKET_DRATE_M 131
+#define PACKET_DRATE_M 131
+
+#define PACKET_DRATE_E_384 10
+#define PACKET_DRATE_E_96 8
+#define PACKET_DRATE_E_24 6
+
+static const struct {
+ uint8_t mdmcfg4;
+ uint8_t deviatn;
+} packet_rate_setup[] = {
+ [AO_RADIO_RATE_38400] = {
+ .mdmcfg4 = ((0xf << 4) |
+ (PACKET_DRATE_E_384 << CC115L_MDMCFG4_DRATE_E)),
+ .deviatn = ((PACKET_DEV_E_384 << CC115L_DEVIATN_DEVIATION_E) |
+ (PACKET_DEV_M_384 << CC115L_DEVIATN_DEVIATION_M)),
+ },
+
+ [AO_RADIO_RATE_9600] = {
+ .mdmcfg4 = ((0xf << 4) |
+ (PACKET_DRATE_E_96 << CC115L_MDMCFG4_DRATE_E)),
+ .deviatn = ((PACKET_DEV_E_96 << CC115L_DEVIATN_DEVIATION_E) |
+ (PACKET_DEV_M_96 << CC115L_DEVIATN_DEVIATION_M)),
+ },
+
+ [AO_RADIO_RATE_2400] = {
+ .mdmcfg4 = ((0xf << 4) |
+ (PACKET_DRATE_E_24 << CC115L_MDMCFG4_DRATE_E)),
+ .deviatn = ((PACKET_DEV_E_24 << CC115L_DEVIATN_DEVIATION_E) |
+ (PACKET_DEV_M_24 << CC115L_DEVIATN_DEVIATION_M)),
+ },
+};
static const uint16_t packet_setup[] = {
- CC115L_DEVIATN, ((PACKET_DEV_E << CC115L_DEVIATN_DEVIATION_E) |
- (PACKET_DEV_M << CC115L_DEVIATN_DEVIATION_M)),
- CC115L_MDMCFG4, ((0xf << 4) |
- (PACKET_DRATE_E << CC115L_MDMCFG4_DRATE_E)),
CC115L_MDMCFG3, (PACKET_DRATE_M),
CC115L_MDMCFG2, (0x00 |
(CC115L_MDMCFG2_MOD_FORMAT_GFSK << CC115L_MDMCFG2_MOD_FORMAT) |
@@ -403,9 +448,13 @@ ao_radio_set_mode(uint16_t new_mode)
return;
changes = new_mode & (~ao_radio_mode);
- if (changes & AO_RADIO_MODE_BITS_PACKET_TX)
+ if (changes & AO_RADIO_MODE_BITS_PACKET_TX) {
+ ao_radio_reg_write(CC115L_MDMCFG4, packet_rate_setup[ao_config.radio_rate].mdmcfg4);
+ ao_radio_reg_write(CC115L_DEVIATN, packet_rate_setup[ao_config.radio_rate].deviatn);
+
for (i = 0; i < sizeof (packet_setup) / sizeof (packet_setup[0]); i += 2)
ao_radio_reg_write(packet_setup[i], packet_setup[i+1]);
+ }
if (changes & AO_RADIO_MODE_BITS_RDF)
for (i = 0; i < sizeof (rdf_setup) / sizeof (rdf_setup[0]); i += 2)
@@ -494,6 +543,7 @@ static void
ao_radio_get(void)
{
static uint32_t last_radio_setting;
+ static uint8_t last_radio_rate;
ao_mutex_get(&ao_radio_mutex);
if (!ao_radio_configured)
@@ -504,6 +554,10 @@ ao_radio_get(void)
ao_radio_reg_write(CC115L_FREQ0, ao_config.radio_setting);
last_radio_setting = ao_config.radio_setting;
}
+ if (ao_config.radio_rate != last_radio_rate) {
+ ao_radio_mode &= ~AO_RADIO_MODE_BITS_PACKET_TX;
+ last_radio_rate = ao_config.radio_rate;
+ }
}
static void
diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c
index 944a37f9..066df6ff 100644
--- a/src/drivers/ao_gps_skytraq.c
+++ b/src/drivers/ao_gps_skytraq.c
@@ -278,16 +278,17 @@ ao_nmea_gga(void)
ao_gps_lexchar();
i = ao_gps_decimal(0xff);
- if (i <= 50) {
- i = (uint8_t) 5 * i;
+ if (i <= 25) {
+ i = (uint8_t) 10 * i;
if (ao_gps_char == '.')
- i = (i + ((uint8_t) ao_gps_decimal(1) >> 1));
+ i = (i + ((uint8_t) ao_gps_decimal(1)));
} else
i = 255;
ao_gps_next.hdop = i;
ao_gps_skip_field();
- ao_gps_next.altitude = ao_gps_decimal(0xff);
+ AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_next, ao_gps_decimal(0xff));
+
ao_gps_skip_field(); /* skip any fractional portion */
ao_nmea_finish();
diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c
index 077698a9..74c29e0a 100644
--- a/src/drivers/ao_gps_ublox.c
+++ b/src/drivers/ao_gps_ublox.c
@@ -728,7 +728,7 @@ ao_gps(void) __reentrant
if (nav_timeutc.valid & (1 << NAV_TIMEUTC_VALID_UTC))
ao_gps_data.flags |= AO_GPS_DATE_VALID;
- ao_gps_data.altitude = nav_posllh.alt_msl / 1000;
+ AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_data, nav_posllh.alt_msl / 1000);
ao_gps_data.latitude = nav_posllh.lat;
ao_gps_data.longitude = nav_posllh.lon;
@@ -740,11 +740,11 @@ ao_gps(void) __reentrant
ao_gps_data.minute = nav_timeutc.min;
ao_gps_data.second = nav_timeutc.sec;
- ao_gps_data.pdop = nav_dop.pdop;
- ao_gps_data.hdop = nav_dop.hdop;
- ao_gps_data.vdop = nav_dop.vdop;
-
- /* mode is not set */
+ /* we report dop scaled by 10, but ublox provides dop scaled by 100
+ */
+ ao_gps_data.pdop = nav_dop.pdop / 10;
+ ao_gps_data.hdop = nav_dop.hdop / 10;
+ ao_gps_data.vdop = nav_dop.vdop / 10;
ao_gps_data.ground_speed = nav_velned.g_speed;
ao_gps_data.climb_rate = -nav_velned.vel_d;
diff --git a/src/drivers/ao_lco_func.c b/src/drivers/ao_lco_func.c
index 9e642836..32c00068 100644
--- a/src/drivers/ao_lco_func.c
+++ b/src/drivers/ao_lco_func.c
@@ -28,7 +28,21 @@ ao_lco_query(uint16_t box, struct ao_pad_query *query, uint16_t *tick_offset)
{
int8_t r;
uint16_t sent_time;
+ uint16_t timeout = AO_MS_TO_TICKS(10);
+#if HAS_RADIO_RATE
+ switch (ao_config.radio_rate) {
+ case AO_RADIO_RATE_38400:
+ default:
+ break;
+ case AO_RADIO_RATE_9600:
+ timeout = AO_MS_TO_TICKS(20);
+ break;
+ case AO_RADIO_RATE_2400:
+ timeout = AO_MS_TO_TICKS(80);
+ break;
+ }
+#endif
ao_mutex_get(&ao_lco_mutex);
command.tick = ao_time() - *tick_offset;
command.box = box;
@@ -36,7 +50,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(10));
+ r = ao_radio_cmac_recv(query, sizeof (*query), timeout);
if (r == AO_RADIO_CMAC_OK)
*tick_offset = sent_time - query->tick;
ao_mutex_put(&ao_lco_mutex);
diff --git a/src/drivers/ao_packet_master.c b/src/drivers/ao_packet_master.c
index d6c99cbd..23545049 100644
--- a/src/drivers/ao_packet_master.c
+++ b/src/drivers/ao_packet_master.c
@@ -57,6 +57,12 @@ static __xdata uint16_t ao_packet_master_time;
#define AO_PACKET_MASTER_DELAY_LONG AO_MS_TO_TICKS(1000)
#define AO_PACKET_MASTER_DELAY_TIMEOUT AO_MS_TO_TICKS(2000)
+#if HAS_RADIO_RATE
+#define AO_PACKET_MASTER_RECV_DELAY AO_MS_TO_TICKS(100) << (ao_config.radio_rate << 1)
+#else
+#define AO_PACKET_MASTER_RECV_DELAY AO_MS_TO_TICKS(100)
+#endif
+
static void
ao_packet_master_busy(void)
{
@@ -91,7 +97,7 @@ ao_packet_master(void)
if (ao_tx_packet.len)
ao_packet_master_busy();
ao_packet_master_check_busy();
- ao_alarm(ao_packet_master_delay);
+ ao_alarm(AO_PACKET_MASTER_RECV_DELAY);
r = ao_packet_recv();
ao_clear_alarm();
if (r) {
diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c
index 144cbd70..dc2c83fe 100644
--- a/src/drivers/ao_pad.c
+++ b/src/drivers/ao_pad.c
@@ -362,14 +362,26 @@ ao_pad_test(void)
void
ao_pad_manual(void)
{
+ uint8_t ignite;
+ int repeat;
ao_cmd_white();
if (!ao_match_word("DoIt"))
return;
ao_cmd_decimal();
if (ao_cmd_status != ao_cmd_success)
return;
- ao_pad_ignite = 1 << ao_cmd_lex_i;
- ao_wakeup(&ao_pad_ignite);
+ ignite = 1 << ao_cmd_lex_i;
+ ao_cmd_decimal();
+ if (ao_cmd_status != ao_cmd_success) {
+ repeat = 1;
+ ao_cmd_status = ao_cmd_success;
+ } else
+ repeat = ao_cmd_lex_i;
+ while (repeat-- > 0) {
+ ao_pad_ignite = ignite;
+ ao_wakeup(&ao_pad_ignite);
+ ao_delay(AO_PAD_FIRE_TIME>>1);
+ }
}
static __xdata struct ao_task ao_pad_task;
diff --git a/src/easymega-v0.1/.gitignore b/src/easymega-v1.0/.gitignore
index 410943d5..410943d5 100644
--- a/src/easymega-v0.1/.gitignore
+++ b/src/easymega-v1.0/.gitignore
diff --git a/src/easymega-v0.1/Makefile b/src/easymega-v1.0/Makefile
index 66619852..c3b360b4 100644
--- a/src/easymega-v0.1/Makefile
+++ b/src/easymega-v1.0/Makefile
@@ -107,13 +107,13 @@ ALTOS_SRC = \
$(SAMPLE_PROFILE) \
$(STACK_GUARD)
-PRODUCT=EasyMega-v0.1
+PRODUCT=EasyMega-v1.0
PRODUCT_DEF=-DEASYMEGA
-IDPRODUCT=0x0023
+IDPRODUCT=0x0028
CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g
-PROGNAME=easymega-v0.1
+PROGNAME=easymega-v1.0
PROG=$(PROGNAME)-$(VERSION).elf
HEX=$(PROGNAME)-$(VERSION).ihx
diff --git a/src/easymega-v0.1/ao_easymega.c b/src/easymega-v1.0/ao_easymega.c
index e217c33c..e217c33c 100644
--- a/src/easymega-v0.1/ao_easymega.c
+++ b/src/easymega-v1.0/ao_easymega.c
diff --git a/src/easymega-v0.1/ao_pins.h b/src/easymega-v1.0/ao_pins.h
index cb6e3980..d6490ba5 100644
--- a/src/easymega-v0.1/ao_pins.h
+++ b/src/easymega-v1.0/ao_pins.h
@@ -65,6 +65,9 @@
#define ao_gps_fifo (ao_stm_usart1.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
diff --git a/src/easymega-v0.1/flash-loader/Makefile b/src/easymega-v1.0/flash-loader/Makefile
index 35312fd6..d83cb70a 100644
--- a/src/easymega-v0.1/flash-loader/Makefile
+++ b/src/easymega-v1.0/flash-loader/Makefile
@@ -4,5 +4,5 @@
#
TOPDIR=../..
-HARDWARE=easymega-v0.1
+HARDWARE=easymega-v1.0
include $(TOPDIR)/stm/Makefile-flash.defs
diff --git a/src/easymega-v0.1/flash-loader/ao_pins.h b/src/easymega-v1.0/flash-loader/ao_pins.h
index 445289bf..445289bf 100644
--- a/src/easymega-v0.1/flash-loader/ao_pins.h
+++ b/src/easymega-v1.0/flash-loader/ao_pins.h
diff --git a/src/kalman/kalman.5c b/src/kalman/kalman.5c
index 46fa8e1f..55fde04c 100755
--- a/src/kalman/kalman.5c
+++ b/src/kalman/kalman.5c
@@ -457,7 +457,7 @@ void main() {
name = sprintf("%s_K%d_%d", prefix, i, time_inc);
else
name = sprintf("%s_K%d%d_%d", prefix, i, j, time_inc);
- printf ("#define %s to_fix32(%12.10f)\n", name, k[i,j]);
+ printf ("#define %s to_fix_k(%12.10f)\n", name, k[i,j]);
}
printf ("\n");
exit(0);
diff --git a/src/kalman/kalman_micro.5c b/src/kalman/kalman_micro.5c
index 266a1182..1b080384 100644
--- a/src/kalman/kalman_micro.5c
+++ b/src/kalman/kalman_micro.5c
@@ -307,7 +307,7 @@ void main() {
name = sprintf("%s_K%d_%d", prefix, i, time_inc);
else
name = sprintf("%s_K%d%d_%d", prefix, i, j, time_inc);
- printf ("#define %s to_fix32(%12.10f)\n", name, k[i,j]);
+ printf ("#define %s to_fix_k(%12.10f)\n", name, k[i,j]);
}
printf ("\n");
exit(0);
diff --git a/src/kernel/ao.h b/src/kernel/ao.h
index 5ff9b518..ad5bbf8e 100644
--- a/src/kernel/ao.h
+++ b/src/kernel/ao.h
@@ -132,6 +132,9 @@ ao_clock_init(void);
*/
#ifndef ao_mutex_get
+uint8_t
+ao_mutex_try(__xdata uint8_t *ao_mutex, uint8_t task_id) __reentrant;
+
void
ao_mutex_get(__xdata uint8_t *ao_mutex) __reentrant;
@@ -275,15 +278,17 @@ ao_report_init(void);
* Given raw data, convert to SI units
*/
+#if HAS_BARO
/* pressure from the sensor to altitude in meters */
-int16_t
-ao_pres_to_altitude(int16_t pres) __reentrant;
+alt_t
+ao_pres_to_altitude(pres_t pres) __reentrant;
-int16_t
-ao_altitude_to_pres(int16_t alt) __reentrant;
+pres_t
+ao_altitude_to_pres(alt_t alt) __reentrant;
int16_t
ao_temp_to_dC(int16_t temp) __reentrant;
+#endif
/*
* ao_convert_pa.c
@@ -293,11 +298,13 @@ ao_temp_to_dC(int16_t temp) __reentrant;
#include <ao_data.h>
+#if HAS_BARO
alt_t
-ao_pa_to_altitude(int32_t pa);
+ao_pa_to_altitude(pres_t pa);
int32_t
ao_altitude_to_pa(alt_t alt);
+#endif
#if HAS_DBG
#include <ao_dbg.h>
@@ -522,6 +529,9 @@ struct ao_telemetry_raw_recv {
#endif
void
+ao_telemetry_reset_interval(void);
+
+void
ao_telemetry_set_interval(uint16_t interval);
void
@@ -558,6 +568,15 @@ extern __xdata int8_t ao_radio_rssi;
#define HAS_RADIO_XMIT HAS_RADIO
#endif
+#define AO_RADIO_RATE_38400 0
+#define AO_RADIO_RATE_9600 1
+#define AO_RADIO_RATE_2400 2
+#define AO_RADIO_RATE_MAX AO_RADIO_RATE_2400
+
+#if defined(HAS_RADIO) && !defined(HAS_RADIO_RATE)
+#define HAS_RADIO_RATE HAS_RADIO
+#endif
+
void
ao_radio_general_isr(void) ao_arch_interrupt(16);
@@ -757,11 +776,13 @@ extern __xdata uint8_t ao_force_freq;
* ao_rssi.c
*/
+#ifdef AO_LED_TYPE
void
-ao_rssi_set(int rssi_value);
+ao_rssi_set(int16_t rssi_value);
void
-ao_rssi_init(uint8_t rssi_led);
+ao_rssi_init(AO_LED_TYPE rssi_led);
+#endif
/*
* ao_product.c
diff --git a/src/kernel/ao_cmd.c b/src/kernel/ao_cmd.c
index 0052bdce..d2f583ef 100644
--- a/src/kernel/ao_cmd.c
+++ b/src/kernel/ao_cmd.c
@@ -290,6 +290,9 @@ version(void)
#if defined(AO_BOOT_APPLICATION_BASE) && defined(AO_BOOT_APPLICATION_BOUND)
"program-space %u\n"
#endif
+#if AO_VALUE_32
+ "altitude-32 1\n"
+#endif
, ao_manufacturer
, ao_product
, ao_serial_number
diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c
index 71445335..6b8a1813 100644
--- a/src/kernel/ao_config.c
+++ b/src/kernel/ao_config.c
@@ -50,17 +50,25 @@ __xdata uint8_t ao_config_mutex;
#error Please define USE_INTERNAL_FLASH
#endif
#endif
+
#ifndef AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX
-#if USE_INTERNAL_FLASH
-#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX ao_storage_config
-#else
-#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX ((uint32_t) 192 * (uint32_t) 1024)
-#endif
+# if FLIGHT_LOG_APPEND
+# define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX ao_storage_log_max
+# else
+# if USE_INTERNAL_FLASH
+# define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX ao_storage_config
+# else
+# define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX ((uint32_t) 192 * (uint32_t) 1024)
+# endif
+# endif
#endif
+
#ifndef AO_CONFIG_DEFAULT_RADIO_POWER
#define AO_CONFIG_DEFAULT_RADIO_POWER 0x60
#endif
#define AO_CONFIG_DEFAULT_RADIO_AMP 0
+#define AO_CONFIG_DEFAULT_APRS_SSID (ao_serial_number % 10)
+#define AO_CONFIG_DEFAULT_RADIO_RATE AO_RADIO_RATE_38400
#if HAS_EEPROM
static void
@@ -85,10 +93,18 @@ ao_config_put(void)
#endif
#if HAS_RADIO
+
+#if HAS_RADIO_FORWARD
+__xdata uint32_t ao_send_radio_setting;
+#endif
+
void
ao_config_set_radio(void)
{
ao_config.radio_setting = ao_freq_to_set(ao_config.frequency, ao_config.radio_cal);
+#if HAS_RADIO_FORWARD
+ ao_send_radio_setting = ao_freq_to_set(ao_config.send_frequency, ao_config.radio_cal);
+#endif
}
#endif /* HAS_RADIO */
@@ -192,6 +208,18 @@ _ao_config_get(void)
if (minor < 18)
ao_config.pyro_time = AO_CONFIG_DEFAULT_PYRO_TIME;
#endif
+#if HAS_APRS
+ if (minor < 19)
+ ao_config.aprs_ssid = AO_CONFIG_DEFAULT_APRS_SSID;
+#endif
+#if HAS_RADIO_RATE
+ if (minor < 20)
+ ao_config.radio_rate = AO_CONFIG_DEFAULT_RADIO_RATE;
+#endif
+#if HAS_RADIO_FORWARD
+ if (minor < 21)
+ ao_config.send_frequency = 434550;
+#endif
ao_config.minor = AO_CONFIG_MINOR;
ao_config_dirty = 1;
}
@@ -283,6 +311,32 @@ ao_config_frequency_set(void) __reentrant
ao_radio_recv_abort();
#endif
}
+
+#endif
+
+#if HAS_RADIO_FORWARD
+void
+ao_config_send_frequency_show(void) __reentrant
+{
+ printf("Send frequency: %ld\n",
+ ao_config.send_frequency);
+}
+
+void
+ao_config_send_frequency_set(void) __reentrant
+{
+ ao_cmd_decimal();
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ _ao_config_edit_start();
+ ao_config.send_frequency = ao_cmd_lex_u32;
+ ao_config_set_radio();
+ _ao_config_edit_finish();
+#if HAS_RADIO_RECV
+ ao_radio_recv_abort();
+#endif
+}
+
#endif
#if HAS_FLIGHT
@@ -477,18 +531,73 @@ ao_config_radio_cal_set(void) __reentrant
ao_config_set_radio();
_ao_config_edit_finish();
}
+
+#endif
+
+#if HAS_RADIO_RATE
+#ifndef HAS_TELEMETRY
+#error Please define HAS_TELEMETRY
+#endif
+
+void
+ao_config_radio_rate_show(void) __reentrant
+{
+ printf("Telemetry rate: %d\n", ao_config.radio_rate);
+}
+
+void
+ao_config_radio_rate_set(void) __reentrant
+{
+ ao_cmd_decimal();
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ if (AO_RADIO_RATE_MAX < ao_cmd_lex_i) {
+ ao_cmd_status = ao_cmd_lex_error;
+ return;
+ }
+ _ao_config_edit_start();
+ ao_config.radio_rate = ao_cmd_lex_i;
+#if HAS_TELEMETRY
+ ao_telemetry_reset_interval();
+#endif
+ _ao_config_edit_finish();
+#if HAS_RADIO_RECV
+ ao_radio_recv_abort();
+#endif
+}
#endif
#if HAS_LOG
+
void
ao_config_log_show(void) __reentrant
{
printf("Max flight log: %d kB\n", (int16_t) (ao_config.flight_log_max >> 10));
+#if FLIGHT_LOG_APPEND
+ printf("Log fixed: 1\n");
+#endif
}
+#if FLIGHT_LOG_APPEND
+void
+ao_config_log_fix_append(void)
+{
+ _ao_config_edit_start();
+ ao_config.flight_log_max = ao_storage_log_max;
+ _ao_config_edit_finish();
+ ao_mutex_get(&ao_config_mutex);
+ _ao_config_put();
+ ao_config_dirty = 0;
+ ao_mutex_put(&ao_config_mutex);
+}
+#endif
+
void
ao_config_log_set(void) __reentrant
{
+#if FLIGHT_LOG_APPEND
+ printf("Flight log fixed size %d kB\n", ao_storage_log_max >> 10);
+#else
uint16_t block = (uint16_t) (ao_storage_block >> 10);
uint16_t log_max = (uint16_t) (ao_storage_log_max >> 10);
@@ -506,6 +615,7 @@ ao_config_log_set(void) __reentrant
ao_config.flight_log_max = (uint32_t) ao_cmd_lex_i << 10;
_ao_config_edit_finish();
}
+#endif
}
#endif /* HAS_LOG */
@@ -737,6 +847,30 @@ ao_config_pyro_time_set(void)
}
#endif
+#if HAS_APRS
+void
+ao_config_aprs_ssid_show(void)
+{
+ printf ("APRS SSID: %d\n",
+ ao_config.aprs_ssid);
+}
+
+void
+ao_config_aprs_ssid_set(void)
+{
+ ao_cmd_decimal();
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ if (15 < ao_cmd_lex_i) {
+ ao_cmd_status = ao_cmd_lex_error;
+ return;
+ }
+ _ao_config_edit_start();
+ ao_config.aprs_ssid = ao_cmd_lex_i;
+ _ao_config_edit_finish();
+}
+#endif /* HAS_APRS */
+
struct ao_config_var {
__code char *str;
void (*set)(void) __reentrant;
@@ -766,12 +900,20 @@ __code struct ao_config_var ao_config_vars[] = {
#if HAS_RADIO
{ "F <freq>\0Frequency (kHz)",
ao_config_frequency_set, ao_config_frequency_show },
+#if HAS_RADIO_FORWARD
+ { "R <freq>\0Repeater output frequency (kHz)",
+ ao_config_send_frequency_set, ao_config_send_frequency_show },
+#endif
{ "c <call>\0Callsign (8 char max)",
ao_config_callsign_set, ao_config_callsign_show },
{ "e <0 disable, 1 enable>\0Enable telemetry and RDF",
ao_config_radio_enable_set, ao_config_radio_enable_show },
{ "f <cal>\0Radio calib (cal = rf/(xtal/2^16))",
ao_config_radio_cal_set, ao_config_radio_cal_show },
+#if HAS_RADIO_RATE
+ { "T <rate>\0Telemetry rate (0=38.4, 1=9.6, 2=2.4)",
+ ao_config_radio_rate_set, ao_config_radio_rate_show },
+#endif
#if HAS_RADIO_POWER
{ "p <setting>\0Radio power setting (0-255)",
ao_config_radio_power_set, ao_config_radio_power_show },
@@ -817,6 +959,10 @@ __code struct ao_config_var ao_config_vars[] = {
{ "t <motion> <interval>\0Tracker configuration",
ao_config_tracker_set, ao_config_tracker_show },
#endif
+#if HAS_APRS
+ { "S <ssid>\0Set APRS SSID (0-15)",
+ ao_config_aprs_ssid_set, ao_config_aprs_ssid_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
index 2b5cd352..164584a5 100644
--- a/src/kernel/ao_config.h
+++ b/src/kernel/ao_config.h
@@ -28,6 +28,10 @@
#define USE_EEPROM_CONFIG 0
#endif
+#ifndef FLIGHT_LOG_APPEND
+#define FLIGHT_LOG_APPEND 0
+#endif
+
#if USE_STORAGE_CONFIG
#include <ao_storage.h>
@@ -53,7 +57,7 @@
#endif
#define AO_CONFIG_MAJOR 1
-#define AO_CONFIG_MINOR 18
+#define AO_CONFIG_MINOR 21
#define AO_AES_LEN 16
@@ -102,8 +106,21 @@ struct ao_config {
#if AO_PYRO_NUM
uint16_t pyro_time; /* minor version 18 */
#endif
+#if HAS_APRS
+ uint8_t aprs_ssid; /* minor version 19 */
+#endif
+#if HAS_RADIO_RATE
+ uint8_t radio_rate; /* minor version 20 */
+#endif
+#if HAS_RADIO_FORWARD
+ uint32_t send_frequency; /* minor version 21 */
+#endif
};
+#if HAS_RADIO_FORWARD
+extern __xdata uint32_t ao_send_radio_setting;
+#endif
+
#define AO_IGNITE_MODE_DUAL 0
#define AO_IGNITE_MODE_APOGEE 1
#define AO_IGNITE_MODE_MAIN 2
@@ -141,6 +158,9 @@ void
ao_config_set_radio(void);
void
+ao_config_log_fix_append(void);
+
+void
ao_config_init(void);
#endif /* _AO_CONFIG_H_ */
diff --git a/src/kernel/ao_convert.c b/src/kernel/ao_convert.c
index aa9b5f48..db1f2301 100644
--- a/src/kernel/ao_convert.c
+++ b/src/kernel/ao_convert.c
@@ -19,14 +19,16 @@
#include "ao.h"
#endif
-static const int16_t altitude_table[] = {
+#include <ao_sample.h>
+
+static const ao_v_t altitude_table[] = {
#include "altitude.h"
};
#define ALT_FRAC_SCALE (1 << ALT_FRAC_BITS)
#define ALT_FRAC_MASK (ALT_FRAC_SCALE - 1)
-int16_t
+ao_v_t
ao_pres_to_altitude(int16_t pres) __reentrant
{
uint8_t o;
@@ -43,9 +45,9 @@ ao_pres_to_altitude(int16_t pres) __reentrant
#if AO_NEED_ALTITUDE_TO_PRES
int16_t
-ao_altitude_to_pres(int16_t alt) __reentrant
+ao_altitude_to_pres(ao_v_t alt) __reentrant
{
- int16_t span, sub_span;
+ ao_v_t span, sub_span;
uint8_t l, h, m;
int32_t pres;
diff --git a/src/kernel/ao_convert_pa.c b/src/kernel/ao_convert_pa.c
index fe6e0ef6..410815b6 100644
--- a/src/kernel/ao_convert_pa.c
+++ b/src/kernel/ao_convert_pa.c
@@ -24,7 +24,11 @@
#endif
static const alt_t altitude_table[] AO_CONST_ATTRIB = {
+#if AO_SMALL_ALTITUDE_TABLE
+#include "altitude-pa-small.h"
+#else
#include "altitude-pa.h"
+#endif
};
#ifndef FETCH_ALT
@@ -35,11 +39,11 @@ static const alt_t altitude_table[] AO_CONST_ATTRIB = {
#define ALT_MASK (ALT_SCALE - 1)
alt_t
-ao_pa_to_altitude(int32_t pa)
+ao_pa_to_altitude(pres_t pa)
{
int16_t o;
int16_t part;
- int32_t low, high;
+ alt_t low, high;
if (pa < 0)
pa = 0;
@@ -48,16 +52,16 @@ ao_pa_to_altitude(int32_t pa)
o = pa >> ALT_SHIFT;
part = pa & ALT_MASK;
- low = (int32_t) FETCH_ALT(o) * (ALT_SCALE - part);
- high = (int32_t) FETCH_ALT(o+1) * part + (ALT_SCALE >> 1);
+ low = (alt_t) FETCH_ALT(o) * (ALT_SCALE - part);
+ high = (alt_t) FETCH_ALT(o+1) * part + (ALT_SCALE >> 1);
return (low + high) >> ALT_SHIFT;
}
#ifdef AO_CONVERT_TEST
-int32_t
-ao_altitude_to_pa(int32_t alt)
+pres_t
+ao_altitude_to_pa(alt_t alt)
{
- int32_t span, sub_span;
+ alt_t span, sub_span;
uint16_t l, h, m;
int32_t pa;
@@ -72,7 +76,7 @@ ao_altitude_to_pa(int32_t alt)
}
span = altitude_table[l] - altitude_table[h];
sub_span = altitude_table[l] - alt;
- pa = ((((int32_t) l * (span - sub_span) + (int32_t) h * sub_span) << ALT_SHIFT) + (span >> 1)) / span;
+ pa = ((((alt_t) l * (span - sub_span) + (alt_t) h * sub_span) << ALT_SHIFT) + (span >> 1)) / span;
if (pa > 120000)
pa = 120000;
if (pa < 0)
diff --git a/src/kernel/ao_convert_pa_test.c b/src/kernel/ao_convert_pa_test.c
index 7d5b1922..95422862 100644
--- a/src/kernel/ao_convert_pa_test.c
+++ b/src/kernel/ao_convert_pa_test.c
@@ -18,6 +18,7 @@
#include <stdint.h>
#define AO_CONVERT_TEST
typedef int32_t alt_t;
+typedef int32_t pres_t;
#include "ao_host.h"
#include "ao_convert_pa.c"
diff --git a/src/kernel/ao_data.h b/src/kernel/ao_data.h
index c4b062fd..8f75ad87 100644
--- a/src/kernel/ao_data.h
+++ b/src/kernel/ao_data.h
@@ -117,9 +117,7 @@ extern volatile __data uint8_t ao_data_count;
typedef int32_t pres_t;
-#ifndef AO_ALT_TYPE
#define AO_ALT_TYPE int32_t
-#endif
typedef AO_ALT_TYPE alt_t;
@@ -146,10 +144,6 @@ typedef int16_t alt_t;
#endif
-#if !HAS_BARO
-typedef int16_t alt_t;
-#endif
-
/*
* Need a few macros to pull data from the sensors:
*
diff --git a/src/kernel/ao_flight.c b/src/kernel/ao_flight.c
index 2b433ee9..251dbc02 100644
--- a/src/kernel/ao_flight.c
+++ b/src/kernel/ao_flight.c
@@ -60,10 +60,10 @@ __xdata uint8_t ao_sensor_errors;
* resting
*/
static __data uint16_t ao_interval_end;
-static __data int16_t ao_interval_min_height;
-static __data int16_t ao_interval_max_height;
+static __data ao_v_t ao_interval_min_height;
+static __data ao_v_t ao_interval_max_height;
#if HAS_ACCEL
-static __data int16_t ao_coast_avg_accel;
+static __data ao_v_t ao_coast_avg_accel;
#endif
__pdata uint8_t ao_flight_force_idle;
@@ -398,14 +398,14 @@ ao_flight(void)
}
#if HAS_FLIGHT_DEBUG
-static inline int int_part(int16_t i) { return i >> 4; }
-static inline int frac_part(int16_t i) { return ((i & 0xf) * 100 + 8) / 16; }
+static inline int int_part(ao_v_t i) { return i >> 4; }
+static inline int frac_part(ao_v_t i) { return ((i & 0xf) * 100 + 8) / 16; }
static void
ao_flight_dump(void)
{
#if HAS_ACCEL
- int16_t accel;
+ ao_v_t accel;
accel = ((ao_config.accel_plus_g - ao_sample_accel) * ao_accel_scale) >> 16;
#endif
diff --git a/src/kernel/ao_forward.c b/src/kernel/ao_forward.c
new file mode 100644
index 00000000..2a937183
--- /dev/null
+++ b/src/kernel/ao_forward.c
@@ -0,0 +1,48 @@
+/*
+ * 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_telem.h"
+
+static void
+ao_monitor_forward(void)
+{
+ uint32_t recv_radio_setting;
+ static __xdata struct ao_telemetry_all_recv packet;
+
+ for (;;) {
+ while (ao_monitoring)
+ ao_sleep(DATA_TO_XDATA(&ao_monitoring));
+
+ if (!ao_radio_recv(&packet, sizeof(packet), 0))
+ continue;
+ if (!(packet.status & PKT_APPEND_STATUS_1_CRC_OK))
+ continue;
+ recv_radio_setting = ao_config.radio_setting;
+ ao_config.radio_setting = ao_send_radio_setting;
+ ao_radio_send(&packet.telemetry, sizeof (packet.telemetry));
+ ao_config.radio_setting = recv_radio_setting;
+ }
+}
+
+static __xdata struct ao_task ao_monitor_forward_task;
+
+void
+ao_monitor_forward_init(void) __reentrant
+{
+ ao_add_task(&ao_monitor_forward_task, ao_monitor_forward, "monitor_forward");
+}
diff --git a/src/kernel/ao_forward.h b/src/kernel/ao_forward.h
new file mode 100644
index 00000000..1897dc08
--- /dev/null
+++ b/src/kernel/ao_forward.h
@@ -0,0 +1,24 @@
+/*
+ * 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_FORWARD_H_
+#define _AO_FORWARD_H_
+
+void
+ao_monitor_forward_init(void) __reentrant;
+
+#endif /* _AO_FORWARD_H_ */
diff --git a/src/kernel/ao_gps_print.c b/src/kernel/ao_gps_print.c
index 47c945d7..d26021da 100644
--- a/src/kernel/ao_gps_print.c
+++ b/src/kernel/ao_gps_print.c
@@ -20,6 +20,10 @@
#endif
#include "ao_telem.h"
+#ifndef AO_TELEMETRY_LOCATION_ALTITUDE
+#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((l)->altitude)
+#endif
+
void
ao_gps_print(__xdata struct ao_gps_orig *gps_data) __reentrant
{
@@ -42,7 +46,7 @@ ao_gps_print(__xdata struct ao_gps_orig *gps_data) __reentrant
AO_TELEM_GPS_ALTITUDE " %d ",
(long) gps_data->latitude,
(long) gps_data->longitude,
- gps_data->altitude);
+ AO_TELEMETRY_LOCATION_ALTITUDE(gps_data));
if (gps_data->flags & AO_GPS_DATE_VALID)
printf(AO_TELEM_GPS_YEAR " %d "
diff --git a/src/kernel/ao_gps_report.c b/src/kernel/ao_gps_report.c
index 07201ac2..7ef98a97 100644
--- a/src/kernel/ao_gps_report.c
+++ b/src/kernel/ao_gps_report.c
@@ -52,8 +52,12 @@ ao_gps_report(void)
gps_log.u.gps_longitude = gps_data.longitude;
ao_log_data(&gps_log);
gps_log.type = AO_LOG_GPS_ALT;
- gps_log.u.gps_altitude.altitude = gps_data.altitude;
- gps_log.u.gps_altitude.unused = 0xffff;
+ gps_log.u.gps_altitude.altitude_low = gps_data.altitude_low;
+#if HAS_WIDE_GPS
+ gps_log.u.gps_altitude.altitude_high = gps_data.altitude_high;
+#else
+ gps_log.u.gps_altitude.altitude_high = 0xffff;
+#endif
ao_log_data(&gps_log);
if (!date_reported && (gps_data.flags & AO_GPS_DATE_VALID)) {
gps_log.type = AO_LOG_GPS_DATE;
diff --git a/src/kernel/ao_gps_report_mega.c b/src/kernel/ao_gps_report_mega.c
index cb0c0fd9..f3711fb1 100644
--- a/src/kernel/ao_gps_report_mega.c
+++ b/src/kernel/ao_gps_report_mega.c
@@ -78,7 +78,8 @@ ao_gps_report_mega(void)
#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))
+ !ao_gps_sparse_should_log(gps_data.latitude, gps_data.longitude,
+ AO_TELEMETRY_LOCATION_ALTITUDE(&gps_data))
continue;
#endif
if ((new & AO_GPS_NEW_DATA) && (gps_data.flags & AO_GPS_VALID)) {
@@ -87,8 +88,8 @@ ao_gps_report_mega(void)
gps_log.type = AO_LOG_GPS_TIME;
gps_log.u.gps.latitude = gps_data.latitude;
gps_log.u.gps.longitude = gps_data.longitude;
- gps_log.u.gps.altitude = gps_data.altitude;
-
+ gps_log.u.gps.altitude_low = gps_data.altitude_low;
+ gps_log.u.gps.altitude_high = gps_data.altitude_high;
gps_log.u.gps.hour = gps_data.hour;
gps_log.u.gps.minute = gps_data.minute;
gps_log.u.gps.second = gps_data.second;
diff --git a/src/kernel/ao_gps_report_metrum.c b/src/kernel/ao_gps_report_metrum.c
index 696a833b..8ce074fe 100644
--- a/src/kernel/ao_gps_report_metrum.c
+++ b/src/kernel/ao_gps_report_metrum.c
@@ -44,7 +44,8 @@ ao_gps_report_metrum(void)
gps_log.type = AO_LOG_GPS_POS;
gps_log.u.gps.latitude = gps_data.latitude;
gps_log.u.gps.longitude = gps_data.longitude;
- gps_log.u.gps.altitude = gps_data.altitude;
+ gps_log.u.gps.altitude_low = gps_data.altitude_low;
+ gps_log.u.gps.altitude_high = gps_data.altitude_high;
ao_log_metrum(&gps_log);
gps_log.type = AO_LOG_GPS_TIME;
@@ -55,6 +56,7 @@ ao_gps_report_metrum(void)
gps_log.u.gps_time.year = gps_data.year;
gps_log.u.gps_time.month = gps_data.month;
gps_log.u.gps_time.day = gps_data.day;
+ gps_log.u.gps_time.pdop = gps_data.pdop;
ao_log_metrum(&gps_log);
}
diff --git a/src/kernel/ao_gps_show.c b/src/kernel/ao_gps_show.c
index 3a05e35a..e45cd795 100644
--- a/src/kernel/ao_gps_show.c
+++ b/src/kernel/ao_gps_show.c
@@ -19,6 +19,8 @@
#include <ao.h>
#endif
+#include <ao_data.h>
+
void
ao_gps_show(void) __reentrant
{
@@ -27,7 +29,11 @@ ao_gps_show(void) __reentrant
printf ("Date: %02d/%02d/%02d\n", ao_gps_data.year, ao_gps_data.month, ao_gps_data.day);
printf ("Time: %02d:%02d:%02d\n", ao_gps_data.hour, ao_gps_data.minute, ao_gps_data.second);
printf ("Lat/Lon: %ld %ld\n", (long) ao_gps_data.latitude, (long) ao_gps_data.longitude);
- printf ("Alt: %d\n", ao_gps_data.altitude);
+#if HAS_WIDE_GPS
+ printf ("Alt: %ld\n", (long) AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data));
+#else
+ printf ("Alt: %d\n", AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_data));
+#endif
printf ("Flags: 0x%x\n", ao_gps_data.flags);
printf ("Sats: %d", ao_gps_tracking_data.channels);
for (i = 0; i < ao_gps_tracking_data.channels; i++)
diff --git a/src/kernel/ao_kalman.c b/src/kernel/ao_kalman.c
index 9aea1f14..7b0f8145 100644
--- a/src/kernel/ao_kalman.c
+++ b/src/kernel/ao_kalman.c
@@ -23,32 +23,31 @@
#include "ao_sample.h"
#include "ao_kalman.h"
+static __pdata ao_k_t ao_k_height;
+static __pdata ao_k_t ao_k_speed;
+static __pdata ao_k_t ao_k_accel;
-static __pdata int32_t ao_k_height;
-static __pdata int32_t ao_k_speed;
-static __pdata int32_t ao_k_accel;
+#define AO_K_STEP_100 to_fix_v(0.01)
+#define AO_K_STEP_2_2_100 to_fix_v(0.00005)
-#define AO_K_STEP_100 to_fix16(0.01)
-#define AO_K_STEP_2_2_100 to_fix16(0.00005)
+#define AO_K_STEP_10 to_fix_v(0.1)
+#define AO_K_STEP_2_2_10 to_fix_v(0.005)
-#define AO_K_STEP_10 to_fix16(0.1)
-#define AO_K_STEP_2_2_10 to_fix16(0.005)
+#define AO_K_STEP_1 to_fix_v(1)
+#define AO_K_STEP_2_2_1 to_fix_v(0.5)
-#define AO_K_STEP_1 to_fix16(1)
-#define AO_K_STEP_2_2_1 to_fix16(0.5)
+__pdata ao_v_t ao_height;
+__pdata ao_v_t ao_speed;
+__pdata ao_v_t ao_accel;
+__xdata ao_v_t ao_max_height;
+static __pdata ao_k_t ao_avg_height_scaled;
+__xdata ao_v_t ao_avg_height;
-__pdata int16_t ao_height;
-__pdata int16_t ao_speed;
-__pdata int16_t ao_accel;
-__xdata int16_t ao_max_height;
-static __pdata int32_t ao_avg_height_scaled;
-__xdata int16_t ao_avg_height;
-
-__pdata int16_t ao_error_h;
-__pdata int16_t ao_error_h_sq_avg;
+__pdata ao_v_t ao_error_h;
+__pdata ao_v_t ao_error_h_sq_avg;
#if HAS_ACCEL
-__pdata int16_t ao_error_a;
+__pdata ao_v_t ao_error_a;
#endif
static void
@@ -56,40 +55,40 @@ ao_kalman_predict(void)
{
#ifdef AO_FLIGHT_TEST
if (ao_sample_tick - ao_sample_prev_tick > 50) {
- ao_k_height += ((int32_t) ao_speed * AO_K_STEP_1 +
- (int32_t) ao_accel * AO_K_STEP_2_2_1) >> 4;
- ao_k_speed += (int32_t) ao_accel * AO_K_STEP_1;
+ ao_k_height += ((ao_k_t) ao_speed * AO_K_STEP_1 +
+ (ao_k_t) ao_accel * AO_K_STEP_2_2_1) >> 4;
+ ao_k_speed += (ao_k_t) ao_accel * AO_K_STEP_1;
return;
}
if (ao_sample_tick - ao_sample_prev_tick > 5) {
- ao_k_height += ((int32_t) ao_speed * AO_K_STEP_10 +
- (int32_t) ao_accel * AO_K_STEP_2_2_10) >> 4;
- ao_k_speed += (int32_t) ao_accel * AO_K_STEP_10;
+ ao_k_height += ((ao_k_t) ao_speed * AO_K_STEP_10 +
+ (ao_k_t) ao_accel * AO_K_STEP_2_2_10) >> 4;
+ ao_k_speed += (ao_k_t) ao_accel * AO_K_STEP_10;
return;
}
if (ao_flight_debug) {
printf ("predict speed %g + (%g * %g) = %g\n",
ao_k_speed / (65536.0 * 16.0), ao_accel / 16.0, AO_K_STEP_100 / 65536.0,
- (ao_k_speed + (int32_t) ao_accel * AO_K_STEP_100) / (65536.0 * 16.0));
+ (ao_k_speed + (ao_k_t) ao_accel * AO_K_STEP_100) / (65536.0 * 16.0));
}
#endif
- ao_k_height += ((int32_t) ao_speed * AO_K_STEP_100 +
- (int32_t) ao_accel * AO_K_STEP_2_2_100) >> 4;
- ao_k_speed += (int32_t) ao_accel * AO_K_STEP_100;
+ ao_k_height += ((ao_k_t) ao_speed * AO_K_STEP_100 +
+ (ao_k_t) ao_accel * AO_K_STEP_2_2_100) >> 4;
+ ao_k_speed += (ao_k_t) ao_accel * AO_K_STEP_100;
}
static void
ao_kalman_err_height(void)
{
- int16_t e;
- int16_t height_distrust;
+ ao_v_t e;
+ ao_v_t height_distrust;
#if HAS_ACCEL
- int16_t speed_distrust;
+ ao_v_t speed_distrust;
#endif
- ao_error_h = ao_sample_height - (int16_t) (ao_k_height >> 16);
+ ao_error_h = ao_sample_height - (ao_v_t) (ao_k_height >> 16);
e = ao_error_h;
if (e < 0)
@@ -123,7 +122,7 @@ ao_kalman_err_height(void)
#endif
if (height_distrust > 0x100)
height_distrust = 0x100;
- ao_error_h = (int16_t) (((int32_t) ao_error_h * (0x100 - height_distrust)) >> 8);
+ ao_error_h = (ao_v_t) (((ao_k_t) ao_error_h * (0x100 - height_distrust)) >> 8);
#ifdef AO_FLIGHT_TEST
if (ao_flight_debug) {
printf("over height %g over speed %g distrust: %g height: error %d -> %d\n",
@@ -142,21 +141,21 @@ ao_kalman_correct_baro(void)
ao_kalman_err_height();
#ifdef AO_FLIGHT_TEST
if (ao_sample_tick - ao_sample_prev_tick > 50) {
- ao_k_height += (int32_t) AO_BARO_K0_1 * ao_error_h;
- ao_k_speed += (int32_t) AO_BARO_K1_1 * ao_error_h;
- ao_k_accel += (int32_t) AO_BARO_K2_1 * ao_error_h;
+ ao_k_height += (ao_k_t) AO_BARO_K0_1 * ao_error_h;
+ ao_k_speed += (ao_k_t) AO_BARO_K1_1 * ao_error_h;
+ ao_k_accel += (ao_k_t) AO_BARO_K2_1 * ao_error_h;
return;
}
if (ao_sample_tick - ao_sample_prev_tick > 5) {
- ao_k_height += (int32_t) AO_BARO_K0_10 * ao_error_h;
- ao_k_speed += (int32_t) AO_BARO_K1_10 * ao_error_h;
- ao_k_accel += (int32_t) AO_BARO_K2_10 * ao_error_h;
+ ao_k_height += (ao_k_t) AO_BARO_K0_10 * ao_error_h;
+ ao_k_speed += (ao_k_t) AO_BARO_K1_10 * ao_error_h;
+ ao_k_accel += (ao_k_t) AO_BARO_K2_10 * ao_error_h;
return;
}
#endif
- ao_k_height += (int32_t) AO_BARO_K0_100 * ao_error_h;
- ao_k_speed += (int32_t) AO_BARO_K1_100 * ao_error_h;
- ao_k_accel += (int32_t) AO_BARO_K2_100 * ao_error_h;
+ ao_k_height += (ao_k_t) AO_BARO_K0_100 * ao_error_h;
+ ao_k_speed += (ao_k_t) AO_BARO_K1_100 * ao_error_h;
+ ao_k_accel += (ao_k_t) AO_BARO_K2_100 * ao_error_h;
}
#if HAS_ACCEL
@@ -164,7 +163,7 @@ ao_kalman_correct_baro(void)
static void
ao_kalman_err_accel(void)
{
- int32_t accel;
+ ao_k_t accel;
accel = (ao_config.accel_plus_g - ao_sample_accel) * ao_accel_scale;
@@ -187,18 +186,18 @@ ao_kalman_correct_both(void)
(double) ao_error_h, AO_BOTH_K10_1 / 65536.0,
(double) ao_error_a, AO_BOTH_K11_1 / 65536.0,
(ao_k_speed +
- (int32_t) AO_BOTH_K10_1 * ao_error_h +
- (int32_t) AO_BOTH_K11_1 * ao_error_a) / (65536.0 * 16.0));
+ (ao_k_t) AO_BOTH_K10_1 * ao_error_h +
+ (ao_k_t) AO_BOTH_K11_1 * ao_error_a) / (65536.0 * 16.0));
}
ao_k_height +=
- (int32_t) AO_BOTH_K00_1 * ao_error_h +
- (int32_t) AO_BOTH_K01_1 * ao_error_a;
+ (ao_k_t) AO_BOTH_K00_1 * ao_error_h +
+ (ao_k_t) AO_BOTH_K01_1 * ao_error_a;
ao_k_speed +=
- (int32_t) AO_BOTH_K10_1 * ao_error_h +
- (int32_t) AO_BOTH_K11_1 * ao_error_a;
+ (ao_k_t) AO_BOTH_K10_1 * ao_error_h +
+ (ao_k_t) AO_BOTH_K11_1 * ao_error_a;
ao_k_accel +=
- (int32_t) AO_BOTH_K20_1 * ao_error_h +
- (int32_t) AO_BOTH_K21_1 * ao_error_a;
+ (ao_k_t) AO_BOTH_K20_1 * ao_error_h +
+ (ao_k_t) AO_BOTH_K21_1 * ao_error_a;
return;
}
if (ao_sample_tick - ao_sample_prev_tick > 5) {
@@ -208,18 +207,18 @@ ao_kalman_correct_both(void)
(double) ao_error_h, AO_BOTH_K10_10 / 65536.0,
(double) ao_error_a, AO_BOTH_K11_10 / 65536.0,
(ao_k_speed +
- (int32_t) AO_BOTH_K10_10 * ao_error_h +
- (int32_t) AO_BOTH_K11_10 * ao_error_a) / (65536.0 * 16.0));
+ (ao_k_t) AO_BOTH_K10_10 * ao_error_h +
+ (ao_k_t) AO_BOTH_K11_10 * ao_error_a) / (65536.0 * 16.0));
}
ao_k_height +=
- (int32_t) AO_BOTH_K00_10 * ao_error_h +
- (int32_t) AO_BOTH_K01_10 * ao_error_a;
+ (ao_k_t) AO_BOTH_K00_10 * ao_error_h +
+ (ao_k_t) AO_BOTH_K01_10 * ao_error_a;
ao_k_speed +=
- (int32_t) AO_BOTH_K10_10 * ao_error_h +
- (int32_t) AO_BOTH_K11_10 * ao_error_a;
+ (ao_k_t) AO_BOTH_K10_10 * ao_error_h +
+ (ao_k_t) AO_BOTH_K11_10 * ao_error_a;
ao_k_accel +=
- (int32_t) AO_BOTH_K20_10 * ao_error_h +
- (int32_t) AO_BOTH_K21_10 * ao_error_a;
+ (ao_k_t) AO_BOTH_K20_10 * ao_error_h +
+ (ao_k_t) AO_BOTH_K21_10 * ao_error_a;
return;
}
if (ao_flight_debug) {
@@ -228,19 +227,19 @@ ao_kalman_correct_both(void)
(double) ao_error_h, AO_BOTH_K10_100 / 65536.0,
(double) ao_error_a, AO_BOTH_K11_100 / 65536.0,
(ao_k_speed +
- (int32_t) AO_BOTH_K10_100 * ao_error_h +
- (int32_t) AO_BOTH_K11_100 * ao_error_a) / (65536.0 * 16.0));
+ (ao_k_t) AO_BOTH_K10_100 * ao_error_h +
+ (ao_k_t) AO_BOTH_K11_100 * ao_error_a) / (65536.0 * 16.0));
}
#endif
ao_k_height +=
- (int32_t) AO_BOTH_K00_100 * ao_error_h +
- (int32_t) AO_BOTH_K01_100 * ao_error_a;
+ (ao_k_t) AO_BOTH_K00_100 * ao_error_h +
+ (ao_k_t) AO_BOTH_K01_100 * ao_error_a;
ao_k_speed +=
- (int32_t) AO_BOTH_K10_100 * ao_error_h +
- (int32_t) AO_BOTH_K11_100 * ao_error_a;
+ (ao_k_t) AO_BOTH_K10_100 * ao_error_h +
+ (ao_k_t) AO_BOTH_K11_100 * ao_error_a;
ao_k_accel +=
- (int32_t) AO_BOTH_K20_100 * ao_error_h +
- (int32_t) AO_BOTH_K21_100 * ao_error_a;
+ (ao_k_t) AO_BOTH_K20_100 * ao_error_h +
+ (ao_k_t) AO_BOTH_K21_100 * ao_error_a;
}
#else
@@ -251,14 +250,14 @@ ao_kalman_correct_accel(void)
ao_kalman_err_accel();
if (ao_sample_tick - ao_sample_prev_tick > 5) {
- ao_k_height +=(int32_t) AO_ACCEL_K0_10 * ao_error_a;
- ao_k_speed += (int32_t) AO_ACCEL_K1_10 * ao_error_a;
- ao_k_accel += (int32_t) AO_ACCEL_K2_10 * ao_error_a;
+ ao_k_height +=(ao_k_t) AO_ACCEL_K0_10 * ao_error_a;
+ ao_k_speed += (ao_k_t) AO_ACCEL_K1_10 * ao_error_a;
+ ao_k_accel += (ao_k_t) AO_ACCEL_K2_10 * ao_error_a;
return;
}
- ao_k_height += (int32_t) AO_ACCEL_K0_100 * ao_error_a;
- ao_k_speed += (int32_t) AO_ACCEL_K1_100 * ao_error_a;
- ao_k_accel += (int32_t) AO_ACCEL_K2_100 * ao_error_a;
+ ao_k_height += (ao_k_t) AO_ACCEL_K0_100 * ao_error_a;
+ ao_k_speed += (ao_k_t) AO_ACCEL_K1_100 * ao_error_a;
+ ao_k_accel += (ao_k_t) AO_ACCEL_K2_100 * ao_error_a;
}
#endif /* else FORCE_ACCEL */
diff --git a/src/kernel/ao_log.c b/src/kernel/ao_log.c
index 91617d93..40a96ef7 100644
--- a/src/kernel/ao_log.c
+++ b/src/kernel/ao_log.c
@@ -142,19 +142,39 @@ ao_log_max_flight(void)
return max_flight;
}
-void
-ao_log_scan(void) __reentrant
+static void
+ao_log_erase(uint8_t slot) __reentrant
{
- uint8_t log_slot;
- uint8_t log_slots;
- uint8_t log_want;
+ uint32_t log_current_pos, log_end_pos;
- ao_config_get();
+ ao_log_erase_mark();
+ 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;
+
+ /*
+ * Check to see if we've reached the end of
+ * the used memory to avoid re-erasing the same
+ * memory over and over again
+ */
+ for (i = 0; i < 16; i++) {
+ if (ao_storage_read(log_current_pos + i, &b, 1))
+ if (b != 0xff)
+ break;
+ }
+ if (i == 16)
+ break;
+ ao_storage_erase(log_current_pos);
+ log_current_pos += ao_storage_block;
+ }
+}
- ao_flight_number = ao_log_max_flight();
- if (ao_flight_number)
- if (++ao_flight_number == 0)
- ao_flight_number = 1;
+static void
+ao_log_find_max_erase_flight(void) __reentrant
+{
+ uint8_t log_slot;
/* Now look through the log of flight numbers from erase operations and
* see if the last one is bigger than what we found above
@@ -170,6 +190,80 @@ ao_log_scan(void) __reentrant
}
if (ao_flight_number == 0)
ao_flight_number = 1;
+}
+
+uint8_t
+ao_log_scan(void) __reentrant
+{
+ uint8_t log_slot;
+ uint8_t log_slots;
+#if FLIGHT_LOG_APPEND
+ uint8_t ret;
+#else
+ uint8_t log_want;
+#endif
+
+ ao_config_get();
+
+ /* Get any existing flight number */
+ ao_flight_number = ao_log_max_flight();
+
+#if FLIGHT_LOG_APPEND
+
+ /* Deal with older OS versions which stored multiple
+ * flights in rom by erasing everything after the first
+ * slot
+ */
+ if (ao_config.flight_log_max != ao_storage_log_max) {
+ log_slots = ao_log_slots();
+ for (log_slot = 1; log_slot < log_slots; log_slot++) {
+ if (ao_log_flight(log_slot) != 0)
+ ao_log_erase(log_slot);
+ }
+ ao_config_log_fix_append();
+ }
+ ao_log_current_pos = ao_log_pos(0);
+ ao_log_end_pos = ao_log_current_pos + ao_storage_log_max;
+
+ if (ao_flight_number) {
+ uint32_t full = ao_log_current_pos;
+ uint32_t empty = ao_log_end_pos - ao_log_size;
+
+ /* If there's already a flight started, then find the
+ * end of it
+ */
+ for (;;) {
+ ao_log_current_pos = (full + empty) >> 1;
+ ao_log_current_pos -= ao_log_current_pos % ao_log_size;
+
+ if (ao_log_current_pos == full) {
+ if (ao_log_check(ao_log_current_pos))
+ ao_log_current_pos += ao_log_size;
+ break;
+ }
+ if (ao_log_current_pos == empty)
+ break;
+
+ if (ao_log_check(ao_log_current_pos)) {
+ full = ao_log_current_pos;
+ } else {
+ empty = ao_log_current_pos;
+ }
+ }
+ ret = 1;
+ } else {
+ ao_log_find_max_erase_flight();
+ ret = 0;
+ }
+ ao_wakeup(&ao_flight_number);
+ return ret;
+#else
+
+ if (ao_flight_number)
+ if (++ao_flight_number == 0)
+ ao_flight_number = 1;
+
+ ao_log_find_max_erase_flight();
/* With a flight number in hand, find a place to write a new log,
* use the target flight number to index the available log slots so
@@ -190,8 +284,9 @@ ao_log_scan(void) __reentrant
if (++log_slot >= log_slots)
log_slot = 0;
} while (log_slot != log_want);
-
ao_wakeup(&ao_flight_number);
+ return 0;
+#endif
}
void
@@ -254,7 +349,6 @@ 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)
@@ -268,28 +362,7 @@ ao_log_delete(void) __reentrant
#if HAS_TRACKER
ao_tracker_erase_start(ao_cmd_lex_i);
#endif
- ao_log_erase_mark();
- 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;
-
- /*
- * Check to see if we've reached the end of
- * the used memory to avoid re-erasing the same
- * memory over and over again
- */
- for (i = 0; i < 16; i++) {
- if (ao_storage_read(log_current_pos + i, &b, 1))
- if (b != 0xff)
- break;
- }
- if (i == 16)
- break;
- ao_storage_erase(log_current_pos);
- log_current_pos += ao_storage_block;
- }
+ ao_log_erase(slot);
#if HAS_TRACKER
ao_tracker_erase_end();
#endif
diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h
index 33cda3eb..c13a2580 100644
--- a/src/kernel/ao_log.h
+++ b/src/kernel/ao_log.h
@@ -51,11 +51,16 @@ extern __pdata enum ao_flight_state ao_log_state;
#define AO_LOG_FORMAT_NONE 127 /* No log at all */
extern __code uint8_t ao_log_format;
+extern __code uint8_t ao_log_size;
/* Return the flight number from the given log slot, 0 if none */
uint16_t
ao_log_flight(uint8_t slot);
+/* Check if there is valid log data at the specified location */
+uint8_t
+ao_log_check(uint32_t pos);
+
/* Flush the log */
void
ao_log_flush(void);
@@ -67,7 +72,7 @@ ao_log(void);
/* functions provided in ao_log.c */
/* Figure out the current flight number */
-void
+uint8_t
ao_log_scan(void) __reentrant;
/* Return the position of the start of the given log slot */
@@ -176,8 +181,8 @@ struct ao_log_record {
int32_t gps_latitude;
int32_t gps_longitude;
struct {
- int16_t altitude;
- uint16_t unused;
+ uint16_t altitude_low;
+ int16_t altitude_high;
} gps_altitude;
struct {
uint16_t svid;
@@ -246,7 +251,7 @@ struct ao_log_mega {
struct {
int32_t latitude; /* 4 */
int32_t longitude; /* 8 */
- int16_t altitude; /* 12 */
+ uint16_t altitude_low; /* 12 */
uint8_t hour; /* 14 */
uint8_t minute; /* 15 */
uint8_t second; /* 16 */
@@ -261,7 +266,8 @@ struct ao_log_mega {
uint8_t hdop; /* 27 */
uint8_t vdop; /* 28 */
uint8_t mode; /* 29 */
- } gps; /* 30 */
+ int16_t altitude_high; /* 30 */
+ } gps; /* 32 */
/* AO_LOG_GPS_SAT */
struct {
uint16_t channels; /* 4 */
@@ -273,6 +279,11 @@ struct ao_log_mega {
} u;
};
+#define AO_LOG_MEGA_GPS_ALTITUDE(l) ((int32_t) ((l)->u.gps.altitude_high << 16) | ((l)->u.gps.altitude_low))
+#define AO_LOG_MEGA_SET_GPS_ALTITUDE(l,a) (((l)->u.gps.mode |= AO_GPS_MODE_ALTITUDE_24), \
+ ((l)->u.gps.altitude_high = (a) >> 16), \
+ (l)->u.gps.altitude_low = (a))
+
struct ao_log_metrum {
char type; /* 0 */
uint8_t csum; /* 1 */
@@ -306,8 +317,9 @@ struct ao_log_metrum {
struct {
int32_t latitude; /* 4 */
int32_t longitude; /* 8 */
- int16_t altitude; /* 12 */
- } gps; /* 14 */
+ uint16_t altitude_low; /* 12 */
+ int16_t altitude_high; /* 14 */
+ } gps; /* 16 */
/* AO_LOG_GPS_TIME */
struct {
uint8_t hour; /* 4 */
@@ -317,7 +329,7 @@ struct ao_log_metrum {
uint8_t year; /* 8 */
uint8_t month; /* 9 */
uint8_t day; /* 10 */
- uint8_t pad; /* 11 */
+ uint8_t pdop; /* 11 */
} gps_time; /* 12 */
/* AO_LOG_GPS_SAT (up to three packets) */
struct {
@@ -381,7 +393,7 @@ struct ao_log_gps {
struct {
int32_t latitude; /* 4 */
int32_t longitude; /* 8 */
- int16_t altitude; /* 12 */
+ uint16_t altitude_low; /* 12 */
uint8_t hour; /* 14 */
uint8_t minute; /* 15 */
uint8_t second; /* 16 */
@@ -396,7 +408,7 @@ struct ao_log_gps {
uint8_t hdop; /* 27 */
uint8_t vdop; /* 28 */
uint8_t mode; /* 29 */
- uint8_t state; /* 30 */
+ int16_t altitude_high; /* 30 */
} gps; /* 31 */
/* AO_LOG_GPS_SAT */
struct {
diff --git a/src/kernel/ao_log_gps.c b/src/kernel/ao_log_gps.c
index 3b728c25..7643091c 100644
--- a/src/kernel/ao_log_gps.c
+++ b/src/kernel/ao_log_gps.c
@@ -26,6 +26,7 @@
static __xdata struct ao_log_gps log;
__code uint8_t ao_log_format = AO_LOG_FORMAT_TELEGPS;
+__code uint8_t ao_log_size = sizeof (struct ao_log_gps);
static uint8_t
ao_log_csum(__xdata uint8_t *b) __reentrant
@@ -75,7 +76,8 @@ ao_log_gps_data(uint16_t tick, struct ao_telemetry_location *gps_data)
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.altitude_low = gps_data->altitude_low;
+ log.u.gps.altitude_high = gps_data->altitude_high;
log.u.gps.hour = gps_data->hour;
log.u.gps.minute = gps_data->minute;
@@ -135,3 +137,16 @@ ao_log_flight(uint8_t slot)
return log.u.flight.flight;
return 0;
}
+
+uint8_t
+ao_log_check(uint32_t pos)
+{
+ if (!ao_storage_read(pos,
+ &log,
+ sizeof (struct ao_log_gps)))
+ return 0;
+
+ if (ao_log_dump_check_data())
+ return 1;
+ return 0;
+}
diff --git a/src/kernel/ao_log_gps.h b/src/kernel/ao_log_gps.h
index 5851f4d1..a9e8c831 100644
--- a/src/kernel/ao_log_gps.h
+++ b/src/kernel/ao_log_gps.h
@@ -21,9 +21,6 @@
#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);
diff --git a/src/kernel/ao_log_micro.c b/src/kernel/ao_log_micro.c
index d665efb5..aef78def 100644
--- a/src/kernel/ao_log_micro.c
+++ b/src/kernel/ao_log_micro.c
@@ -22,10 +22,17 @@
static uint16_t ao_log_offset = STARTING_LOG_OFFSET;
+#define AO_LOG_ID_SHIFT 12
+#define AO_LOG_ID_MASK ((1 << AO_LOG_ID_SHIFT) - 1)
+
void
ao_log_micro_save(void)
{
uint16_t n_samples = (ao_log_offset - STARTING_LOG_OFFSET) / sizeof (uint16_t);
+
+#if AO_LOG_ID
+ n_samples |= AO_LOG_ID << AO_LOG_ID_SHIFT;
+#endif
ao_eeprom_write(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground));
ao_eeprom_write(PA_MIN_OFFSET, &pa_min, sizeof (pa_min));
ao_eeprom_write(N_SAMPLES_OFFSET, &n_samples, sizeof (n_samples));
@@ -99,8 +106,12 @@ ao_log_micro_dump(void)
uint16_t crc = 0xffff;
ao_eeprom_read(N_SAMPLES_OFFSET, &n_samples, sizeof (n_samples));
+
if (n_samples == 0xffff)
n_samples = 0;
+#if AO_LOG_ID
+ n_samples &= AO_LOG_ID_MASK;
+#endif
nbytes = STARTING_LOG_OFFSET + sizeof (uint16_t) * n_samples;
ao_async_start();
ao_async_byte('M');
diff --git a/src/kernel/ao_microflight.c b/src/kernel/ao_microflight.c
index f680e400..f7521f21 100644
--- a/src/kernel/ao_microflight.c
+++ b/src/kernel/ao_microflight.c
@@ -43,10 +43,12 @@ void
ao_microflight(void)
{
int16_t sample_count;
+ int16_t log_count;
uint16_t time;
uint32_t pa_interval_min, pa_interval_max;
int32_t pa_diff;
- uint8_t h, i;
+ uint8_t h;
+ uint8_t i;
uint8_t accel_lock = 0;
uint32_t pa_sum = 0;
@@ -60,19 +62,25 @@ ao_microflight(void)
h = 0;
for (;;) {
time += SAMPLE_SLEEP;
+#if BOOST_DETECT
if ((sample_count & 0x1f) == 0)
ao_led_on(AO_LED_REPORT);
+#endif
ao_delay_until(time);
ao_microsample();
+#if BOOST_DETECT
if ((sample_count & 0x1f) == 0)
ao_led_off(AO_LED_REPORT);
+#endif
pa_hist[h] = pa;
h = SKIP_PA_HIST(h,1);
pa_diff = pa_ground - ao_pa;
+#if BOOST_DETECT
/* Check for a significant pressure change */
if (pa_diff > BOOST_DETECT)
break;
+#endif
if (sample_count < GROUND_AVG * 2) {
if (sample_count < GROUND_AVG)
@@ -82,6 +90,9 @@ ao_microflight(void)
pa_ground = pa_sum >> GROUND_AVG_SHIFT;
pa_sum = 0;
sample_count = 0;
+#if !BOOST_DETECT
+ break;
+#endif
}
}
@@ -93,7 +104,10 @@ ao_microflight(void)
}
/* Log the remaining samples so we get a complete history since leaving the ground */
- for (; i != h; i = SKIP_PA_HIST(i,2)) {
+#if LOG_INTERVAL < NUM_PA_HIST
+ for (; i != h; i = SKIP_PA_HIST(i,2))
+#endif
+ {
pa = pa_hist[i];
ao_log_micro_data();
}
@@ -101,6 +115,7 @@ ao_microflight(void)
/* Now sit around until the pressure is stable again and record the max */
sample_count = 0;
+ log_count = 0;
pa_min = ao_pa;
pa_interval_min = ao_pa;
pa_interval_max = ao_pa;
@@ -112,8 +127,11 @@ ao_microflight(void)
ao_microsample();
if ((sample_count & 3) == 0)
ao_led_off(AO_LED_REPORT);
- if (sample_count & 1)
+ if (log_count == LOG_INTERVAL - 1) {
ao_log_micro_data();
+ log_count = 0;
+ } else
+ log_count++;
/* If accelerating upwards, don't look for min pressure */
if (ao_pa_accel < ACCEL_LOCK_PA)
diff --git a/src/kernel/ao_microkalman.c b/src/kernel/ao_microkalman.c
index 0684ea2b..75a29cc4 100644
--- a/src/kernel/ao_microkalman.c
+++ b/src/kernel/ao_microkalman.c
@@ -22,19 +22,19 @@
#define FIX_BITS 16
-#define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5))
-#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5))
+#define to_fix_v(x) ((int16_t) ((x) * 65536.0 + 0.5))
+#define to_fix_k(x) ((int32_t) ((x) * 65536.0 + 0.5))
#define from_fix8(x) ((x) >> 8)
#define from_fix(x) ((x) >> 16)
-#define fix8_to_fix16(x) ((x) << 8)
+#define fix8_to_fix_v(x) ((x) << 8)
#define fix16_to_fix8(x) ((x) >> 8)
#include <ao_kalman.h>
/* Basic time step (96ms) */
-#define AO_MK_STEP to_fix16(0.096)
+#define AO_MK_STEP to_fix_v(0.096)
/* step ** 2 / 2 */
-#define AO_MK_STEP_2_2 to_fix16(0.004608)
+#define AO_MK_STEP_2_2 to_fix_v(0.004608)
uint32_t ao_k_pa; /* 24.8 fixed point */
int32_t ao_k_pa_speed; /* 16.16 fixed point */
@@ -49,7 +49,7 @@ ao_microkalman_init(void)
{
ao_pa = pa;
ao_k_pa = pa << 8;
-}
+}
void
ao_microkalman_predict(void)
diff --git a/src/kernel/ao_monitor.c b/src/kernel/ao_monitor.c
index 18f170b4..2d75c41c 100644
--- a/src/kernel/ao_monitor.c
+++ b/src/kernel/ao_monitor.c
@@ -115,6 +115,8 @@ ao_monitor_put(void)
{
#if LEGACY_MONITOR
__xdata char callsign[AO_MAX_CALLSIGN+1];
+#endif
+#if LEGACY_MONITOR || HAS_RSSI
int16_t rssi;
#endif
uint8_t ao_monitor_tail;
@@ -240,7 +242,7 @@ ao_monitor_put(void)
hex(sum);
putchar ('\n');
#if HAS_RSSI
- if (recv_raw.packet[ao_monitoring + 1] & PKT_APPEND_STATUS_1_CRC_OK) {
+ if (recv_raw.packet[ao_monitoring + 1] & AO_RADIO_STATUS_CRC_OK) {
rssi = AO_RSSI_FROM_RADIO(recv_raw.packet[ao_monitoring]);
ao_rssi_set(rssi);
}
diff --git a/src/kernel/ao_mutex.c b/src/kernel/ao_mutex.c
index 952ff462..a36fe939 100644
--- a/src/kernel/ao_mutex.c
+++ b/src/kernel/ao_mutex.c
@@ -17,6 +17,29 @@
#include "ao.h"
+#ifndef HAS_MUTEX_TRY
+#define HAS_MUTEX_TRY 1
+#endif
+
+#if HAS_MUTEX_TRY
+
+uint8_t
+ao_mutex_try(__xdata uint8_t *mutex, uint8_t task_id) __reentrant
+{
+ uint8_t ret;
+ if (*mutex == task_id)
+ ao_panic(AO_PANIC_MUTEX);
+ ao_arch_critical(
+ if (*mutex)
+ ret = 0;
+ else {
+ *mutex = task_id;
+ ret = 1;
+ });
+ return ret;
+}
+#endif
+
void
ao_mutex_get(__xdata uint8_t *mutex) __reentrant
{
diff --git a/src/kernel/ao_pyro.c b/src/kernel/ao_pyro.c
index 85d88d98..3044d565 100644
--- a/src/kernel/ao_pyro.c
+++ b/src/kernel/ao_pyro.c
@@ -69,6 +69,16 @@ ao_pyro_print_status(void)
uint16_t ao_pyro_fired;
+#ifndef PYRO_DBG
+#define PYRO_DBG 0
+#endif
+
+#if PYRO_DBG
+#define DBG(...) do { printf("\t%d: ", (int) (pyro - ao_config.pyro)); printf(__VA_ARGS__); } while (0)
+#else
+#define DBG(...)
+#endif
+
/*
* Given a pyro structure, figure out
* if the current flight state satisfies all
@@ -88,63 +98,73 @@ ao_pyro_ready(struct ao_pyro *pyro)
case ao_pyro_accel_less:
if (ao_accel <= pyro->accel_less)
continue;
+ DBG("accel %d > %d\n", ao_accel, pyro->accel_less);
break;
case ao_pyro_accel_greater:
if (ao_accel >= pyro->accel_greater)
continue;
+ DBG("accel %d < %d\n", ao_accel, pyro->accel_greater);
break;
-
-
case ao_pyro_speed_less:
if (ao_speed <= pyro->speed_less)
continue;
+ DBG("speed %d > %d\n", ao_speed, pyro->speed_less);
break;
case ao_pyro_speed_greater:
if (ao_speed >= pyro->speed_greater)
continue;
+ DBG("speed %d < %d\n", ao_speed, pyro->speed_greater);
break;
-
case ao_pyro_height_less:
if (ao_height <= pyro->height_less)
continue;
+ DBG("height %d > %d\n", ao_height, pyro->height_less);
break;
case ao_pyro_height_greater:
if (ao_height >= pyro->height_greater)
continue;
+ DBG("height %d < %d\n", ao_height, pyro->height_greater);
break;
#if HAS_GYRO
case ao_pyro_orient_less:
if (ao_sample_orient <= pyro->orient_less)
continue;
+ DBG("orient %d > %d\n", ao_sample_orient, pyro->orient_less);
break;
case ao_pyro_orient_greater:
if (ao_sample_orient >= pyro->orient_greater)
continue;
+ DBG("orient %d < %d\n", ao_sample_orient, pyro->orient_greater);
break;
#endif
case ao_pyro_time_less:
if ((int16_t) (ao_time() - ao_boost_tick) <= pyro->time_less)
continue;
+ DBG("time %d > %d\n", (int16_t)(ao_time() - ao_boost_tick), pyro->time_less);
break;
case ao_pyro_time_greater:
if ((int16_t) (ao_time() - ao_boost_tick) >= pyro->time_greater)
continue;
+ DBG("time %d < %d\n", (int16_t)(ao_time() - ao_boost_tick), pyro->time_greater);
break;
case ao_pyro_ascending:
if (ao_speed > 0)
continue;
+ DBG("not ascending speed %d\n", ao_speed);
break;
case ao_pyro_descending:
if (ao_speed < 0)
continue;
+ DBG("not descending speed %d\n", ao_speed);
break;
case ao_pyro_after_motor:
if (ao_motor_number == pyro->motor)
continue;
+ DBG("motor %d != %d\n", ao_motor_number, pyro->motor);
break;
case ao_pyro_delay:
@@ -154,10 +174,12 @@ ao_pyro_ready(struct ao_pyro *pyro)
case ao_pyro_state_less:
if (ao_flight_state < pyro->state_less)
continue;
+ DBG("state %d >= %d\n", ao_flight_state, pyro->state_less);
break;
case ao_pyro_state_greater_or_equal:
if (ao_flight_state >= pyro->state_greater_or_equal)
continue;
+ DBG("state %d >= %d\n", ao_flight_state, pyro->state_less);
break;
default:
@@ -230,7 +252,7 @@ ao_pyro_check(void)
struct ao_pyro *pyro;
uint8_t p, any_waiting;
uint16_t fire = 0;
-
+
any_waiting = 0;
for (p = 0; p < AO_PYRO_NUM; p++) {
pyro = &ao_config.pyro[p];
@@ -266,6 +288,16 @@ ao_pyro_check(void)
* the delay to expire
*/
if (pyro->delay_done) {
+
+ /* Check to make sure the required conditions
+ * remain valid. If not, inhibit the channel
+ * by setting the fired bit
+ */
+ if (!ao_pyro_ready(pyro)) {
+ pyro->fired = 1;
+ continue;
+ }
+
if ((int16_t) (ao_time() - pyro->delay_done) < 0)
continue;
}
@@ -443,7 +475,7 @@ ao_pyro_set(void)
printf ("invalid pyro channel %d\n", p);
return;
}
- pyro_tmp.flags = 0;
+ memset(&pyro_tmp, '\0', sizeof (pyro_tmp));
for (;;) {
ao_cmd_white();
if (ao_cmd_lex_c == '\n')
@@ -467,13 +499,26 @@ ao_pyro_set(void)
}
pyro_tmp.flags |= ao_pyro_values[v].flag;
if (ao_pyro_values[v].offset != NO_VALUE) {
+ uint8_t negative = 0;
+ ao_cmd_white();
+ if (ao_cmd_lex_c == '-') {
+ negative = 1;
+ ao_cmd_lex();
+ }
ao_cmd_decimal();
if (ao_cmd_status != ao_cmd_success)
return;
- if (ao_pyro_values[v].flag & AO_PYRO_8_BIT_VALUE)
+ if (ao_pyro_values[v].flag & AO_PYRO_8_BIT_VALUE) {
+ if (negative) {
+ ao_cmd_status = ao_cmd_syntax_error;
+ return;
+ }
*((uint8_t *) ((char *) &pyro_tmp + ao_pyro_values[v].offset)) = ao_cmd_lex_i;
- else
+ } else {
+ if (negative)
+ ao_cmd_lex_i = -ao_cmd_lex_i;
*((int16_t *) ((char *) &pyro_tmp + ao_pyro_values[v].offset)) = ao_cmd_lex_i;
+ }
}
}
_ao_config_edit_start();
diff --git a/src/kernel/ao_pyro.h b/src/kernel/ao_pyro.h
index b37aaeb1..0fde725a 100644
--- a/src/kernel/ao_pyro.h
+++ b/src/kernel/ao_pyro.h
@@ -83,6 +83,9 @@ ao_pyro_init(void);
void
ao_pyro_manual(uint8_t p);
+enum ao_igniter_status
+ao_pyro_status(uint8_t p);
+
void
ao_pyro_print_status(void);
diff --git a/src/kernel/ao_report.c b/src/kernel/ao_report.c
index f2263154..5314fc8f 100644
--- a/src/kernel/ao_report.c
+++ b/src/kernel/ao_report.c
@@ -211,12 +211,23 @@ ao_report_continuity(void) __reentrant
pause(AO_MS_TO_TICKS(100));
}
} else {
- c = 10;
+ c = 5;
while (c--) {
high(AO_MS_TO_TICKS(20));
low(AO_MS_TO_TICKS(20));
}
}
+#if AO_PYRO_NUM
+ pause(AO_MS_TO_TICKS(250));
+ for(c = 0; c < AO_PYRO_NUM; c++) {
+ enum ao_igniter_status status = ao_pyro_status(c);
+ if (status == ao_igniter_ready)
+ mid(AO_MS_TO_TICKS(25));
+ else
+ low(AO_MS_TO_TICKS(25));
+ pause(AO_MS_TO_TICKS(200));
+ }
+#endif
#if HAS_LOG
if (ao_log_full()) {
pause(AO_MS_TO_TICKS(100));
diff --git a/src/kernel/ao_rssi.c b/src/kernel/ao_rssi.c
index 244a84fe..793b190b 100644
--- a/src/kernel/ao_rssi.c
+++ b/src/kernel/ao_rssi.c
@@ -17,9 +17,9 @@
#include "ao.h"
-static __xdata uint16_t ao_rssi_time;
-static __pdata uint16_t ao_rssi_delay;
-static __pdata uint8_t ao_rssi_led;
+static __xdata uint16_t ao_rssi_time;
+static __pdata uint16_t ao_rssi_delay;
+static __pdata AO_LED_TYPE ao_rssi_led;
void
ao_rssi(void)
@@ -33,7 +33,7 @@ ao_rssi(void)
}
void
-ao_rssi_set(int rssi_value)
+ao_rssi_set(int16_t rssi_value)
{
if (rssi_value > 0)
rssi_value = 0;
@@ -45,7 +45,7 @@ ao_rssi_set(int rssi_value)
__xdata struct ao_task ao_rssi_task;
void
-ao_rssi_init(uint8_t rssi_led)
+ao_rssi_init(AO_LED_TYPE rssi_led)
{
ao_rssi_led = rssi_led;
ao_rssi_delay = 0;
diff --git a/src/kernel/ao_sample.c b/src/kernel/ao_sample.c
index 34658951..29bf2bf6 100644
--- a/src/kernel/ao_sample.c
+++ b/src/kernel/ao_sample.c
@@ -245,7 +245,7 @@ ao_sample_preflight(void)
} else {
#if HAS_ACCEL
ao_accel_2g = ao_config.accel_minus_g - ao_config.accel_plus_g;
- ao_accel_scale = to_fix32(GRAVITY * 2 * 16) / ao_accel_2g;
+ ao_accel_scale = to_fix_32(GRAVITY * 2 * 16) / ao_accel_2g;
#endif
ao_sample_preflight_set();
ao_preflight = FALSE;
diff --git a/src/kernel/ao_sample.h b/src/kernel/ao_sample.h
index 16d4c507..2ec998bd 100644
--- a/src/kernel/ao_sample.h
+++ b/src/kernel/ao_sample.h
@@ -24,6 +24,24 @@
* ao_sample.c
*/
+#ifndef AO_VALUE_32
+#define AO_VALUE_32 1
+#endif
+
+#if AO_VALUE_32
+/*
+ * For 32-bit computed values, use 64-bit intermediates.
+ */
+typedef int64_t ao_k_t;
+typedef int32_t ao_v_t;
+#else
+/*
+ * For 16-bit computed values, use 32-bit intermediates.
+ */
+typedef int32_t ao_k_t;
+typedef int16_t ao_v_t;
+#endif
+
/*
* Barometer calibration
*
@@ -87,9 +105,9 @@
* 2047m/s² (over 200g)
*/
-#define AO_M_TO_HEIGHT(m) ((int16_t) (m))
-#define AO_MS_TO_SPEED(ms) ((int16_t) ((ms) * 16))
-#define AO_MSS_TO_ACCEL(mss) ((int16_t) ((mss) * 16))
+#define AO_M_TO_HEIGHT(m) ((ao_v_t) (m))
+#define AO_MS_TO_SPEED(ms) ((ao_v_t) ((ms) * 16))
+#define AO_MSS_TO_ACCEL(mss) ((ao_v_t) ((mss) * 16))
extern __pdata uint16_t ao_sample_tick; /* time of last data */
extern __data uint8_t ao_sample_adc; /* Ring position of last processed sample */
@@ -134,21 +152,33 @@ uint8_t ao_sample(void);
* ao_kalman.c
*/
-#define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5))
-#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5))
+#define to_fix_16(x) ((int16_t) ((x) * 65536.0 + 0.5))
+#define to_fix_32(x) ((int32_t) ((x) * 65536.0 + 0.5))
+#define to_fix_64(x) ((int64_t) ((x) * 65536.0 + 0.5))
+
+#ifdef AO_VALUE_32
+#if AO_VALUE_32
+#define to_fix_v(x) to_fix_32(x)
+#define to_fix_k(x) to_fix_64(x)
+#else
+#define to_fix_v(x) to_fix_16(x)
+#define to_fix_k(x) to_fix_32(x)
+#endif
+
#define from_fix(x) ((x) >> 16)
-extern __pdata int16_t ao_height; /* meters */
-extern __pdata int16_t ao_speed; /* m/s * 16 */
-extern __pdata int16_t ao_accel; /* m/s² * 16 */
-extern __xdata int16_t ao_max_height; /* max of ao_height */
-extern __xdata int16_t ao_avg_height; /* running average of height */
+extern __pdata ao_v_t ao_height; /* meters */
+extern __pdata ao_v_t ao_speed; /* m/s * 16 */
+extern __pdata ao_v_t ao_accel; /* m/s² * 16 */
+extern __xdata ao_v_t ao_max_height; /* max of ao_height */
+extern __xdata ao_v_t ao_avg_height; /* running average of height */
-extern __pdata int16_t ao_error_h;
-extern __pdata int16_t ao_error_h_sq_avg;
+extern __pdata ao_v_t ao_error_h;
+extern __pdata ao_v_t ao_error_h_sq_avg;
#if HAS_ACCEL
-extern __pdata int16_t ao_error_a;
+extern __pdata ao_v_t ao_error_a;
+#endif
#endif
void ao_kalman(void);
diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c
index 9f778b09..56bd715e 100644
--- a/src/kernel/ao_telemetry.c
+++ b/src/kernel/ao_telemetry.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ * Copyright © 2011 Keth 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
@@ -25,6 +25,10 @@
static __pdata uint16_t ao_telemetry_interval;
+#if HAS_RADIO_RATE
+static __xdata uint16_t ao_telemetry_desired_interval;
+#endif
+
#if HAS_RDF
static __pdata uint8_t ao_rdf = 0;
static __pdata uint16_t ao_rdf_time;
@@ -64,7 +68,7 @@ static void
ao_send_sensor(void)
{
__xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)];
-
+
telemetry.generic.tick = packet->tick;
telemetry.generic.type = AO_TELEMETRY_SENSOR;
@@ -106,12 +110,13 @@ ao_send_sensor(void)
#ifdef AO_SEND_MEGA
+
/* Send mega sensor packet */
static void
ao_send_mega_sensor(void)
{
__xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)];
-
+
telemetry.generic.tick = packet->tick;
telemetry.generic.type = AO_TELEMETRY_MEGA_SENSOR;
@@ -240,7 +245,7 @@ static void
ao_send_mini(void)
{
__xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)];
-
+
telemetry.generic.tick = packet->tick;
telemetry.generic.type = AO_TELEMETRY_MINI;
@@ -339,7 +344,7 @@ ao_send_location(void)
ao_mutex_get(&ao_gps_mutex);
ao_xmemcpy(&telemetry.location.flags,
&ao_gps_data.flags,
- 26);
+ 27);
telemetry.location.tick = ao_gps_tick;
ao_mutex_put(&ao_gps_mutex);
ao_radio_send(&telemetry, sizeof (telemetry));
@@ -490,12 +495,33 @@ ao_telemetry(void)
}
}
+#if HAS_RADIO_RATE
+void
+ao_telemetry_reset_interval(void)
+{
+ ao_telemetry_set_interval(ao_telemetry_desired_interval);
+}
+#endif
+
void
ao_telemetry_set_interval(uint16_t interval)
{
int8_t cur = 0;
+
+#if HAS_RADIO_RATE
+ /* Limit max telemetry rate based on available radio bandwidth.
+ */
+ static __xdata const uint16_t min_interval[] = {
+ /* [AO_RADIO_RATE_38400] = */ AO_MS_TO_TICKS(100),
+ /* [AO_RADIO_RATE_9600] = */ AO_MS_TO_TICKS(500),
+ /* [AO_RADIO_RATE_2400] = */ AO_MS_TO_TICKS(1000)
+ };
+
+ ao_telemetry_desired_interval = interval;
+ if (interval < min_interval[ao_config.radio_rate])
+ interval = min_interval[ao_config.radio_rate];
+#endif
ao_telemetry_interval = interval;
-
#if AO_SEND_MEGA
if (interval > 1)
ao_telemetry_mega_data_max = 1;
@@ -521,7 +547,7 @@ ao_telemetry_set_interval(uint16_t interval)
ao_telemetry_companion_cur = cur;
#endif
- ao_telemetry_config_max = AO_SEC_TO_TICKS(1) / interval;
+ ao_telemetry_config_max = AO_SEC_TO_TICKS(5) / interval;
#if HAS_COMPANION
if (ao_telemetry_config_max > cur)
cur++;
diff --git a/src/kernel/ao_telemetry.h b/src/kernel/ao_telemetry.h
index be7d0340..83d432cf 100644
--- a/src/kernel/ao_telemetry.h
+++ b/src/kernel/ao_telemetry.h
@@ -86,12 +86,9 @@ struct ao_telemetry_configuration {
#define AO_TELEMETRY_LOCATION 0x05
-#define AO_GPS_MODE_NOT_VALID 'N'
-#define AO_GPS_MODE_AUTONOMOUS 'A'
-#define AO_GPS_MODE_DIFFERENTIAL 'D'
-#define AO_GPS_MODE_ESTIMATED 'E'
-#define AO_GPS_MODE_MANUAL 'M'
-#define AO_GPS_MODE_SIMULATED 'S'
+/* Mode bits */
+
+#define AO_GPS_MODE_ALTITUDE_24 (1 << 0) /* reports 24-bits of altitude */
struct ao_telemetry_location {
uint16_t serial; /* 0 */
@@ -99,7 +96,7 @@ struct ao_telemetry_location {
uint8_t type; /* 4 */
uint8_t flags; /* 5 Number of sats and other flags */
- int16_t altitude; /* 6 GPS reported altitude (m) */
+ uint16_t altitude_low; /* 6 GPS reported altitude (m) */
int32_t latitude; /* 8 latitude (degrees * 10⁷) */
int32_t longitude; /* 12 longitude (degrees * 10⁷) */
uint8_t year; /* 16 (- 2000) */
@@ -115,10 +112,31 @@ 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; /* 31 unused */
+ int8_t altitude_high; /* 31 high byte of altitude */
/* 32 */
};
+#if HAS_GPS
+
+#ifndef HAS_WIDE_GPS
+#define HAS_WIDE_GPS 1
+#endif
+
+#if HAS_WIDE_GPS
+typedef int32_t gps_alt_t;
+#define AO_TELEMETRY_LOCATION_ALTITUDE(l) (((gps_alt_t) (l)->altitude_high << 16) | ((l)->altitude_low))
+#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->mode |= AO_GPS_MODE_ALTITUDE_24), \
+ ((l)->altitude_high = (a) >> 16), \
+ ((l)->altitude_low = (a)))
+#else
+typedef int16_t gps_alt_t;
+#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((gps_alt_t) (l)->altitude_low)
+#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->mode = 0, \
+ (l)->altitude_low = (a)))
+#endif /* HAS_WIDE_GPS */
+
+#endif /* HAS_GPS */
+
#define AO_TELEMETRY_SATELLITE 0x06
struct ao_telemetry_satellite_info {
diff --git a/src/kernel/ao_tracker.c b/src/kernel/ao_tracker.c
index 9febc7f0..9b007af8 100644
--- a/src/kernel/ao_tracker.c
+++ b/src/kernel/ao_tracker.c
@@ -36,9 +36,9 @@ ao_usb_connected(void)
#endif
struct gps_position {
- int32_t latitude;
- int32_t longitude;
- int16_t altitude;
+ int32_t latitude;
+ int32_t longitude;
+ gps_alt_t altitude;
};
#define GPS_RING 16
@@ -72,7 +72,7 @@ ao_tracker(void)
#if !HAS_USB_CONNECT
ao_tracker_force_telem = 1;
#endif
- ao_log_scan();
+ log_started = ao_log_scan();
ao_rdf_set(1);
@@ -122,12 +122,13 @@ ao_tracker(void)
{
uint8_t ring;
uint8_t moving = 0;
+ gps_alt_t altitude = AO_TELEMETRY_LOCATION_ALTITUDE(&gps_data);
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;
+ height = gps_position[ring].altitude - altitude;
if (height < 0)
height = -height;
@@ -153,7 +154,7 @@ ao_tracker(void)
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_position[gps_head].altitude = altitude;
gps_head = ao_gps_ring_next(gps_head);
ao_mutex_put(&tracker_mutex);
}
@@ -180,8 +181,7 @@ void
ao_tracker_erase_end(void)
{
if (erasing_current) {
- ao_log_scan();
- log_started = 0;
+ log_started = ao_log_scan();
ao_mutex_put(&tracker_mutex);
}
}
@@ -203,7 +203,7 @@ ao_tracker_set_telem(void)
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 ("altitude: %ld\n", AO_TELEMETRY_LOCATION_ALTITUDE(&gps_data));
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);
diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h
index 0891903e..21a7a8e5 100644
--- a/src/lpc/ao_arch_funcs.h
+++ b/src/lpc/ao_arch_funcs.h
@@ -161,16 +161,17 @@ static inline void ao_arch_restore_stack(void) {
#endif /* HAS_TASK */
-#define ao_arch_wait_interrupt() do { \
- asm(".global ao_idle_loc\n\twfi\nao_idle_loc:"); \
- ao_arch_release_interrupts(); \
- ao_arch_block_interrupts(); \
+#define ao_arch_wait_interrupt() do { \
+ asm("\twfi\n"); \
+ ao_arch_release_interrupts(); \
+ asm(".global ao_idle_loc\n\nao_idle_loc:"); \
+ ao_arch_block_interrupts(); \
} while (0)
-#define ao_arch_critical(b) do { \
- ao_arch_block_interrupts(); \
- do { b } while (0); \
- ao_arch_release_interrupts(); \
+#define ao_arch_critical(b) do { \
+ uint32_t __mask = ao_arch_irqsave(); \
+ do { b } while (0); \
+ ao_arch_irqrestore(__mask); \
} while (0)
/*
diff --git a/src/megadongle-v0.1/Makefile b/src/megadongle-v0.1/Makefile
index ade8e496..bbe2ea58 100644
--- a/src/megadongle-v0.1/Makefile
+++ b/src/megadongle-v0.1/Makefile
@@ -53,6 +53,7 @@ ALTOS_SRC = \
ao_rssi.c \
ao_send_packet.c \
ao_packet_master.c \
+ ao_eeprom_stm.c \
ao_packet.c
PRODUCT=MegaDongle-v0.1
diff --git a/src/megadongle-v0.1/ao_megadongle.c b/src/megadongle-v0.1/ao_megadongle.c
index 2792af22..68d6de60 100644
--- a/src/megadongle-v0.1/ao_megadongle.c
+++ b/src/megadongle-v0.1/ao_megadongle.c
@@ -24,7 +24,7 @@ int
main(void)
{
ao_clock_init();
-
+
#if HAS_STACK_GUARD
ao_mpu_init();
#endif
@@ -48,7 +48,7 @@ main(void)
ao_send_packet_init();
ao_config_init();
-
+
ao_start_scheduler();
return 0;
}
diff --git a/src/megadongle-v0.1/ao_pins.h b/src/megadongle-v0.1/ao_pins.h
index d460a490..9edd91f4 100644
--- a/src/megadongle-v0.1/ao_pins.h
+++ b/src/megadongle-v0.1/ao_pins.h
@@ -15,6 +15,8 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
+/* Using TeleMetrum v1.9 board */
+
#ifndef _AO_PINS_H_
#define _AO_PINS_H_
@@ -46,7 +48,7 @@
#define HAS_SERIAL_1 0
#define USE_SERIAL_1_STDIN 0
#define SERIAL_1_PB6_PB7 0
-#define SERIAL_1_PA9_PA10 1
+#define SERIAL_1_PA9_PA10 0
#define HAS_SERIAL_2 0
#define USE_SERIAL_2_STDIN 0
@@ -56,19 +58,18 @@
#define HAS_SERIAL_3 0
#define USE_SERIAL_3_STDIN 0
#define SERIAL_3_PB10_PB11 0
-#define SERIAL_3_PC10_PC11 1
+#define SERIAL_3_PC10_PC11 0
#define SERIAL_3_PD8_PD9 0
-#define ao_gps_getchar ao_serial3_getchar
-#define ao_gps_putchar ao_serial3_putchar
-#define ao_gps_set_speed ao_serial3_set_speed
-
-#define HAS_EEPROM 0
-#define USE_INTERNAL_FLASH 0
+#define HAS_EEPROM 1
+#define USE_INTERNAL_FLASH 1
+#define USE_STORAGE_CONFIG 0
+#define USE_EEPROM_CONFIG 1
#define HAS_USB 1
#define HAS_BEEP 0
#define HAS_RADIO 1
#define HAS_TELEMETRY 0
+#define HAS_RSSI 1
#define HAS_SPI_1 0
#define SPI_1_PA5_PA6_PA7 0 /* Barometer */
@@ -76,7 +77,7 @@
#define SPI_1_PE13_PE14_PE15 0 /* Accelerometer */
#define HAS_SPI_2 1
-#define SPI_2_PB13_PB14_PB15 1 /* Flash, Companion */
+#define SPI_2_PB13_PB14_PB15 1 /* Radio */
#define SPI_2_PD1_PD3_PD4 0
#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz
@@ -85,27 +86,17 @@
#define SPI_2_MISO_PIN 14
#define SPI_2_MOSI_PIN 15
-#define HAS_I2C_1 0
-#define I2C_1_PB8_PB9 1
-
-#define HAS_I2C_2 0
-#define I2C_2_PB10_PB11 1
-
#define PACKET_HAS_SLAVE 0
#define PACKET_HAS_MASTER 1
#define LOW_LEVEL_DEBUG 0
-#define LED_PORT_0_ENABLE STM_RCC_AHBENR_GPIOAEN
-#define LED_PORT_1_ENABLE STM_RCC_AHBENR_GPIOBEN
-#define LED_PORT_0 (&stm_gpioa)
-#define LED_PORT_0_MASK (0xff)
+#define LED_PORT_0_ENABLE STM_RCC_AHBENR_GPIOCEN
+#define LED_PORT_0 (&stm_gpioc)
+#define LED_PORT_0_MASK (0xffff)
#define LED_PORT_0_SHIFT 0
-#define LED_PORT_1_MASK (0xff00)
-#define LED_PORT_1_SHIFT 0
-#define LED_PORT_1 (&stm_gpiob)
-#define LED_PIN_RED 1
-#define LED_PIN_GREEN 12
+#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)
@@ -134,15 +125,15 @@
#define AO_FEC_DEBUG 0
#define AO_CC1120_SPI_CS_PORT (&stm_gpioa)
-#define AO_CC1120_SPI_CS_PIN 0
+#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_gpioc)
-#define AO_CC1120_INT_PIN 13
+#define AO_CC1120_INT_PORT (&stm_gpioa)
+#define AO_CC1120_INT_PIN 3
-#define AO_CC1120_MCU_WAKEUP_PORT (&stm_gpioc)
-#define AO_CC1120_MCU_WAKEUP_PIN (0)
+#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
diff --git a/src/microkite/.gitignore b/src/microkite/.gitignore
new file mode 100644
index 00000000..7a5d0a1f
--- /dev/null
+++ b/src/microkite/.gitignore
@@ -0,0 +1,2 @@
+ao_product.h
+microkite-*
diff --git a/src/microkite/Makefile b/src/microkite/Makefile
new file mode 100644
index 00000000..b7523758
--- /dev/null
+++ b/src/microkite/Makefile
@@ -0,0 +1,134 @@
+#
+# Tiny AltOS build
+#
+#
+vpath % ../attiny:../drivers:../kernel:../product:..
+vpath ao-make-product.5c ../util
+vpath make-altitude-pa ../util
+
+include ../avr/Makefile.defs
+
+PROGNAME=microkite-v0.1
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SCRIPT=microkite-load
+
+PUBLISH_DIR=$(HOME)/altusmetrumllc/Binaries
+PUBLISH_HEX=$(PUBLISH_DIR)/$(HEX)
+PUBLISH_SCRIPT=$(PUBLISH_DIR)/$(SCRIPT)
+
+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=MicroKite-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
+
+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) $(HEX) microkite-load
+
+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)
+
+$(HEX): $(PROG)
+ avr-size $(PROG)
+ $(OBJCOPY) -R .eeprom -O ihex $(PROG) $@
+
+
+load: $(HEX)
+ $(LOADCMD) $(LOADARG)$(HEX)
+
+load-slow: $(HEX)
+ $(LOADCMD) $(LOADSLOW) $(LOADARG)$(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) $(HEX) $(SCRIPT)
+ rm -f ao_product.h
+
+publish: $(PUBLISH_HEX) $(PUBLISH_SCRIPT)
+
+$(PUBLISH_HEX): $(HEX)
+ cp -a $(HEX) $@
+
+$(PUBLISH_SCRIPT): $(SCRIPT)
+ cp -a $(SCRIPT) $@
+
+load-product:
+ ./$(SCRIPT) fast
+
+load-product-slow:
+ ./$(SCRIPT) slow
+
+../altitude-pa.h: make-altitude-pa
+ nickle $< > $@
+
+$(SCRIPT): $(SCRIPT).tmpl Makefile ../Version
+ sed -e 's/%HEX%/$(HEX)/' -e 's/%LOADCMD%/$(LOADCMD)/' -e 's/%LOADARG%/$(LOADARG)/' -e 's/%LOADSLOW%/$(LOADSLOW)/' $(SCRIPT).tmpl > $@ || (rm $@ && exit 1)
+ chmod +x $@
+
+install:
+
+uninstall:
+
+$(OBJ): ao_product.h $(INC)
diff --git a/src/microkite/ao_pins.h b/src/microkite/ao_pins.h
new file mode 100644
index 00000000..346b63a1
--- /dev/null
+++ b/src/microkite/ao_pins.h
@@ -0,0 +1,71 @@
+/*
+ * 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)
+
+#define BOOST_DETECT 0 /* none */
+#define LOG_INTERVAL 200 /* 19.2 seconds */
+#define BOOST_DELAY 0
+
+#define AO_LOG_ID AO_LOG_ID_MICROKITE
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/microkite/microkite-load.tmpl b/src/microkite/microkite-load.tmpl
new file mode 100644
index 00000000..08236a15
--- /dev/null
+++ b/src/microkite/microkite-load.tmpl
@@ -0,0 +1,20 @@
+#!/bin/sh
+dir=`dirname $0`
+
+HEX="$dir"/"%HEX%"
+LOADCMD="%LOADCMD%"
+LOADARG="%LOADARG%"
+LOADSLOW="%LOADSLOW%"
+LOADFAST=""
+
+case "$1" in
+fast)
+ LOADSPEED="$LOADFAST"
+ ;;
+*)
+ LOADSPEED="$LOADSLOW"
+ ;;
+esac
+
+echo ${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX}
+${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX}
diff --git a/src/micropeak/Makefile b/src/micropeak/Makefile
index 6ae3d0be..ac00f635 100644
--- a/src/micropeak/Makefile
+++ b/src/micropeak/Makefile
@@ -8,8 +8,15 @@ vpath make-altitude-pa ../util
include ../avr/Makefile.defs
+PROGNAME=micropeak-v0.1
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SCRIPT=micropeak-load
+
PUBLISH_DIR=$(HOME)/altusmetrumllc/Binaries
-PUBLISH_FILE=$(PUBLISH_DIR)/$(PROG)-$(VERSION).hex
+PUBLISH_HEX=$(PUBLISH_DIR)/$(HEX)
+PUBLISH_SCRIPT=$(PUBLISH_DIR)/$(SCRIPT)
MCU=attiny85
DUDECPUTYPE=t85
@@ -55,8 +62,6 @@ CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTIN
NICKLE=nickle
-PROG=micropeak-v0.1
-
SRC=$(ALTOS_SRC)
OBJ=$(SRC:.c=.o)
@@ -68,7 +73,7 @@ endif
# Otherwise, print the full command line.
quiet ?= $($1)
-all: $(PROG) $(PROG).hex
+all: $(PROG) $(HEX) micropeak-load
CHECK=sh ../util/check-avr-mem
@@ -76,16 +81,16 @@ $(PROG): Makefile $(OBJ)
$(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ)
$(call quiet,CHECK) $(PROG) || ($(RM) -f $(PROG); exit 1)
-$(PROG).hex: $(PROG)
+$(HEX): $(PROG)
avr-size $(PROG)
$(OBJCOPY) -R .eeprom -O ihex $(PROG) $@
-load: $(PROG).hex
- $(LOADCMD) $(LOADARG)$(PROG).hex
+load: $(HEX)
+ $(LOADCMD) $(LOADARG)$(HEX)
-load-slow: $(PROG).hex
- $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PROG).hex
+load-slow: $(HEX)
+ $(LOADCMD) $(LOADSLOW) $(LOADARG)$(HEX)
ao_product.h: ao-make-product.5c ../Version
$(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
@@ -98,22 +103,30 @@ ao_product.o: ao_product.c ao_product.h
distclean: clean
clean:
- rm -f *.o $(PROG) $(PROG).hex
+ rm -f *.o $(PROG) $(HEX) $(SCRIPT)
rm -f ao_product.h
+publish: $(PUBLISH_HEX) $(PUBLISH_SCRIPT)
-publish: $(PROG).hex
- cp -a $(PROG).hex $(PUBLISH_FILE)
+$(PUBLISH_HEX): $(HEX)
+ cp -a $(HEX) $@
+
+$(PUBLISH_SCRIPT): $(SCRIPT)
+ cp -a $(SCRIPT) $@
load-product:
- $(LOADCMD) $(LOADARG)$(PUBLISH_FILE)
+ ./$(SCRIPT) fast
load-product-slow:
- $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PUBLISH_FILE)
+ ./$(SCRIPT) slow
../altitude-pa.h: make-altitude-pa
nickle $< > $@
+$(SCRIPT): $(SCRIPT).tmpl Makefile ../Version
+ sed -e 's/%HEX%/$(HEX)/' -e 's/%LOADCMD%/$(LOADCMD)/' -e 's/%LOADARG%/$(LOADARG)/' -e 's/%LOADSLOW%/$(LOADSLOW)/' $(SCRIPT).tmpl > $@ || (rm $@ && exit 1)
+ chmod +x $@
+
install:
uninstall:
diff --git a/src/micropeak/micropeak-load.tmpl b/src/micropeak/micropeak-load.tmpl
new file mode 100644
index 00000000..08236a15
--- /dev/null
+++ b/src/micropeak/micropeak-load.tmpl
@@ -0,0 +1,20 @@
+#!/bin/sh
+dir=`dirname $0`
+
+HEX="$dir"/"%HEX%"
+LOADCMD="%LOADCMD%"
+LOADARG="%LOADARG%"
+LOADSLOW="%LOADSLOW%"
+LOADFAST=""
+
+case "$1" in
+fast)
+ LOADSPEED="$LOADFAST"
+ ;;
+*)
+ LOADSPEED="$LOADSLOW"
+ ;;
+esac
+
+echo ${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX}
+${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX}
diff --git a/src/product/Makefile.teledongle b/src/product/Makefile.teledongle
index 81151364..b7c28987 100644
--- a/src/product/Makefile.teledongle
+++ b/src/product/Makefile.teledongle
@@ -83,7 +83,7 @@ quiet ?= $($1)
all: $(PROG)
$(PROG): $(REL) Makefile
- $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) ..
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL)
$(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@
ao_product.h: ao-make-product.5c ../Version
diff --git a/src/product/Makefile.telelaunch b/src/product/Makefile.telelaunch
index 90fe7833..7311c21e 100644
--- a/src/product/Makefile.telelaunch
+++ b/src/product/Makefile.telelaunch
@@ -85,7 +85,7 @@ quiet ?= $($1)
all: $(PROG)
$(PROG): $(REL) Makefile
- $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) ..
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL)
$(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@
ao_product.h: ao-make-product.5c ../Version
diff --git a/src/product/Makefile.telemetrum b/src/product/Makefile.telemetrum
index dbbf57d8..e9b144c0 100644
--- a/src/product/Makefile.telemetrum
+++ b/src/product/Makefile.telemetrum
@@ -24,6 +24,7 @@ INC = \
altitude.h \
ao_kalman.h \
ao_product.h \
+ ao_telemetry.h \
$(TM_INC)
CORE_SRC = \
diff --git a/src/product/Makefile.telenano b/src/product/Makefile.telenano
index d2fcb6d8..e1e350a6 100644
--- a/src/product/Makefile.telenano
+++ b/src/product/Makefile.telenano
@@ -85,7 +85,7 @@ quiet ?= $($1)
all: $(PROG)
$(PROG): $(REL) Makefile
- $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) ..
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL)
$(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@
ao_product.h: ao-make-product.5c ../Version
diff --git a/src/product/ao_micropeak.c b/src/product/ao_micropeak.c
index 10f0d192..54522d86 100644
--- a/src/product/ao_micropeak.c
+++ b/src/product/ao_micropeak.c
@@ -73,8 +73,9 @@ main(void)
ao_report_altitude();
ao_pips();
ao_log_micro_dump();
-
+#if BOOST_DELAY
ao_delay(BOOST_DELAY);
+#endif
ao_microflight();
diff --git a/src/product/ao_micropeak.h b/src/product/ao_micropeak.h
index 0ec407d7..622f5a69 100644
--- a/src/product/ao_micropeak.h
+++ b/src/product/ao_micropeak.h
@@ -29,8 +29,21 @@
#define BOOST_DETECT 360 /* 30m at sea level, 36m at 2000m */
#endif
+#ifndef LOG_INTERVAL
+#define LOG_INTERVAL 2 /* 192 ms */
+#endif
+
+#define AO_LOG_ID_MICROPEAK 0
+#define AO_LOG_ID_MICROKITE 1
+
+#ifndef AO_LOG_ID
+#define AO_LOG_ID AO_LOG_ID_MICROPEAK
+#endif
+
/* Wait after power on before doing anything to give the user time to assemble the rocket */
+#ifndef BOOST_DELAY
#define BOOST_DELAY AO_SEC_TO_TICKS(60)
+#endif
/* Pressure change (in Pa) to detect landing */
#define LAND_DETECT 24 /* 2m at sea level, 2.4m at 2000m */
diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h
index b461cd3f..7ad3b4b8 100644
--- a/src/stm/ao_arch_funcs.h
+++ b/src/stm/ao_arch_funcs.h
@@ -64,6 +64,9 @@
#define AO_SPI_INDEX(id) ((id) & AO_SPI_INDEX_MASK)
#define AO_SPI_CONFIG(id) ((id) & AO_SPI_CONFIG_MASK)
+uint8_t
+ao_spi_try_get(uint8_t spi_index, uint32_t speed, uint8_t task_id);
+
void
ao_spi_get(uint8_t spi_index, uint32_t speed);
@@ -77,6 +80,9 @@ void
ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index);
void
+ao_spi_send_sync(void *block, uint16_t len, uint8_t spi_index);
+
+void
ao_spi_recv(void *block, uint16_t len, uint8_t spi_index);
void
@@ -95,6 +101,15 @@ ao_spi_init(void);
ao_spi_set_cs(reg,mask); \
} while (0)
+static inline uint8_t
+ao_spi_try_get_mask(struct stm_gpio *reg, uint16_t mask, uint8_t bus, uint32_t speed, uint8_t task_id)
+{
+ if (!ao_spi_try_get(bus, speed, task_id))
+ return 0;
+ ao_spi_set_cs(reg, mask);
+ return 1;
+}
+
#define ao_spi_put_mask(reg,mask,bus) do { \
ao_spi_clr_cs(reg,mask); \
ao_spi_put(bus); \
@@ -252,6 +267,8 @@ extern struct ao_stm_usart ao_stm_usart3;
#define ARM_PUSH32(stack, val) (*(--(stack)) = (val))
+typedef uint32_t ao_arch_irq_t;
+
static inline uint32_t
ao_arch_irqsave(void) {
uint32_t primask;
@@ -369,10 +386,10 @@ static inline void ao_arch_start_scheduler(void) {
ao_arch_block_interrupts(); \
} while (0)
-#define ao_arch_critical(b) do { \
- ao_arch_block_interrupts(); \
- do { b } while (0); \
- ao_arch_release_interrupts(); \
+#define ao_arch_critical(b) do { \
+ uint32_t __mask = ao_arch_irqsave(); \
+ do { b } while (0); \
+ ao_arch_irqrestore(__mask); \
} while (0)
#endif /* _AO_ARCH_FUNCS_H_ */
diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c
index 56329c24..885af544 100644
--- a/src/stm/ao_spi_stm.c
+++ b/src/stm/ao_spi_stm.c
@@ -154,6 +154,28 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index)
}
void
+ao_spi_send_sync(void *block, uint16_t len, uint8_t spi_index)
+{
+ uint8_t *b = block;
+ struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi;
+
+ stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) |
+ (0 << STM_SPI_CR2_RXNEIE) |
+ (0 << STM_SPI_CR2_ERRIE) |
+ (0 << STM_SPI_CR2_SSOE) |
+ (0 << STM_SPI_CR2_TXDMAEN) |
+ (0 << STM_SPI_CR2_RXDMAEN));
+
+ /* Clear RXNE */
+ (void) stm_spi->dr;
+
+ while (len--) {
+ while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE)));
+ stm_spi->dr = *b++;
+ }
+}
+
+void
ao_spi_recv(void *block, uint16_t len, uint8_t spi_index)
{
struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi;
@@ -356,13 +378,11 @@ ao_spi_enable_index(uint8_t spi_index)
}
}
-void
-ao_spi_get(uint8_t spi_index, uint32_t speed)
+static void
+ao_spi_config(uint8_t spi_index, uint32_t speed)
{
uint8_t id = AO_SPI_INDEX(spi_index);
struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi;
-
- ao_mutex_get(&ao_spi_mutex[id]);
stm_spi->cr1 = ((0 << STM_SPI_CR1_BIDIMODE) | /* Three wire mode */
(0 << STM_SPI_CR1_BIDIOE) |
(0 << STM_SPI_CR1_CRCEN) | /* CRC disabled */
@@ -378,7 +398,7 @@ ao_spi_get(uint8_t spi_index, uint32_t speed)
(0 << STM_SPI_CR1_CPOL) | /* Format 0 */
(0 << STM_SPI_CR1_CPHA));
if (spi_index != ao_spi_index[id]) {
-
+
/* Disable old config
*/
ao_spi_disable_index(ao_spi_index[id]);
@@ -386,13 +406,32 @@ ao_spi_get(uint8_t spi_index, uint32_t speed)
/* Enable new config
*/
ao_spi_enable_index(spi_index);
-
+
/* Remember current config
*/
ao_spi_index[id] = spi_index;
}
}
+uint8_t
+ao_spi_try_get(uint8_t spi_index, uint32_t speed, uint8_t task_id)
+{
+ uint8_t id = AO_SPI_INDEX(spi_index);
+
+ if (!ao_mutex_try(&ao_spi_mutex[id], task_id))
+ return 0;
+ ao_spi_config(spi_index, speed);
+ return 1;
+}
+
+void
+ao_spi_get(uint8_t spi_index, uint32_t speed)
+{
+ uint8_t id = AO_SPI_INDEX(spi_index);
+ ao_mutex_get(&ao_spi_mutex[id]);
+ ao_spi_config(spi_index, speed);
+}
+
void
ao_spi_put(uint8_t spi_index)
{
diff --git a/src/telebt-v1.0/ao_pins.h b/src/telebt-v1.0/ao_pins.h
index 9e47f3b8..4181ef35 100644
--- a/src/telebt-v1.0/ao_pins.h
+++ b/src/telebt-v1.0/ao_pins.h
@@ -48,6 +48,8 @@
#define BT_LINK_PIN P1_7
#define HAS_MONITOR 1
#define LEGACY_MONITOR 0
+#define HAS_TELEMETRY 0
+#define AO_RADIO_REG_TEST 1
#define HAS_ADC 1
#define AO_PAD_ADC_BATT 0
diff --git a/src/telefire-v0.1/Makefile b/src/telefire-v0.1/Makefile
index 25267268..99d29826 100644
--- a/src/telefire-v0.1/Makefile
+++ b/src/telefire-v0.1/Makefile
@@ -25,7 +25,6 @@ INC = \
CORE_SRC = \
ao_cmd.c \
ao_config.c \
- ao_convert.c \
ao_mutex.c \
ao_panic.c \
ao_stdio.c \
diff --git a/src/telefire-v0.1/ao_pins.h b/src/telefire-v0.1/ao_pins.h
index f7a3ff2c..47ae663f 100644
--- a/src/telefire-v0.1/ao_pins.h
+++ b/src/telefire-v0.1/ao_pins.h
@@ -18,7 +18,8 @@
#ifndef _AO_PINS_H_
#define _AO_PINS_H_
-#define HAS_RADIO 1
+#define HAS_RADIO 1
+#define HAS_TELEMETRY 0
#define HAS_FLIGHT 0
#define HAS_USB 1
diff --git a/src/telefire-v0.2/Makefile b/src/telefire-v0.2/Makefile
index ad5065c1..944543c5 100644
--- a/src/telefire-v0.2/Makefile
+++ b/src/telefire-v0.2/Makefile
@@ -25,7 +25,6 @@ INC = \
CORE_SRC = \
ao_cmd.c \
ao_config.c \
- ao_convert.c \
ao_mutex.c \
ao_panic.c \
ao_stdio.c \
diff --git a/src/telefire-v0.2/ao_pins.h b/src/telefire-v0.2/ao_pins.h
index 96e6b066..28cc65b9 100644
--- a/src/telefire-v0.2/ao_pins.h
+++ b/src/telefire-v0.2/ao_pins.h
@@ -18,7 +18,9 @@
#ifndef _AO_PINS_H_
#define _AO_PINS_H_
-#define HAS_RADIO 1
+#define HAS_RADIO 1
+#define HAS_RADIO_RATE 1
+#define HAS_TELEMETRY 0
#define HAS_FLIGHT 0
#define HAS_USB 1
@@ -95,11 +97,13 @@
#define AO_PAD_ALL_PINS ((1 << AO_PAD_PIN_0) | (1 << AO_PAD_PIN_1) | (1 << AO_PAD_PIN_2) | (1 << AO_PAD_PIN_3))
#define AO_PAD_ALL_CHANNELS ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
+/* Alarm 2 */
#define AO_SIREN_PORT P2
#define AO_SIREN_DIR P2DIR
#define AO_SIREN_PIN 3
#define AO_SIREN P2_3
+/* Alarm 1 */
#define AO_STROBE_PORT P2
#define AO_STROBE_DIR P2DIR
#define AO_STROBE_PIN 4
diff --git a/src/telegps-v1.0/ao_pins.h b/src/telegps-v1.0/ao_pins.h
index 5f53dd9d..d2382a56 100644
--- a/src/telegps-v1.0/ao_pins.h
+++ b/src/telegps-v1.0/ao_pins.h
@@ -71,11 +71,11 @@
#define HAS_GPS 1
#define HAS_FLIGHT 0
#define HAS_LOG 1
+#define FLIGHT_LOG_APPEND 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
diff --git a/src/telelco-v0.2/ao_lco.c b/src/telelco-v0.2/ao_lco.c
index b3f5bb16..4b5f7a9b 100644
--- a/src/telelco-v0.2/ao_lco.c
+++ b/src/telelco-v0.2/ao_lco.c
@@ -258,7 +258,7 @@ ao_lco_search(void)
for (box = 0; box < AO_PAD_MAX_BOXES; box++) {
if ((box % 10) == 0)
ao_lco_set_box(box);
- for (try = 0; try < 5; try++) {
+ for (try = 0; try < 3; try++) {
tick_offset = 0;
r = ao_lco_query(box, &ao_pad_query, &tick_offset);
PRINTD("box %d result %d\n", box, r);
diff --git a/src/telelco-v0.2/ao_pins.h b/src/telelco-v0.2/ao_pins.h
index a6fd4ff8..da790b14 100644
--- a/src/telelco-v0.2/ao_pins.h
+++ b/src/telelco-v0.2/ao_pins.h
@@ -48,6 +48,7 @@
#define HAS_USB 1
#define HAS_BEEP 1
#define HAS_RADIO 1
+#define HAS_RADIO_RATE 1
#define HAS_TELEMETRY 0
#define HAS_AES 1
diff --git a/src/telemega-v1.0/Makefile b/src/telemega-v1.0/Makefile
index 46c768e4..4a1b3908 100644
--- a/src/telemega-v1.0/Makefile
+++ b/src/telemega-v1.0/Makefile
@@ -31,6 +31,7 @@ INC = \
ao_mpu.h \
stm32l.h \
math.h \
+ ao_ms5607_convert.c \
Makefile
#
diff --git a/src/telemini-v2.0/Makefile b/src/telemini-v2.0/Makefile
index ca69dc41..8657e9a9 100644
--- a/src/telemini-v2.0/Makefile
+++ b/src/telemini-v2.0/Makefile
@@ -25,7 +25,8 @@ INC = \
ao_int64.h \
ao_sample.h \
ao_exti.h \
- ao_task.h
+ ao_task.h \
+ altitude-pa-small.h
CORE_SRC = \
ao_cmd.c \
diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h
index f202ccd1..ed911798 100644
--- a/src/telemini-v2.0/ao_pins.h
+++ b/src/telemini-v2.0/ao_pins.h
@@ -22,15 +22,18 @@
#define HAS_FLIGHT 1
#define HAS_USB 1
+#define AO_VALUE_32 0
#define HAS_USB_PULLUP 1
#define AO_USB_PULLUP_PORT P1
#define AO_USB_PULLUP_PIN 0
#define AO_USB_PULLUP P1_0
+#define AO_SMALL_ALTITUDE_TABLE 1
+
#define USB_FORCE_FLIGHT_IDLE 1
#define HAS_BEEP 1
-#define HAS_BEEP_CONFIG 0
+#define HAS_BEEP_CONFIG 1
#define HAS_BATTERY_REPORT 1
#define HAS_GPS 0
#define HAS_SERIAL_1 0
@@ -39,6 +42,8 @@
#define USE_INTERNAL_FLASH 0
#define HAS_DBG 0
#define PACKET_HAS_SLAVE 1
+#define HAS_RADIO_RATE 1
+#define HAS_TELEMETRY 1
#define AO_LED_RED 2
#define LEDS_AVAILABLE AO_LED_RED
diff --git a/src/telerepeat-v1.0/Makefile b/src/telerepeat-v1.0/Makefile
new file mode 100644
index 00000000..17f68377
--- /dev/null
+++ b/src/telerepeat-v1.0/Makefile
@@ -0,0 +1,100 @@
+#
+# TeleRepeat build file
+#
+
+TELEREPEAT_VER=1.0
+TELEREPEAT_DEF=1_0
+
+vpath %.c ..:../kernel:../cc1111:../drivers:../product
+vpath %.h ..:../kernel:../cc1111:../drivers:../product
+vpath ao-make-product.5c ../util
+
+ifndef VERSION
+include ../Version
+endif
+
+INC = \
+ ao.h \
+ ao_pins.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ cc1111.h \
+ ao_product.h
+
+CORE_SRC = \
+ ao_cmd.c \
+ ao_config.c \
+ ao_monitor.c \
+ ao_mutex.c \
+ ao_panic.c \
+ ao_state.c \
+ ao_stdio.c \
+ ao_task.c \
+ ao_forward.c \
+ ao_storage.c \
+ ao_freq.c
+
+CC1111_SRC = \
+ ao_dbg.c \
+ ao_adc.c \
+ ao_dma.c \
+ ao_led.c \
+ ao_packet.c \
+ ao_intflash.c \
+ ao_packet_master.c \
+ ao_radio.c \
+ ao_romconfig.c \
+ ao_serial.c \
+ ao_string.c \
+ ao_timer.c \
+ ao_usb.c \
+ _bp.c
+
+DRIVER_SRC = \
+ ao_btm.c
+
+PRODUCT_SRC = \
+ ao_telerepeat.c
+
+SRC = \
+ $(CORE_SRC) \
+ $(CC1111_SRC) \
+ $(DRIVER_SRC) \
+ $(PRODUCT_SRC)
+
+PROGNAME = telerepeat-v$(TELEREPEAT_VER)
+PROG = $(PROGNAME)-$(VERSION).ihx
+PRODUCT=TeleRepeat-v$(TELEREPEAT_VER)
+PRODUCT_DEF=-DTELEREPEAT_V_$(TELEREPEAT_DEF)
+IDPRODUCT=0x000e
+CODESIZE=0x7800
+
+include ../cc1111/Makefile.cc1111
+
+NICKLE=nickle
+CHECK_STACK=sh ../util/check-stack
+
+V=0
+# The user has explicitly enabled quiet compilation.
+ifeq ($(V),0)
+quiet = @printf " $1 $2 $@\n"; $($1)
+endif
+# Otherwise, print the full command line.
+quiet ?= $($1)
+
+all: $(PROG)
+
+$(PROG): $(REL) Makefile
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL)
+ $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@
+
+ao_product.h: ao-make-product.5c ../Version
+ $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
+
+distclean: clean
+
+clean: clean-cc1111
+
+install:
+
+uninstall:
diff --git a/src/telerepeat-v1.0/ao_pins.h b/src/telerepeat-v1.0/ao_pins.h
new file mode 100644
index 00000000..2a7dbd3b
--- /dev/null
+++ b/src/telerepeat-v1.0/ao_pins.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2010 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+#define HAS_RADIO 1
+#define HAS_RADIO_FORWARD 1
+#define HAS_FLIGHT 0
+#define HAS_USB 1
+#define HAS_BEEP 0
+#define HAS_SERIAL_1 1
+#define HAS_SERIAL_1_ALT_1 1
+#define HAS_SERIAL_1_ALT_2 0
+#define HAS_SERIAL_1_HW_FLOW 1
+#define USE_SERIAL_1_STDIN 1
+#define DELAY_SERIAL_1_STDIN 1
+#define HAS_DBG 1
+#define HAS_EEPROM 1
+#define HAS_LOG 0
+#define USE_INTERNAL_FLASH 1
+#define HAS_BTM 1
+#define DBG_ON_P1 1
+#define DBG_ON_P0 0
+#define PACKET_HAS_MASTER 1
+#define PACKET_HAS_SLAVE 0
+#define AO_LED_RED 1
+#define AO_LED_BLUE 2
+#define LEDS_AVAILABLE (AO_LED_RED|AO_LED_BLUE)
+#define AO_MONITOR_LED AO_LED_RED
+#define AO_BT_LED AO_LED_BLUE
+#define BT_LINK_ON_P2 0
+#define BT_LINK_ON_P1 1
+#define BT_LINK_PIN_INDEX 7
+#define BT_LINK_PIN P1_7
+#define HAS_MONITOR 1
+#define HAS_MONITOR_PUT 1
+#define LEGACY_MONITOR 0
+#define HAS_TELEMETRY 0
+#define AO_RADIO_REG_TEST 1
+
+#define HAS_ADC 1
+#define AO_PAD_ADC_BATT 0
+#define AO_ADC_PINS (1 << AO_PAD_ADC_BATT)
+
+struct ao_adc {
+ int16_t batt;
+};
+
+#define AO_ADC_DUMP(p) \
+ printf ("tick: %5u batt %5d\n", \
+ (p)->tick, \
+ (p)->adc.batt)
+
+#define FETCH_ADC() do { \
+ a = (uint8_t __xdata *) (&ao_data_ring[ao_data_head].adc.batt); \
+ a[0] = ADCL; \
+ a[1] = ADCH; \
+ } while (0)
+
+#if DBG_ON_P1
+
+ #define DBG_CLOCK (1 << 4) /* mi0 */
+ #define DBG_DATA (1 << 5) /* mo0 */
+ #define DBG_RESET_N (1 << 3) /* c0 */
+
+ #define DBG_CLOCK_PIN (P1_4)
+ #define DBG_DATA_PIN (P1_5)
+ #define DBG_RESET_N_PIN (P1_3)
+
+ #define DBG_PORT_NUM 1
+ #define DBG_PORT P1
+ #define DBG_PORT_SEL P1SEL
+ #define DBG_PORT_INP P1INP
+ #define DBG_PORT_DIR P1DIR
+
+#endif /* DBG_ON_P1 */
+
+#if DBG_ON_P0
+
+ #define DBG_CLOCK (1 << 3)
+ #define DBG_DATA (1 << 4)
+ #define DBG_RESET_N (1 << 5)
+
+ #define DBG_CLOCK_PIN (P0_3)
+ #define DBG_DATA_PIN (P0_4)
+ #define DBG_RESET_N_PIN (P0_5)
+
+ #define DBG_PORT_NUM 0
+ #define DBG_PORT P0
+ #define DBG_PORT_SEL P0SEL
+ #define DBG_PORT_INP P0INP
+ #define DBG_PORT_DIR P0DIR
+
+#endif /* DBG_ON_P0 */
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telerepeat-v1.0/ao_telerepeat.c b/src/telerepeat-v1.0/ao_telerepeat.c
new file mode 100644
index 00000000..21bf8a73
--- /dev/null
+++ b/src/telerepeat-v1.0/ao_telerepeat.c
@@ -0,0 +1,47 @@
+/*
+ * 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_forward.h"
+
+void
+main(void)
+{
+ ao_clock_init();
+
+ /* Turn on the LED until the system is stable */
+ ao_led_init(LEDS_AVAILABLE);
+ ao_led_on(AO_LED_RED);
+
+ ao_task_init();
+
+ ao_timer_init();
+ ao_cmd_init();
+ ao_usb_init();
+ ao_monitor_init();
+ ao_radio_init();
+ ao_packet_master_init();
+ ao_adc_init();
+ ao_btm_init();
+ ao_monitor_forward_init();
+ ao_storage_init();
+#if HAS_DBG
+ ao_dbg_init();
+#endif
+ ao_config_init();
+ ao_start_scheduler();
+}
diff --git a/src/teleshield-v0.1/ao_pins.h b/src/teleshield-v0.1/ao_pins.h
index 30239afc..68bb44ee 100644
--- a/src/teleshield-v0.1/ao_pins.h
+++ b/src/teleshield-v0.1/ao_pins.h
@@ -62,6 +62,7 @@
#define HAS_RSSI 0
#define HAS_AES 0
#define HAS_RADIO 1
+ #define HAS_TELEMETRY 0
#endif
#if DBG_ON_P1
diff --git a/src/teleterra-v0.2/ao_pins.h b/src/teleterra-v0.2/ao_pins.h
index 1c12c437..472af534 100644
--- a/src/teleterra-v0.2/ao_pins.h
+++ b/src/teleterra-v0.2/ao_pins.h
@@ -71,7 +71,9 @@
#define HAS_P2_ISR 1
#define BATTERY_PIN 5
-
+ #define HAS_TELEMETRY 0
+
+ #define AO_VALUE_32 0
#endif
#if DBG_ON_P1
diff --git a/src/test/Makefile b/src/test/Makefile
index 017f7f71..02e1d22b 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -1,6 +1,7 @@
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_flight_test_metrum \
ao_gps_test ao_gps_test_skytraq ao_gps_test_ublox ao_convert_test ao_convert_pa_test ao_fec_test \
ao_aprs_test ao_micropeak_test ao_fat_test ao_aes_test ao_int64_test \
ao_ms5607_convert_test ao_quaternion_test
@@ -33,6 +34,9 @@ ao_flight_test_accel: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kal
ao_flight_test_mm: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS)
cc -DTELEMEGA=1 $(CFLAGS) -o $@ $< -lm
+ao_flight_test_metrum: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c ao_pyro.c ao_pyro.h $(INCS)
+ cc -DTELEMETRUM_V2=1 $(CFLAGS) -o $@ $< -lm
+
ao_gps_test: ao_gps_test.c ao_gps_sirf.c ao_gps_print.c ao_host.h
cc $(CFLAGS) -o $@ $<
diff --git a/src/test/ao_aprs_test.c b/src/test/ao_aprs_test.c
index 86cf527a..ae505dea 100644
--- a/src/test/ao_aprs_test.c
+++ b/src/test/ao_aprs_test.c
@@ -21,6 +21,8 @@
#include <stdint.h>
#include <stdarg.h>
+#define HAS_GPS 1
+
#include <ao_telemetry.h>
#define AO_GPS_NUM_SAT_MASK (0xf << 0)
@@ -97,41 +99,14 @@ 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_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_data, 84);
ao_gps_data.flags = (AO_GPS_VALID|AO_GPS_RUNNING);
/* Transmit one packet */
diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c
index 0647fc6c..8b737ca1 100644
--- a/src/test/ao_flight_test.c
+++ b/src/test/ao_flight_test.c
@@ -34,15 +34,21 @@
#define ao_data_ring_next(n) (((n) + 1) & (AO_DATA_RING - 1))
#define ao_data_ring_prev(n) (((n) - 1) & (AO_DATA_RING - 1))
+#if 0
#define AO_M_TO_HEIGHT(m) ((int16_t) (m))
#define AO_MS_TO_SPEED(ms) ((int16_t) ((ms) * 16))
#define AO_MSS_TO_ACCEL(mss) ((int16_t) ((mss) * 16))
+#endif
#define AO_GPS_NEW_DATA 1
#define AO_GPS_NEW_TRACKING 2
int ao_gps_new;
+#if !defined(TELEMEGA) && !defined(TELEMETRUM_V2)
+#define TELEMETRUM_V1 1
+#endif
+
#if TELEMEGA
#define AO_ADC_NUM_SENSE 6
#define HAS_MS5607 1
@@ -50,6 +56,7 @@ int ao_gps_new;
#define HAS_MMA655X 1
#define HAS_HMC5883 1
#define HAS_BEEP 1
+#define AO_CONFIG_MAX_SIZE 1024
struct ao_adc {
int16_t sense[AO_ADC_NUM_SENSE];
@@ -57,7 +64,25 @@ struct ao_adc {
int16_t v_pbatt;
int16_t temp;
};
-#else
+#endif
+
+#if TELEMETRUM_V2
+#define AO_ADC_NUM_SENSE 2
+#define HAS_MS5607 1
+#define HAS_MMA655X 1
+#define HAS_BEEP 1
+#define AO_CONFIG_MAX_SIZE 1024
+
+struct ao_adc {
+ int16_t sense_a;
+ int16_t sense_m;
+ int16_t v_batt;
+ int16_t temp;
+};
+#endif
+
+
+#if TELEMETRUM_V1
/*
* One set of samples read from the A/D converter
*/
@@ -92,6 +117,7 @@ struct ao_adc {
#include <ao_data.h>
#include <ao_log.h>
#include <ao_telemetry.h>
+#include <ao_sample.h>
#if TELEMEGA
int ao_gps_count;
@@ -174,7 +200,7 @@ ao_gps_angle(void)
ao_gps_static.latitude / 1e7,
ao_gps_static.longitude / 1e7,
&dist, &bearing);
- height = ao_gps_static.altitude - ao_gps_prev.altitude;
+ height = AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_static) - AO_TELEMETRY_LOCATION_ALTITUDE(&ao_gps_prev);
angle = atan2(dist, height);
return angle * 180/M_PI;
@@ -185,17 +211,6 @@ ao_gps_angle(void)
#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5))
#define from_fix(x) ((x) >> 16)
-/*
- * Above this height, the baro sensor doesn't work
- */
-#define AO_BARO_SATURATE 13000
-#define AO_MIN_BARO_VALUE ao_altitude_to_pres(AO_BARO_SATURATE)
-
-/*
- * Above this speed, baro measurements are unreliable
- */
-#define AO_MAX_BARO_SPEED 200
-
#define ACCEL_NOSE_UP (ao_accel_2g >> 2)
extern enum ao_flight_state ao_flight_state;
@@ -233,7 +248,7 @@ double main_time;
int tick_offset;
-static int32_t ao_k_height;
+static ao_k_t ao_k_height;
int16_t
ao_time(void)
@@ -305,7 +320,7 @@ struct ao_cmds {
#define ao_xmemcmp(d,s,c) memcmp(d,s,c)
#define AO_NEED_ALTITUDE_TO_PRES 1
-#if TELEMEGA
+#if TELEMEGA || TELEMETRUM_V2
#include "ao_convert_pa.c"
#include <ao_ms5607.h>
struct ao_ms5607_prom ao_ms5607_prom;
@@ -455,7 +470,7 @@ ao_insert(void)
#else
double accel = 0.0;
#endif
-#if TELEMEGA
+#if TELEMEGA || TELEMETRUM_V2
double height;
ao_ms5607_convert(&ao_data_static.ms5607_raw, &ao_data_static.ms5607_cooked);
@@ -550,6 +565,7 @@ ao_insert(void)
mag_azel.el,
mag_azel.az);
#endif
+#if 0
printf ("%7.2f state %-8.8s height %8.4f tilt %4d rot %4d dist %12.2f gps_tilt %4d gps_sats %2d\n",
time,
ao_state_names[ao_flight_state],
@@ -559,6 +575,7 @@ ao_insert(void)
(int) floor (ao_gps_angle() + 0.5),
(ao_gps_static.flags & 0xf) * 10);
+#endif
#if 0
printf ("\t\tstate %-8.8s ground az: %4d el %4d mag az %4d el %4d rot az %4d el %4d el_diff %4d az_diff %4d angle %4d tilt %4d ground %8.5f %8.5f %8.5f cur %8.5f %8.5f %8.5f rot %8.5f %8.5f %8.5f\n",
ao_state_names[ao_flight_state],
@@ -581,9 +598,9 @@ ao_insert(void)
#endif
#endif
-#if 0
+#if 1
printf("%7.2f height %8.2f accel %8.3f "
-#if TELEMEGA
+#if TELEMEGA && 0
"angle %5d "
"accel_x %8.3f accel_y %8.3f accel_z %8.3f gyro_x %8.3f gyro_y %8.3f gyro_z %8.3f mag_x %8d mag_y %8d, mag_z %8d mag_angle %4d "
#endif
@@ -591,7 +608,7 @@ ao_insert(void)
time,
height,
accel,
-#if TELEMEGA
+#if TELEMEGA && 0
ao_sample_orient,
ao_mpu6000_accel(ao_data_static.mpu6000.accel_x),
@@ -674,7 +691,8 @@ ao_sleep(void *wchan)
{
#if TELEMEGA
ao_data_static.mpu6000 = ao_ground_mpu6000;
-#else
+#endif
+#if TELEMETRUM_V1
ao_data_static.adc.accel = ao_flight_ground_accel;
#endif
ao_insert();
@@ -755,7 +773,10 @@ ao_sleep(void *wchan)
ao_gps_static.tick = tick;
ao_gps_static.latitude = int32(bytes, 0);
ao_gps_static.longitude = int32(bytes, 4);
- ao_gps_static.altitude = int32(bytes, 8);
+ {
+ int32_t altitude = int32(bytes, 8);
+ AO_TELEMETRY_LOCATION_SET_ALTITUDE(&ao_gps_static, altitude);
+ }
ao_gps_static.flags = bytes[13];
if (!ao_gps_count)
ao_gps_first = ao_gps_static;
@@ -795,11 +816,64 @@ ao_sleep(void *wchan)
pyro->flags |= ao_pyro_values[j].flag;
if (ao_pyro_values[j].offset != NO_VALUE && i + 1 < nword) {
int16_t val = strtoul(words[++i], NULL, 10);
+ printf("pyro %d condition %s value %d\n", p, words[i-1], val);
*((int16_t *) ((char *) pyro + ao_pyro_values[j].offset)) = val;
}
}
}
-#else
+#endif
+#if TELEMETRUM_V2
+ if (log_format == AO_LOG_FORMAT_TELEMETRUM && nword == 14 && strlen(words[0]) == 1) {
+ int i;
+ struct ao_ms5607_value value;
+
+ type = words[0][0];
+ tick = strtoul(words[1], NULL, 16);
+// printf ("%c %04x", type, tick);
+ for (i = 2; i < nword; i++) {
+ bytes[i - 2] = strtoul(words[i], NULL, 16);
+// printf(" %02x", bytes[i-2]);
+ }
+// printf ("\n");
+ switch (type) {
+ case 'F':
+ ao_flight_ground_accel = int16(bytes, 2);
+ ao_flight_started = 1;
+ ao_ground_pres = int32(bytes, 4);
+ ao_ground_height = ao_pa_to_altitude(ao_ground_pres);
+ break;
+ case 'A':
+ ao_data_static.tick = tick;
+ ao_data_static.ms5607_raw.pres = int32(bytes, 0);
+ ao_data_static.ms5607_raw.temp = int32(bytes, 4);
+ ao_ms5607_convert(&ao_data_static.ms5607_raw, &value);
+ ao_data_static.mma655x = int16(bytes, 8);
+ ao_records_read++;
+ ao_insert();
+ return;
+ }
+ continue;
+ } else if (nword == 3 && strcmp(words[0], "ms5607") == 0) {
+ if (strcmp(words[1], "reserved:") == 0)
+ ao_ms5607_prom.reserved = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "sens:") == 0)
+ ao_ms5607_prom.sens = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "off:") == 0)
+ ao_ms5607_prom.off = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "tcs:") == 0)
+ ao_ms5607_prom.tcs = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "tco:") == 0)
+ ao_ms5607_prom.tco = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "tref:") == 0)
+ ao_ms5607_prom.tref = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "tempsens:") == 0)
+ ao_ms5607_prom.tempsens = strtoul(words[2], NULL, 10);
+ else if (strcmp(words[1], "crc:") == 0)
+ ao_ms5607_prom.crc = strtoul(words[2], NULL, 10);
+ continue;
+ }
+#endif
+#if TELEMETRUM_V1
if (nword == 4 && log_format != AO_LOG_FORMAT_TELEMEGA) {
type = words[0][0];
tick = strtoul(words[1], NULL, 16);
@@ -924,7 +998,7 @@ ao_sleep(void *wchan)
if (type != 'F' && !ao_flight_started)
continue;
-#if TELEMEGA
+#if TELEMEGA || TELEMETRUM_V2
(void) a;
(void) b;
#else
@@ -945,8 +1019,6 @@ ao_sleep(void *wchan)
ao_data_static.tick = tick;
ao_data_static.adc.accel = a;
ao_data_static.adc.pres_real = b;
- if (b < AO_MIN_BARO_VALUE)
- b = AO_MIN_BARO_VALUE;
ao_data_static.adc.pres = b;
ao_records_read++;
ao_insert();
diff --git a/src/test/ao_gps_test.c b/src/test/ao_gps_test.c
index e799ab0f..543bbcc3 100644
--- a/src/test/ao_gps_test.c
+++ b/src/test/ao_gps_test.c
@@ -53,6 +53,9 @@ struct ao_gps_orig {
uint16_t v_error; /* m */
};
+#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((l)->altitude)
+#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) ((l)->altitude = (a))
+
#define SIRF_SAT_STATE_ACQUIRED (1 << 0)
#define SIRF_SAT_STATE_CARRIER_PHASE_VALID (1 << 1)
#define SIRF_SAT_BIT_SYNC_COMPLETE (1 << 2)
@@ -433,7 +436,7 @@ ao_dump_state(void *wchan)
if (wchan != &ao_gps_new)
return;
-
+
if (ao_gps_new & AO_GPS_NEW_DATA) {
ao_gps_print(&ao_gps_data);
putchar('\n');
diff --git a/src/test/ao_gps_test_skytraq.c b/src/test/ao_gps_test_skytraq.c
index 1b590d5e..5eb7118d 100644
--- a/src/test/ao_gps_test_skytraq.c
+++ b/src/test/ao_gps_test_skytraq.c
@@ -16,6 +16,7 @@
*/
#define AO_GPS_TEST
+#define HAS_GPS 1
#include "ao_host.h"
#include <termios.h>
#include <errno.h>
@@ -53,6 +54,9 @@ struct ao_gps_orig {
uint16_t v_error; /* m */
};
+#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((l)->altitude)
+#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) ((l)->altitude = (a))
+
#define SIRF_SAT_STATE_ACQUIRED (1 << 0)
#define SIRF_SAT_STATE_CARRIER_PHASE_VALID (1 << 1)
#define SIRF_SAT_BIT_SYNC_COMPLETE (1 << 2)
diff --git a/src/test/ao_gps_test_ublox.c b/src/test/ao_gps_test_ublox.c
index 4eb4b837..5ea205d6 100644
--- a/src/test/ao_gps_test_ublox.c
+++ b/src/test/ao_gps_test_ublox.c
@@ -16,6 +16,7 @@
*/
#define AO_GPS_TEST
+#define HAS_GPS 1
#include "ao_host.h"
#include <termios.h>
#include <errno.h>
@@ -44,7 +45,7 @@ struct ao_telemetry_location {
uint8_t flags;
int32_t latitude; /* degrees * 10⁷ */
int32_t longitude; /* degrees * 10⁷ */
- int16_t altitude; /* m */
+ int16_t altitude_low; /* m */
uint16_t ground_speed; /* cm/s */
uint8_t course; /* degrees / 2 */
uint8_t pdop; /* * 5 */
@@ -53,8 +54,14 @@ struct ao_telemetry_location {
int16_t climb_rate; /* cm/s */
uint16_t h_error; /* m */
uint16_t v_error; /* m */
+ int16_t altitude_high; /* m */
};
+typedef int32_t gps_alt_t;
+#define AO_TELEMETRY_LOCATION_ALTITUDE(l) (((gps_alt_t) (l)->altitude_high << 16) | ((l)->altitude_low))
+#define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->altitude_high = (a) >> 16), \
+ ((l)->altitude_low = (a)))
+
#define UBLOX_SAT_STATE_ACQUIRED (1 << 0)
#define UBLOX_SAT_STATE_CARRIER_PHASE_VALID (1 << 1)
#define UBLOX_SAT_BIT_SYNC_COMPLETE (1 << 2)
diff --git a/src/test/ao_micropeak_test.c b/src/test/ao_micropeak_test.c
index 5961bd93..f4af707e 100644
--- a/src/test/ao_micropeak_test.c
+++ b/src/test/ao_micropeak_test.c
@@ -33,6 +33,7 @@ uint8_t ao_flight_debug;
#define AO_FLIGHT_TEST
typedef int32_t alt_t;
+typedef int32_t pres_t;
#define AO_MS_TO_TICKS(ms) ((ms) / 10)
diff --git a/src/test/plottest b/src/test/plottest
index 76af5ee7..7d253ff1 100755
--- a/src/test/plottest
+++ b/src/test/plottest
@@ -10,7 +10,7 @@ plot "$1" using 1:3 with lines axes x1y1 title "raw height",\
"$1" using 1:9 with lines axes x1y1 title "height",\
"$1" using 1:11 with lines axes x1y2 title "speed",\
"$1" using 1:13 with lines axes x1y2 title "accel",\
-"$1" using 1:15 with lines axes x1y1 title "drogue",\
-"$1" using 1:17 with lines axes x1y1 title "main",\
-"$1" using 1:19 with lines axes x1y1 title "error"
+"$1" using 1:17 with lines axes x1y1 title "drogue",\
+"$1" using 1:19 with lines axes x1y1 title "main",\
+"$1" using 1:21 with lines axes x1y1 title "error"
EOF
diff --git a/src/util/make-altitude-pa b/src/util/make-altitude-pa
index 22831d50..d36f3f41 100644
--- a/src/util/make-altitude-pa
+++ b/src/util/make-altitude-pa
@@ -185,105 +185,135 @@ line_t best_fit(real[] values, int first, int last) {
return (line_t) { m = m, b = b };
}
-real min_Pa = 0;
-real max_Pa = 120000;
+void print_table (int pa_sample_shift, int pa_part_shift)
+{
+ real min_Pa = 0;
+ real max_Pa = 120000;
-/* Target is an array of < 1000 entries */
-int pa_sample_shift = 2;
-int pa_part_shift = 6;
-int pa_part_mask = (1 << pa_part_shift) - 1;
+ int pa_part_mask = (1 << pa_part_shift) - 1;
-int num_part = ceil(max_Pa / (2 ** (pa_part_shift + pa_sample_shift)));
+ int num_part = ceil(max_Pa / (2 ** (pa_part_shift + pa_sample_shift)));
-int num_samples = num_part << pa_part_shift;
+ int num_samples = num_part << pa_part_shift;
-real sample_to_Pa(int sample) = sample << pa_sample_shift;
+ real sample_to_Pa(int sample) = sample << pa_sample_shift;
-real sample_to_altitude(int sample) = pressure_to_altitude(sample_to_Pa(sample));
+ real sample_to_altitude(int sample) = pressure_to_altitude(sample_to_Pa(sample));
-int part_to_sample(int part) = part << pa_part_shift;
+ int part_to_sample(int part) = part << pa_part_shift;
-int sample_to_part(int sample) = sample >> pa_part_shift;
+ int sample_to_part(int sample) = sample >> pa_part_shift;
-bool is_part(int sample) = (sample & pa_part_mask) == 0;
+ bool is_part(int sample) = (sample & pa_part_mask) == 0;
-real[num_samples] alt = { [n] = sample_to_altitude(n) };
+ real[num_samples] alt = { [n] = sample_to_altitude(n) };
-int seg_len = 1 << pa_part_shift;
+ int seg_len = 1 << pa_part_shift;
-line_t [num_part] fit = {
- [n] = best_fit(alt, n * seg_len, n * seg_len + seg_len - 1)
-};
-
-real[num_samples/seg_len + 1] alt_part;
-real[dim(alt_part)] alt_error = {0...};
-
-alt_part[0] = fit[0].b;
-alt_part[dim(fit)] = fit[dim(fit)-1].m * dim(fit) * seg_len + fit[dim(fit)-1].b;
+ line_t [num_part] fit = {
+ [n] = best_fit(alt, n * seg_len, n * seg_len + seg_len - 1)
+ };
-for (int i = 0; i < dim(fit) - 1; i++) {
- real here, there;
- here = fit[i].m * (i+1) * seg_len + fit[i].b;
- there = fit[i+1].m * (i+1) * seg_len + fit[i+1].b;
-# printf ("at %d mis-fit %8.2f\n", i, there - here);
- alt_part[i+1] = (here + there) / 2;
-}
+ real[num_samples/seg_len + 1] alt_part;
+ real[dim(alt_part)] alt_error = {0...};
-real round(real x) = floor(x + 0.5);
+ alt_part[0] = fit[0].b;
+ alt_part[dim(fit)] = fit[dim(fit)-1].m * dim(fit) * seg_len + fit[dim(fit)-1].b;
-real sample_to_fit_altitude(int sample) {
- int sub = sample // seg_len;
- int off = sample % seg_len;
- line_t l = fit[sub];
- real r_v;
- real i_v;
+ for (int i = 0; i < dim(fit) - 1; i++) {
+ real here, there;
+ here = fit[i].m * (i+1) * seg_len + fit[i].b;
+ there = fit[i+1].m * (i+1) * seg_len + fit[i+1].b;
+# printf ("at %d mis-fit %8.2f\n", i, there - here);
+ alt_part[i+1] = (here + there) / 2;
+ }
- r_v = sample * l.m + l.b;
- i_v = (round(alt_part[sub]*10) * (seg_len - off) + round(alt_part[sub+1]*10) * off) / seg_len;
- return i_v/10;
-}
+ real round(real x) = floor(x + 0.5);
-real max_error = 0;
-int max_error_sample = 0;
-real total_error = 0;
+ real sample_to_fit_altitude(int sample) {
+ int sub = sample // seg_len;
+ int off = sample % seg_len;
+ line_t l = fit[sub];
+ real r_v;
+ real i_v;
-for (int sample = 0; sample < num_samples; sample++) {
- real Pa = sample_to_Pa(sample);
- real meters = alt[sample];
+ r_v = sample * l.m + l.b;
+ i_v = (round(alt_part[sub]*10) * (seg_len - off) + round(alt_part[sub+1]*10) * off) / seg_len;
+ return i_v/10;
+ }
- real meters_approx = sample_to_fit_altitude(sample);
- real error = abs(meters - meters_approx);
+ real max_error = 0;
+ int max_error_sample = 0;
+ real total_error = 0;
+
+ for (int sample = 0; sample < num_samples; sample++) {
+ real Pa = sample_to_Pa(sample);
+ real meters = alt[sample];
+
+ real meters_approx = sample_to_fit_altitude(sample);
+ real error = abs(meters - meters_approx);
+
+ int part = sample_to_part(sample);
+
+ if (error > alt_error[part])
+ alt_error[part] = error;
+
+ total_error += error;
+ if (error > max_error) {
+ max_error = error;
+ max_error_sample = sample;
+ }
+ if (false) {
+ printf (" %8.1f %8.2f %8.2f %8.2f %s\n",
+ Pa,
+ meters,
+ meters_approx,
+ meters - meters_approx,
+ is_part(sample) ? "*" : "");
+ }
+ }
- int part = sample_to_part(sample);
+ printf ("/*max error %f at %7.3f kPa. Average error %f*/\n",
+ max_error, sample_to_Pa(max_error_sample) / 1000, total_error / num_samples);
- if (error > alt_error[part])
- alt_error[part] = error;
+ printf ("#define NALT %d\n", dim(alt_part));
+ printf ("#define ALT_SHIFT %d\n", pa_part_shift + pa_sample_shift);
+ printf ("#ifndef AO_ALT_VALUE\n#define AO_ALT_VALUE(x) (alt_t) (x)\n#endif\n");
- total_error += error;
- if (error > max_error) {
- max_error = error;
- max_error_sample = sample;
- }
- if (false) {
- printf (" %8.1f %8.2f %8.2f %8.2f %s\n",
- Pa,
- meters,
- meters_approx,
- meters - meters_approx,
- is_part(sample) ? "*" : "");
+ for (int part = 0; part < dim(alt_part); part++) {
+ real kPa = sample_to_Pa(part_to_sample(part)) / 1000;
+ printf ("AO_ALT_VALUE(%10.1f), /* %6.2f kPa error %6.2fm */\n",
+ round (alt_part[part]*10) / 10, kPa,
+ alt_error[part]);
}
}
-printf ("/*max error %f at %7.3f kPa. Average error %f*/\n",
- max_error, sample_to_Pa(max_error_sample) / 1000, total_error / num_samples);
-
-printf ("#define NALT %d\n", dim(alt_part));
-printf ("#define ALT_SHIFT %d\n", pa_part_shift + pa_sample_shift);
-printf ("#ifndef AO_ALT_VALUE\n#define AO_ALT_VALUE(x) (alt_t) (x)\n#endif\n");
-
-for (int part = 0; part < dim(alt_part); part++) {
- real kPa = sample_to_Pa(part_to_sample(part)) / 1000;
- printf ("AO_ALT_VALUE(%10.1f), /* %6.2f kPa error %6.2fm */\n",
- round (alt_part[part]*10) / 10, kPa,
- alt_error[part]);
+autoload ParseArgs;
+
+void main()
+{
+ /* Target is an array of < 1000 entries */
+ int pa_sample_shift = 2;
+ int pa_part_shift = 6;
+
+ ParseArgs::argdesc argd = {
+ .args = {
+ { .var = { .arg_int = &pa_sample_shift },
+ .abbr = 's',
+ .name = "sample",
+ .expr_name = "sample_shift",
+ .desc = "sample shift value" },
+ { .var = { .arg_int = &pa_part_shift },
+ .abbr = 'p',
+ .name = "part",
+ .expr_name = "part_shift",
+ .desc = "part shift value" },
+ }
+ };
+
+ ParseArgs::parseargs(&argd, &argv);
+
+ print_table(pa_sample_shift, pa_part_shift);
}
+
+main();