diff options
| -rw-r--r-- | Makefile.am | 2 | ||||
| -rw-r--r-- | altosui/Makefile.am | 36 | ||||
| -rw-r--r-- | configure.ac | 3 | ||||
| -rw-r--r-- | icon/micropeak-128.png | bin | 0 -> 4394 bytes | |||
| -rw-r--r-- | icon/micropeak-16.png | bin | 0 -> 534 bytes | |||
| -rw-r--r-- | icon/micropeak-256.png | bin | 0 -> 8055 bytes | |||
| -rw-r--r-- | icon/micropeak-32.png | bin | 0 -> 1072 bytes | |||
| -rw-r--r-- | icon/micropeak-48.png | bin | 0 -> 1662 bytes | |||
| -rw-r--r-- | icon/micropeak-64.png | bin | 0 -> 2240 bytes | |||
| -rw-r--r-- | libaltos/.gitignore (renamed from altosui/libaltos/.gitignore) | 0 | ||||
| -rw-r--r-- | libaltos/Makefile-standalone (renamed from altosui/libaltos/Makefile-standalone) | 0 | ||||
| -rw-r--r-- | libaltos/Makefile.am (renamed from altosui/libaltos/Makefile.am) | 0 | ||||
| -rw-r--r-- | libaltos/cjnitest.c (renamed from altosui/libaltos/cjnitest.c) | 0 | ||||
| -rw-r--r-- | libaltos/libaltos.c (renamed from altosui/libaltos/libaltos.c) | 53 | ||||
| -rwxr-xr-x | libaltos/libaltos.dylib (renamed from altosui/libaltos/libaltos.dylib) | bin | 41648 -> 41648 bytes | |||
| -rw-r--r-- | libaltos/libaltos.h (renamed from altosui/libaltos/libaltos.h) | 0 | ||||
| -rw-r--r-- | libaltos/libaltos.i0 (renamed from altosui/libaltos/libaltos.i0) | 0 | ||||
| -rw-r--r-- | micropeak/Makefile.am | 140 | ||||
| -rw-r--r-- | micropeak/MicroData.java | 270 | ||||
| -rw-r--r-- | micropeak/MicroFileChooser.java | 65 | ||||
| -rw-r--r-- | micropeak/MicroFontListener.java | 22 | ||||
| -rw-r--r-- | micropeak/MicroFrame.java | 74 | ||||
| -rw-r--r-- | micropeak/MicroGraph.java | 110 | ||||
| -rw-r--r-- | micropeak/MicroPeak.java | 147 | ||||
| -rw-r--r-- | micropeak/MicroPreferences.java | 221 | ||||
| -rw-r--r-- | micropeak/MicroPreferencesBackend.java | 101 | ||||
| -rw-r--r-- | micropeak/MicroSerial.java | 49 | ||||
| -rw-r--r-- | micropeak/MicroUIListener.java | 22 | ||||
| -rw-r--r-- | micropeak/MicroUSB.java | 103 | ||||
| -rw-r--r-- | src/micropeak/Makefile | 14 | ||||
| -rw-r--r-- | src/micropeak/ao_async.c | 43 | ||||
| -rw-r--r-- | src/micropeak/ao_async.h | 6 | ||||
| -rw-r--r-- | src/micropeak/ao_log_micro.c | 116 | ||||
| -rw-r--r-- | src/micropeak/ao_log_micro.h | 19 | ||||
| -rw-r--r-- | src/micropeak/ao_micropeak.c | 134 | ||||
| -rw-r--r-- | src/micropeak/ao_micropeak.h | 56 | 
36 files changed, 1600 insertions, 206 deletions
| diff --git a/Makefile.am b/Makefile.am index aaa0ae14..2e45aff0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS=src doc altoslib altosui ao-tools ao-utils altosdroid +SUBDIRS=src doc altoslib libaltos altosui ao-tools ao-utils altosdroid  EXTRA_DIST = ChangeLog diff --git a/altosui/Makefile.am b/altosui/Makefile.am index 306a396e..a42426cd 100644 --- a/altosui/Makefile.am +++ b/altosui/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS=libaltos +  JAVAROOT=classes  AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation @@ -6,7 +6,7 @@ man_MANS=altosui.1  altoslibdir=$(libdir)/altos -CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH=".:classes:../altoslib/*:libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar:$(FREETTS)/freetts.jar" +CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH=".:classes:../altoslib/*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar:$(FREETTS)/freetts.jar"  bin_SCRIPTS=altosui @@ -233,13 +233,13 @@ $(JAR): classaltosui.stamp Manifest.txt $(JAVA_ICONS) $(ALTOSLIB_CLASS)  	jar cfm $@ Manifest.txt \  		$(ICONJAR) \  		-C classes altosui \ -		-C libaltos libaltosJNI +		-C ../libaltos libaltosJNI  $(FATJAR): classaltosui.stamp Manifest-fat.txt $(ALTOSLIB_CLASS) $(FREETTS_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) $(JAVA_ICONS)  	jar cfm $@ Manifest-fat.txt \  		$(ICONJAR) \  		-C classes altosui \ -		-C libaltos libaltosJNI +		-C ../libaltos libaltosJNI  Manifest.txt: Makefile  	echo 'Main-Class: altosui.AltosUI' > $@ @@ -256,43 +256,43 @@ altosui: Makefile  altosui-test: Makefile  	echo "#!/bin/sh" > $@ -	echo 'exec java -cp "./*:$(FREETTS)/freetts.jar:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="libaltos/.libs" -jar altosui.jar "$$@"' >> $@ +	echo 'exec java -cp "./*:../libaltos:$(FREETTS)/freetts.jar:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="../libaltos/.libs" -jar altosui.jar "$$@"' >> $@  	chmod +x $@  altosui-jdb: Makefile  	echo "#!/bin/sh" > $@ -	echo 'exec jdb -classpath "classes:libaltos:$(FREETTS)/freetts.jar:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="libaltos/.libs" altosui/AltosUI "$$@"' >> $@ +	echo 'exec jdb -classpath "classes:../libaltos:$(FREETTS)/freetts.jar:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="../libaltos/.libs" altosui/AltosUI "$$@"' >> $@  	chmod +x $@  libaltos.so: build-libaltos  	-rm -f "$@" -	$(LN_S) libaltos/.libs/"$@" . +	$(LN_S) ../libaltos/.libs/"$@" .  libaltos.dylib:  	-rm -f "$@" -	$(LN_S) libaltos/"$@" . +	$(LN_S) ../libaltos/"$@" . -altos.dll: libaltos/altos.dll +altos.dll: ../libaltos/altos.dll  	-rm -f "$@" -	$(LN_S) libaltos/"$@" . +	$(LN_S) ../libaltos/"$@" . -altos64.dll: libaltos/altos64.dll +altos64.dll: ../libaltos/altos64.dll  	-rm -f "$@" -	$(LN_S) libaltos/"$@" . +	$(LN_S) ../libaltos/"$@" . -libaltos/.libs/libaltos.so: build-libaltos +../libaltos/.libs/libaltos.so: build-libaltos -libaltos/altos.dll: build-altos-dll +../libaltos/altos.dll: build-altos-dll -libaltos/altos64.dll: build-altos64-dll +../libaltos/altos64.dll: build-altos64-dll  build-libaltos: -	+cd libaltos && make libaltos.la +	+cd ../libaltos && make libaltos.la  build-altos-dll: -	+cd libaltos && make altos.dll +	+cd ../libaltos && make altos.dll  build-altos64-dll: -	+cd libaltos && make altos64.dll +	+cd ../libaltos && make altos64.dll  $(ALTOSLIB_CLASS):  	-rm -f "$@" diff --git a/configure.ac b/configure.ac index 0fcd97e2..55dd20ec 100644 --- a/configure.ac +++ b/configure.ac @@ -149,7 +149,8 @@ altoslib/Makefile  altosui/Makefile  altosui/AltosVersion.java  altosui/Info.plist -altosui/libaltos/Makefile +libaltos/Makefile +micropeak/Makefile  altosdroid/Makefile  altosdroid/local.properties  ao-tools/Makefile diff --git a/icon/micropeak-128.png b/icon/micropeak-128.pngBinary files differ new file mode 100644 index 00000000..f045dc6a --- /dev/null +++ b/icon/micropeak-128.png diff --git a/icon/micropeak-16.png b/icon/micropeak-16.pngBinary files differ new file mode 100644 index 00000000..d8140802 --- /dev/null +++ b/icon/micropeak-16.png diff --git a/icon/micropeak-256.png b/icon/micropeak-256.pngBinary files differ new file mode 100644 index 00000000..b96d4706 --- /dev/null +++ b/icon/micropeak-256.png diff --git a/icon/micropeak-32.png b/icon/micropeak-32.pngBinary files differ new file mode 100644 index 00000000..d34c5c12 --- /dev/null +++ b/icon/micropeak-32.png diff --git a/icon/micropeak-48.png b/icon/micropeak-48.pngBinary files differ new file mode 100644 index 00000000..86dc4f7f --- /dev/null +++ b/icon/micropeak-48.png diff --git a/icon/micropeak-64.png b/icon/micropeak-64.pngBinary files differ new file mode 100644 index 00000000..6ca7c2eb --- /dev/null +++ b/icon/micropeak-64.png diff --git a/altosui/libaltos/.gitignore b/libaltos/.gitignore index c490e6f8..c490e6f8 100644 --- a/altosui/libaltos/.gitignore +++ b/libaltos/.gitignore diff --git a/altosui/libaltos/Makefile-standalone b/libaltos/Makefile-standalone index 4e438050..4e438050 100644 --- a/altosui/libaltos/Makefile-standalone +++ b/libaltos/Makefile-standalone diff --git a/altosui/libaltos/Makefile.am b/libaltos/Makefile.am index b5ab1ddb..b5ab1ddb 100644 --- a/altosui/libaltos/Makefile.am +++ b/libaltos/Makefile.am diff --git a/altosui/libaltos/cjnitest.c b/libaltos/cjnitest.c index f0fe78f7..f0fe78f7 100644 --- a/altosui/libaltos/cjnitest.c +++ b/libaltos/cjnitest.c diff --git a/altosui/libaltos/libaltos.c b/libaltos/libaltos.c index ab6ca878..d7b266cf 100644 --- a/altosui/libaltos/libaltos.c +++ b/libaltos/libaltos.c @@ -20,16 +20,6 @@  #include <stdlib.h>  #include <string.h> -#define USB_VENDOR_FSF			0xfffe -#define USB_VENDOR_ALTUSMETRUM		USB_VENDOR_FSF -#define USB_PRODUCT_ALTUSMETRUM		0x000a -#define USB_PRODUCT_ALTUSMETRUM_MIN	0x000a -#define USB_PRODUCT_ALTUSMETRUM_MAX	0x00ff - -#define USB_IS_ALTUSMETRUM(v,p)	((v) == USB_VENDOR_ALTUSMETRUM && \ -		(USB_PRODUCT_ALTUSMETRUM_MIN <= (p) && \ -		 (p) <= USB_PRODUCT_ALTUSMETRUM_MAX)) -  #define BLUETOOTH_PRODUCT_TELEBT	"TeleBT"  #define USE_POLL @@ -473,6 +463,7 @@ usb_tty(char *sys)  				base, config, interface);  			endpoint_full = cc_fullname(sys, endpoint_base); +  			/* Check for tty:ttyACMx style names  			 */  			ntty = scandir(endpoint_full, &namelist, @@ -485,6 +476,18 @@ usb_tty(char *sys)  				return tty;  			} +			/* Check for ttyACMx style names +			 */ +			ntty = scandir(endpoint_full, &namelist, +				       dir_filter_tty, +				       alphasort); +			if (ntty > 0) { +				free(endpoint_full); +				tty = cc_fullname("/dev", namelist[0]->d_name); +				free(namelist); +				return tty; +			} +  			/* Check for tty/ttyACMx style names  			 */  			tty_dir = cc_fullname(endpoint_full, "tty"); @@ -498,6 +501,7 @@ usb_tty(char *sys)  				free(namelist);  				return tty;  			} +  		}  	}  	return NULL; @@ -507,7 +511,11 @@ static struct altos_usbdev *  usb_scan_device(char *sys)  {  	struct altos_usbdev *usbdev; +	char *tty; +	tty = usb_tty(sys); +	if (!tty) +		return NULL;  	usbdev = calloc(1, sizeof (struct altos_usbdev));  	if (!usbdev)  		return NULL; @@ -517,7 +525,7 @@ usb_scan_device(char *sys)  	usbdev->serial = load_dec(sys, "serial");  	usbdev->idProduct = load_hex(sys, "idProduct");  	usbdev->idVendor = load_hex(sys, "idVendor"); -	usbdev->tty = usb_tty(sys); +	usbdev->tty = tty;  	return usbdev;  } @@ -581,15 +589,15 @@ altos_list_start(void)  	for (e = 0; e < n; e++) {  		dir = cc_fullname(USB_DEVICES, ents[e]->d_name);  		dev = usb_scan_device(dir); +		if (!dev) +			continue;  		free(dir); -		if (USB_IS_ALTUSMETRUM(dev->idVendor, dev->idProduct)) { -			if (devs->dev) -				devs->dev = realloc(devs->dev, -						    (devs->ndev + 1) * sizeof (struct usbdev *)); -			else -				devs->dev = malloc (sizeof (struct usbdev *)); -			devs->dev[devs->ndev++] = dev; -		} +		if (devs->dev) +			devs->dev = realloc(devs->dev, +					    (devs->ndev + 1) * sizeof (struct usbdev *)); +		else +			devs->dev = malloc (sizeof (struct usbdev *)); +		devs->dev[devs->ndev++] = dev;  	}  	free(ents);  	devs->current = 0; @@ -600,8 +608,9 @@ int  altos_list_next(struct altos_list *list, struct altos_device *device)  {  	struct altos_usbdev *dev; -	if (list->current >= list->ndev) +	if (list->current >= list->ndev) {  		return 0; +	}  	dev = list->dev[list->current];  	strcpy(device->name, dev->product_name);  	device->vendor = dev->idVendor; @@ -1026,10 +1035,6 @@ altos_list_next(struct altos_list *list, struct altos_device *device)  		       "%04X", &pid);  		sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1,  		       "%d", &serial); -		if (!USB_IS_ALTUSMETRUM(vid, pid)) { -			RegCloseKey(dev_key); -			continue; -		}  		/* Fetch the com port name */  		port_len = sizeof (port); diff --git a/altosui/libaltos/libaltos.dylib b/libaltos/libaltos.dylibBinary files differ index 1038817d..1038817d 100755 --- a/altosui/libaltos/libaltos.dylib +++ b/libaltos/libaltos.dylib diff --git a/altosui/libaltos/libaltos.h b/libaltos/libaltos.h index f90fbb87..f90fbb87 100644 --- a/altosui/libaltos/libaltos.h +++ b/libaltos/libaltos.h diff --git a/altosui/libaltos/libaltos.i0 b/libaltos/libaltos.i0 index d06468f5..d06468f5 100644 --- a/altosui/libaltos/libaltos.i0 +++ b/libaltos/libaltos.i0 diff --git a/micropeak/Makefile.am b/micropeak/Makefile.am new file mode 100644 index 00000000..2cfd2ad3 --- /dev/null +++ b/micropeak/Makefile.am @@ -0,0 +1,140 @@ +JAVAROOT=classes +AM_JAVACFLAGS=-encoding UTF-8 -Xlint:deprecation + +CLASSPATH_ENV=mkdir -p $(JAVAROOT); CLASSPATH=".:classes:../altoslib/*:../libaltos:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" + +bin_SCRIPTS=micropeak + +micropeakdir=$(datadir)/java + +micropeak_JAVA= \ +	MicroPeak.java \ +	MicroData.java \ +	MicroFrame.java \ +	MicroGraph.java \ +	MicroSerial.java \ +	MicroFileChooser.java \ +	MicroPreferences.java \ +	MicroPreferencesBackend.java \ +	MicroFontListener.java \ +	MicroUIListener.java \ +	MicroUSB.java + +JFREECHART_CLASS= \ +    jfreechart.jar + +JCOMMON_CLASS=\ +    jcommon.jar + +JAR=micropeak.jar + +FATJAR=micropeak-fat.jar + +LIBALTOS= \ +	libaltos.so \ +	libaltos.dylib \ +	altos.dll + +ALTOSLIB_CLASS=\ +	AltosLib.jar + +# Icons +ICONDIR=$(top_srcdir)/icon + +JAVA_ICONS=\ +	$(ICONDIR)/micropeak-16.png \ +	$(ICONDIR)/micropeak-32.png \ +	$(ICONDIR)/micropeak-48.png \ +	$(ICONDIR)/micropeak-64.png \ +	$(ICONDIR)/micropeak-128.png \ +	$(ICONDIR)/micropeak-256.png + +# icon base names for jar +ICONJAR= -C $(ICONDIR) micropeak-16.png \ +	-C $(ICONDIR) micropeak-32.png \ +	-C $(ICONDIR) micropeak-48.png \ +	-C $(ICONDIR) micropeak-64.png \ +	-C $(ICONDIR) micropeak-128.png \ +	-C $(ICONDIR) micropeak-256.png + +all-local: micropeak-test $(JAR) + +clean-local: +	-rm -rf classes $(JAR) $(FATJAR) \ +		$(ALTOSLIB_CLASS) \ +		$(JFREECHART_CLASS) $(JCOMMON_CLASS) $(LIBALTOS) Manifest.txt \ +		micropeak micropeak-test macosx linux windows + +micropeak: Makefile +	echo "#!/bin/sh" > $@ +	echo 'exec java  -cp "$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="$(altoslibdir)" -jar "$(micropeakdir)/micropeak.jar" "$$@"' >> $@ +	chmod +x $@ + +micropeak-test: Makefile +	echo "#!/bin/sh" > $@ +	echo 'exec java -cp "./*:../libaltos/*:$(JCOMMON)/jcommon.jar:$(JFREECHART)/jfreechart.jar" -Djava.library.path="../libaltos/.libs" -jar micropeak.jar "$$@"' >> $@ +	chmod +x $@ + +$(JAR): classmicropeak.stamp Manifest.txt $(JAVA_ICONS) $(ALTOSLIB_CLASS) +	jar cfm $@ Manifest.txt \ +		$(ICONJAR) \ +		-C classes org \ +		-C ../libaltos libaltosJNI + +$(FATJAR): classmicropeak.stamp Manifest-fat.txt $(ALTOSLIB_CLASS) $(JFREECHART_CLASS) $(JCOMMON_CLASS) $(JAVA_ICONS) +	jar cfm $@ Manifest-fat.txt \ +		$(ICONJAR) \ +		-C classes org \ +		-C ../libaltos libaltosJNI + + +libaltos.so: build-libaltos +	-rm -f "$@" +	$(LN_S) ../libaltos/.libs/"$@" . + +libaltos.dylib: +	-rm -f "$@" +	$(LN_S) ../libaltos/"$@" . + +altos.dll: ../libaltos/altos.dll +	-rm -f "$@" +	$(LN_S) ../libaltos/"$@" . + +altos64.dll: ../libaltos/altos64.dll +	-rm -f "$@" +	$(LN_S) ../libaltos/"$@" . + +../libaltos/.libs/libaltos.so: build-libaltos + +../libaltos/altos.dll: build-altos-dll + +../libaltos/altos64.dll: build-altos64-dll + +build-libaltos: +	+cd ../libaltos && make libaltos.la +build-altos-dll: +	+cd ../libaltos && make altos.dll + +build-altos64-dll: +	+cd ../libaltos && make altos64.dll + +$(ALTOSLIB_CLASS): +	-rm -f "$@" +	$(LN_S) ../altoslib/"$@" . + +$(JFREECHART_CLASS): +	-rm -f "$@" +	$(LN_S) "$(JFREECHART)"/"$@" . + +$(JCOMMON_CLASS): +	-rm -f "$@" +	$(LN_S) "$(JCOMMON)"/"$@" . + +Manifest.txt: Makefile +	echo 'Main-Class: org.altusmetrum.micropeak.MicroPeak' > $@ +	echo "Class-Path: AltosLib.jar $(JCOMMON)/jcommon.jar $(JFREECHART)/jfreechart.jar" >> $@ + +Manifest-fat.txt: +	echo 'Main-Class: org.altusmetrum.micropeak.MicroPeak' > $@ +	echo "Class-Path: AltosLib.jar jcommon.jar jfreechart.jar" >> $@ + diff --git a/micropeak/MicroData.java b/micropeak/MicroData.java new file mode 100644 index 00000000..783ae40f --- /dev/null +++ b/micropeak/MicroData.java @@ -0,0 +1,270 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; + +import java.lang.*; +import java.io.*; +import java.util.*; +import org.altusmetrum.AltosLib.*; + +public class MicroData { +	public int		ground_pressure; +	public int		min_pressure; +	public int[]		pressures; +	private double		time_step; +	private double		ground_altitude; +	private ArrayList<Integer>	bytes; +	 + +	class FileEndedException extends Exception { +	} + +	class NonHexcharException extends Exception { +	} + +	class InvalidCrcException extends Exception { +	} + +	private int getc(InputStream f) throws IOException, FileEndedException { +		int	c = f.read(); + +		if (c == -1) +			throw new FileEndedException(); +		bytes.add(c); +		return c; +	} + +	private int get_nonwhite(InputStream f) throws IOException, FileEndedException { +		int	c; + +		for (;;) { +			c = getc(f); +			if (!Character.isWhitespace(c)) +				return c; +		} +	} + +	private int get_hexc(InputStream f) throws IOException, FileEndedException, NonHexcharException { +		int	c = get_nonwhite(f); + +		if ('0' <= c && c <= '9') +			return c - '0'; +		if ('a' <= c && c <= 'f') +			return c - 'a' + 10; +		if ('A' <= c && c <= 'F') +			return c - 'A' + 10; +		throw new NonHexcharException(); +	} + +	private static final int POLY = 0x8408; + +	private int log_crc(int crc, int b) { +		int	i; + +		for (i = 0; i < 8; i++) { +			if (((crc & 0x0001) ^ (b & 0x0001)) != 0) +				crc = (crc >> 1) ^ POLY; +			else +				crc = crc >> 1; +			b >>= 1; +		} +		return crc & 0xffff; +	} + +	int	file_crc; + +	private int get_hex(InputStream f) throws IOException, FileEndedException, NonHexcharException { +		int	a = get_hexc(f); +		int	b = get_hexc(f); + +		int h = (a << 4) + b; + +		file_crc = log_crc(file_crc, h); +		return h; +	} + +	private boolean find_header(InputStream f) throws IOException { +		try { +			for (;;) { +				if (get_nonwhite(f) == 'M' && get_nonwhite(f) == 'P') +					return true; +			} +		} catch (FileEndedException fe) { +			return false; +		} +	}  + +	private int get_32(InputStream f)  throws IOException, FileEndedException, NonHexcharException { +		int	v = 0; +		for (int i = 0; i < 4; i++) { +			v += get_hex(f) << (i * 8); +		} +		return v; +	} + +	private int get_16(InputStream f) throws IOException, FileEndedException, NonHexcharException { +		int	v = 0; +		for (int i = 0; i < 2; i++) { +			v += get_hex(f) << (i * 8); +		} +		return v; +	} + +	private int swap16(int i) { +		return ((i << 8) & 0xff00) | ((i >> 8) & 0xff); +	} + +	public boolean	crc_valid; + +	int mix_in (int high, int low) { +		return  high - (high & 0xffff) + low; +	} + +	boolean closer (int target, int a, int b) { +		return Math.abs (target - a) < Math.abs(target - b); +	} + +	public double altitude(int i) { +		return AltosConvert.pressure_to_altitude(pressures[i]); +	} + +	int fact(int n) { +		if (n == 0) +			return 1; +		return n * fact(n-1); +	} + +	int choose(int n, int k) { +		return fact(n) / (fact(k) * fact(n-k)); +	} + + +	public double avg_altitude(int center, int dist) { +		int	start = center - dist; +		int	stop = center + dist; + +		if (start < 0) +			start = 0; +		if (stop >= pressures.length) +			stop = pressures.length - 1; + +		double	sum = 0; +		double	div = 0; + +		int	n = dist * 2; + +		for (int i = start; i <= stop; i++) { +			int	k = i - (center - dist); +			int	c = choose (n, k); + +			sum += c * pressures[i]; +			div += c; +		} + +		double pres = sum / div; + +		double alt = AltosConvert.pressure_to_altitude(pres); +		return alt; +	} + +	public double height(int i) { +		return altitude(i) - ground_altitude; +	} + +	static final int speed_avg = 3; +	static final int accel_avg = 5; + +	private double avg_speed(int center, int dist) { +		if (center == 0) +			return 0; + +		double ai = avg_altitude(center, dist); +		double aj = avg_altitude(center - 1, dist); +		double s = (ai - aj) / time_step; + +		return s; +	} + +	public double speed(int i) { +		return avg_speed(i, speed_avg); +	} + +	public double acceleration(int i) { +		if (i == 0) +			return 0; +		return (avg_speed(i, accel_avg) - avg_speed(i-1, accel_avg)) / time_step; +	} + +	public double time(int i) { +		return i * time_step; +	} + +	public void save (OutputStream f) throws IOException { +		for (int c : bytes) +			f.write(c); +	} + +	public MicroData (InputStream f) throws IOException { +		bytes = new ArrayList<Integer>(); +		if (!find_header(f)) +			throw new IOException(); +		try { +			file_crc = 0xffff; +			ground_pressure = get_32(f); +			min_pressure = get_32(f); +			int nsamples = get_16(f); +			pressures = new int[nsamples + 1]; + +			ground_altitude = AltosConvert.pressure_to_altitude(ground_pressure); +			int cur = ground_pressure; +			pressures[0] = cur; +			for (int i = 0; i < nsamples; i++) { +				int	k = get_16(f); +				int	same = mix_in(cur, k); +				int	up = mix_in(cur + 0x10000, k); +				int	down = mix_in(cur - 0x10000, k); + +				if (closer (cur, same, up)) { +					if (closer (cur, same, down)) +						cur = same; +					else +						cur = down; +				} else { +					if (closer (cur, up, down)) +						cur = up; +					else +						cur = down; +				} +				 +				pressures[i+1] = cur; +			} + +			int current_crc = swap16(~file_crc & 0xffff); +			int crc = get_16(f); + +			crc_valid = crc == current_crc; + +			time_step = 0.192; +		} catch (FileEndedException fe) { +			throw new IOException(); +		} catch (NonHexcharException ne) { +			throw new IOException(); +		} +	} +	 +} diff --git a/micropeak/MicroFileChooser.java b/micropeak/MicroFileChooser.java new file mode 100644 index 00000000..0fd63a27 --- /dev/null +++ b/micropeak/MicroFileChooser.java @@ -0,0 +1,65 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; + +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.io.*; +import org.altusmetrum.AltosLib.*; + +public class MicroFileChooser extends JFileChooser { +	JFrame	frame; +	String	filename; +	File	file; + +	public String filename() { +		return filename; +	} + +	public File file() { +		return file; +	} + +	public InputStream runDialog() { +		int	ret; + +		ret = showOpenDialog(frame); +		if (ret == APPROVE_OPTION) { +			file = getSelectedFile(); +			if (file == null) +				return null; +			filename = file.getName(); +			try { +				return new FileInputStream(file); +			} catch (FileNotFoundException fe) { +				JOptionPane.showMessageDialog(frame, +							      fe.getMessage(), +							      "Cannot open file", +							      JOptionPane.ERROR_MESSAGE); +			} +		} +		return null; +	} + +	public MicroFileChooser(JFrame in_frame) { +		frame = in_frame; +		setDialogTitle("Select MicroPeak Data File"); +		setFileFilter(new FileNameExtensionFilter("MicroPeak data file", +							  "mpd")); +	} +} diff --git a/micropeak/MicroFontListener.java b/micropeak/MicroFontListener.java new file mode 100644 index 00000000..a902584c --- /dev/null +++ b/micropeak/MicroFontListener.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; + +public interface MicroFontListener { +	void font_size_changed(int font_size); +} diff --git a/micropeak/MicroFrame.java b/micropeak/MicroFrame.java new file mode 100644 index 00000000..a9b9a37a --- /dev/null +++ b/micropeak/MicroFrame.java @@ -0,0 +1,74 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.util.*; + +class MicroFrameListener extends WindowAdapter { +	public void windowClosing (WindowEvent e) { +		MicroPreferences.unregister_ui_listener((MicroFrame) e.getWindow()); +	} +} + +public class MicroFrame extends JFrame implements MicroUIListener { + +	public void ui_changed(String look_and_feel) { +		SwingUtilities.updateComponentTreeUI(this); +		this.pack(); +	} + +	static final String[] icon_names = { +		"/micropeak-16.png", +		"/micropeak-32.png", +		"/micropeak-48.png", +		"/micropeak-64.png", +		"/micropeak-128.png", +		"/micropeak-256.png" +	}; + +	public void set_icon() { +		ArrayList<Image> icons = new ArrayList<Image>(); +		 +		for (int i = 0; i < icon_names.length; i++) { +			java.net.URL imgURL = MicroPeak.class.getResource(icon_names[i]); +			if (imgURL != null) +				icons.add(new ImageIcon(imgURL).getImage()); +		} + +		setIconImages(icons); +	} +			 +	public MicroFrame() { +		super(); +		MicroPreferences.set_component(this); +		MicroPreferences.register_ui_listener(this); +		addWindowListener(new MicroFrameListener()); +		set_icon(); +	} + +	public MicroFrame(String name) { +		super(name); +		MicroPreferences.set_component(this); +		MicroPreferences.register_ui_listener(this); +		addWindowListener(new MicroFrameListener()); +		set_icon(); +	} +} diff --git a/micropeak/MicroGraph.java b/micropeak/MicroGraph.java new file mode 100644 index 00000000..9192cad9 --- /dev/null +++ b/micropeak/MicroGraph.java @@ -0,0 +1,110 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; + +import java.io.*; +import java.util.ArrayList; + +import java.awt.*; +import javax.swing.*; +import org.altusmetrum.AltosLib.*; + +import org.jfree.ui.*; +import org.jfree.chart.*; +import org.jfree.chart.plot.*; +import org.jfree.chart.axis.*; +import org.jfree.chart.renderer.*; +import org.jfree.chart.renderer.xy.*; +import org.jfree.chart.labels.*; +import org.jfree.data.xy.*; +import org.jfree.data.*; + +public class MicroGraph { + +	XYPlot		plot; +	JFreeChart	chart; +	ChartPanel	panel; +	NumberAxis	xAxis; +	XYSeries	heightSeries; +	XYSeries	speedSeries; +	XYSeries	accelSeries; + +	MicroData	data; + +	public JPanel panel() { +		return panel; +	} + +	private void addSeries(XYSeries series, int index, String label, String units) { +		XYSeriesCollection	dataset = new XYSeriesCollection(series); +		NumberAxis		axis = new NumberAxis(String.format("%s (%s)", label, units)); +		XYItemRenderer		renderer = new XYLineAndShapeRenderer(true, false); + +		renderer.setPlot(plot); +		renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})", units), +										new java.text.DecimalFormat("0.00"), +										new java.text.DecimalFormat("0.00"))); +		plot.setRangeAxis(index, axis); +		plot.setDataset(index, dataset); +		plot.setRenderer(index, renderer); +		plot.mapDatasetToRangeAxis(index, index); +	} +	 +	public void setData (MicroData data) { +		heightSeries.clear(); +		speedSeries.clear(); +		accelSeries.clear(); +		for (int i = 0; i < data.pressures.length; i++) { +			double x = data.time(i); +			heightSeries.add(x, data.height(i)); +			speedSeries.add(x, data.speed(i)); +			accelSeries.add(x, data.acceleration(i)); +		} +	} + +	public MicroGraph(MicroData data) { + +		this.data = data; + +		heightSeries = new XYSeries("Height"); +		speedSeries = new XYSeries("Speed"); +		accelSeries = new XYSeries("Acceleration"); + +		xAxis = new NumberAxis("Time (s)"); +		 +		xAxis.setAutoRangeIncludesZero(true); + +		plot = new XYPlot(); +		plot.setDomainAxis(xAxis); +		plot.setOrientation(PlotOrientation.VERTICAL); +		plot.setDomainPannable(true); +		plot.setRangePannable(true); + +		addSeries(heightSeries, 0, "Height", "m"); +		addSeries(speedSeries, 1, "Speed", "m/s"); +		addSeries(accelSeries, 2, "Acceleration", "m/s²"); + +		chart = new JFreeChart("Flight", JFreeChart.DEFAULT_TITLE_FONT, +				       plot, true); + +		ChartUtilities.applyCurrentTheme(chart); +		panel = new ChartPanel(chart); +		panel.setMouseWheelEnabled(true); +		panel.setPreferredSize(new java.awt.Dimension(800, 500)); +	} +}
\ No newline at end of file diff --git a/micropeak/MicroPeak.java b/micropeak/MicroPeak.java new file mode 100644 index 00000000..c9074348 --- /dev/null +++ b/micropeak/MicroPeak.java @@ -0,0 +1,147 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.io.*; +import java.util.concurrent.*; +import java.util.*; +import org.altusmetrum.AltosLib.*; + +public class MicroPeak extends MicroFrame implements ActionListener, ItemListener { + +	File		filename; +	MicroGraph	graph; +	MicroData	data; +	Container	pane; + +	private void RunFile(InputStream input) { +		try { +			data = new MicroData(input); +			graph.setData(data); +		} catch (IOException ioe) { +		} +		try { +			input.close(); +		} catch (IOException ioe) { +		} +	} + +	private void OpenFile(File filename) { +		try { +			RunFile (new FileInputStream(filename)); +		} catch (FileNotFoundException fne) { +		} +	} + +	private void SelectFile() { +		MicroFileChooser	chooser = new MicroFileChooser(this); +		InputStream		input = chooser.runDialog(); + +		if (input != null) +			RunFile(input); +	} + +	private void DownloadData() { +		java.util.List<MicroUSB>	devices = MicroUSB.list(); +		for (MicroUSB device : devices) +			System.out.printf("device %s\n", device.toString()); +	} + +	public void actionPerformed(ActionEvent ev) { +		System.out.printf("action %s %s\n", ev.getActionCommand(), ev.paramString()); +		if ("Exit".equals(ev.getActionCommand())) +			System.exit(0); +		else if ("Open".equals(ev.getActionCommand())) +			SelectFile(); +		else if ("New".equals(ev.getActionCommand())) +			new MicroPeak(); +		else if ("Download".equals(ev.getActionCommand())) +			DownloadData(); +	} + +	public void itemStateChanged(ItemEvent e) { +	} + +	public MicroPeak() { + +		this.filename = filename; + +		pane = getContentPane(); + +		setTitle("MicroPeak"); + +		JMenuBar menuBar = new JMenuBar(); +		setJMenuBar(menuBar); + +		JMenu fileMenu = new JMenu("File"); +		menuBar.add(fileMenu); + +		JMenuItem newAction = new JMenuItem("New"); +		fileMenu.add(newAction); +		newAction.addActionListener(this); + +		JMenuItem openAction = new JMenuItem("Open"); +		fileMenu.add(openAction); +		openAction.addActionListener(this); + +		JMenuItem downloadAction = new JMenuItem("Download"); +		fileMenu.add(downloadAction); +		downloadAction.addActionListener(this); + +		JMenuItem exitAction = new JMenuItem("Exit"); +		fileMenu.add(exitAction); +		exitAction.addActionListener(this); + +		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); +		addWindowListener(new WindowAdapter() { +			@Override +			public void windowClosing(WindowEvent e) { +				System.exit(0); +			} +		}); + +		graph = new MicroGraph(data); +		pane.add(graph.panel); +		pane.doLayout(); +		pane.validate(); +		doLayout(); +		validate(); +		Insets i = getInsets(); +		Dimension ps = pane.getPreferredSize(); +		ps.width += i.left + i.right; +		ps.height += i.top + i.bottom; +		setPreferredSize(ps); +		setSize(ps); +		setVisible(true); +	} + +	public static void main(final String[] args) { +		boolean	opened = false; + +		for (int i = 0; i < args.length; i++) { +			MicroPeak m = new MicroPeak(); +			m.OpenFile(new File(args[i])); +			opened = true; +		} +		if (!opened) +			new MicroPeak(); +	} +}
\ No newline at end of file diff --git a/micropeak/MicroPreferences.java b/micropeak/MicroPreferences.java new file mode 100644 index 00000000..70c2557c --- /dev/null +++ b/micropeak/MicroPreferences.java @@ -0,0 +1,221 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; + +import java.io.*; +import java.util.*; +import java.awt.Component; +import javax.swing.*; +import java.awt.*; +import org.altusmetrum.AltosLib.*; + +public class MicroPreferences extends AltosPreferences { + +	static final int tab_elt_pad = 5; + +	static Font label_font; +	static Font value_font; +	static Font status_font; +	static Font table_label_font; +	static Font table_value_font; + +	final static int font_size_small = 1; +	final static int font_size_medium = 2; +	final static int font_size_large = 3; + +	static void set_fonts(int size) { +		int	brief_size; +		int	table_size; +		int	status_size; + +		switch (size) { +		case font_size_small: +			brief_size = 16; +			status_size = 18; +			table_size = 11; +			break; +		default: +		case font_size_medium: +			brief_size = 22; +			status_size = 24; +			table_size = 14; +			break; +		case font_size_large: +			brief_size = 26; +			status_size = 30; +			table_size = 17; +			break; +		} +		label_font = new Font("Dialog", Font.PLAIN, brief_size); +		value_font = new Font("Monospaced", Font.PLAIN, brief_size); +		status_font = new Font("SansSerif", Font.BOLD, status_size); +		table_label_font = new Font("SansSerif", Font.PLAIN, table_size); +		table_value_font = new Font("Monospaced", Font.PLAIN, table_size); +	} + +	/* font size preferences name */ +	final static String fontSizePreference = "FONT-SIZE"; + +	/* Look&Feel preference name */ +	final static String lookAndFeelPreference = "LOOK-AND-FEEL"; + +	/* UI Component to pop dialogs up */ +	static Component component; + +	static LinkedList<MicroFontListener> font_listeners; + +	static int font_size = font_size_medium; + +	static LinkedList<MicroUIListener> ui_listeners; + +	static String look_and_feel = null; + +	/* Serial debug */ +	static boolean serial_debug; + +	public static void init() { +		AltosPreferences.init(new MicroPreferencesBackend()); + +		font_listeners = new LinkedList<MicroFontListener>(); + +		font_size = backend.getInt(fontSizePreference, font_size_medium); +		set_fonts(font_size); +		look_and_feel = backend.getString(lookAndFeelPreference, UIManager.getSystemLookAndFeelClassName()); + +		ui_listeners = new LinkedList<MicroUIListener>(); +		serial_debug = backend.getBoolean(serialDebugPreference, false); +	} + +	static { init(); } + +	static void set_component(Component in_component) { +		component = in_component; +	} + +	private static boolean check_dir(File dir) { +		if (!dir.exists()) { +			if (!dir.mkdirs()) { +				JOptionPane.showMessageDialog(component, +							      dir.getName(), +							      "Cannot create directory", +							      JOptionPane.ERROR_MESSAGE); +				return false; +			} +		} else if (!dir.isDirectory()) { +			JOptionPane.showMessageDialog(component, +						      dir.getName(), +						      "Is not a directory", +						      JOptionPane.ERROR_MESSAGE); +			return false; +		} +		return true; +	} + +	/* Configure the log directory. This is where all telemetry and eeprom files +	 * will be written to, and where replay will look for telemetry files +	 */ +	public static void ConfigureLog() { +		JFileChooser	logdir_chooser = new JFileChooser(logdir.getParentFile()); + +		logdir_chooser.setDialogTitle("Configure Data Logging Directory"); +		logdir_chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + +		if (logdir_chooser.showDialog(component, "Select Directory") == JFileChooser.APPROVE_OPTION) { +			File dir = logdir_chooser.getSelectedFile(); +			if (check_dir(dir)) +				set_logdir(dir); +		} +	} +	public static int font_size() { +		synchronized (backend) { +			return font_size; +		} +	} + +	static void set_fonts() { +	} + +	public static void set_font_size(int new_font_size) { +		synchronized (backend) { +			font_size = new_font_size; +			backend.putInt(fontSizePreference, font_size); +			flush_preferences(); +			set_fonts(font_size); +			for (MicroFontListener l : font_listeners) +				l.font_size_changed(font_size); +		} +	} + +	public static void register_font_listener(MicroFontListener l) { +		synchronized (backend) { +			font_listeners.add(l); +		} +	} + +	public static void unregister_font_listener(MicroFontListener l) { +		synchronized (backend) { +			font_listeners.remove(l); +		} +	} + +	public static void set_look_and_feel(String new_look_and_feel) { +		try { +			UIManager.setLookAndFeel(new_look_and_feel); +		} catch (Exception e) { +		} +		synchronized(backend) { +			look_and_feel = new_look_and_feel; +			backend.putString(lookAndFeelPreference, look_and_feel); +			flush_preferences(); +			for (MicroUIListener l : ui_listeners) +				l.ui_changed(look_and_feel); +		} +	} + +	public static String look_and_feel() { +		synchronized (backend) { +			return look_and_feel; +		} +	} + +	public static void register_ui_listener(MicroUIListener l) { +		synchronized(backend) { +			ui_listeners.add(l); +		} +	} + +	public static void unregister_ui_listener(MicroUIListener l) { +		synchronized (backend) { +			ui_listeners.remove(l); +		} +	} +	public static void set_serial_debug(boolean new_serial_debug) { +		synchronized (backend) { +			serial_debug = new_serial_debug; +			backend.putBoolean(serialDebugPreference, serial_debug); +			flush_preferences(); +		} +	} + +	public static boolean serial_debug() { +		synchronized (backend) { +			return serial_debug; +		} +	} + +} diff --git a/micropeak/MicroPreferencesBackend.java b/micropeak/MicroPreferencesBackend.java new file mode 100644 index 00000000..7d92f6be --- /dev/null +++ b/micropeak/MicroPreferencesBackend.java @@ -0,0 +1,101 @@ +/* + * Copyright © 2012 Mike Beattie <mike@ethernal.org> + * + * 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. + */ + +package org.altusmetrum.micropeak; + +import java.io.File; +import java.util.prefs.*; +import org.altusmetrum.AltosLib.*; +import javax.swing.filechooser.FileSystemView; + +public class MicroPreferencesBackend implements AltosPreferencesBackend { + +	private Preferences _preferences = null; +	 +	public MicroPreferencesBackend() { +		_preferences = Preferences.userRoot().node("/org/altusmetrum/altosui"); +	} + +	public MicroPreferencesBackend(Preferences in_preferences) { +		_preferences = in_preferences; +	} + +	public String  getString(String key, String def) { +		return _preferences.get(key, def); +	} +	public void    putString(String key, String value) { +		_preferences.put(key, value); +	} + +	public int     getInt(String key, int def) { +		return _preferences.getInt(key, def); +	} +	public void    putInt(String key, int value) { +		_preferences.putInt(key, value); +	} + +	public double  getDouble(String key, double def) { +		return _preferences.getDouble(key, def); +	} +	public void    putDouble(String key, double value) { +		_preferences.putDouble(key, value); +	} + +	public boolean getBoolean(String key, boolean def) { +		return _preferences.getBoolean(key, def); +	} +	public void    putBoolean(String key, boolean value) { +		_preferences.putBoolean(key, value); +	} + +	public boolean nodeExists(String key) { +		try { +			return _preferences.nodeExists(key); +		} catch (BackingStoreException be) { +			return false; +		} +	} + +	public AltosPreferencesBackend node(String key) { +		return new MicroPreferencesBackend(_preferences.node(key)); +	} + +	public String[] keys() { +		try { +			return _preferences.keys(); +		} catch (BackingStoreException be) { +			return null; +		} +	} + +	public void remove(String key) { +		_preferences.remove(key); +	} + +	public void    flush() { +		try { +			_preferences.flush(); +		} catch (BackingStoreException ee) { +			System.err.printf("Cannot save preferences\n"); +		} +	} + +	public File homeDirectory() { +		/* Use the file system view default directory */ +		return FileSystemView.getFileSystemView().getDefaultDirectory(); +	} +} diff --git a/micropeak/MicroSerial.java b/micropeak/MicroSerial.java new file mode 100644 index 00000000..8546276e --- /dev/null +++ b/micropeak/MicroSerial.java @@ -0,0 +1,49 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; +import java.util.*; +import java.io.*; +import libaltosJNI.*; + +public class MicroSerial extends InputStream { +	SWIGTYPE_p_altos_file	file; + +	public int read() { +		int	c = libaltos.altos_getchar(file, 0); +		if (MicroPreferences.serial_debug) +			System.out.printf("%c", c); +		return c; +	} + +	public void close() { +		if (file != null) { +			libaltos.altos_close(file); +			file = null; +		} +	} + +	public MicroSerial(MicroUSB usb) throws FileNotFoundException { +		file = usb.open(); +		if (file == null) { +			final String message = usb.getErrorString(); +			throw new FileNotFoundException(String.format("%s (%s)", +								      usb.toShortString(), +								      message)); +		} +	} +} diff --git a/micropeak/MicroUIListener.java b/micropeak/MicroUIListener.java new file mode 100644 index 00000000..9aed8dae --- /dev/null +++ b/micropeak/MicroUIListener.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; + +public interface MicroUIListener { +	public void ui_changed(String look_and_feel); +} diff --git a/micropeak/MicroUSB.java b/micropeak/MicroUSB.java new file mode 100644 index 00000000..d48610fe --- /dev/null +++ b/micropeak/MicroUSB.java @@ -0,0 +1,103 @@ +/* + * Copyright © 2010 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.micropeak; +import java.util.*; +import libaltosJNI.*; + +public class MicroUSB extends altos_device { + +	static boolean	initialized = false; +	static boolean	loaded_library = false; + +	public static boolean load_library() { +		if (!initialized) { +			try { +				System.loadLibrary("altos"); +				libaltos.altos_init(); +				loaded_library = true; +			} catch (UnsatisfiedLinkError e) { +				try { +					System.loadLibrary("altos64"); +					libaltos.altos_init(); +					loaded_library = true; +				} catch (UnsatisfiedLinkError e2) { +					loaded_library = false; +				} +			} +			initialized = true; +		} +		return loaded_library; +	} + +	public String toString() { +		String	name = getName(); +		if (name == null) +			name = "Altus Metrum"; +		return String.format("%-20.20s %4d %s", +				     name, getSerial(), getPath()); +	} + +	public String toShortString() { +		String	name = getName(); +		if (name == null) +			name = "Altus Metrum"; +		return String.format("%s %d %s", +				     name, getSerial(), getPath()); + +	} + +	public String getErrorString() { +		altos_error	error = new altos_error(); + +		libaltos.altos_get_last_error(error); +		return String.format("%s (%d)", error.getString(), error.getCode()); +	} + +	public SWIGTYPE_p_altos_file open() { +		return libaltos.altos_open(this); +	} + +	private boolean isMicro() { +		if (getVendor() != 0x0403) +			return false; +		if (getProduct() != 0x6001) +			return false; +		return true; +	} + +	static java.util.List<MicroUSB> list() { +		if (!load_library()) +			return null; + +		SWIGTYPE_p_altos_list list = libaltos.altos_list_start(); + +		ArrayList<MicroUSB> device_list = new ArrayList<MicroUSB>(); +		if (list != null) { +			for (;;) { +				MicroUSB device = new MicroUSB(); +				if (libaltos.altos_list_next(list, device) == 0) +					break; +				if (device.isMicro()) +					device_list.add(device); +			} +			libaltos.altos_list_finish(list); +		} + +		return device_list; +	} +}
\ No newline at end of file diff --git a/src/micropeak/Makefile b/src/micropeak/Makefile index 0c48ed66..ff0a4499 100644 --- a/src/micropeak/Makefile +++ b/src/micropeak/Makefile @@ -20,13 +20,6 @@ ifndef VERSION  include ../Version  endif -# Support for a logging EEPROM -# -#EEPROM_SRC=ao_async.c \ -#	ao_i2c_attiny.c \ -#	ao_at24c.c -# -  ALTOS_SRC = \  	ao_micropeak.c \  	ao_spi_attiny.c \ @@ -39,7 +32,8 @@ ALTOS_SRC = \  	ao_notask.c \  	ao_eeprom_tiny.c \  	ao_panic.c \ -	$(EEPROM_SRC) +	ao_log_micro.c \ +	ao_async.c  INC=\  	ao.h \ @@ -48,13 +42,15 @@ INC=\  	ao_arch_funcs.h \  	ao_exti.h \  	ao_ms5607.h \ +	ao_log_micro.h \ +	ao_micropeak.h \  	altitude-pa.h  IDPRODUCT=0  PRODUCT=MicroPeak-v0.1  PRODUCT_DEF=-DMICROPEAK  CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../core -I.. -I../drivers -CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O3 -mcall-prologues -DATTINY +CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTINY  NICKLE=nickle diff --git a/src/micropeak/ao_async.c b/src/micropeak/ao_async.c index 04bba9e8..3556f54c 100644 --- a/src/micropeak/ao_async.c +++ b/src/micropeak/ao_async.c @@ -21,20 +21,51 @@  #define AO_ASYNC_BAUD	38400l  #define AO_ASYNC_DELAY	(uint8_t) (1000000l / AO_ASYNC_BAUD) +#define LED_PORT	PORTB + +void +ao_async_start(void) +{ +	LED_PORT |= (1 << AO_LED_SERIAL); +} + +void +ao_async_stop(void) +{ +	LED_PORT &= ~(1 << AO_LED_SERIAL); +} +  void  ao_async_byte(uint8_t byte)  {  	uint8_t		b;  	uint16_t	w; -	/* start bit */ - -	/* start     data         stop */ -	w = 0x001 | (byte << 1) | 0x000; +	/*    start           data           stop */ +	w = (0x000 << 0) | (byte << 1) | (0x001 << 9); +	ao_arch_block_interrupts();  	for (b = 0; b < 10; b++) { -		ao_led_set((w & 1) << AO_LED_SERIAL); +		uint8_t	v = LED_PORT & ~(1 << AO_LED_SERIAL); +		v |= (w & 1) << AO_LED_SERIAL; +		LED_PORT = v;  		w >>= 1; -		ao_delay_us(26); + +		/* Carefully timed to hit around 9600 baud */ +		asm volatile ("nop"); +		asm volatile ("nop"); + +		asm volatile ("nop"); +		asm volatile ("nop"); +		asm volatile ("nop"); +		asm volatile ("nop"); +		asm volatile ("nop"); + +		asm volatile ("nop"); +		asm volatile ("nop"); +		asm volatile ("nop"); +		asm volatile ("nop"); +		asm volatile ("nop");  	} +	ao_arch_release_interrupts();  } diff --git a/src/micropeak/ao_async.h b/src/micropeak/ao_async.h index a06d2e1a..1b239712 100644 --- a/src/micropeak/ao_async.h +++ b/src/micropeak/ao_async.h @@ -19,6 +19,12 @@  #define _AO_ASYNC_H_  void +ao_async_start(void); + +void +ao_async_stop(void); + +void  ao_async_byte(uint8_t byte);  #endif /* _AO_ASYNC_H_ */ diff --git a/src/micropeak/ao_log_micro.c b/src/micropeak/ao_log_micro.c index eda0d1d2..d665efb5 100644 --- a/src/micropeak/ao_log_micro.c +++ b/src/micropeak/ao_log_micro.c @@ -16,58 +16,106 @@   */  #include <ao.h> +#include <ao_micropeak.h>  #include <ao_log_micro.h>  #include <ao_async.h> -#if HAS_EEPROM - -ao_pos_t	ao_log_micro_pos; +static uint16_t ao_log_offset = STARTING_LOG_OFFSET;  void -ao_log_micro_data(uint32_t data) +ao_log_micro_save(void)  { -	ao_storage_write(ao_log_micro_pos, &data, sizeof (data)); -	ao_log_micro_pos += sizeof (data); +	uint16_t	n_samples = (ao_log_offset - STARTING_LOG_OFFSET) / sizeof (uint16_t); +	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));  } -uint32_t	ao_log_last_ground; -uint32_t	ao_log_last_done; +void +ao_log_micro_restore(void) +{ +	ao_eeprom_read(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground)); +	ao_eeprom_read(PA_MIN_OFFSET, &pa_min, sizeof (pa_min)); +} -uint8_t -ao_log_micro_scan(void) +void +ao_log_micro_data(void)  { -	uint32_t	data; -	ao_pos_t	pos; +	uint16_t	low_bits = pa; -	ao_storage_read(0, &data, sizeof (data)); -	if ((data & AO_LOG_MICRO_MASK) != AO_LOG_MICRO_GROUND) -		return 0; +	if (ao_log_offset < MAX_LOG_OFFSET) { +		ao_eeprom_write(ao_log_offset, &low_bits, sizeof (low_bits)); +		ao_log_offset += sizeof (low_bits); +	} +} + +#define POLY 0x8408 + +static uint16_t +ao_log_micro_crc(uint16_t crc, uint8_t byte) +{ +	uint8_t	i; -	ao_log_last_ground = data & ~(AO_LOG_MICRO_MASK); -	for (pos = 4; pos < ao_storage_total; pos += 4) { -		ao_storage_read(pos, &data, sizeof (data)); -		if ((data & AO_LOG_MICRO_MASK) == AO_LOG_MICRO_GROUND) { -			ao_log_last_done = data & ~(AO_LOG_MICRO_MASK); -			return 1; -		} +	for (i = 0; i < 8; i++) { +		if ((crc & 0x0001) ^ (byte & 0x0001)) +			crc = (crc >> 1) ^ POLY; +		else +			crc = crc >> 1; +		byte >>= 1;  	} -	return 0; +	return crc; +} + +static void +ao_log_hex_nibble(uint8_t b) +{ +	if (b < 10) +		ao_async_byte('0' + b); +	else +		ao_async_byte('a' - 10 + b); +} + +static void +ao_log_hex(uint8_t b) +{ +	ao_log_hex_nibble(b>>4); +	ao_log_hex_nibble(b&0xf); +} + +static void +ao_log_newline(void) +{ +	ao_async_byte('\r'); +	ao_async_byte('\n');  }  void  ao_log_micro_dump(void)  { -	ao_pos_t	pos; -	uint8_t		data[4]; -	uint8_t		i; +	uint16_t	n_samples; +	uint16_t	nbytes; +	uint8_t		byte; +	uint16_t	b; +	uint16_t	crc = 0xffff; -	for (pos = 0; pos < ao_storage_total; pos += 4) { -		ao_storage_read(pos, data, 4); -		for (i = 0; i < 4; i++) -			ao_async_byte(data[i]); -		if (data[3] == (uint8_t) (AO_LOG_MICRO_GROUND >> 24)) -			break; +	ao_eeprom_read(N_SAMPLES_OFFSET, &n_samples, sizeof (n_samples)); +	if (n_samples == 0xffff) +		n_samples = 0; +	nbytes = STARTING_LOG_OFFSET + sizeof (uint16_t) * n_samples; +	ao_async_start(); +	ao_async_byte('M'); +	ao_async_byte('P'); +	for (b = 0; b < nbytes; b++) { +		if ((b & 0xf) == 0) +			ao_log_newline(); +		ao_eeprom_read(b, &byte, 1); +		ao_log_hex(byte); +		crc = ao_log_micro_crc(crc, byte);  	} +	ao_log_newline(); +	crc = ~crc; +	ao_log_hex(crc >> 8); +	ao_log_hex(crc); +	ao_log_newline(); +	ao_async_stop();  } - -#endif diff --git a/src/micropeak/ao_log_micro.h b/src/micropeak/ao_log_micro.h index 15b2d178..976852ee 100644 --- a/src/micropeak/ao_log_micro.h +++ b/src/micropeak/ao_log_micro.h @@ -18,19 +18,20 @@  #ifndef _AO_LOG_MICRO_H_  #define _AO_LOG_MICRO_H_ -#define AO_LOG_MICRO_GROUND	(0l << 24) -#define AO_LOG_MICRO_DATA	(1l << 24) -#define AO_LOG_MICRO_DONE	(0xaal << 24) -#define AO_LOG_MICRO_MASK	(0xffl << 24) +#define PA_GROUND_OFFSET	0 +#define PA_MIN_OFFSET		4 +#define N_SAMPLES_OFFSET	8 +#define STARTING_LOG_OFFSET	10 +#define MAX_LOG_OFFSET		512  void -ao_log_micro_data(uint32_t data); +ao_log_micro_save(void); -extern uint32_t	ao_log_last_ground; -extern uint32_t	ao_log_last_done; +void +ao_log_micro_restore(void); -uint8_t -ao_log_micro_scan(void); +void +ao_log_micro_data(void);  void  ao_log_micro_dump(void); diff --git a/src/micropeak/ao_micropeak.c b/src/micropeak/ao_micropeak.c index 525cfa42..82012800 100644 --- a/src/micropeak/ao_micropeak.c +++ b/src/micropeak/ao_micropeak.c @@ -16,22 +16,23 @@   */  #include <ao.h> +#include <ao_micropeak.h>  #include <ao_ms5607.h>  #include <ao_log_micro.h> +#include <ao_async.h>  static struct ao_ms5607_sample	sample;  static struct ao_ms5607_value	value; -static uint32_t	pa; -static uint32_t	pa_sum; -static uint32_t	pa_avg; -static int32_t	pa_diff; -static uint32_t	pa_ground; -static uint32_t	pa_min; -static uint32_t	pa_interval_min, pa_interval_max; -static alt_t	ground_alt, max_alt; +uint32_t	pa; +uint32_t	pa_avg; +uint32_t	pa_ground; +uint32_t	pa_min; +alt_t		ground_alt, max_alt;  alt_t		ao_max_height; +static uint32_t	pa_sum; +  static void  ao_pa_get(void)  { @@ -40,22 +41,6 @@ ao_pa_get(void)  	pa = value.pres;  } -#define FILTER_SHIFT		3 -#define SAMPLE_SLEEP		AO_MS_TO_TICKS(96) - -/* 16 sample, or about two seconds worth */ -#define GROUND_AVG_SHIFT	4 -#define GROUND_AVG		(1 << GROUND_AVG_SHIFT) - -/* Pressure change (in Pa) to detect boost */ -#define BOOST_DETECT		120	/* 10m at sea level, 12m at 2000m */ - -/* Wait after power on before doing anything to give the user time to assemble the rocket */ -#define BOOST_DELAY		AO_SEC_TO_TICKS(30) - -/* Pressure change (in Pa) to detect landing */ -#define LAND_DETECT		12	/* 1m at sea level, 1.2m at 2000m */ -  static void  ao_compute_height(void)  { @@ -64,90 +49,42 @@ ao_compute_height(void)  	ao_max_height = max_alt - ground_alt;  } -#if !HAS_EEPROM - -#define PA_GROUND_OFFSET	0 -#define PA_MIN_OFFSET		4 -#define N_SAMPLES_OFFSET	8 -#define STARTING_LOG_OFFSET	10 -#define MAX_LOG_OFFSET		512 - -static uint16_t ao_log_offset = STARTING_LOG_OFFSET; - -void -ao_save_flight(void) -{ -	uint16_t	n_samples = (ao_log_offset - STARTING_LOG_OFFSET) / sizeof (uint16_t); -	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)); -} - -void -ao_restore_flight(void) -{ -	ao_eeprom_read(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground)); -	ao_eeprom_read(PA_MIN_OFFSET, &pa_min, sizeof (pa_min)); -} - -void -ao_log_micro(void) +static void +ao_pips(void)  { -	uint16_t	low_bits = pa; - -	if (ao_log_offset < MAX_LOG_OFFSET) { -		ao_eeprom_write(ao_log_offset, &low_bits, sizeof (low_bits)); -		ao_log_offset += sizeof (low_bits); +	uint8_t	i; +	for (i = 0; i < 10; i++) { +		ao_led_toggle(AO_LED_REPORT); +		ao_delay(AO_MS_TO_TICKS(80));  	} +	ao_delay(AO_MS_TO_TICKS(200));  } -#endif  int  main(void)  {  	int16_t		sample_count;  	uint16_t	time; -#if HAS_EEPROM -	uint8_t	dump_eeprom = 0; -#endif +	uint32_t	pa_interval_min, pa_interval_max; +	int32_t		pa_diff; +  	ao_led_init(LEDS_AVAILABLE);  	ao_timer_init(); -#if HAS_EEPROM - -	/* Set MOSI and CLK as inputs with pull-ups */ -	DDRB &= ~(1 << 0) | (1 << 2); -	PORTB |= (1 << 0) | (1 << 2); - -	/* Check to see if either MOSI or CLK are pulled low by the -	 * user shorting them to ground. If so, dump the eeprom out -	 * via the LED. Wait for the shorting wire to go away before -	 * continuing. -	 */ -	while ((PINB & ((1 << 0) | (1 << 2))) != ((1 << 0) | (1 << 2))) -		dump_eeprom = 1; -	PORTB &= ~(1 << 0) | (1 << 2); - -	ao_i2c_init(); -#endif -	ao_restore_flight(); -	ao_compute_height(); -	/* Give the person a second to get their finger out of the way */ -	ao_delay(AO_MS_TO_TICKS(1000)); -	ao_report_altitude(); -	 +	/* Init external hardware */  	ao_spi_init();  	ao_ms5607_init();  	ao_ms5607_setup(); -#if HAS_EEPROM -	ao_storage_init(); - -	/* Check to see if there's a flight recorded in memory */ -	if (dump_eeprom && ao_log_micro_scan()) -		ao_log_micro_dump(); -#endif	 +	/* Give the person a second to get their finger out of the way */ +	ao_delay(AO_MS_TO_TICKS(1000)); +	ao_log_micro_restore(); +	ao_compute_height(); +	ao_report_altitude(); +	ao_pips(); +	ao_log_micro_dump(); +	  	ao_delay(BOOST_DELAY);  	/* Wait for motion, averaging values to get ground pressure */  	time = ao_time(); @@ -182,10 +119,6 @@ main(void)  	pa_ground >>= FILTER_SHIFT; -#if HAS_EEPROM -	ao_log_micro_data(AO_LOG_MICRO_GROUND | pa_ground); -#endif -  	/* Now sit around until the pressure is stable again and record the max */  	sample_count = 0; @@ -200,12 +133,8 @@ main(void)  		ao_pa_get();  		if ((sample_count & 3) == 0)  			ao_led_off(AO_LED_REPORT); -#if HAS_EEPROM -		ao_log_micro_data(AO_LOG_MICRO_DATA | pa); -#else  		if (sample_count & 1) -			ao_log_micro(); -#endif +			ao_log_micro_data();  		pa_avg = pa_avg - (pa_avg >> FILTER_SHIFT) + pa;  		if (pa_avg < pa_min)  			pa_min = pa_avg; @@ -228,10 +157,7 @@ main(void)  		}  	}  	pa_min >>= FILTER_SHIFT; -#if HAS_EEPROM -	ao_log_micro_data(AO_LOG_MICRO_DONE | pa_min); -#endif -	ao_save_flight(); +	ao_log_micro_save();  	ao_compute_height();  	ao_report_altitude();  	for (;;) { diff --git a/src/micropeak/ao_micropeak.h b/src/micropeak/ao_micropeak.h new file mode 100644 index 00000000..e408d7c5 --- /dev/null +++ b/src/micropeak/ao_micropeak.h @@ -0,0 +1,56 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_MICROPEAK_H_ +#define _AO_MICROPEAK_H_ + +#define FILTER_SHIFT		3 +#define SAMPLE_SLEEP		AO_MS_TO_TICKS(96) + +/* 16 sample, or about two seconds worth */ +#define GROUND_AVG_SHIFT	4 +#define GROUND_AVG		(1 << GROUND_AVG_SHIFT) + +/* Pressure change (in Pa) to detect boost */ +#define BOOST_DETECT		120	/* 10m at sea level, 12m at 2000m */ + +/* Wait after power on before doing anything to give the user time to assemble the rocket */ +#define BOOST_DELAY		AO_SEC_TO_TICKS(30) + +/* Pressure change (in Pa) to detect landing */ +#define LAND_DETECT		12	/* 1m at sea level, 1.2m at 2000m */ + +/* Current sensor pressure value */ +extern uint32_t	pa; + +/* IIR filtered pressure value */ +extern uint32_t	pa_avg; + +/* Average pressure value on ground */ +extern uint32_t	pa_ground; + +/* Minimum recorded filtered pressure value */ +extern uint32_t	pa_min; + +/* Pressure values converted to altitudes */ +extern alt_t	ground_alt, max_alt; + +/* max_alt - ground_alt */ +extern alt_t	ao_max_height; + +#endif + | 
