diff options
author | Bdale Garbee <bdale@gag.com> | 2014-06-24 21:17:53 -0600 |
---|---|---|
committer | Bdale Garbee <bdale@gag.com> | 2014-06-24 21:17:53 -0600 |
commit | bd440afc2a6e37b74fffcf1b977e149485095316 (patch) | |
tree | 3e42f1102d68d49dae3061b9592e23907e245f23 /src | |
parent | 5d4f912bcc6784f975c82f7b0ed8dc360e60aae8 (diff) | |
parent | a0ccab8e4235934538a03f8be3b37aa1bbd6b144 (diff) |
Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
Diffstat (limited to 'src')
-rw-r--r-- | src/drivers/ao_aprs.c | 102 | ||||
-rw-r--r-- | src/kernel/ao_config.c | 34 | ||||
-rw-r--r-- | src/kernel/ao_config.h | 5 | ||||
-rw-r--r-- | src/kernel/ao_pyro.c | 28 | ||||
-rw-r--r-- | src/micropeak/Makefile | 41 | ||||
-rw-r--r-- | src/micropeak/micropeak-load.tmpl | 20 | ||||
-rw-r--r-- | src/test/ao_aprs_test.c | 24 | ||||
-rw-r--r-- | src/test/ao_flight_test.c | 2 |
8 files changed, 168 insertions, 88 deletions
diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c index 8a1b6a4d..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 <ao.h> + +#if !HAS_APRS +#error HAS_APRS not set +#endif #endif #include <ao_aprs.h> @@ -176,11 +180,11 @@ static uint16_t sysCRC16(const uint8_t *buffer, uint8_t length, uint16_t crc) { uint8_t i, bit, value; - for (i = 0; i < length; ++i) + for (i = 0; i < length; ++i) { value = buffer[i]; - for (bit = 0; bit < 8; ++bit) + for (bit = 0; bit < 8; ++bit) { crc ^= (value & 0x01); crc = ( crc & 0x01 ) ? ( crc >> 1 ) ^ 0x8408 : ( crc >> 1 ); @@ -253,7 +257,7 @@ typedef enum /// AX.25 compliant packet header that contains destination, station call sign, and path. /// 0x76 for SSID-11, 0x78 for SSID-12 -static uint8_t TNC_AX25_HEADER[] = { +static uint8_t TNC_AX25_HEADER[] = { 'A' << 1, 'P' << 1, 'A' << 1, 'M' << 1, ' ' << 1, ' ' << 1, 0x60, 'N' << 1, '0' << 1, 'C' << 1, 'A' << 1, 'L' << 1, 'L' << 1, 0x78, 'W' << 1, 'I' << 1, 'D' << 1, 'E' << 1, '2' << 1, ' ' << 1, 0x65, @@ -261,6 +265,7 @@ static uint8_t TNC_AX25_HEADER[] = { #define TNC_CALLSIGN_OFF 7 #define TNC_CALLSIGN_LEN 6 +#define TNC_SSID_OFF 13 static void tncSetCallsign(void) @@ -275,6 +280,9 @@ tncSetCallsign(void) } for (; i < TNC_CALLSIGN_LEN; i++) TNC_AX25_HEADER[TNC_CALLSIGN_OFF + i] = ' ' << 1; + + /* Fill in the SSID with the low digit of the serial number */ + TNC_AX25_HEADER[TNC_SSID_OFF] = 0x60 | ((ao_config.aprs_ssid & 0xf) << 1); #endif } @@ -302,7 +310,7 @@ static uint8_t tncBitStuff; /// Buffer to hold the message portion of the AX.25 packet as we prepare it. static uint8_t tncBuffer[TNC_BUFFER_SIZE]; -/** +/** * Initialize the TNC internal variables. */ static void tncInit() @@ -323,7 +331,7 @@ static void tnc1200TimerTick() else timeNCOFreq = 0x3aab; - switch (tncMode) + switch (tncMode) { case TNC_TX_READY: // Generate a test signal alteranting between high and low tones. @@ -339,16 +347,16 @@ static void tnc1200TimerTick() else tncTxBit = 0; } - + // When the flag is done, determine if we need to send more or data. - if (++tncBitCount == 8) + if (++tncBitCount == 8) { tncBitCount = 0; tncShift = 0x7e; // Once we transmit x mS of flags, send the data. // txDelay bytes * 8 bits/byte * 833uS/bit = x mS - if (++tncIndex == TNC_TX_DELAY) + if (++tncIndex == TNC_TX_DELAY) { tncIndex = 0; tncShift = TNC_AX25_HEADER[0]; @@ -361,7 +369,7 @@ static void tnc1200TimerTick() case TNC_TX_HEADER: // Determine if we have sent 5 ones in a row, if we have send a zero. - if (tncBitStuff == 0x1f) + if (tncBitStuff == 0x1f) { if (tncTxBit == 0) tncTxBit = 1; @@ -381,17 +389,17 @@ static void tnc1200TimerTick() tncTxBit = 0; } - // Save the data stream so we can determine if bit stuffing is + // Save the data stream so we can determine if bit stuffing is // required on the next bit time. tncBitStuff = ((tncBitStuff << 1) | (tncShift & 0x01)) & 0x1f; // If all the bits were shifted, get the next byte. - if (++tncBitCount == 8) + if (++tncBitCount == 8) { tncBitCount = 0; // After the header is sent, then send the data. - if (++tncIndex == sizeof(TNC_AX25_HEADER)) + if (++tncIndex == sizeof(TNC_AX25_HEADER)) { tncIndex = 0; tncShift = tncBuffer[0]; @@ -406,7 +414,7 @@ static void tnc1200TimerTick() case TNC_TX_DATA: // Determine if we have sent 5 ones in a row, if we have send a zero. - if (tncBitStuff == 0x1f) + if (tncBitStuff == 0x1f) { if (tncTxBit == 0) tncTxBit = 1; @@ -426,17 +434,17 @@ static void tnc1200TimerTick() tncTxBit = 0; } - // Save the data stream so we can determine if bit stuffing is + // Save the data stream so we can determine if bit stuffing is // required on the next bit time. tncBitStuff = ((tncBitStuff << 1) | (tncShift & 0x01)) & 0x1f; // If all the bits were shifted, get the next byte. - if (++tncBitCount == 8) + if (++tncBitCount == 8) { tncBitCount = 0; // If everything was sent, transmit closing flags. - if (++tncIndex == tncLength) + if (++tncIndex == tncLength) { tncIndex = 0; tncShift = 0x7e; @@ -451,7 +459,7 @@ static void tnc1200TimerTick() case TNC_TX_END: // The variable tncShift contains the lastest data byte. - // NRZI enocde the data stream. + // NRZI enocde the data stream. if ((tncShift & 0x01) == 0x00) { if (tncTxBit == 0) tncTxBit = 1; @@ -460,13 +468,13 @@ static void tnc1200TimerTick() } // If all the bits were shifted, get the next one. - if (++tncBitCount == 8) + if (++tncBitCount == 8) { tncBitCount = 0; tncShift = 0x7e; - + // Transmit two closing flags. - if (++tncIndex == 2) + if (++tncIndex == 2) { tncMode = TNC_TX_READY; @@ -530,6 +538,7 @@ static int tncComment(uint8_t *buf) #ifdef AO_SENSE_MAIN " M%d.%d" #endif + " %d" , ao_gps_locked(), ao_num_sats(), battery/10, @@ -542,6 +551,7 @@ static int tncComment(uint8_t *buf) , main/10, main%10 #endif + , ao_serial_number ); #else return sprintf((char *) buf, @@ -759,7 +769,7 @@ tncFill(uint8_t *buf, int16_t len) return l; } -/** +/** * Prepare an AX.25 data packet. Each time this method is called, it automatically * rotates through 1 of 3 messages. * diff --git a/src/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 @@ -192,6 +193,10 @@ _ao_config_get(void) if (minor < 18) ao_config.pyro_time = AO_CONFIG_DEFAULT_PYRO_TIME; #endif +#if HAS_APRS + if (minor < 19) + ao_config.aprs_ssid = AO_CONFIG_DEFAULT_APRS_SSID; +#endif 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; @@ -817,6 +847,10 @@ __code struct ao_config_var ao_config_vars[] = { { "t <motion> <interval>\0Tracker configuration", ao_config_tracker_set, ao_config_tracker_show }, #endif +#if HAS_APRS + { "S <ssid>\0Set APRS SSID (0-15)", + ao_config_aprs_ssid_set, ao_config_aprs_ssid_show }, +#endif { "s\0Show", ao_config_show, 0 }, #if HAS_EEPROM diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h index 2b5cd352..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 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: diff --git a/src/micropeak/Makefile b/src/micropeak/Makefile index 6ae3d0be..ac00f635 100644 --- a/src/micropeak/Makefile +++ b/src/micropeak/Makefile @@ -8,8 +8,15 @@ vpath make-altitude-pa ../util include ../avr/Makefile.defs +PROGNAME=micropeak-v0.1 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SCRIPT=micropeak-load + PUBLISH_DIR=$(HOME)/altusmetrumllc/Binaries -PUBLISH_FILE=$(PUBLISH_DIR)/$(PROG)-$(VERSION).hex +PUBLISH_HEX=$(PUBLISH_DIR)/$(HEX) +PUBLISH_SCRIPT=$(PUBLISH_DIR)/$(SCRIPT) MCU=attiny85 DUDECPUTYPE=t85 @@ -55,8 +62,6 @@ CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTIN NICKLE=nickle -PROG=micropeak-v0.1 - SRC=$(ALTOS_SRC) OBJ=$(SRC:.c=.o) @@ -68,7 +73,7 @@ endif # Otherwise, print the full command line. quiet ?= $($1) -all: $(PROG) $(PROG).hex +all: $(PROG) $(HEX) micropeak-load CHECK=sh ../util/check-avr-mem @@ -76,16 +81,16 @@ $(PROG): Makefile $(OBJ) $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(call quiet,CHECK) $(PROG) || ($(RM) -f $(PROG); exit 1) -$(PROG).hex: $(PROG) +$(HEX): $(PROG) avr-size $(PROG) $(OBJCOPY) -R .eeprom -O ihex $(PROG) $@ -load: $(PROG).hex - $(LOADCMD) $(LOADARG)$(PROG).hex +load: $(HEX) + $(LOADCMD) $(LOADARG)$(HEX) -load-slow: $(PROG).hex - $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PROG).hex +load-slow: $(HEX) + $(LOADCMD) $(LOADSLOW) $(LOADARG)$(HEX) ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ @@ -98,22 +103,30 @@ ao_product.o: ao_product.c ao_product.h distclean: clean clean: - rm -f *.o $(PROG) $(PROG).hex + rm -f *.o $(PROG) $(HEX) $(SCRIPT) rm -f ao_product.h +publish: $(PUBLISH_HEX) $(PUBLISH_SCRIPT) -publish: $(PROG).hex - cp -a $(PROG).hex $(PUBLISH_FILE) +$(PUBLISH_HEX): $(HEX) + cp -a $(HEX) $@ + +$(PUBLISH_SCRIPT): $(SCRIPT) + cp -a $(SCRIPT) $@ load-product: - $(LOADCMD) $(LOADARG)$(PUBLISH_FILE) + ./$(SCRIPT) fast load-product-slow: - $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PUBLISH_FILE) + ./$(SCRIPT) slow ../altitude-pa.h: make-altitude-pa nickle $< > $@ +$(SCRIPT): $(SCRIPT).tmpl Makefile ../Version + sed -e 's/%HEX%/$(HEX)/' -e 's/%LOADCMD%/$(LOADCMD)/' -e 's/%LOADARG%/$(LOADARG)/' -e 's/%LOADSLOW%/$(LOADSLOW)/' $(SCRIPT).tmpl > $@ || (rm $@ && exit 1) + chmod +x $@ + install: uninstall: diff --git a/src/micropeak/micropeak-load.tmpl b/src/micropeak/micropeak-load.tmpl new file mode 100644 index 00000000..08236a15 --- /dev/null +++ b/src/micropeak/micropeak-load.tmpl @@ -0,0 +1,20 @@ +#!/bin/sh +dir=`dirname $0` + +HEX="$dir"/"%HEX%" +LOADCMD="%LOADCMD%" +LOADARG="%LOADARG%" +LOADSLOW="%LOADSLOW%" +LOADFAST="" + +case "$1" in +fast) + LOADSPEED="$LOADFAST" + ;; +*) + LOADSPEED="$LOADSLOW" + ;; +esac + +echo ${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX} +${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX} diff --git a/src/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 <math.h> - -int -ao_aprs_encode_altitude_expensive(int meters) -{ - double feet = meters / 0.3048; - - double encode = log(feet) / log(1.002); - return floor(encode + 0.5); -} - // This is where we go after reset. int main(int argc, char **argv) { int e, x; int a; - for (a = 1; a < 100000; a++) { - e = ao_aprs_encode_altitude(a); - x = ao_aprs_encode_altitude_expensive(a); - - if (e != x) { - double back_feet, back_meters; - back_feet = pow(1.002, e); - back_meters = back_feet * 0.3048; - fprintf (stderr, "APRS altitude encoding failure: altitude %d actual %d expected %d actual meters %f\n", - a, e, x, back_meters); - } - } - audio_gap(1); ao_gps_data.latitude = (45.0 + 28.25 / 60.0) * 10000000; 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; } } |