From 6579e4cae8fea65780f1c4677f29c1fc17ca41e2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Jun 2014 15:59:09 -0700 Subject: altos/micropeak: Create a script to load firmware. The micropeak-load script flashes micropeak with firmware from whatever directory it is sitting in. A 'publish' target in the source directory copies the script and hex to ~/altusmetrumllc/Binaries Signed-off-by: Keith Packard --- src/micropeak/Makefile | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'src') 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: -- cgit v1.2.3 From b397e4ff45f054acb1347ffa5468950febc431f7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Jun 2014 23:03:49 -0700 Subject: altos/micropeak: Add load script template Signed-off-by: Keith Packard --- src/micropeak/micropeak-load.tmpl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/micropeak/micropeak-load.tmpl (limited to 'src') 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} -- cgit v1.2.3 From 602d6a2424a5c16e22febf6b4e6b3816022261c7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 20 Jun 2014 00:41:17 -0700 Subject: altos/aprs: Encode last serial number in SSID. Transmit serial in comment This makes it a lot easier to tell which device is sending information, and to receive data from multiple devices on the same receiver. Signed-off-by: Keith Packard --- src/drivers/ao_aprs.c | 4 ++++ src/test/ao_aprs_test.c | 24 ------------------------ telegps/Makefile.am | 2 -- 3 files changed, 4 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index 8a1b6a4d..c33016f0 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -261,6 +261,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 +276,7 @@ tncSetCallsign(void) } for (; i < TNC_CALLSIGN_LEN; i++) TNC_AX25_HEADER[TNC_CALLSIGN_OFF + i] = ' ' << 1; + TNC_AX25_HEADER[TNC_SSID_OFF] = 0x60 | ((ao_serial_number % 10) << 1); #endif } @@ -530,6 +532,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 +545,7 @@ static int tncComment(uint8_t *buf) , main/10, main%10 #endif + , ao_serial_number ); #else return sprintf((char *) buf, diff --git a/src/test/ao_aprs_test.c b/src/test/ao_aprs_test.c index 86cf527a..573b5cb2 100644 --- a/src/test/ao_aprs_test.c +++ b/src/test/ao_aprs_test.c @@ -97,36 +97,12 @@ audio_gap(int secs) #endif } -#include - -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; diff --git a/telegps/Makefile.am b/telegps/Makefile.am index a7defb8a..3f53b949 100644 --- a/telegps/Makefile.am +++ b/telegps/Makefile.am @@ -205,8 +205,6 @@ $(FATJAR): classtelegps.stamp Manifest-fat.txt $(ALTOSLIB_CLASS) $(ALTOSUILIB_CL -C classes org \ -C ../libaltos libaltosJNI -classtelegps.stamp: $(ALTOSLIB_CLASS) $(ALTOSUILIB_CLASS) - libaltos.so: build-libaltos -rm -f "$@" $(LN_S) ../libaltos/.libs/"$@" . -- cgit v1.2.3 From 3f3382126bf1122b1a78abe8458af5ec112a1f95 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 22 Jun 2014 21:05:05 -0700 Subject: altos: Make APRS SSID configurable This uses the low-digit from the serial number by default, but lets the user change it if desired. Signed-off-by: Keith Packard --- src/drivers/ao_aprs.c | 100 ++++++++++++++++++++++++++----------------------- src/kernel/ao_config.c | 34 +++++++++++++++++ src/kernel/ao_config.h | 5 ++- 3 files changed, 91 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index c33016f0..a9047149 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 + +#if !HAS_APRS +#error HAS_APRS not set +#endif #endif #include @@ -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, @@ -276,7 +280,9 @@ tncSetCallsign(void) } for (; i < TNC_CALLSIGN_LEN; i++) TNC_AX25_HEADER[TNC_CALLSIGN_OFF + i] = ' ' << 1; - TNC_AX25_HEADER[TNC_SSID_OFF] = 0x60 | ((ao_serial_number % 10) << 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 } @@ -304,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() @@ -325,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. @@ -341,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]; @@ -363,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; @@ -383,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]; @@ -408,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; @@ -428,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; @@ -453,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; @@ -462,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; @@ -763,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/kernel/ao_config.c b/src/kernel/ao_config.c index 71445335..58fa7354 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -61,6 +61,7 @@ __xdata uint8_t ao_config_mutex; #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) #if HAS_EEPROM static void @@ -191,6 +192,10 @@ _ao_config_get(void) #if AO_PYRO_NUM 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 ao_config.minor = AO_CONFIG_MINOR; ao_config_dirty = 1; @@ -283,6 +288,7 @@ ao_config_frequency_set(void) __reentrant ao_radio_recv_abort(); #endif } + #endif #if HAS_FLIGHT @@ -737,6 +743,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; @@ -816,6 +846,10 @@ __code struct ao_config_var ao_config_vars[] = { #if HAS_TRACKER { "t \0Tracker configuration", ao_config_tracker_set, ao_config_tracker_show }, +#endif +#if HAS_APRS + { "S \0Set APRS SSID (0-15)", + ao_config_aprs_ssid_set, ao_config_aprs_ssid_show }, #endif { "s\0Show", ao_config_show, 0 }, diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h index 2b5cd352..70f9f33b 100644 --- a/src/kernel/ao_config.h +++ b/src/kernel/ao_config.h @@ -53,7 +53,7 @@ #endif #define AO_CONFIG_MAJOR 1 -#define AO_CONFIG_MINOR 18 +#define AO_CONFIG_MINOR 19 #define AO_AES_LEN 16 @@ -102,6 +102,9 @@ 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 }; #define AO_IGNITE_MODE_DUAL 0 -- cgit v1.2.3 From 443bbb09468df7c1a10f2c76996c92380d8b8c23 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Jun 2014 15:56:11 -0700 Subject: altos: Add optional debugging to print out pyro firing status This dumps pyro check failures for ao_flight_test so you can see why pyro charges aren't firing. Signed-off-by: Keith Packard --- src/kernel/ao_pyro.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/kernel/ao_pyro.c b/src/kernel/ao_pyro.c index 85d88d98..0b286466 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: -- cgit v1.2.3 From 309d91d25099bebda21e165165efa9ce86cb0a47 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Jun 2014 15:57:13 -0700 Subject: altos/ao_flight_test: Get the Tmega version compiling again A few changes broke this recently. Signed-off-by: Keith Packard --- src/test/ao_flight_test.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 0647fc6c..1ab22e5b 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -50,6 +50,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]; @@ -795,6 +796,7 @@ 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; } } -- cgit v1.2.3 From 500353ec83af0da7fce3d67f2707f4725b1f50ba Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jul 2014 22:42:43 -0700 Subject: altos: ao_rssi subsystem needs to use AO_LED_TYPE instead of uint8_t Signed-off-by: Keith Packard --- src/kernel/ao.h | 2 +- src/kernel/ao_rssi.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/kernel/ao.h b/src/kernel/ao.h index 5ff9b518..b8189e43 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -761,7 +761,7 @@ void ao_rssi_set(int rssi_value); void -ao_rssi_init(uint8_t rssi_led); +ao_rssi_init(AO_LED_TYPE rssi_led); /* * ao_product.c diff --git a/src/kernel/ao_rssi.c b/src/kernel/ao_rssi.c index 244a84fe..f8eeb217 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) @@ -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; -- cgit v1.2.3 From 48508479b0f6f8d6e73db1cae8ee8acdaba022d8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jul 2014 22:45:01 -0700 Subject: altos: Stop sticking cc1111 firmware in src directory This just clutters src. Signed-off-by: Keith Packard --- src/product/Makefile.teledongle | 2 +- src/product/Makefile.telelaunch | 2 +- src/product/Makefile.telenano | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') 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.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 -- cgit v1.2.3 From 657d455a2fad36193e6b3a7037d9ba7f09ae1168 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jul 2014 22:46:07 -0700 Subject: altos: Use TeleMetrum v1.9 board for MegaDongle experiments This configures the MegaDongle v0.1 directory to use the pin assignments in TeleMetrum v1.9 boards. Signed-off-by: Keith Packard --- src/kernel/ao.h | 4 ++- src/kernel/ao_monitor.c | 4 ++- src/kernel/ao_rssi.c | 2 +- src/megadongle-v0.1/Makefile | 1 + src/megadongle-v0.1/ao_megadongle.c | 4 +-- src/megadongle-v0.1/ao_pins.h | 49 +++++++++++++++---------------------- 6 files changed, 30 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/kernel/ao.h b/src/kernel/ao.h index b8189e43..1df2ea8b 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -757,11 +757,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(AO_LED_TYPE rssi_led); +#endif /* * ao_product.c 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_rssi.c b/src/kernel/ao_rssi.c index f8eeb217..793b190b 100644 --- a/src/kernel/ao_rssi.c +++ b/src/kernel/ao_rssi.c @@ -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; 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 -- cgit v1.2.3 From f8567a7be7ccd5dcc57ab65e63efe45e62008127 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 4 Jul 2014 23:26:57 -0700 Subject: altos: Reduce configuration data telemetry to once per 5 seconds This data is constant, so we don't need to send it very often. Once every five seconds should be plenty. Signed-off-by: Keith Packard --- src/kernel/ao_telemetry.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index 9f778b09..6fb30069 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -521,7 +521,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++; -- cgit v1.2.3 From 0605b5a1cdff5cfd71fc9ef3161a62d74a1124b4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jul 2014 22:42:10 -0700 Subject: altos: Add defines for 2400 and 9600 baud telemetry rates Signed-off-by: Keith Packard --- src/kernel/ao.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/kernel/ao.h b/src/kernel/ao.h index 1df2ea8b..6c6abd36 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -521,6 +521,10 @@ struct ao_telemetry_raw_recv { #define AO_TELEMETRY_INTERVAL_RECOVER AO_MS_TO_TICKS(1000) #endif +#define AO_RADIO_RATE_38400 0 +#define AO_RADIO_RATE_9600 1 +#define AO_RADIO_RATE_2400 2 + void ao_telemetry_set_interval(uint16_t interval); @@ -558,6 +562,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); -- cgit v1.2.3 From 214a38eb2b084baec526aa42016eddb954038639 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jul 2014 22:44:07 -0700 Subject: altos: Add config support for 2400 and 9600 baud telemetry rates Signed-off-by: Keith Packard --- src/kernel/ao_config.c | 33 +++++++++++++++++++++++++++++++++ src/kernel/ao_config.h | 5 ++++- 2 files changed, 37 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 58fa7354..52c0c4f6 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -62,6 +62,7 @@ __xdata uint8_t ao_config_mutex; #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 @@ -196,6 +197,10 @@ _ao_config_get(void) #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 ao_config.minor = AO_CONFIG_MINOR; ao_config_dirty = 1; @@ -483,6 +488,30 @@ ao_config_radio_cal_set(void) __reentrant ao_config_set_radio(); _ao_config_edit_finish(); } + +#endif + +#if HAS_RADIO_RATE +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; + _ao_config_edit_finish(); +} #endif #if HAS_LOG @@ -802,6 +831,10 @@ __code struct ao_config_var ao_config_vars[] = { ao_config_radio_enable_set, ao_config_radio_enable_show }, { "f \0Radio calib (cal = rf/(xtal/2^16))", ao_config_radio_cal_set, ao_config_radio_cal_show }, +#if HAS_RADIO_RATE + { "T \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 \0Radio power setting (0-255)", ao_config_radio_power_set, ao_config_radio_power_show }, diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h index 70f9f33b..a650ffc6 100644 --- a/src/kernel/ao_config.h +++ b/src/kernel/ao_config.h @@ -53,7 +53,7 @@ #endif #define AO_CONFIG_MAJOR 1 -#define AO_CONFIG_MINOR 19 +#define AO_CONFIG_MINOR 20 #define AO_AES_LEN 16 @@ -105,6 +105,9 @@ struct ao_config { #if HAS_APRS uint8_t aprs_ssid; /* minor version 19 */ #endif +#if HAS_RADIO_RATE + uint8_t radio_rate; /* minor version 20 */ +#endif }; #define AO_IGNITE_MODE_DUAL 0 -- cgit v1.2.3 From ea5887027e7a39da2b7d84a142d74950b7a24703 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 5 Jul 2014 00:09:25 -0700 Subject: altos: Call ao_telemetry_reset_interval when telemetry rate changes This lets the radio code adjust the telemetry packet sending pattern when the data rate changes. Signed-off-by: Keith Packard --- src/cc1111/ao_pins.h | 15 +++++++++++++++ src/kernel/ao.h | 5 ++--- src/kernel/ao_config.c | 7 +++++++ src/kernel/ao_telemetry.c | 34 ++++++++++++++++++++++++++++++---- src/telebt-v1.0/ao_pins.h | 1 + src/telefire-v0.1/ao_pins.h | 3 ++- src/telefire-v0.2/ao_pins.h | 3 ++- src/telemini-v2.0/ao_pins.h | 1 + src/teleshield-v0.1/ao_pins.h | 1 + src/teleterra-v0.2/ao_pins.h | 2 +- 10 files changed, 62 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 2b19f1f6..b40acbbd 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -56,6 +56,7 @@ #define HAS_ACCEL 1 #define HAS_IGNITE 1 #define HAS_MONITOR 0 + #define HAS_TELEMETRY 1 #endif #if defined(TELEMETRUM_V_1_1) @@ -96,6 +97,7 @@ #define HAS_ACCEL 1 #define HAS_IGNITE 1 #define HAS_MONITOR 0 + #define HAS_TELEMETRY 1 #endif #if defined(TELEMETRUM_V_1_2) @@ -136,6 +138,7 @@ #define HAS_ACCEL 1 #define HAS_IGNITE 1 #define HAS_MONITOR 0 + #define HAS_TELEMETRY 1 #endif #if defined(TELEDONGLE_V_0_2) @@ -164,6 +167,7 @@ #define LEGACY_MONITOR 1 #define HAS_RSSI 1 #define HAS_AES 0 + #define HAS_TELEMETRY 0 #endif #if defined(TELEMINI_V_1_0) @@ -193,6 +197,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 +226,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 +260,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 +293,7 @@ #define LEGACY_MONITOR 1 #define HAS_RSSI 1 #define HAS_AES 0 + #define HAS_TELEMETRY 0 #endif #if defined(TIDONGLE) @@ -312,6 +323,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 +362,7 @@ #define LEGACY_MONITOR 1 #define HAS_RSSI 0 #define HAS_AES 0 + #define HAS_TELEMETRY 0 #endif #if defined(TELEBT_V_0_1) @@ -396,6 +409,7 @@ #define LEGACY_MONITOR 1 #define HAS_RSSI 0 #define HAS_AES 0 + #define HAS_TELEMETRY 0 #endif #if defined(TELELAUNCH_V_0_1) @@ -428,6 +442,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/kernel/ao.h b/src/kernel/ao.h index 6c6abd36..c11aa028 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -521,9 +521,8 @@ struct ao_telemetry_raw_recv { #define AO_TELEMETRY_INTERVAL_RECOVER AO_MS_TO_TICKS(1000) #endif -#define AO_RADIO_RATE_38400 0 -#define AO_RADIO_RATE_9600 1 -#define AO_RADIO_RATE_2400 2 +void +ao_telemetry_reset_interval(void); void ao_telemetry_set_interval(uint16_t interval); diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 52c0c4f6..32a0967c 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -492,6 +492,10 @@ ao_config_radio_cal_set(void) __reentrant #endif #if HAS_RADIO_RATE +#ifndef HAS_TELEMETRY +#error Please define HAS_TELEMETRY +#endif + void ao_config_radio_rate_show(void) __reentrant { @@ -510,6 +514,9 @@ ao_config_radio_rate_set(void) __reentrant } _ao_config_edit_start(); ao_config.radio_rate = ao_cmd_lex_i; +#if HAS_TELEMETRY + ao_telemetry_reset_interval(); +#endif _ao_config_edit_finish(); } #endif diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index 6fb30069..f4fcf400 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -25,6 +25,10 @@ static __pdata uint16_t ao_telemetry_interval; +#if HAS_RADIO_RATE +static __pdata 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; @@ -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 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; diff --git a/src/telebt-v1.0/ao_pins.h b/src/telebt-v1.0/ao_pins.h index 9e47f3b8..b5562573 100644 --- a/src/telebt-v1.0/ao_pins.h +++ b/src/telebt-v1.0/ao_pins.h @@ -48,6 +48,7 @@ #define BT_LINK_PIN P1_7 #define HAS_MONITOR 1 #define LEGACY_MONITOR 0 +#define HAS_TELEMETRY 0 #define HAS_ADC 1 #define AO_PAD_ADC_BATT 0 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/ao_pins.h b/src/telefire-v0.2/ao_pins.h index 96e6b066..9e6631ce 100644 --- a/src/telefire-v0.2/ao_pins.h +++ b/src/telefire-v0.2/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/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h index f202ccd1..c9f9de62 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -39,6 +39,7 @@ #define USE_INTERNAL_FLASH 0 #define HAS_DBG 0 #define PACKET_HAS_SLAVE 1 +#define HAS_RADIO_RATE 0 /* not enough space for this */ #define AO_LED_RED 2 #define LEDS_AVAILABLE AO_LED_RED 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..60d627ad 100644 --- a/src/teleterra-v0.2/ao_pins.h +++ b/src/teleterra-v0.2/ao_pins.h @@ -71,7 +71,7 @@ #define HAS_P2_ISR 1 #define BATTERY_PIN 5 - + #define HAS_TELEMETRY 0 #endif #if DBG_ON_P1 -- cgit v1.2.3 From c20ddde2f9eb0ad8dbb982e9d0cbe91639160a34 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jul 2014 22:30:23 -0700 Subject: altos/cc1111: Adjust receive parameters to improve sensitivity This removes the packet quality test and carrier sense tests when deciding whether to start decoding a packet. This lets more bad packets through, but the CRC check catches those and now we're regularly receiving packets down to -110 or even -112 dBm. Before this change, we'd rarely see packets as low as -105dBm Signed-off-by: Keith Packard --- src/cc1111/ao_pins.h | 3 +++ src/cc1111/ao_radio.c | 51 ++++++++++++++++++++++++++++++--------- src/cc1111/cc1111.h | 61 +++++++++++++++++++++++++++++++++++++++++++++++ src/telebt-v1.0/ao_pins.h | 1 + 4 files changed, 105 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index b40acbbd..2d524188 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -168,6 +168,7 @@ #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) @@ -363,6 +364,7 @@ #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) @@ -410,6 +412,7 @@ #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) diff --git a/src/cc1111/ao_radio.c b/src/cc1111/ao_radio.c index 190647ce..fbdf7762 100644 --- a/src/cc1111/ao_radio.c +++ b/src/cc1111/ao_radio.c @@ -126,9 +126,9 @@ static __code uint8_t radio_setup[] = { (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)), @@ -155,8 +155,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 +187,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, @@ -212,7 +218,7 @@ 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), @@ -223,9 +229,9 @@ static __code uint8_t fixed_pkt_setup[] = { (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)), @@ -551,8 +557,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 \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/telebt-v1.0/ao_pins.h b/src/telebt-v1.0/ao_pins.h index b5562573..4181ef35 100644 --- a/src/telebt-v1.0/ao_pins.h +++ b/src/telebt-v1.0/ao_pins.h @@ -49,6 +49,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 -- cgit v1.2.3 From aba1703a1cff3da001d64bf2d15a591816e3350e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jul 2014 22:31:59 -0700 Subject: altos/cc1111: Add 2400 and 9600 baud telemetry rate support Signed-off-by: Keith Packard --- src/cc1111/ao_pins.h | 3 ++ src/cc1111/ao_radio.c | 86 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 2d524188..83a3c774 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -57,6 +57,7 @@ #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(TELEMETRUM_V_1_1) @@ -98,6 +99,7 @@ #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(TELEMETRUM_V_1_2) @@ -139,6 +141,7 @@ #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(TELEDONGLE_V_0_2) diff --git a/src/cc1111/ao_radio.c b/src/cc1111/ao_radio.c index fbdf7762..8f519958 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 + * + * 20.5 kHz deviation, 9.6kbps signal + * + * m = 41 / 9.6, which is < 5.5: + * + * bw = 2.6 * 20.5 + 0.55 * 9.6 = 58.58kHz + * + * M = 2, E = 3, bw = 62.5kHz + * + * 20.5kHz deviation, 2.4kbps signal + * + * m = 41 / 2.4, which is > 5.5: + * + * bw = 2.1 * 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 2 +#define CHANBW_M_24 3 #define CHANBW_E 3 /* @@ -55,12 +93,23 @@ * * 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: * @@ -122,9 +171,6 @@ 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_ON | RF_MDMCFG2_MOD_FORMAT_GFSK | @@ -204,7 +250,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 | @@ -225,9 +271,11 @@ static __code uint8_t rdf_setup[] = { }; 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_ON | RF_MDMCFG2_MOD_FORMAT_GFSK | @@ -249,6 +297,23 @@ static __code uint8_t fixed_pkt_setup[] = { RF_PKTCTRL0_LENGTH_CONFIG_FIXED), }; +#if HAS_RADIO_RATE +static __code uint8_t 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)), + /* 9600 */ + ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) | + (CHANBW_M_96 << RF_MDMCFG4_CHANBW_M_SHIFT) | + (DRATE_E_96 << RF_MDMCFG4_DRATE_E_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)), +}; +#endif + __xdata uint8_t ao_radio_dma; __xdata uint8_t ao_radio_dma_done; __xdata uint8_t ao_radio_done; @@ -314,6 +379,9 @@ 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]; +#endif } -- cgit v1.2.3 From 8935e29e5aa9c01cd00b275a35dd7b99c00980c3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jul 2014 22:41:20 -0700 Subject: altos: Add 2400 and 9600 baud telemetry support to cc115l driver Signed-off-by: Keith Packard --- src/drivers/ao_cc115l.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_cc115l.c b/src/drivers/ao_cc115l.c index f250e714..b5103f9b 100644 --- a/src/drivers/ao_cc115l.c +++ b/src/drivers/ao_cc115l.c @@ -269,16 +269,30 @@ ao_radio_idle(void) * (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 uint16_t packet_rate_setup[] = { + [AO_RADIO_RATE_38400] = ((0xf << 4) | + (PACKET_DRATE_E_384 << CC115L_MDMCFG4_DRATE_E)), + + [AO_RADIO_RATE_9600] = ((0xf << 4) | + (PACKET_DRATE_E_96 << CC115L_MDMCFG4_DRATE_E)), + + [AO_RADIO_RATE_2400] = ((0xf << 4) | + (PACKET_DRATE_E_24 << CC115L_MDMCFG4_DRATE_E)), +}; 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 +417,12 @@ 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]); + 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 +511,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 +522,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 -- cgit v1.2.3 From 91461251f3aa8e1b37a3456f8fb94ab16bc0bec2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 4 Jul 2014 23:42:30 -0700 Subject: altos: Packet reception tuning for cc1120 driver This adjusts the cc1120 receive parameters to increase sensitivity at the expense of reporting many more invalid packets to the UI. Signed-off-by: Keith Packard --- src/drivers/ao_cc1120.h | 2 +- src/drivers/ao_cc1120_CC1120.h | 56 ++++++++++++++---------------------------- 2 files changed, 20 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_cc1120.h b/src/drivers/ao_cc1120.h index a1d78c01..5d24c49a 100644 --- a/src/drivers/ao_cc1120.h +++ b/src/drivers/ao_cc1120.h @@ -294,7 +294,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, /* */ -- cgit v1.2.3 From e0ee2ac6bc68b73e13bf34fac3ffd4a3b79dce98 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 2 Jul 2014 22:34:48 -0700 Subject: altos: Add telemetry rate support to CC1120 driver This supports the new 2400 and 9600 baud rates Signed-off-by: Keith Packard --- src/drivers/ao_cc1120.c | 121 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 94 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 31225939..5d51fbcd 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -245,7 +245,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; @@ -297,26 +297,47 @@ ao_radio_idle(void) #define PACKET_DEV_M 80 /* - * 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 * + * Symbol rate 38400 Baud: * * DATARATE_M = 239914 * DATARATE_E = 9 + * CHANBW = 74.42 (round to 100) + * + * Symbol rate 9600 Baud: + * + * DATARATE_M = 239914 + * DATARATE_E = 7 + * CHANBW = 58.58 (round to 62.5) + * + * Symbol rate 2400 Baud: + * + * DATARATE_M = 239914 + * DATARATE_E = 5 + * CHANBW = 47.61 (round to 50) */ -#define PACKET_DRATE_E 9 + #define PACKET_DRATE_M 239914 +#define PACKET_DRATE_E_384 9 +#define PACKET_CHAN_BW_384 0x02 /* 200 / 2 = 100 */ + +#define PACKET_DRATE_E_96 7 +#define PACKET_CHAN_BW_96 0x42 /* 125 / 2 = 62.5 */ + +#define PACKET_DRATE_E_24 5 +#define PACKET_CHAN_BW_24 0x04 /* 200 / 4 = 50 */ + 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 +356,27 @@ 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_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_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_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 +439,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 +486,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, }; /* @@ -505,24 +549,49 @@ static uint16_t ao_radio_mode; #define AO_RADIO_MODE_APRS_FINISH (AO_RADIO_MODE_BITS_APRS | AO_RADIO_MODE_BITS_FIXED | AO_RADIO_MODE_BITS_TX_FINISH) #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 +599,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 +628,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 +654,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 +666,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 +763,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 +860,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(); -- cgit v1.2.3 From 292cb8380b478542555b5f370e8252eafa2f74ac Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 5 Jul 2014 00:04:06 -0700 Subject: altos: Rework packet receive for cc1120 Instead of blocking on PQT, just set up the receiver to start going and when the first bit interrupt comes in, grab the SPI bus if possible and configure it for reception. This improves sensitivity in the radio by a significant amount while making the code conceptually a bit nicer. Signed-off-by: Keith Packard --- src/cc1111/ao_pins.h | 3 + src/drivers/ao_cc1120.c | 160 +++++++++++++++++++++++++++++++----------------- src/kernel/ao.h | 3 + src/kernel/ao_mutex.c | 23 +++++++ src/lpc/ao_arch_funcs.h | 17 ++--- src/stm/ao_arch_funcs.h | 25 ++++++-- src/stm/ao_spi_stm.c | 51 +++++++++++++-- 7 files changed, 208 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 83a3c774..1bc3d716 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -58,6 +58,7 @@ #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) @@ -100,6 +101,7 @@ #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) @@ -142,6 +144,7 @@ #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) diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 5d51fbcd..1b907940 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) { @@ -275,11 +277,13 @@ 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); @@ -948,6 +952,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; @@ -962,13 +971,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) @@ -987,24 +1017,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 @@ -1044,48 +1070,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 */ @@ -1100,7 +1145,7 @@ abort: radio_rssi = AO_RADIO_FROM_RSSI (rssi); } - ao_radio_strobe(CC1120_SIDLE); + ao_radio_idle(); ao_radio_put(); @@ -1139,7 +1184,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" }, @@ -1320,7 +1365,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(); @@ -1331,6 +1376,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(); } @@ -1354,12 +1403,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 @@ -1375,13 +1424,12 @@ ao_radio_test_recv() #include 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/kernel/ao.h b/src/kernel/ao.h index c11aa028..a225bc4a 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; 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/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/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); @@ -76,6 +79,9 @@ ao_spi_send(void *block, uint16_t len, uint8_t spi_index); 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); @@ -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 @@ -153,6 +153,28 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index) ao_dma_done_transfer(miso_dma_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) { @@ -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) { -- cgit v1.2.3 From d1527a5457210eb914312cf8857bfb88982a8462 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 6 Jul 2014 12:35:13 -0700 Subject: Add support for the "kite" micropeak variant This uses a 100m 'launch detect' altitude and logs data every 19.2s instead of every .192s. Signed-off-by: Keith Packard --- micropeak/MicroData.java | 26 ++++++-- micropeak/MicroPeak.java | 4 +- src/Makefile | 2 +- src/kernel/ao_log_micro.c | 11 ++++ src/kernel/ao_microflight.c | 15 ++++- src/microkite/.gitignore | 2 + src/microkite/Makefile | 134 ++++++++++++++++++++++++++++++++++++++ src/microkite/ao_pins.h | 70 ++++++++++++++++++++ src/microkite/microkite-load.tmpl | 20 ++++++ src/product/ao_micropeak.h | 11 ++++ 10 files changed, 284 insertions(+), 11 deletions(-) create mode 100644 src/microkite/.gitignore create mode 100644 src/microkite/Makefile create mode 100644 src/microkite/ao_pins.h create mode 100644 src/microkite/microkite-load.tmpl (limited to 'src') diff --git a/micropeak/MicroData.java b/micropeak/MicroData.java index 6c9447aa..c38ada91 100644 --- a/micropeak/MicroData.java +++ b/micropeak/MicroData.java @@ -97,9 +97,15 @@ public class MicroData implements AltosUIDataSet { private double time_step; private double ground_altitude; private ArrayList bytes; + public int log_id; String name; MicroStats stats; - + + public static final int LOG_ID_MICROPEAK = 0; + public static final int LOG_ID_MICROKITE = 1; + + public static final double CLOCK = 0.096; + public class FileEndedException extends Exception { } @@ -172,7 +178,7 @@ public class MicroData implements AltosUIDataSet { if (get_nonwhite(f) == 'M' && get_nonwhite(f) == 'P') return true; } - } + } private int get_32(InputStream f) throws IOException, FileEndedException, NonHexcharException { int v = 0; @@ -345,6 +351,9 @@ public class MicroData implements AltosUIDataSet { ground_pressure = get_32(f); min_pressure = get_32(f); int nsamples = get_16(f); + + log_id = nsamples >> 12; + nsamples &= 0xfff; pressures = new int[nsamples + 1]; ground_altitude = AltosConvert.pressure_to_altitude(ground_pressure); @@ -367,7 +376,7 @@ public class MicroData implements AltosUIDataSet { else cur = down; } - + pressures[i+1] = cur; } @@ -376,7 +385,14 @@ public class MicroData implements AltosUIDataSet { crc_valid = crc == current_crc; - time_step = 0.192; + switch (log_id) { + case LOG_ID_MICROPEAK: + time_step = 2 * CLOCK; + break; + case LOG_ID_MICROKITE: + time_step = 200 * CLOCK; + break; + } stats = new MicroStats(this); } catch (FileEndedException fe) { throw new IOException("File Ended Unexpectedly"); @@ -389,5 +405,5 @@ public class MicroData implements AltosUIDataSet { pressures = new int[1]; pressures[0] = 101000; } - + } diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java index 8bdf4b77..1744e803 100644 --- a/micropeak/MicroPeak.java +++ b/micropeak/MicroPeak.java @@ -107,7 +107,7 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene private void DownloadData() { AltosDevice device = MicroDeviceDialog.show(this); - + if (device != null) new MicroDownload(this, device); } @@ -128,7 +128,7 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene if (save.runDialog()) SetName(data.name); } - + private void Export() { if (data == null) { no_data(); diff --git a/src/Makefile b/src/Makefile index 4e8b3c20..df7a31ee 100644 --- a/src/Makefile +++ b/src/Makefile @@ -39,7 +39,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= 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..df624e79 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; @@ -93,7 +95,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 +106,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 +118,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/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..3c56dfb8 --- /dev/null +++ b/src/microkite/ao_pins.h @@ -0,0 +1,70 @@ +/* + * Copyright © 2011 Keith Packard + * + * 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 + +#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 1200 /* 100m (ish) */ +#define LOG_INTERVAL 200 /* 19.2 seconds */ + +#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/product/ao_micropeak.h b/src/product/ao_micropeak.h index 0ec407d7..396b9a23 100644 --- a/src/product/ao_micropeak.h +++ b/src/product/ao_micropeak.h @@ -29,6 +29,17 @@ #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 */ #define BOOST_DELAY AO_SEC_TO_TICKS(60) -- cgit v1.2.3 From 1a55cbe1923280f7009c13d5eb5b2ccac89219c2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 8 Jul 2014 23:45:10 -0700 Subject: altos/telemini-v2.0: Add memory decorations to new telemetry variables This lets TeleMini-v2.0 compile. Signed-off-by: Keith Packard --- src/kernel/ao_telemetry.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index f4fcf400..d321c8ff 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -1,5 +1,5 @@ /* - * Copyright © 2011 Keith Packard + * Copyright © 2011 Keth Packard * * 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 @@ -26,7 +26,7 @@ static __pdata uint16_t ao_telemetry_interval; #if HAS_RADIO_RATE -static __pdata uint16_t ao_telemetry_desired_interval; +static __xdata uint16_t ao_telemetry_desired_interval; #endif #if HAS_RDF @@ -511,7 +511,7 @@ ao_telemetry_set_interval(uint16_t interval) #if HAS_RADIO_RATE /* Limit max telemetry rate based on available radio bandwidth. */ - static const uint16_t min_interval[] = { + 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) -- cgit v1.2.3 From d926ccfbd4596eb3f981d2fcf8f6fc6ccc427db6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 8 Jul 2014 23:46:24 -0700 Subject: altos: Add smaller pa to altitude table for TeleMini TeleMini doesn't have space for the larger table, and the smaller one isn't that much less accurate at lower altitudes. Signed-off-by: Keith Packard --- src/Makefile | 5 +- src/kernel/ao_convert_pa.c | 4 + src/util/make-altitude-pa | 184 ++++++++++++++++++++++++++------------------- 3 files changed, 115 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index df7a31ee..a7a26b26 100644 --- a/src/Makefile +++ b/src/Makefile @@ -98,7 +98,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,6 +106,9 @@ altitude.h: make-altitude altitude-pa.h: make-altitude-pa nickle $< > $@ +altitude-pa-small.h: make-altitude-pa + nickle $< --sample 3 > $@ + ao_kalman.h: make-kalman kalman.5c kalman_filter.5c load_csv.5c matrix.5c bash $< kalman > $@ diff --git a/src/kernel/ao_convert_pa.c b/src/kernel/ao_convert_pa.c index fe6e0ef6..20162c1f 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 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(); -- cgit v1.2.3 From 1684291ba9a4f3bc2828e7b079ac27efcba6a163 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 8 Jul 2014 23:47:09 -0700 Subject: altos/telemini-v2.0: Enable beep config and radio rate config use the smaller pa to altitude table to make room for the new code Signed-off-by: Keith Packard --- src/telemini-v2.0/Makefile | 3 ++- src/telemini-v2.0/ao_pins.h | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src') 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 c9f9de62..948310e5 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -28,9 +28,11 @@ #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,7 +41,8 @@ #define USE_INTERNAL_FLASH 0 #define HAS_DBG 0 #define PACKET_HAS_SLAVE 1 -#define HAS_RADIO_RATE 0 /* not enough space for this */ +#define HAS_RADIO_RATE 1 +#define HAS_TELEMETRY 1 #define AO_LED_RED 2 #define LEDS_AVAILABLE AO_LED_RED -- cgit v1.2.3 From 34d5be68ca23e8beb05db9a480faef63ecc911d0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:07:48 -0700 Subject: altos: Extend GPS altitudes to at least 24 bits everywhere Telemetry gets a special 'mode' flag indicating that 24-bit data is present; log files get new data and log readers are expected to detect that via the firmware version number. Signed-off-by: Keith Packard --- src/cc1111/ao_pins.h | 1 + src/drivers/ao_aprs.c | 2 +- src/drivers/ao_gps_skytraq.c | 3 ++- src/drivers/ao_gps_ublox.c | 2 +- src/kernel/ao_gps_report.c | 8 ++++++-- src/kernel/ao_gps_report_mega.c | 7 ++++--- src/kernel/ao_gps_report_metrum.c | 3 ++- src/kernel/ao_gps_show.c | 8 +++++++- src/kernel/ao_log.h | 23 +++++++++++++++-------- src/kernel/ao_log_gps.c | 3 ++- src/kernel/ao_log_gps.h | 3 --- src/kernel/ao_telemetry.c | 2 +- src/kernel/ao_telemetry.h | 34 ++++++++++++++++++++++++++-------- src/kernel/ao_tracker.c | 13 +++++++------ src/test/ao_aprs_test.c | 7 +++---- src/test/ao_flight_test.c | 7 +++++-- src/test/ao_gps_test.c | 5 ++++- src/test/ao_gps_test_skytraq.c | 4 ++++ src/test/ao_gps_test_ublox.c | 9 ++++++++- 19 files changed, 99 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 1bc3d716..4db49215 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -20,6 +20,7 @@ #define HAS_RADIO 1 #define DISABLE_LOG_SPACE 1 +#define HAS_WIDE_GPS 0 #if defined(TELEMETRUM_V_1_0) /* Discontinued and was never built with CC1111 chips needing this */ diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index a9047149..19beb78f 100644 --- a/src/drivers/ao_aprs.c +++ b/src/drivers/ao_aprs.c @@ -713,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; } diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index 944a37f9..81178051 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -287,7 +287,8 @@ ao_nmea_gga(void) 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..48765998 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; 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..31939385 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; 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 #endif +#include + 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_log.h b/src/kernel/ao_log.h index 33cda3eb..080cfb02 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -176,8 +176,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 +246,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 +261,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 +274,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 +312,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 */ @@ -381,7 +388,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 +403,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..a5a6358b 100644 --- a/src/kernel/ao_log_gps.c +++ b/src/kernel/ao_log_gps.c @@ -75,7 +75,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; 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_telemetry.c b/src/kernel/ao_telemetry.c index d321c8ff..56bd715e 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -344,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)); 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..d9434048 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 @@ -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); } @@ -203,7 +204,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/test/ao_aprs_test.c b/src/test/ao_aprs_test.c index 573b5cb2..ae505dea 100644 --- a/src/test/ao_aprs_test.c +++ b/src/test/ao_aprs_test.c @@ -21,6 +21,8 @@ #include #include +#define HAS_GPS 1 + #include #define AO_GPS_NUM_SAT_MASK (0xf << 0) @@ -100,14 +102,11 @@ audio_gap(int secs) // This is where we go after reset. int main(int argc, char **argv) { - int e, x; - int a; - 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 1ab22e5b..314998c1 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -175,7 +175,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; @@ -756,7 +756,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; 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 #include @@ -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 #include @@ -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) -- cgit v1.2.3 From 47e62bb26984f6c84660c1d0451f77c2d6ad7e5a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:13:09 -0700 Subject: altos: Scale DOP values by 10 in GPS drivers sky traq was scaling by 5, ublox was scaling by 100. Signed-off-by: Keith Packard --- src/drivers/ao_gps_skytraq.c | 6 +++--- src/drivers/ao_gps_ublox.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index 81178051..066df6ff 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -278,10 +278,10 @@ 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; diff --git a/src/drivers/ao_gps_ublox.c b/src/drivers/ao_gps_ublox.c index 48765998..74c29e0a 100644 --- a/src/drivers/ao_gps_ublox.c +++ b/src/drivers/ao_gps_ublox.c @@ -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; -- cgit v1.2.3 From 31ae24b5da3e198e7555ea3768d3cbdec3a28a5f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:15:09 -0700 Subject: altos: Record pdop value in TeleMetrumV2 log There's only one byte free, so we'll record the pdop value Signed-off-by: Keith Packard --- src/kernel/ao_gps_report_metrum.c | 1 + src/kernel/ao_log.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/kernel/ao_gps_report_metrum.c b/src/kernel/ao_gps_report_metrum.c index 31939385..8ce074fe 100644 --- a/src/kernel/ao_gps_report_metrum.c +++ b/src/kernel/ao_gps_report_metrum.c @@ -56,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_log.h b/src/kernel/ao_log.h index 080cfb02..da20e067 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -324,7 +324,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 { -- cgit v1.2.3 From 013e9ccfbe76dc46e8c69ea314950bed83d9a39f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 10 Jul 2014 17:18:38 -0700 Subject: altos: Use 32-bits for flight state data (alt/speed/accel) Stores 32-bits for all of the flight parameters. Uses 64-bit intermediates for kalman computation. Signed-off-by: Keith Packard --- src/Makefile | 2 +- src/cc1111/ao_pins.h | 1 + src/kalman/kalman.5c | 2 +- src/kalman/kalman_micro.5c | 2 +- src/kernel/ao.h | 14 ++-- src/kernel/ao_cmd.c | 3 + src/kernel/ao_convert.c | 10 +-- src/kernel/ao_convert_pa.c | 16 ++--- src/kernel/ao_convert_pa_test.c | 1 + src/kernel/ao_data.h | 6 -- src/kernel/ao_flight.c | 12 ++-- src/kernel/ao_kalman.c | 147 ++++++++++++++++++++-------------------- src/kernel/ao_microkalman.c | 12 ++-- src/kernel/ao_sample.c | 2 +- src/kernel/ao_sample.h | 56 +++++++++++---- src/product/Makefile.telemetrum | 1 + src/telefire-v0.1/Makefile | 1 - src/telefire-v0.2/Makefile | 1 - src/telemega-v1.0/Makefile | 1 + src/telemini-v2.0/ao_pins.h | 1 + src/teleterra-v0.2/ao_pins.h | 2 + src/test/ao_flight_test.c | 5 +- src/test/ao_micropeak_test.c | 1 + 23 files changed, 170 insertions(+), 129 deletions(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index a7a26b26..3494ba62 100644 --- a/src/Makefile +++ b/src/Makefile @@ -109,7 +109,7 @@ altitude-pa.h: make-altitude-pa altitude-pa-small.h: make-altitude-pa nickle $< --sample 3 > $@ -ao_kalman.h: make-kalman kalman.5c kalman_filter.5c load_csv.5c matrix.5c +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_pins.h b/src/cc1111/ao_pins.h index 4db49215..e12f813f 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -20,6 +20,7 @@ #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) 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 a225bc4a..ad5bbf8e 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -278,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 @@ -296,11 +298,13 @@ ao_temp_to_dC(int16_t temp) __reentrant; #include +#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 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 @@ -289,6 +289,9 @@ version(void) #endif #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 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 + +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 20162c1f..410815b6 100644 --- a/src/kernel/ao_convert_pa.c +++ b/src/kernel/ao_convert_pa.c @@ -39,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; @@ -52,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; @@ -76,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 #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_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_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 /* 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_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/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/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.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/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/ao_pins.h b/src/telemini-v2.0/ao_pins.h index 948310e5..ed911798 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -22,6 +22,7 @@ #define HAS_FLIGHT 1 #define HAS_USB 1 +#define AO_VALUE_32 0 #define HAS_USB_PULLUP 1 #define AO_USB_PULLUP_PORT P1 diff --git a/src/teleterra-v0.2/ao_pins.h b/src/teleterra-v0.2/ao_pins.h index 60d627ad..472af534 100644 --- a/src/teleterra-v0.2/ao_pins.h +++ b/src/teleterra-v0.2/ao_pins.h @@ -72,6 +72,8 @@ #define BATTERY_PIN 5 #define HAS_TELEMETRY 0 + + #define AO_VALUE_32 0 #endif #if DBG_ON_P1 diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 314998c1..bb5c3a7d 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -34,9 +34,11 @@ #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 @@ -93,6 +95,7 @@ struct ao_adc { #include #include #include +#include #if TELEMEGA int ao_gps_count; @@ -234,7 +237,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) 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) -- cgit v1.2.3 From a60ba449ec237ad3b8dade9dcea603b349dbccb1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 12 Jul 2014 23:52:05 -0700 Subject: altos/telefire,telelco: Add HAS_RADIO_RATE to launch system software This lets us set the rate to a lower value to improve range. 9600 baud works great; 2400 baud makes the initial search take a long time. Signed-off-by: Keith Packard --- src/drivers/ao_lco_func.c | 16 +++++++++++++++- src/telefire-v0.2/ao_pins.h | 1 + src/telelco-v0.2/ao_lco.c | 2 +- src/telelco-v0.2/ao_pins.h | 1 + 4 files changed, 18 insertions(+), 2 deletions(-) (limited to 'src') 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/telefire-v0.2/ao_pins.h b/src/telefire-v0.2/ao_pins.h index 9e6631ce..ef2d4822 100644 --- a/src/telefire-v0.2/ao_pins.h +++ b/src/telefire-v0.2/ao_pins.h @@ -19,6 +19,7 @@ #define _AO_PINS_H_ #define HAS_RADIO 1 +#define HAS_RADIO_RATE 1 #define HAS_TELEMETRY 0 #define HAS_FLIGHT 0 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 -- cgit v1.2.3 From 6c3d09bf40f2af6e8722f33a70b41e5d94ceaf9f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jul 2014 20:42:41 -0700 Subject: altos: Interrupt radio receive when changing data rate This aborts any pending radio receive when changing the data rate so that the radio can be reprogrammed to receive at the correct rate. Signed-off-by: Keith Packard --- src/kernel/ao_config.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 32a0967c..d73a3733 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -518,6 +518,9 @@ ao_config_radio_rate_set(void) __reentrant ao_telemetry_reset_interval(); #endif _ao_config_edit_finish(); +#if HAS_RADIO_RECV + ao_radio_recv_abort(); +#endif } #endif -- cgit v1.2.3 From 50aec54bdc35962145eff9b465f9cd7b3d9fea0b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jul 2014 20:43:27 -0700 Subject: altos: Make ao_gps_print deal with telem containing 32-bit altitude values ao_gps_print is used with new telem packets from a few places; use AO_TELEMETRY_LOCATION_ALTITUDE when necessary. Signed-off-by: Keith Packard --- src/kernel/ao_gps_print.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') 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 " -- cgit v1.2.3 From 0fd867f504dd7df62e95da98ded511bb7b9e4c66 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jul 2014 20:44:39 -0700 Subject: altos/test: Build TeleMetrumV2 flight test variant Parses TeleMetrumV2 eeprom files and runs the TeleMetrumV2 flight code. Signed-off-by: Keith Packard --- src/test/Makefile | 4 ++ src/test/ao_flight_test.c | 108 ++++++++++++++++++++++++++++++++++++---------- src/test/plottest | 6 +-- 3 files changed, 93 insertions(+), 25 deletions(-) (limited to 'src') 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_flight_test.c b/src/test/ao_flight_test.c index bb5c3a7d..8b737ca1 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -45,6 +45,10 @@ 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 @@ -60,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 */ @@ -189,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; @@ -309,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 struct ao_ms5607_prom ao_ms5607_prom; @@ -459,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); @@ -554,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], @@ -563,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], @@ -585,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 @@ -595,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), @@ -678,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(); @@ -807,7 +821,59 @@ ao_sleep(void *wchan) } } } -#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); @@ -932,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 @@ -953,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/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 -- cgit v1.2.3 From 59976c44d1b6ee6505cfa4efd9a26ec4302f6c33 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Thu, 14 Aug 2014 18:16:14 -0600 Subject: change easymega from v0.1 to v1.0, tweak to build on master, add to Makefile --- ao-bringup/turnon_easymega | 57 +++++ src/Makefile | 1 + src/easymega-v0.1/.gitignore | 2 - src/easymega-v0.1/Makefile | 144 ------------- src/easymega-v0.1/ao_easymega.c | 95 --------- src/easymega-v0.1/ao_pins.h | 352 ------------------------------ src/easymega-v0.1/flash-loader/Makefile | 8 - src/easymega-v0.1/flash-loader/ao_pins.h | 34 --- src/easymega-v1.0/.gitignore | 2 + src/easymega-v1.0/Makefile | 144 +++++++++++++ src/easymega-v1.0/ao_easymega.c | 95 +++++++++ src/easymega-v1.0/ao_pins.h | 355 +++++++++++++++++++++++++++++++ src/easymega-v1.0/flash-loader/Makefile | 8 + src/easymega-v1.0/flash-loader/ao_pins.h | 34 +++ 14 files changed, 696 insertions(+), 635 deletions(-) create mode 100755 ao-bringup/turnon_easymega delete mode 100644 src/easymega-v0.1/.gitignore delete mode 100644 src/easymega-v0.1/Makefile delete mode 100644 src/easymega-v0.1/ao_easymega.c delete mode 100644 src/easymega-v0.1/ao_pins.h delete mode 100644 src/easymega-v0.1/flash-loader/Makefile delete mode 100644 src/easymega-v0.1/flash-loader/ao_pins.h create mode 100644 src/easymega-v1.0/.gitignore create mode 100644 src/easymega-v1.0/Makefile create mode 100644 src/easymega-v1.0/ao_easymega.c create mode 100644 src/easymega-v1.0/ao_pins.h create mode 100644 src/easymega-v1.0/flash-loader/Makefile create mode 100644 src/easymega-v1.0/flash-loader/ao_pins.h (limited to 'src') diff --git a/ao-bringup/turnon_easymega b/ao-bringup/turnon_easymega new file mode 100755 index 00000000..7d23f5f7 --- /dev/null +++ b/ao-bringup/turnon_easymega @@ -0,0 +1,57 @@ +#!/bin/sh + +if [ -x /usr/bin/ao-flash-stm ]; then + STMLOAD=/usr/bin/ao-flash-stm +else + echo "Can't find ao-flash-stm! Aborting." + exit 1 +fi + +if [ -x /usr/bin/ao-usbload ]; then + USBLOAD=/usr/bin/ao-usbload +else + echo "Can't find ao-usbload! Aborting." + exit 1 +fi + +VERSION=1.0 +REPO=~/altusmetrumllc/Binaries + +echo "EasyMega v$VERSION Turn-On and Calibration Program" +echo "Copyright 2014 by Bdale Garbee. Released under GPL v2" +echo +echo "Expectations:" +echo "\tEasyMega v$VERSION" +echo "\t\twith USB cable attached" +echo "\t\twith ST-Link-V2 cabled to debug header" +echo +echo -n "EasyMega-$VERSION serial number: " +read SERIAL + +echo $STMLOAD + +$STMLOAD $REPO/loaders/easymega-v$VERSION*.elf || exit 1 + +sleep 2 + +$USBLOAD --serial=$SERIAL $REPO/easymega-v$VERSION*.elf || exit 1 + +sleep 2 + +dev=`ao-list | awk '/EasyMega-v'"$VERSION"'/ { print $3; exit(0); }'` + +case "$dev" in +/dev/tty*) + echo "EasyMega found on $dev" + ;; +*) + echo 'No EasyMega-v'"$VERSION"' found' + exit 1 + ;; +esac + +echo 'E 0' > $dev + +./cal-accel $dev + +echo 'E 1' > $dev diff --git a/src/Makefile b/src/Makefile index 3494ba62..7f09db02 100644 --- a/src/Makefile +++ b/src/Makefile @@ -25,6 +25,7 @@ SDCCDIRS=\ telefire-v0.1 telefire-v0.2 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 \ diff --git a/src/easymega-v0.1/.gitignore b/src/easymega-v0.1/.gitignore deleted file mode 100644 index 410943d5..00000000 --- a/src/easymega-v0.1/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -ao_product.h -easymega-*.elf diff --git a/src/easymega-v0.1/Makefile b/src/easymega-v0.1/Makefile deleted file mode 100644 index 66619852..00000000 --- a/src/easymega-v0.1/Makefile +++ /dev/null @@ -1,144 +0,0 @@ -# -# AltOS build -# -# - -include ../stm/Makefile.defs - -INC = \ - ao.h \ - ao_arch.h \ - ao_arch_funcs.h \ - ao_boot.h \ - ao_companion.h \ - ao_data.h \ - ao_sample.h \ - ao_pins.h \ - altitude-pa.h \ - ao_kalman.h \ - ao_product.h \ - ao_ms5607.h \ - ao_hmc5883.h \ - ao_mpu6000.h \ - ao_mma655x.h \ - ao_profile.h \ - ao_task.h \ - ao_whiten.h \ - ao_sample_profile.h \ - ao_quaternion.h \ - math.h \ - ao_mpu.h \ - stm32l.h \ - math.h \ - Makefile - -# -# Common AltOS sources -# -# ao_hmc5883.c - -#PROFILE=ao_profile.c -#PROFILE_DEF=-DAO_PROFILE=1 - -#SAMPLE_PROFILE=ao_sample_profile.c \ -# ao_sample_profile_timer.c -#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1 - -#STACK_GUARD=ao_mpu_stm.c -#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1 - -MATH_SRC=\ - ef_acos.c \ - ef_sqrt.c \ - ef_rem_pio2.c \ - kf_cos.c \ - kf_sin.c \ - kf_rem_pio2.c \ - sf_copysign.c \ - sf_cos.c \ - sf_fabs.c \ - sf_floor.c \ - sf_scalbn.c \ - sf_sin.c \ - ef_log.c - -ALTOS_SRC = \ - ao_boot_chain.c \ - ao_interrupt.c \ - ao_product.c \ - ao_romconfig.c \ - ao_cmd.c \ - ao_config.c \ - ao_task.c \ - ao_led.c \ - ao_stdio.c \ - ao_panic.c \ - ao_timer.c \ - ao_mutex.c \ - ao_ignite.c \ - ao_freq.c \ - ao_dma_stm.c \ - ao_spi_stm.c \ - ao_data.c \ - ao_ms5607.c \ - ao_mma655x.c \ - ao_hmc5883.c \ - ao_adc_stm.c \ - ao_beep_stm.c \ - ao_eeprom_stm.c \ - ao_storage.c \ - ao_m25.c \ - ao_usb_stm.c \ - ao_exti_stm.c \ - ao_report.c \ - ao_i2c_stm.c \ - ao_mpu6000.c \ - ao_convert_pa.c \ - ao_convert_volt.c \ - ao_log.c \ - ao_log_mega.c \ - ao_sample.c \ - ao_kalman.c \ - ao_flight.c \ - ao_companion.c \ - ao_pyro.c \ - $(MATH_SRC) \ - $(PROFILE) \ - $(SAMPLE_PROFILE) \ - $(STACK_GUARD) - -PRODUCT=EasyMega-v0.1 -PRODUCT_DEF=-DEASYMEGA -IDPRODUCT=0x0023 - -CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g - -PROGNAME=easymega-v0.1 -PROG=$(PROGNAME)-$(VERSION).elf -HEX=$(PROGNAME)-$(VERSION).ihx - -SRC=$(ALTOS_SRC) ao_easymega.c -OBJ=$(SRC:.c=.o) - -all: $(PROG) $(HEX) - -$(PROG): Makefile $(OBJ) altos.ld - $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) - -../altitude-pa.h: make-altitude-pa - nickle $< > $@ - -$(OBJ): $(INC) - -ao_product.h: ao-make-product.5c ../Version - $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ - -distclean: clean - -clean: - rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx - rm -f ao_product.h - -install: - -uninstall: diff --git a/src/easymega-v0.1/ao_easymega.c b/src/easymega-v0.1/ao_easymega.c deleted file mode 100644 index e217c33c..00000000 --- a/src/easymega-v0.1/ao_easymega.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright © 2014 Bdale Garbee - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#if HAS_SAMPLE_PROFILE -#include -#endif -#include -#if HAS_STACK_GUARD -#include -#endif - -int -main(void) -{ - ao_clock_init(); - -#if HAS_STACK_GUARD - ao_mpu_init(); -#endif - - ao_task_init(); - ao_led_init(LEDS_AVAILABLE); - ao_led_on(AO_LED_GREEN); - ao_timer_init(); - - ao_i2c_init(); - ao_spi_init(); - ao_dma_init(); - ao_exti_init(); - - ao_adc_init(); -#if HAS_BEEP - ao_beep_init(); -#endif - ao_cmd_init(); - -#if HAS_MS5607 - ao_ms5607_init(); -#endif -#if HAS_HMC5883 - ao_hmc5883_init(); -#endif -#if HAS_MPU6000 - ao_mpu6000_init(); -#endif -#if HAS_MMA655X - ao_mma655x_init(); -#endif - - ao_eeprom_init(); - ao_storage_init(); - - ao_flight_init(); - ao_log_init(); - ao_report_init(); - - ao_usb_init(); - ao_igniter_init(); - ao_companion_init(); - ao_pyro_init(); - - ao_config_init(); -#if AO_PROFILE - ao_profile_init(); -#endif -#if HAS_SAMPLE_PROFILE - ao_sample_profile_init(); -#endif - - ao_start_scheduler(); - return 0; -} diff --git a/src/easymega-v0.1/ao_pins.h b/src/easymega-v0.1/ao_pins.h deleted file mode 100644 index cb6e3980..00000000 --- a/src/easymega-v0.1/ao_pins.h +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright © 2014 Bdale Garbee - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#ifndef _AO_PINS_H_ -#define _AO_PINS_H_ - -#define HAS_TASK_QUEUE 1 - -/* 8MHz High speed external crystal */ -#define AO_HSE 8000000 - -/* PLLVCO = 96MHz (so that USB will work) */ -#define AO_PLLMUL 12 -#define AO_RCC_CFGR_PLLMUL (STM_RCC_CFGR_PLLMUL_12) - -/* SYSCLK = 32MHz (no need to go faster than CPU) */ -#define AO_PLLDIV 3 -#define AO_RCC_CFGR_PLLDIV (STM_RCC_CFGR_PLLDIV_3) - -/* HCLK = 32MHz (CPU clock) */ -#define AO_AHB_PRESCALER 1 -#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1 - -/* Run APB1 at 16MHz (HCLK/2) */ -#define AO_APB1_PRESCALER 2 -#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE2_DIV_2 - -/* Run APB2 at 16MHz (HCLK/2) */ -#define AO_APB2_PRESCALER 2 -#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_2 - -#define HAS_SERIAL_1 0 -#define USE_SERIAL_1_STDIN 0 -#define SERIAL_1_PB6_PB7 0 -#define SERIAL_1_PA9_PA10 0 - -#define HAS_SERIAL_2 0 -#define USE_SERIAL_2_STDIN 0 -#define SERIAL_2_PA2_PA3 0 -#define SERIAL_2_PD5_PD6 0 - -#define HAS_SERIAL_3 0 -#define USE_SERIAL_3_STDIN 0 -#define SERIAL_3_PB10_PB11 0 -#define SERIAL_3_PC10_PC11 0 -#define SERIAL_3_PD8_PD9 0 - -#define ao_gps_getchar ao_serial1_getchar -#define ao_gps_putchar ao_serial1_putchar -#define ao_gps_set_speed ao_serial1_set_speed -#define ao_gps_fifo (ao_stm_usart1.rx_fifo) - -#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1024 * 1024) -#define HAS_EEPROM 1 -#define USE_INTERNAL_FLASH 0 -#define USE_EEPROM_CONFIG 1 -#define USE_STORAGE_CONFIG 0 -#define HAS_USB 1 -#define HAS_BEEP 1 -#define HAS_BATTERY_REPORT 1 -#define HAS_RADIO 0 -#define HAS_TELEMETRY 0 -#define HAS_APRS 0 - -#define HAS_SPI_1 1 -#define SPI_1_PA5_PA6_PA7 1 /* Barometer */ -#define SPI_1_PB3_PB4_PB5 1 /* Accelerometer, Gyro */ -#define SPI_1_PE13_PE14_PE15 0 -#define SPI_1_OSPEEDR STM_OSPEEDR_10MHz - -#define HAS_SPI_2 1 -#define SPI_2_PB13_PB14_PB15 1 /* Flash, Companion */ -#define SPI_2_PD1_PD3_PD4 0 -#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz - -#define SPI_2_PORT (&stm_gpiob) -#define SPI_2_SCK_PIN 13 -#define SPI_2_MISO_PIN 14 -#define SPI_2_MOSI_PIN 15 - -#define HAS_I2C_1 1 -#define I2C_1_PB8_PB9 1 - -#define HAS_I2C_2 0 -#define I2C_2_PB10_PB11 0 - -#define PACKET_HAS_SLAVE 0 -#define PACKET_HAS_MASTER 0 - -#define LOW_LEVEL_DEBUG 0 - -#define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOAEN -#define LED_PORT (&stm_gpioa) -#define LED_PIN_RED 9 -#define LED_PIN_GREEN 10 -#define AO_LED_RED (1 << LED_PIN_RED) -#define AO_LED_GREEN (1 << LED_PIN_GREEN) - -#define LEDS_AVAILABLE (AO_LED_RED | AO_LED_GREEN) - -#define HAS_GPS 0 -#define HAS_FLIGHT 1 -#define HAS_ADC 1 -#define HAS_ADC_TEMP 1 -#define HAS_LOG 1 - -/* - * Igniter - */ - -#define HAS_IGNITE 1 -#define HAS_IGNITE_REPORT 1 - -#define AO_SENSE_PYRO(p,n) ((p)->adc.sense[n]) -#define AO_SENSE_DROGUE(p) ((p)->adc.sense[4]) -#define AO_SENSE_MAIN(p) ((p)->adc.sense[5]) -#define AO_IGNITER_CLOSED 400 -#define AO_IGNITER_OPEN 60 - -/* Pyro A */ -#define AO_PYRO_PORT_0 (&stm_gpioa) -#define AO_PYRO_PIN_0 15 - -/* Pyro B */ -#define AO_PYRO_PORT_1 (&stm_gpioc) -#define AO_PYRO_PIN_1 10 - -/* Pyro C */ -#define AO_PYRO_PORT_2 (&stm_gpiob) -#define AO_PYRO_PIN_2 11 - -/* Pyro D */ -#define AO_PYRO_PORT_3 (&stm_gpiob) -#define AO_PYRO_PIN_3 10 - -/* Drogue */ -#define AO_IGNITER_DROGUE_PORT (&stm_gpioa) -#define AO_IGNITER_DROGUE_PIN 0 - -/* Main */ -#define AO_IGNITER_MAIN_PORT (&stm_gpioa) -#define AO_IGNITER_MAIN_PIN 1 - -/* Number of general purpose pyro channels available */ -#define AO_PYRO_NUM 4 - -#define AO_IGNITER_SET_DROGUE(v) stm_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, v) -#define AO_IGNITER_SET_MAIN(v) stm_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, v) - -/* - * ADC - */ -#define AO_DATA_RING 32 -#define AO_ADC_NUM_SENSE 6 - -struct ao_adc { - int16_t sense[AO_ADC_NUM_SENSE]; - int16_t v_batt; - int16_t v_pbatt; - int16_t temp; -}; - -#define AO_ADC_DUMP(p) \ - printf("tick: %5u A: %5d B: %5d C: %5d D: %5d drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \ - (p)->tick, \ - (p)->adc.sense[0], (p)->adc.sense[1], (p)->adc.sense[2], \ - (p)->adc.sense[3], (p)->adc.sense[4], (p)->adc.sense[5], \ - (p)->adc.v_batt, (p)->adc.v_pbatt, (p)->adc.temp) - -#define AO_ADC_SENSE_A 14 -#define AO_ADC_SENSE_A_PORT (&stm_gpioc) -#define AO_ADC_SENSE_A_PIN 4 - -#define AO_ADC_SENSE_B 15 -#define AO_ADC_SENSE_B_PORT (&stm_gpioc) -#define AO_ADC_SENSE_B_PIN 5 - -#define AO_ADC_SENSE_C 13 -#define AO_ADC_SENSE_C_PORT (&stm_gpioc) -#define AO_ADC_SENSE_C_PIN 3 - -#define AO_ADC_SENSE_D 12 -#define AO_ADC_SENSE_D_PORT (&stm_gpioc) -#define AO_ADC_SENSE_D_PIN 2 - -#define AO_ADC_SENSE_DROGUE 11 -#define AO_ADC_SENSE_DROGUE_PORT (&stm_gpioc) -#define AO_ADC_SENSE_DROGUE_PIN 1 - -#define AO_ADC_SENSE_MAIN 10 -#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioc) -#define AO_ADC_SENSE_MAIN_PIN 0 - -#define AO_ADC_V_BATT 8 -#define AO_ADC_V_BATT_PORT (&stm_gpiob) -#define AO_ADC_V_BATT_PIN 0 - -#define AO_ADC_V_PBATT 9 -#define AO_ADC_V_PBATT_PORT (&stm_gpiob) -#define AO_ADC_V_PBATT_PIN 1 - -#define AO_ADC_TEMP 16 - -#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_GPIOAEN) | \ - (1 << STM_RCC_AHBENR_GPIOEEN) | \ - (1 << STM_RCC_AHBENR_GPIOBEN)) - -#define AO_NUM_ADC_PIN (AO_ADC_NUM_SENSE + 2) - -#define AO_ADC_PIN0_PORT AO_ADC_SENSE_A_PORT -#define AO_ADC_PIN0_PIN AO_ADC_SENSE_A_PIN -#define AO_ADC_PIN1_PORT AO_ADC_SENSE_B_PORT -#define AO_ADC_PIN1_PIN AO_ADC_SENSE_B_PIN -#define AO_ADC_PIN2_PORT AO_ADC_SENSE_C_PORT -#define AO_ADC_PIN2_PIN AO_ADC_SENSE_C_PIN -#define AO_ADC_PIN3_PORT AO_ADC_SENSE_D_PORT -#define AO_ADC_PIN3_PIN AO_ADC_SENSE_D_PIN -#define AO_ADC_PIN4_PORT AO_ADC_SENSE_DROGUE_PORT -#define AO_ADC_PIN4_PIN AO_ADC_SENSE_DROGUE_PIN -#define AO_ADC_PIN5_PORT AO_ADC_SENSE_MAIN_PORT -#define AO_ADC_PIN5_PIN AO_ADC_SENSE_MAIN_PIN -#define AO_ADC_PIN6_PORT AO_ADC_V_BATT_PORT -#define AO_ADC_PIN6_PIN AO_ADC_V_BATT_PIN -#define AO_ADC_PIN7_PORT AO_ADC_V_PBATT_PORT -#define AO_ADC_PIN7_PIN AO_ADC_V_PBATT_PIN - -#define AO_NUM_ADC (AO_ADC_NUM_SENSE + 3) - -#define AO_ADC_SQ1 AO_ADC_SENSE_A -#define AO_ADC_SQ2 AO_ADC_SENSE_B -#define AO_ADC_SQ3 AO_ADC_SENSE_C -#define AO_ADC_SQ4 AO_ADC_SENSE_D -#define AO_ADC_SQ5 AO_ADC_SENSE_DROGUE -#define AO_ADC_SQ6 AO_ADC_SENSE_MAIN -#define AO_ADC_SQ7 AO_ADC_V_BATT -#define AO_ADC_SQ8 AO_ADC_V_PBATT -#define AO_ADC_SQ9 AO_ADC_TEMP - -/* - * Voltage divider on ADC battery sampler - */ -#define AO_BATTERY_DIV_PLUS 56 /* 5.6k */ -#define AO_BATTERY_DIV_MINUS 100 /* 10k */ - -/* - * Voltage divider on ADC igniter samplers - */ -#define AO_IGNITE_DIV_PLUS 100 /* 100k */ -#define AO_IGNITE_DIV_MINUS 27 /* 27k */ - -/* - * ADC reference in decivolts - */ -#define AO_ADC_REFERENCE_DV 33 - -/* - * Pressure sensor settings - */ -#define HAS_MS5607 1 -#define HAS_MS5611 0 -#define AO_MS5607_PRIVATE_PINS 1 -#define AO_MS5607_CS_PORT (&stm_gpioa) -#define AO_MS5607_CS_PIN 3 -#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS_PIN) -#define AO_MS5607_MISO_PORT (&stm_gpioa) -#define AO_MS5607_MISO_PIN 6 -#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO_PIN) -#define AO_MS5607_SPI_INDEX AO_SPI_1_PA5_PA6_PA7 - -/* - * SPI Flash memory - */ - -#define M25_MAX_CHIPS 1 -#define AO_M25_SPI_CS_PORT (&stm_gpiob) -#define AO_M25_SPI_CS_PIN 12 -#define AO_M25_SPI_CS_MASK (1 << AO_M25_SPI_CS_PIN) -#define AO_M25_SPI_BUS AO_SPI_2_PB13_PB14_PB15 - -/* - * Mag sensor (hmc5883) - */ - -#define HAS_HMC5883 1 -#define AO_HMC5883_INT_PORT (&stm_gpioc) -#define AO_HMC5883_INT_PIN 14 -#define AO_HMC5883_I2C_INDEX STM_I2C_INDEX(1) - -/* - * mpu6000 - */ - -#define HAS_MPU6000 1 -#define AO_MPU6000_INT_PORT (&stm_gpioc) -#define AO_MPU6000_INT_PIN 15 -#define AO_MPU6000_SPI_BUS AO_SPI_1_PB3_PB4_PB5 -#define AO_MPU6000_SPI_CS_PORT (&stm_gpioc) -#define AO_MPU6000_SPI_CS_PIN 13 -#define HAS_IMU 1 - -/* - * mma655x - */ - -#define HAS_MMA655X 1 -#define AO_MMA655X_SPI_INDEX AO_SPI_1_PB3_PB4_PB5 -#define AO_MMA655X_CS_PORT (&stm_gpioc) -#define AO_MMA655X_CS_PIN 12 - -#define NUM_CMDS 16 - -/* - * Companion - */ - -#define AO_COMPANION_CS_PORT (&stm_gpiob) -#define AO_COMPANION_CS_PIN (6) -#define AO_COMPANION_SPI_BUS AO_SPI_2_PB13_PB14_PB15 - -/* - * Monitor - */ - -#define HAS_MONITOR 0 -#define LEGACY_MONITOR 0 -#define HAS_MONITOR_PUT 0 -#define AO_MONITOR_LED 0 -#define HAS_RSSI 0 - -/* - * Profiling Viterbi decoding - */ - -#ifndef AO_PROFILE -#define AO_PROFILE 0 -#endif - -#endif /* _AO_PINS_H_ */ diff --git a/src/easymega-v0.1/flash-loader/Makefile b/src/easymega-v0.1/flash-loader/Makefile deleted file mode 100644 index 35312fd6..00000000 --- a/src/easymega-v0.1/flash-loader/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# AltOS flash loader build -# -# - -TOPDIR=../.. -HARDWARE=easymega-v0.1 -include $(TOPDIR)/stm/Makefile-flash.defs diff --git a/src/easymega-v0.1/flash-loader/ao_pins.h b/src/easymega-v0.1/flash-loader/ao_pins.h deleted file mode 100644 index 445289bf..00000000 --- a/src/easymega-v0.1/flash-loader/ao_pins.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright © 2013 Keith Packard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#ifndef _AO_PINS_H_ -#define _AO_PINS_H_ - -/* External crystal at 8MHz */ -#define AO_HSE 8000000 - -#include - -/* Companion port cs_companion0 PD0 */ - -#define AO_BOOT_PIN 1 -#define AO_BOOT_APPLICATION_GPIO stm_gpiob -#define AO_BOOT_APPLICATION_PIN 6 -#define AO_BOOT_APPLICATION_VALUE 1 -#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP - -#endif /* _AO_PINS_H_ */ diff --git a/src/easymega-v1.0/.gitignore b/src/easymega-v1.0/.gitignore new file mode 100644 index 00000000..410943d5 --- /dev/null +++ b/src/easymega-v1.0/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +easymega-*.elf diff --git a/src/easymega-v1.0/Makefile b/src/easymega-v1.0/Makefile new file mode 100644 index 00000000..708ce1c6 --- /dev/null +++ b/src/easymega-v1.0/Makefile @@ -0,0 +1,144 @@ +# +# AltOS build +# +# + +include ../stm/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_boot.h \ + ao_companion.h \ + ao_data.h \ + ao_sample.h \ + ao_pins.h \ + altitude-pa.h \ + ao_kalman.h \ + ao_product.h \ + ao_ms5607.h \ + ao_hmc5883.h \ + ao_mpu6000.h \ + ao_mma655x.h \ + ao_profile.h \ + ao_task.h \ + ao_whiten.h \ + ao_sample_profile.h \ + ao_quaternion.h \ + math.h \ + ao_mpu.h \ + stm32l.h \ + math.h \ + Makefile + +# +# Common AltOS sources +# +# ao_hmc5883.c + +#PROFILE=ao_profile.c +#PROFILE_DEF=-DAO_PROFILE=1 + +#SAMPLE_PROFILE=ao_sample_profile.c \ +# ao_sample_profile_timer.c +#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1 + +#STACK_GUARD=ao_mpu_stm.c +#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1 + +MATH_SRC=\ + ef_acos.c \ + ef_sqrt.c \ + ef_rem_pio2.c \ + kf_cos.c \ + kf_sin.c \ + kf_rem_pio2.c \ + sf_copysign.c \ + sf_cos.c \ + sf_fabs.c \ + sf_floor.c \ + sf_scalbn.c \ + sf_sin.c \ + ef_log.c + +ALTOS_SRC = \ + ao_boot_chain.c \ + ao_interrupt.c \ + ao_product.c \ + ao_romconfig.c \ + ao_cmd.c \ + ao_config.c \ + ao_task.c \ + ao_led.c \ + ao_stdio.c \ + ao_panic.c \ + ao_timer.c \ + ao_mutex.c \ + ao_ignite.c \ + ao_freq.c \ + ao_dma_stm.c \ + ao_spi_stm.c \ + ao_data.c \ + ao_ms5607.c \ + ao_mma655x.c \ + ao_hmc5883.c \ + ao_adc_stm.c \ + ao_beep_stm.c \ + ao_eeprom_stm.c \ + ao_storage.c \ + ao_m25.c \ + ao_usb_stm.c \ + ao_exti_stm.c \ + ao_report.c \ + ao_i2c_stm.c \ + ao_mpu6000.c \ + ao_convert_pa.c \ + ao_convert_volt.c \ + ao_log.c \ + ao_log_mega.c \ + ao_sample.c \ + ao_kalman.c \ + ao_flight.c \ + ao_companion.c \ + ao_pyro.c \ + $(MATH_SRC) \ + $(PROFILE) \ + $(SAMPLE_PROFILE) \ + $(STACK_GUARD) + +PRODUCT=EasyMega-v1.0 +PRODUCT_DEF=-DEASYMEGA +IDPRODUCT=0x0023 + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g + +PROGNAME=easymega-v1.0 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SRC=$(ALTOS_SRC) ao_easymega.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) $(HEX) + +$(PROG): Makefile $(OBJ) altos.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) + +../altitude-pa.h: make-altitude-pa + nickle $< > $@ + +$(OBJ): $(INC) + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +distclean: clean + +clean: + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/easymega-v1.0/ao_easymega.c b/src/easymega-v1.0/ao_easymega.c new file mode 100644 index 00000000..e217c33c --- /dev/null +++ b/src/easymega-v1.0/ao_easymega.c @@ -0,0 +1,95 @@ +/* + * Copyright © 2014 Bdale Garbee + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#if HAS_SAMPLE_PROFILE +#include +#endif +#include +#if HAS_STACK_GUARD +#include +#endif + +int +main(void) +{ + ao_clock_init(); + +#if HAS_STACK_GUARD + ao_mpu_init(); +#endif + + ao_task_init(); + ao_led_init(LEDS_AVAILABLE); + ao_led_on(AO_LED_GREEN); + ao_timer_init(); + + ao_i2c_init(); + ao_spi_init(); + ao_dma_init(); + ao_exti_init(); + + ao_adc_init(); +#if HAS_BEEP + ao_beep_init(); +#endif + ao_cmd_init(); + +#if HAS_MS5607 + ao_ms5607_init(); +#endif +#if HAS_HMC5883 + ao_hmc5883_init(); +#endif +#if HAS_MPU6000 + ao_mpu6000_init(); +#endif +#if HAS_MMA655X + ao_mma655x_init(); +#endif + + ao_eeprom_init(); + ao_storage_init(); + + ao_flight_init(); + ao_log_init(); + ao_report_init(); + + ao_usb_init(); + ao_igniter_init(); + ao_companion_init(); + ao_pyro_init(); + + ao_config_init(); +#if AO_PROFILE + ao_profile_init(); +#endif +#if HAS_SAMPLE_PROFILE + ao_sample_profile_init(); +#endif + + ao_start_scheduler(); + return 0; +} diff --git a/src/easymega-v1.0/ao_pins.h b/src/easymega-v1.0/ao_pins.h new file mode 100644 index 00000000..d6490ba5 --- /dev/null +++ b/src/easymega-v1.0/ao_pins.h @@ -0,0 +1,355 @@ +/* + * Copyright © 2014 Bdale Garbee + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +#define HAS_TASK_QUEUE 1 + +/* 8MHz High speed external crystal */ +#define AO_HSE 8000000 + +/* PLLVCO = 96MHz (so that USB will work) */ +#define AO_PLLMUL 12 +#define AO_RCC_CFGR_PLLMUL (STM_RCC_CFGR_PLLMUL_12) + +/* SYSCLK = 32MHz (no need to go faster than CPU) */ +#define AO_PLLDIV 3 +#define AO_RCC_CFGR_PLLDIV (STM_RCC_CFGR_PLLDIV_3) + +/* HCLK = 32MHz (CPU clock) */ +#define AO_AHB_PRESCALER 1 +#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1 + +/* Run APB1 at 16MHz (HCLK/2) */ +#define AO_APB1_PRESCALER 2 +#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE2_DIV_2 + +/* Run APB2 at 16MHz (HCLK/2) */ +#define AO_APB2_PRESCALER 2 +#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_2 + +#define HAS_SERIAL_1 0 +#define USE_SERIAL_1_STDIN 0 +#define SERIAL_1_PB6_PB7 0 +#define SERIAL_1_PA9_PA10 0 + +#define HAS_SERIAL_2 0 +#define USE_SERIAL_2_STDIN 0 +#define SERIAL_2_PA2_PA3 0 +#define SERIAL_2_PD5_PD6 0 + +#define HAS_SERIAL_3 0 +#define USE_SERIAL_3_STDIN 0 +#define SERIAL_3_PB10_PB11 0 +#define SERIAL_3_PC10_PC11 0 +#define SERIAL_3_PD8_PD9 0 + +#define ao_gps_getchar ao_serial1_getchar +#define ao_gps_putchar ao_serial1_putchar +#define ao_gps_set_speed ao_serial1_set_speed +#define ao_gps_fifo (ao_stm_usart1.rx_fifo) + +#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX (1024 * 1024) +#define AO_CONFIG_MAX_SIZE 1024 +#define LOG_ERASE_MARK 0x55 +#define LOG_MAX_ERASE 128 +#define HAS_EEPROM 1 +#define USE_INTERNAL_FLASH 0 +#define USE_EEPROM_CONFIG 1 +#define USE_STORAGE_CONFIG 0 +#define HAS_USB 1 +#define HAS_BEEP 1 +#define HAS_BATTERY_REPORT 1 +#define HAS_RADIO 0 +#define HAS_TELEMETRY 0 +#define HAS_APRS 0 + +#define HAS_SPI_1 1 +#define SPI_1_PA5_PA6_PA7 1 /* Barometer */ +#define SPI_1_PB3_PB4_PB5 1 /* Accelerometer, Gyro */ +#define SPI_1_PE13_PE14_PE15 0 +#define SPI_1_OSPEEDR STM_OSPEEDR_10MHz + +#define HAS_SPI_2 1 +#define SPI_2_PB13_PB14_PB15 1 /* Flash, Companion */ +#define SPI_2_PD1_PD3_PD4 0 +#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz + +#define SPI_2_PORT (&stm_gpiob) +#define SPI_2_SCK_PIN 13 +#define SPI_2_MISO_PIN 14 +#define SPI_2_MOSI_PIN 15 + +#define HAS_I2C_1 1 +#define I2C_1_PB8_PB9 1 + +#define HAS_I2C_2 0 +#define I2C_2_PB10_PB11 0 + +#define PACKET_HAS_SLAVE 0 +#define PACKET_HAS_MASTER 0 + +#define LOW_LEVEL_DEBUG 0 + +#define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOAEN +#define LED_PORT (&stm_gpioa) +#define LED_PIN_RED 9 +#define LED_PIN_GREEN 10 +#define AO_LED_RED (1 << LED_PIN_RED) +#define AO_LED_GREEN (1 << LED_PIN_GREEN) + +#define LEDS_AVAILABLE (AO_LED_RED | AO_LED_GREEN) + +#define HAS_GPS 0 +#define HAS_FLIGHT 1 +#define HAS_ADC 1 +#define HAS_ADC_TEMP 1 +#define HAS_LOG 1 + +/* + * Igniter + */ + +#define HAS_IGNITE 1 +#define HAS_IGNITE_REPORT 1 + +#define AO_SENSE_PYRO(p,n) ((p)->adc.sense[n]) +#define AO_SENSE_DROGUE(p) ((p)->adc.sense[4]) +#define AO_SENSE_MAIN(p) ((p)->adc.sense[5]) +#define AO_IGNITER_CLOSED 400 +#define AO_IGNITER_OPEN 60 + +/* Pyro A */ +#define AO_PYRO_PORT_0 (&stm_gpioa) +#define AO_PYRO_PIN_0 15 + +/* Pyro B */ +#define AO_PYRO_PORT_1 (&stm_gpioc) +#define AO_PYRO_PIN_1 10 + +/* Pyro C */ +#define AO_PYRO_PORT_2 (&stm_gpiob) +#define AO_PYRO_PIN_2 11 + +/* Pyro D */ +#define AO_PYRO_PORT_3 (&stm_gpiob) +#define AO_PYRO_PIN_3 10 + +/* Drogue */ +#define AO_IGNITER_DROGUE_PORT (&stm_gpioa) +#define AO_IGNITER_DROGUE_PIN 0 + +/* Main */ +#define AO_IGNITER_MAIN_PORT (&stm_gpioa) +#define AO_IGNITER_MAIN_PIN 1 + +/* Number of general purpose pyro channels available */ +#define AO_PYRO_NUM 4 + +#define AO_IGNITER_SET_DROGUE(v) stm_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, v) +#define AO_IGNITER_SET_MAIN(v) stm_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, v) + +/* + * ADC + */ +#define AO_DATA_RING 32 +#define AO_ADC_NUM_SENSE 6 + +struct ao_adc { + int16_t sense[AO_ADC_NUM_SENSE]; + int16_t v_batt; + int16_t v_pbatt; + int16_t temp; +}; + +#define AO_ADC_DUMP(p) \ + printf("tick: %5u A: %5d B: %5d C: %5d D: %5d drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \ + (p)->tick, \ + (p)->adc.sense[0], (p)->adc.sense[1], (p)->adc.sense[2], \ + (p)->adc.sense[3], (p)->adc.sense[4], (p)->adc.sense[5], \ + (p)->adc.v_batt, (p)->adc.v_pbatt, (p)->adc.temp) + +#define AO_ADC_SENSE_A 14 +#define AO_ADC_SENSE_A_PORT (&stm_gpioc) +#define AO_ADC_SENSE_A_PIN 4 + +#define AO_ADC_SENSE_B 15 +#define AO_ADC_SENSE_B_PORT (&stm_gpioc) +#define AO_ADC_SENSE_B_PIN 5 + +#define AO_ADC_SENSE_C 13 +#define AO_ADC_SENSE_C_PORT (&stm_gpioc) +#define AO_ADC_SENSE_C_PIN 3 + +#define AO_ADC_SENSE_D 12 +#define AO_ADC_SENSE_D_PORT (&stm_gpioc) +#define AO_ADC_SENSE_D_PIN 2 + +#define AO_ADC_SENSE_DROGUE 11 +#define AO_ADC_SENSE_DROGUE_PORT (&stm_gpioc) +#define AO_ADC_SENSE_DROGUE_PIN 1 + +#define AO_ADC_SENSE_MAIN 10 +#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioc) +#define AO_ADC_SENSE_MAIN_PIN 0 + +#define AO_ADC_V_BATT 8 +#define AO_ADC_V_BATT_PORT (&stm_gpiob) +#define AO_ADC_V_BATT_PIN 0 + +#define AO_ADC_V_PBATT 9 +#define AO_ADC_V_PBATT_PORT (&stm_gpiob) +#define AO_ADC_V_PBATT_PIN 1 + +#define AO_ADC_TEMP 16 + +#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_GPIOAEN) | \ + (1 << STM_RCC_AHBENR_GPIOEEN) | \ + (1 << STM_RCC_AHBENR_GPIOBEN)) + +#define AO_NUM_ADC_PIN (AO_ADC_NUM_SENSE + 2) + +#define AO_ADC_PIN0_PORT AO_ADC_SENSE_A_PORT +#define AO_ADC_PIN0_PIN AO_ADC_SENSE_A_PIN +#define AO_ADC_PIN1_PORT AO_ADC_SENSE_B_PORT +#define AO_ADC_PIN1_PIN AO_ADC_SENSE_B_PIN +#define AO_ADC_PIN2_PORT AO_ADC_SENSE_C_PORT +#define AO_ADC_PIN2_PIN AO_ADC_SENSE_C_PIN +#define AO_ADC_PIN3_PORT AO_ADC_SENSE_D_PORT +#define AO_ADC_PIN3_PIN AO_ADC_SENSE_D_PIN +#define AO_ADC_PIN4_PORT AO_ADC_SENSE_DROGUE_PORT +#define AO_ADC_PIN4_PIN AO_ADC_SENSE_DROGUE_PIN +#define AO_ADC_PIN5_PORT AO_ADC_SENSE_MAIN_PORT +#define AO_ADC_PIN5_PIN AO_ADC_SENSE_MAIN_PIN +#define AO_ADC_PIN6_PORT AO_ADC_V_BATT_PORT +#define AO_ADC_PIN6_PIN AO_ADC_V_BATT_PIN +#define AO_ADC_PIN7_PORT AO_ADC_V_PBATT_PORT +#define AO_ADC_PIN7_PIN AO_ADC_V_PBATT_PIN + +#define AO_NUM_ADC (AO_ADC_NUM_SENSE + 3) + +#define AO_ADC_SQ1 AO_ADC_SENSE_A +#define AO_ADC_SQ2 AO_ADC_SENSE_B +#define AO_ADC_SQ3 AO_ADC_SENSE_C +#define AO_ADC_SQ4 AO_ADC_SENSE_D +#define AO_ADC_SQ5 AO_ADC_SENSE_DROGUE +#define AO_ADC_SQ6 AO_ADC_SENSE_MAIN +#define AO_ADC_SQ7 AO_ADC_V_BATT +#define AO_ADC_SQ8 AO_ADC_V_PBATT +#define AO_ADC_SQ9 AO_ADC_TEMP + +/* + * Voltage divider on ADC battery sampler + */ +#define AO_BATTERY_DIV_PLUS 56 /* 5.6k */ +#define AO_BATTERY_DIV_MINUS 100 /* 10k */ + +/* + * Voltage divider on ADC igniter samplers + */ +#define AO_IGNITE_DIV_PLUS 100 /* 100k */ +#define AO_IGNITE_DIV_MINUS 27 /* 27k */ + +/* + * ADC reference in decivolts + */ +#define AO_ADC_REFERENCE_DV 33 + +/* + * Pressure sensor settings + */ +#define HAS_MS5607 1 +#define HAS_MS5611 0 +#define AO_MS5607_PRIVATE_PINS 1 +#define AO_MS5607_CS_PORT (&stm_gpioa) +#define AO_MS5607_CS_PIN 3 +#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS_PIN) +#define AO_MS5607_MISO_PORT (&stm_gpioa) +#define AO_MS5607_MISO_PIN 6 +#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO_PIN) +#define AO_MS5607_SPI_INDEX AO_SPI_1_PA5_PA6_PA7 + +/* + * SPI Flash memory + */ + +#define M25_MAX_CHIPS 1 +#define AO_M25_SPI_CS_PORT (&stm_gpiob) +#define AO_M25_SPI_CS_PIN 12 +#define AO_M25_SPI_CS_MASK (1 << AO_M25_SPI_CS_PIN) +#define AO_M25_SPI_BUS AO_SPI_2_PB13_PB14_PB15 + +/* + * Mag sensor (hmc5883) + */ + +#define HAS_HMC5883 1 +#define AO_HMC5883_INT_PORT (&stm_gpioc) +#define AO_HMC5883_INT_PIN 14 +#define AO_HMC5883_I2C_INDEX STM_I2C_INDEX(1) + +/* + * mpu6000 + */ + +#define HAS_MPU6000 1 +#define AO_MPU6000_INT_PORT (&stm_gpioc) +#define AO_MPU6000_INT_PIN 15 +#define AO_MPU6000_SPI_BUS AO_SPI_1_PB3_PB4_PB5 +#define AO_MPU6000_SPI_CS_PORT (&stm_gpioc) +#define AO_MPU6000_SPI_CS_PIN 13 +#define HAS_IMU 1 + +/* + * mma655x + */ + +#define HAS_MMA655X 1 +#define AO_MMA655X_SPI_INDEX AO_SPI_1_PB3_PB4_PB5 +#define AO_MMA655X_CS_PORT (&stm_gpioc) +#define AO_MMA655X_CS_PIN 12 + +#define NUM_CMDS 16 + +/* + * Companion + */ + +#define AO_COMPANION_CS_PORT (&stm_gpiob) +#define AO_COMPANION_CS_PIN (6) +#define AO_COMPANION_SPI_BUS AO_SPI_2_PB13_PB14_PB15 + +/* + * Monitor + */ + +#define HAS_MONITOR 0 +#define LEGACY_MONITOR 0 +#define HAS_MONITOR_PUT 0 +#define AO_MONITOR_LED 0 +#define HAS_RSSI 0 + +/* + * Profiling Viterbi decoding + */ + +#ifndef AO_PROFILE +#define AO_PROFILE 0 +#endif + +#endif /* _AO_PINS_H_ */ diff --git a/src/easymega-v1.0/flash-loader/Makefile b/src/easymega-v1.0/flash-loader/Makefile new file mode 100644 index 00000000..d83cb70a --- /dev/null +++ b/src/easymega-v1.0/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=easymega-v1.0 +include $(TOPDIR)/stm/Makefile-flash.defs diff --git a/src/easymega-v1.0/flash-loader/ao_pins.h b/src/easymega-v1.0/flash-loader/ao_pins.h new file mode 100644 index 00000000..445289bf --- /dev/null +++ b/src/easymega-v1.0/flash-loader/ao_pins.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +/* External crystal at 8MHz */ +#define AO_HSE 8000000 + +#include + +/* Companion port cs_companion0 PD0 */ + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO stm_gpiob +#define AO_BOOT_APPLICATION_PIN 6 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP + +#endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From d8e2b661e895fc59ded002a02191dcccce75f548 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 19 Jul 2014 22:35:30 -0700 Subject: altos: Have MicroKite just start recording at startup This avoids having MicroKite try to detect boost and has it just start recording data immediately. Signed-off-by: Keith Packard --- src/kernel/ao_microflight.c | 9 +++++++++ src/microkite/ao_pins.h | 3 ++- src/product/ao_micropeak.c | 3 ++- src/product/ao_micropeak.h | 2 ++ 4 files changed, 15 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/kernel/ao_microflight.c b/src/kernel/ao_microflight.c index df624e79..f7521f21 100644 --- a/src/kernel/ao_microflight.c +++ b/src/kernel/ao_microflight.c @@ -62,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) @@ -84,6 +90,9 @@ ao_microflight(void) pa_ground = pa_sum >> GROUND_AVG_SHIFT; pa_sum = 0; sample_count = 0; +#if !BOOST_DETECT + break; +#endif } } diff --git a/src/microkite/ao_pins.h b/src/microkite/ao_pins.h index 3c56dfb8..346b63a1 100644 --- a/src/microkite/ao_pins.h +++ b/src/microkite/ao_pins.h @@ -62,8 +62,9 @@ typedef int32_t alt_t; #define AO_ALT_VALUE(x) ((x) * (alt_t) 10) -#define BOOST_DETECT 1200 /* 100m (ish) */ +#define BOOST_DETECT 0 /* none */ #define LOG_INTERVAL 200 /* 19.2 seconds */ +#define BOOST_DELAY 0 #define AO_LOG_ID AO_LOG_ID_MICROKITE 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 396b9a23..622f5a69 100644 --- a/src/product/ao_micropeak.h +++ b/src/product/ao_micropeak.h @@ -41,7 +41,9 @@ #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 */ -- cgit v1.2.3 From c4dd29fcbbb93e991993a0aa444748dba4ee7dde Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 22 Jul 2014 14:18:06 -0700 Subject: altos: Document which TeleFire alarm pins are which Signed-off-by: Keith Packard --- src/telefire-v0.2/ao_pins.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/telefire-v0.2/ao_pins.h b/src/telefire-v0.2/ao_pins.h index ef2d4822..28cc65b9 100644 --- a/src/telefire-v0.2/ao_pins.h +++ b/src/telefire-v0.2/ao_pins.h @@ -97,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 -- cgit v1.2.3 From e935ebe55705cb0506aac0859583d54fd8e5ca46 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 14 Aug 2014 19:03:29 -0700 Subject: altos: Report additional pyro channels via beeper Send a beep for each additional pyro channel, low for no igniter, mid for igniter. Does not change the reporting for the apogee/main channels. Signed-off-by: Keith Packard --- src/kernel/ao_pyro.h | 3 +++ src/kernel/ao_report.c | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src') 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)); -- cgit v1.2.3 From 1530c24cc75cdf9ba87c7e153ff28bf7beb4384c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 17 Aug 2014 20:57:16 -0700 Subject: cc1111: Wait for internal flash write to complete This ensures that we don't try to start another write too soon. Signed-off-by: Keith Packard --- src/cc1111/ao_intflash.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') 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 -- cgit v1.2.3 From bb7522acf040f41740ecd059e3d5d2480b652420 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 17 Aug 2014 20:59:45 -0700 Subject: telegps-v1.0: Provide one log and append to it Instead of creating per-flight logs, create a single log and append data to it each time TeleGPS is powered on. This avoids potentially running out of log space just because the device is powered off/on. Signed-off-by: Keith Packard --- src/kernel/ao_config.c | 38 +++++++++++-- src/kernel/ao_config.h | 7 +++ src/kernel/ao_log.c | 134 +++++++++++++++++++++++++++++++++------------ src/kernel/ao_log.h | 5 ++ src/kernel/ao_log_gps.c | 14 +++++ src/telegps-v1.0/ao_pins.h | 2 +- 6 files changed, 160 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index d73a3733..d1b93122 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -50,13 +50,19 @@ __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 @@ -525,15 +531,36 @@ ao_config_radio_rate_set(void) __reentrant #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); @@ -551,6 +578,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 */ diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h index a650ffc6..0be3e14d 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 @@ -146,6 +150,9 @@ ao_config_put(void); void ao_config_set_radio(void); +void +ao_config_log_fix_append(void); + void ao_config_init(void); diff --git a/src/kernel/ao_log.c b/src/kernel/ao_log.c index 91617d93..dc3b6486 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,74 @@ ao_log_scan(void) __reentrant } if (ao_flight_number == 0) ao_flight_number = 1; +} + +void +ao_log_scan(void) __reentrant +{ + uint8_t log_slot; + uint8_t log_slots; +#if !FLIGHT_LOG_APPEND + 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; + } + } + } else { + ao_log_find_max_erase_flight(); + } +#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,7 +278,7 @@ ao_log_scan(void) __reentrant if (++log_slot >= log_slots) log_slot = 0; } while (log_slot != log_want); - +#endif ao_wakeup(&ao_flight_number); } @@ -254,7 +342,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 +355,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 da20e067..c5fa7fab 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); diff --git a/src/kernel/ao_log_gps.c b/src/kernel/ao_log_gps.c index a5a6358b..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 @@ -136,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/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 -- cgit v1.2.3 From 44e389c31e5958c1a050fbe0dce5d7971a9d6a86 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 17 Aug 2014 21:03:12 -0700 Subject: altos: Add telerepeat-v1.0 This uses TeleBT hardware to provide a telemetry repeater, receiving packets on one frequency and re-transmitting them on another. Signed-off-by: Keith Packard --- src/Makefile | 3 +- src/kernel/ao_config.c | 41 +++++++++++++ src/kernel/ao_config.h | 9 ++- src/kernel/ao_forward.c | 48 ++++++++++++++++ src/kernel/ao_forward.h | 24 ++++++++ src/telerepeat-v1.0/Makefile | 100 ++++++++++++++++++++++++++++++++ src/telerepeat-v1.0/ao_pins.h | 111 ++++++++++++++++++++++++++++++++++++ src/telerepeat-v1.0/ao_telerepeat.c | 47 +++++++++++++++ 8 files changed, 381 insertions(+), 2 deletions(-) create mode 100644 src/kernel/ao_forward.c create mode 100644 src/kernel/ao_forward.h create mode 100644 src/telerepeat-v1.0/Makefile create mode 100644 src/telerepeat-v1.0/ao_pins.h create mode 100644 src/telerepeat-v1.0/ao_telerepeat.c (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 7f09db02..20126de6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -22,7 +22,8 @@ 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 \ diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index d1b93122..6b8a1813 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -93,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 */ @@ -207,6 +215,10 @@ _ao_config_get(void) #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; @@ -302,6 +314,31 @@ ao_config_frequency_set(void) __reentrant #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 void @@ -863,6 +900,10 @@ __code struct ao_config_var ao_config_vars[] = { #if HAS_RADIO { "F \0Frequency (kHz)", ao_config_frequency_set, ao_config_frequency_show }, +#if HAS_RADIO_FORWARD + { "R \0Repeater output frequency (kHz)", + ao_config_send_frequency_set, ao_config_send_frequency_show }, +#endif { "c \0Callsign (8 char max)", ao_config_callsign_set, ao_config_callsign_show }, { "e <0 disable, 1 enable>\0Enable telemetry and RDF", diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h index 0be3e14d..164584a5 100644 --- a/src/kernel/ao_config.h +++ b/src/kernel/ao_config.h @@ -57,7 +57,7 @@ #endif #define AO_CONFIG_MAJOR 1 -#define AO_CONFIG_MINOR 20 +#define AO_CONFIG_MINOR 21 #define AO_AES_LEN 16 @@ -112,8 +112,15 @@ struct ao_config { #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 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 + * + * 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 + * + * 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/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 + * + * 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 + * + * 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(); +} -- cgit v1.2.3 From 5872bd10df14b47de0e541bff16d9220af0558aa Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 29 Aug 2014 15:12:38 -0500 Subject: altos: Make sure pyro remains valid during delay Keep checking pyro status while waiting for delay to expire to make sure nothing changes. Disable pyro channel if something does. Signed-off-by: Keith Packard --- src/kernel/ao_pyro.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/kernel/ao_pyro.c b/src/kernel/ao_pyro.c index 0b286466..154edad5 100644 --- a/src/kernel/ao_pyro.c +++ b/src/kernel/ao_pyro.c @@ -252,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]; @@ -288,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; } @@ -465,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') -- cgit v1.2.3 From a4202b4180e77e2a39ca071d3b8b8256ff0fc7b5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 1 Sep 2014 18:12:29 -0500 Subject: altos: Don't add AO_LOG_FLIGHT to existing GPS logs When appending to a TeleGPS log, don't stick another flight value into the log. That just confuses the ground station software. Signed-off-by: Keith Packard --- src/kernel/ao_log.c | 13 ++++++++++--- src/kernel/ao_log.h | 2 +- src/kernel/ao_tracker.c | 5 ++--- 3 files changed, 13 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/kernel/ao_log.c b/src/kernel/ao_log.c index dc3b6486..40a96ef7 100644 --- a/src/kernel/ao_log.c +++ b/src/kernel/ao_log.c @@ -192,12 +192,14 @@ ao_log_find_max_erase_flight(void) __reentrant ao_flight_number = 1; } -void +uint8_t ao_log_scan(void) __reentrant { uint8_t log_slot; uint8_t log_slots; -#if !FLIGHT_LOG_APPEND +#if FLIGHT_LOG_APPEND + uint8_t ret; +#else uint8_t log_want; #endif @@ -248,9 +250,13 @@ ao_log_scan(void) __reentrant 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) @@ -278,8 +284,9 @@ ao_log_scan(void) __reentrant if (++log_slot >= log_slots) log_slot = 0; } while (log_slot != log_want); -#endif ao_wakeup(&ao_flight_number); + return 0; +#endif } void diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h index c5fa7fab..c13a2580 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -72,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 */ diff --git a/src/kernel/ao_tracker.c b/src/kernel/ao_tracker.c index d9434048..9b007af8 100644 --- a/src/kernel/ao_tracker.c +++ b/src/kernel/ao_tracker.c @@ -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); @@ -181,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); } } -- cgit v1.2.3 From adc46e2f1346d98ef4f6c2351fef95fbc8ddf831 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 3 Sep 2014 22:12:15 -0700 Subject: altos/telefire: Add firing length to manual pad command This adds an optional length of time (in 1/10s of a second) to the ao_pad_manual function to enable testing of igniters without needing to use TeleLCO. Signed-off-by: Keith Packard --- src/drivers/ao_pad.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src') 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; -- cgit v1.2.3 From be38fb88d11bda1ba1caca38220773d3abcede19 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 3 Sep 2014 22:58:22 -0700 Subject: altos: Allow negative values for pyro configuration data All of the integer pyro configuration parameters may be negative, so parse that correctly. Signed-off-by: Keith Packard --- src/kernel/ao_pyro.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/kernel/ao_pyro.c b/src/kernel/ao_pyro.c index 154edad5..3044d565 100644 --- a/src/kernel/ao_pyro.c +++ b/src/kernel/ao_pyro.c @@ -499,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(); -- cgit v1.2.3 From f395bcaa620490954d4a42de9b4870bc12bedc91 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 6 Sep 2014 20:39:37 -0700 Subject: altos: Reduce deviation at 2400/9600 baud There's no reason to use 20.5kHz deviation at 2400 and 9600 baud, and if we get a better receiver, we'll want to use narrower deviation to have less bandwidth sucking noise into the radio. The new values are (nominally) 5.125kHz deviation for 9600 baud and 1.5kHz deviation for 2400 baud. Signed-off-by: Keith Packard --- src/cc1111/ao_radio.c | 77 ++++++++++++++++++++++++++++++++----------------- src/drivers/ao_cc1120.c | 69 +++++++++++++++++++++++++++++++++++--------- src/drivers/ao_cc1120.h | 6 ++++ src/drivers/ao_cc115l.c | 64 ++++++++++++++++++++++++++++++---------- 4 files changed, 160 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/cc1111/ao_radio.c b/src/cc1111/ao_radio.c index 8f519958..b9821a42 100644 --- a/src/cc1111/ao_radio.c +++ b/src/cc1111/ao_radio.c @@ -60,19 +60,19 @@ * * M = 1, E = 3, bw = 75kHz * - * 20.5 kHz deviation, 9.6kbps signal + * 5.125 kHz deviation, 9.6kbps signal * - * m = 41 / 9.6, which is < 5.5: + * m = 10.25 / 9.6, which is < 5.5: * - * bw = 2.6 * 20.5 + 0.55 * 9.6 = 58.58kHz + * bw = 2.6 * 5.125 + 0.55 * 9.6 = 18.6kHz * - * M = 2, E = 3, bw = 62.5kHz + * M = 2, E = 3, bw = 53.6kHz * - * 20.5kHz deviation, 2.4kbps signal + * 1.28125kHz deviation, 2.4kbps signal * - * m = 41 / 2.4, which is > 5.5: + * m = 2.565 / 2.4, which is < 5.5: * - * bw = 2.1 * 20.5 + 1.9 * 2.4 = 47.61kHz + * bw = 2.6 * 20.5 + 1.9 * 2.4 = 47.61kHz * * M = 3, E = 3, bw = 53.6kHz * @@ -84,7 +84,7 @@ */ #define CHANBW_M_384 1 -#define CHANBW_M_96 2 +#define CHANBW_M_96 3 #define CHANBW_M_24 3 #define CHANBW_E 3 @@ -115,11 +115,19 @@ * * 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), @@ -182,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 */ @@ -284,8 +289,10 @@ static __code uint8_t fixed_pkt_setup[] = { 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)| @@ -298,19 +305,34 @@ static __code uint8_t fixed_pkt_setup[] = { }; #if HAS_RADIO_RATE -static __code uint8_t packet_rate_setup[] = { +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)), + { + ((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)), + { + ((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)), + { + ((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 @@ -380,7 +402,8 @@ ao_radio_get(uint8_t len) RF_FREQ0 = (uint8_t) (ao_config.radio_setting); RF_PKTLEN = len; #if HAS_RADIO_RATE - RF_MDMCFG4 = packet_rate_setup[ao_config.radio_rate]; + RF_MDMCFG4 = packet_rate_setup[ao_config.radio_rate].mdmcfg4; + RF_DEVIATN = packet_rate_setup[ao_config.radio_rate].deviatn; #endif } diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 1b907940..3ea8b704 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -290,15 +290,32 @@ ao_radio_idle(void) } /* - * 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 @@ -307,41 +324,55 @@ ao_radio_idle(void) * 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 = 74.42 (round to 100) + * CHANBW = 79.4 (round to 100) * * Symbol rate 9600 Baud: * * DATARATE_M = 239914 * DATARATE_E = 7 - * CHANBW = 58.58 (round to 62.5) + * CHANBW = 19.9 (round to 20) * * Symbol rate 2400 Baud: * * DATARATE_M = 239914 * DATARATE_E = 5 - * CHANBW = 47.61 (round to 50) + * CHANBW = 5.0 (round to 8.0) */ #define PACKET_DRATE_M 239914 #define PACKET_DRATE_E_384 9 -#define PACKET_CHAN_BW_384 0x02 /* 200 / 2 = 100 */ + +/* 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 -#define PACKET_CHAN_BW_96 0x42 /* 125 / 2 = 62.5 */ +/* 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 -#define PACKET_CHAN_BW_24 0x04 /* 200 / 4 = 50 */ +/* 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_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) | @@ -361,6 +392,10 @@ static const uint16_t packet_setup[] = { }; 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, @@ -368,6 +403,10 @@ static const uint16_t packet_setup_384[] = { }; 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, @@ -375,6 +414,10 @@ static const uint16_t packet_setup_96[] = { }; 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, diff --git a/src/drivers/ao_cc1120.h b/src/drivers/ao_cc1120.h index 5d24c49a..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 diff --git a/src/drivers/ao_cc115l.c b/src/drivers/ao_cc115l.c index b5103f9b..cf61acfe 100644 --- a/src/drivers/ao_cc115l.c +++ b/src/drivers/ao_cc115l.c @@ -249,23 +249,41 @@ 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 @@ -279,20 +297,33 @@ ao_radio_idle(void) #define PACKET_DRATE_E_96 8 #define PACKET_DRATE_E_24 6 -static const uint16_t packet_rate_setup[] = { - [AO_RADIO_RATE_38400] = ((0xf << 4) | - (PACKET_DRATE_E_384 << CC115L_MDMCFG4_DRATE_E)), - - [AO_RADIO_RATE_9600] = ((0xf << 4) | - (PACKET_DRATE_E_96 << CC115L_MDMCFG4_DRATE_E)), - - [AO_RADIO_RATE_2400] = ((0xf << 4) | - (PACKET_DRATE_E_24 << CC115L_MDMCFG4_DRATE_E)), +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_MDMCFG3, (PACKET_DRATE_M), CC115L_MDMCFG2, (0x00 | (CC115L_MDMCFG2_MOD_FORMAT_GFSK << CC115L_MDMCFG2_MOD_FORMAT) | @@ -418,7 +449,8 @@ ao_radio_set_mode(uint16_t new_mode) changes = new_mode & (~ao_radio_mode); if (changes & AO_RADIO_MODE_BITS_PACKET_TX) { - ao_radio_reg_write(CC115L_MDMCFG4, packet_rate_setup[ao_config.radio_rate]); + 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]); -- cgit v1.2.3 From d83afa9320c24056469984873af0a3c70bee0962 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 6 Sep 2014 20:44:30 -0700 Subject: altos: Scale packet master receive delay by baud rate Increase the time we wait for return packets based on the remote protocol baud rate. Signed-off-by: Keith Packard --- src/drivers/ao_packet_master.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') 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) { -- cgit v1.2.3 From 08a82617c53718055d97df4fa60f3e5051d65383 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 9 Sep 2014 09:09:22 -0700 Subject: altos/easymega: Set USB PID for EasyMega to 0x0028 It was using 0x0023, which is for TeleMega. 0x0028 is what's listed in usbvidpid.h. Signed-off-by: Keith Packard --- src/easymega-v1.0/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/easymega-v1.0/Makefile b/src/easymega-v1.0/Makefile index 708ce1c6..c3b360b4 100644 --- a/src/easymega-v1.0/Makefile +++ b/src/easymega-v1.0/Makefile @@ -109,7 +109,7 @@ ALTOS_SRC = \ 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 -- cgit v1.2.3