Use autotools, move altos to src subdir
authorKeith Packard <keithp@keithp.com>
Thu, 4 Jun 2009 17:41:34 +0000 (10:41 -0700)
committerKeith Packard <keithp@keithp.com>
Thu, 4 Jun 2009 17:41:34 +0000 (10:41 -0700)
Signed-off-by: Keith Packard <keithp@keithp.com>
109 files changed:
.gitignore
25lc1024.h [deleted file]
AUTHORS [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile [deleted file]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
_bp.c [deleted file]
altitude.h [deleted file]
ao-make-product.5c [deleted file]
ao.h [deleted file]
ao_adc.c [deleted file]
ao_adc_fake.c [deleted file]
ao_beep.c [deleted file]
ao_cmd.c [deleted file]
ao_config.c [deleted file]
ao_convert.c [deleted file]
ao_dbg.c [deleted file]
ao_dma.c [deleted file]
ao_ee.c [deleted file]
ao_ee_fake.c [deleted file]
ao_flight.c [deleted file]
ao_flight_test.c [deleted file]
ao_gps.c [deleted file]
ao_gps_print.c [deleted file]
ao_gps_report.c [deleted file]
ao_ignite.c [deleted file]
ao_led.c [deleted file]
ao_log.c [deleted file]
ao_main.c [deleted file]
ao_monitor.c [deleted file]
ao_mutex.c [deleted file]
ao_panic.c [deleted file]
ao_product.c [deleted file]
ao_radio.c [deleted file]
ao_report.c [deleted file]
ao_rssi.c [deleted file]
ao_serial.c [deleted file]
ao_state.c [deleted file]
ao_stdio.c [deleted file]
ao_task.c [deleted file]
ao_teledongle.c [deleted file]
ao_telemetrum.c [deleted file]
ao_telemetry.c [deleted file]
ao_teleterra.c [deleted file]
ao_test.c [deleted file]
ao_tidongle.c [deleted file]
ao_timer.c [deleted file]
ao_usb.c [deleted file]
ao_usb.h [deleted file]
aoview/Makefile [deleted file]
aoview/Makefile.am [new file with mode: 0644]
aoview/aoview_convert.c
autogen.sh [new file with mode: 0755]
cc1111.h [deleted file]
check-stack [deleted file]
configure.ac [new file with mode: 0644]
gps-cksum [deleted file]
make-altitude [deleted file]
src/25lc1024.h [new file with mode: 0644]
src/Makefile [new file with mode: 0644]
src/_bp.c [new file with mode: 0644]
src/altitude.h [new file with mode: 0644]
src/ao-make-product.5c [new file with mode: 0644]
src/ao.h [new file with mode: 0644]
src/ao_adc.c [new file with mode: 0644]
src/ao_adc_fake.c [new file with mode: 0644]
src/ao_beep.c [new file with mode: 0644]
src/ao_cmd.c [new file with mode: 0644]
src/ao_config.c [new file with mode: 0644]
src/ao_convert.c [new file with mode: 0644]
src/ao_dbg.c [new file with mode: 0644]
src/ao_dma.c [new file with mode: 0644]
src/ao_ee.c [new file with mode: 0644]
src/ao_ee_fake.c [new file with mode: 0644]
src/ao_flight.c [new file with mode: 0644]
src/ao_flight_test.c [new file with mode: 0644]
src/ao_gps.c [new file with mode: 0644]
src/ao_gps_print.c [new file with mode: 0644]
src/ao_gps_report.c [new file with mode: 0644]
src/ao_ignite.c [new file with mode: 0644]
src/ao_led.c [new file with mode: 0644]
src/ao_log.c [new file with mode: 0644]
src/ao_main.c [new file with mode: 0644]
src/ao_monitor.c [new file with mode: 0644]
src/ao_mutex.c [new file with mode: 0644]
src/ao_panic.c [new file with mode: 0644]
src/ao_product.c [new file with mode: 0644]
src/ao_radio.c [new file with mode: 0644]
src/ao_report.c [new file with mode: 0644]
src/ao_rssi.c [new file with mode: 0644]
src/ao_serial.c [new file with mode: 0644]
src/ao_state.c [new file with mode: 0644]
src/ao_stdio.c [new file with mode: 0644]
src/ao_task.c [new file with mode: 0644]
src/ao_teledongle.c [new file with mode: 0644]
src/ao_telemetrum.c [new file with mode: 0644]
src/ao_telemetry.c [new file with mode: 0644]
src/ao_teleterra.c [new file with mode: 0644]
src/ao_test.c [new file with mode: 0644]
src/ao_tidongle.c [new file with mode: 0644]
src/ao_timer.c [new file with mode: 0644]
src/ao_usb.c [new file with mode: 0644]
src/ao_usb.h [new file with mode: 0644]
src/cc1111.h [new file with mode: 0644]
src/check-stack [new file with mode: 0755]
src/gps-cksum [new file with mode: 0755]
src/make-altitude [new file with mode: 0644]

index 24dee3b0810c25ccd67fe0bd5a6afc4950e93142..190ba2fd4c3b3a9c001d36c9a6d2a7b3de4ece72 100644 (file)
@@ -18,3 +18,15 @@ ao-telemetrum.h
 ao-teleterra.h
 ao-teledongle.h
 ao-tidongle.h
+Makefile.in
+aclocal.m4
+.deps
+autom4te.cache
+config.*
+depcomp
+install-sh
+missing
+stamp-h1
+configure
+Makefile
+aoview/Makefile
diff --git a/25lc1024.h b/25lc1024.h
deleted file mode 100644 (file)
index 44e5238..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright Â© 2009 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.
- */
-
-/* Defines for the 25LC1024 1Mbit SPI Bus Serial EEPROM */
-
-#ifndef _25LC1024_H_
-#define _25LC1024_H_
-
-#define EE_READ                0x03
-#define EE_WRITE       0x02
-#define EE_WREN                0x06
-#define EE_WRDI                0x04
-#define EE_RDSR                0x05
-#define EE_WRSR                0x01
-#define EE_PE          0x42
-#define EE_SE          0xd8
-#define EE_CE          0xc7
-#define EE_RDID                0xab
-#define EE_DPD         0xb9
-
-#define EE_STATUS_WIP  (1 << 0)
-#define EE_STATUS_WEL  (1 << 1)
-#define EE_STATUS_BP0  (1 << 2)
-#define EE_STATUS_BP1  (1 << 3)
-#define EE_STATUS_WPEN (1 << 7)
-
-#endif /* _25LC1024_H_ */
diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..9cee037
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Keith Packard <keithp@keithp.com>
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..c9fd2c0
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,290 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007, 2008 Free Software Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+  6. Often, you can also type `make uninstall' to remove the installed
+     files again.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+   On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor.  Like
+this:
+
+     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CPP="gcc -E" CXXCPP="g++ -E"
+
+   This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+   By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Particular systems
+==================
+
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+     ./configure CC="cc -Ae"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
+a workaround.  If GNU CC is not installed, it is therefore recommended
+to try
+
+     ./configure CC="cc"
+
+and if that doesn't work, try
+
+     ./configure CC="cc -nodtk"
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+     Print a summary of the options unique to this package's
+     `configure', and exit.  The `short' variant lists options used
+     only in the top level, while the `recursive' variant lists options
+     also present in any nested packages.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+     Use DIR as the installation prefix.  *Note Installation Names::
+     for more details, including other options available for fine-tuning
+     the installation locations.
+
+`--no-create'
+`-n'
+     Run the configure checks, but stop before creating any output
+     files.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
diff --git a/Makefile b/Makefile
deleted file mode 100644 (file)
index ca296c6..0000000
--- a/Makefile
+++ /dev/null
@@ -1,262 +0,0 @@
-#
-# AltOS build
-#
-# 
-CC=sdcc
-
-VERSION=$(shell git describe)
-
-CFLAGS=--model-small --debug --opt-code-speed 
-
-LDFLAGS=--out-fmt-ihx --code-loc 0x0000 --code-size 0x8000 \
-       --xram-loc 0xf000 --xram-size 0xda2 --iram-size 0xff
-
-INC = \
-       ao.h \
-       cc1111.h \
-       altitude.h \
-       25lc1024.h
-
-#
-# Common AltOS sources
-#
-ALTOS_SRC = \
-       ao_cmd.c \
-       ao_dbg.c \
-       ao_dma.c \
-       ao_mutex.c \
-       ao_panic.c \
-       ao_task.c \
-       ao_timer.c \
-       _bp.c
-
-#
-# Shared AltOS drivers
-#
-ALTOS_DRIVER_SRC = \
-       ao_beep.c \
-       ao_config.c \
-       ao_led.c \
-       ao_radio.c \
-       ao_stdio.c \
-       ao_usb.c
-
-TELE_COMMON_SRC = \
-       ao_gps_print.c \
-       ao_state.c
-
-#
-# Receiver code
-#
-TELE_RECEIVER_SRC =\
-       ao_monitor.c \
-       ao_rssi.c
-
-#
-# Shared Tele drivers (on TeleMetrum, TeleTerra, TeleDongle)
-#
-
-TELE_DRIVER_SRC = \
-       ao_convert.c \
-       ao_gps.c \
-       ao_serial.c
-
-#
-# Drivers for partially-flled boards (TT, TD and TI)
-#
-TELE_FAKE_SRC = \
-       ao_adc_fake.c \
-       ao_ee_fake.c
-
-# 
-# Drivers only on TeleMetrum
-#
-TM_DRIVER_SRC = \
-       ao_adc.c \
-       ao_ee.c \
-       ao_gps_report.c \
-       ao_ignite.c
-
-#
-# Tasks run on TeleMetrum
-#
-TM_TASK_SRC = \
-       ao_flight.c \
-       ao_log.c \
-       ao_report.c \
-       ao_telemetry.c
-
-TM_MAIN_SRC = \
-       ao_telemetrum.c
-
-#
-# All sources for TeleMetrum
-#
-TM_SRC = \
-       $(ALTOS_SRC) \
-       $(ALTOS_DRIVER_SRC) \
-       $(TELE_DRIVER_SRC) \
-       $(TELE_COMMON_SRC) \
-       $(TM_DRIVER_SRC) \
-       $(TM_TASK_SRC) \
-       $(TM_MAIN_SRC)
-
-TI_MAIN_SRC = \
-       ao_tidongle.c
-
-#
-# All sources for the TI debug dongle
-#
-TI_SRC = \
-       $(ALTOS_SRC) \
-       $(ALTOS_DRIVER_SRC) \
-       $(TELE_RECEIVER_SRC) \
-       $(TELE_COMMON_SRC) \
-       $(TELE_FAKE_SRC) \
-       $(TI_MAIN_SRC)
-       
-TT_MAIN_SRC = \
-       ao_teleterra.c
-#
-# All sources for TeleTerra
-#
-TT_SRC = \
-       $(ALTOS_SRC) \
-       $(ALTOS_DRIVER_SRC) \
-       $(TELE_RECEIVER_SRC) \
-       $(TELE_DRIVER_SRC) \
-       $(TELE_COMMON_SRC) \
-       $(TELE_FAKE_SRC) \
-       $(TT_MAIN_SRC)
-       
-       
-#
-# Sources for TeleDongle
-#
-
-TD_MAIN_SRC = \
-       ao_teledongle.c
-
-TD_SRC = \
-       $(ALTOS_SRC) \
-       $(ALTOS_DRIVER_SRC) \
-       $(TELE_RECEIVER_SRC) \
-       $(TELE_COMMON_SRC) \
-       $(TELE_FAKE_SRC) \
-       $(TD_MAIN_SRC)
-
-SRC = \
-       $(ALTOS_SRC) \
-       $(ALTOS_DRIVER_SRC) \
-       $(TELE_DRIVER_SRC) \
-       $(TELE_RECEIVER_SRC) \
-       $(TELE_COMMON_SRC) \
-       $(TELE_FAKE_SRC) \
-       $(TM_DRIVER_SRC) \
-       $(TM_TASK_SRC) \
-       $(TM_MAIN_SRC) \
-       $(TI_MAIN_SRC) \
-       $(TD_MAIN_SRC) \
-       $(TT_MAIN_SRC)
-
-TM_REL=$(TM_SRC:.c=.rel) ao_product-telemetrum.rel
-TI_REL=$(TI_SRC:.c=.rel) ao_product-tidongle.rel
-TT_REL=$(TT_SRC:.c=.rel) ao_product-teleterra.rel
-TD_REL=$(TD_SRC:.c=.rel) ao_product-teledongle.rel
-
-PROD_REL=\
-       ao_product-telemetrum.rel \
-       ao_product-tidongle.rel \
-       ao_product-teleterra.rel \
-       ao_product-teledongle.rel
-
-REL=$(SRC:.c=.rel) $(PROD_REL)
-ADB=$(REL:.rel=.adb)
-ASM=$(REL:.rel=.asm)
-LNK=$(REL:.rel=.lnk)
-LST=$(REL:.rel=.lst)
-RST=$(REL:.rel=.rst)
-SYM=$(REL:.rel=.sym)
-
-PROGS= telemetrum.ihx tidongle.ihx \
-       teleterra.ihx teledongle.ihx
-
-HOST_PROGS=ao_flight_test
-
-PCDB=$(PROGS:.ihx=.cdb)
-PLNK=$(PROGS:.ihx=.lnk)
-PMAP=$(PROGS:.ihx=.map)
-PMEM=$(PROGS:.ihx=.mem)
-PAOM=$(PROGS:.ihx=)
-
-%.rel : %.c $(INC)
-       $(CC) -c $(CFLAGS) -o$*.rel $*.c
-
-all: $(PROGS) $(HOST_PROGS)
-
-telemetrum.ihx: $(TM_REL) Makefile
-       $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(TM_REL)
-       sh check-stack ao.h telemetrum.mem
-
-tidongle.ihx: $(TI_REL) Makefile
-       $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(TI_REL)
-       sh check-stack ao.h tidongle.mem
-
-tidongle.ihx: telemetrum.ihx
-
-teleterra.ihx: $(TT_REL) Makefile
-       $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(TT_REL)
-       sh check-stack ao.h teleterra.mem
-
-teleterra.ihx: tidongle.ihx
-
-teledongle.ihx: $(TD_REL) Makefile
-       $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(TD_REL)
-       sh check-stack ao.h teledongle.mem
-
-teledongle.ihx: teleterra.ihx
-
-altitude.h: make-altitude
-       nickle make-altitude > altitude.h
-
-TELEMETRUM_DEFS=ao-telemetrum.h
-TELETERRA_DEFS=ao-teleterra.h
-TELEDONGLE_DEFS=ao-teledongle.h
-TIDONGLE_DEFS=ao-tidongle.h
-
-ALL_DEFS=$(TELEMETRUM_DEFS) $(TELETERRA_DEFS) \
-       $(TELEDONGLE_DEFS) $(TIDONGLE_DEFS)
-ao_product-telemetrum.rel: ao_product.c $(TELEMETRUM_DEFS)
-       $(CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"$(TELEMETRUM_DEFS)\"' -o$@ ao_product.c
-
-ao_product-teleterra.rel: ao_product.c $(TELETERRA_DEFS)
-       $(CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"$(TELETERRA_DEFS)\"' -o$@ ao_product.c
-
-ao_product-teledongle.rel: ao_product.c $(TELEDONGLE_DEFS)
-       $(CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"$(TELEDONGLE_DEFS)\"' -o$@ ao_product.c
-
-ao_product-tidongle.rel: ao_product.c $(TIDONGLE_DEFS)
-       $(CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"$(TIDONGLE_DEFS)\"' -o$@ ao_product.c
-
-$(TELEMETRUM_DEFS): ao-make-product.5c
-       nickle ao-make-product.5c -m altusmetrum.org -p TeleMetrum -v $(VERSION) > $@
-
-$(TELETERRA_DEFS): ao-make-product.5c
-       nickle ao-make-product.5c -m altusmetrum.org -p TeleTerra -v $(VERSION) > $@
-
-$(TELEDONGLE_DEFS): ao-make-product.5c
-       nickle ao-make-product.5c -m altusmetrum.org -p TeleDongle -v $(VERSION) > $@
-
-$(TIDONGLE_DEFS): ao-make-product.5c
-       nickle ao-make-product.5c -m altusmetrum.org -p TIDongle -v $(VERSION) > $@
-
-clean:
-       rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
-       rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
-       rm -f $(ALL_DEFS) $(HOST_PROGS)
-       rm -f $(TELEMETRUM_DEFS) $(TELETERRA_DEFS) $(TELEDONGLE_DEFS) $(TIDONGLE_DEFS)
-
-install:
-
-ao_flight_test: ao_flight.c ao_flight_test.c
-       cc -g -o $@ ao_flight_test.c
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..e5c0c1e
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS=src aoview
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/_bp.c b/_bp.c
deleted file mode 100644 (file)
index a57b99b..0000000
--- a/_bp.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*-------------------------------------------------------------------------
-
-  _bp.c :- just declares bp as a variable                
-
-             Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
-
-   This library is free software; you can redistribute it and/or modify it
-   under the terms of the GNU Library General Public License as published by the
-   Free Software Foundation; either version 2, or (at your option) any
-   later version.
-   
-   This library 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 Library General Public License for more details.
-   
-   You should have received a copy of the GNU Library General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
-   In other words, you are welcome to use, share and improve this program.
-   You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
--------------------------------------------------------------------------*/
-
-__data unsigned char bp ;
diff --git a/altitude.h b/altitude.h
deleted file mode 100644 (file)
index 5225df4..0000000
+++ /dev/null
@@ -1,2048 +0,0 @@
-       15837,  /*  10.56 kPa 0 count */
-       15804,  /*  10.61 kPa 1 count */
-       15772,  /*  10.66 kPa 2 count */
-       15740,  /*  10.72 kPa 3 count */
-       15708,  /*  10.77 kPa 4 count */
-       15676,  /*  10.83 kPa 5 count */
-       15644,  /*  10.88 kPa 6 count */
-       15613,  /*  10.94 kPa 7 count */
-       15581,  /*  10.99 kPa 8 count */
-       15550,  /*  11.04 kPa 9 count */
-       15519,  /*  11.10 kPa 10 count */
-       15488,  /*  11.15 kPa 11 count */
-       15457,  /*  11.21 kPa 12 count */
-       15426,  /*  11.26 kPa 13 count */
-       15396,  /*  11.32 kPa 14 count */
-       15366,  /*  11.37 kPa 15 count */
-       15335,  /*  11.42 kPa 16 count */
-       15305,  /*  11.48 kPa 17 count */
-       15275,  /*  11.53 kPa 18 count */
-       15246,  /*  11.59 kPa 19 count */
-       15216,  /*  11.64 kPa 20 count */
-       15187,  /*  11.70 kPa 21 count */
-       15157,  /*  11.75 kPa 22 count */
-       15128,  /*  11.80 kPa 23 count */
-       15099,  /*  11.86 kPa 24 count */
-       15070,  /*  11.91 kPa 25 count */
-       15041,  /*  11.97 kPa 26 count */
-       15012,  /*  12.02 kPa 27 count */
-       14984,  /*  12.08 kPa 28 count */
-       14955,  /*  12.13 kPa 29 count */
-       14927,  /*  12.18 kPa 30 count */
-       14899,  /*  12.24 kPa 31 count */
-       14871,  /*  12.29 kPa 32 count */
-       14843,  /*  12.35 kPa 33 count */
-       14815,  /*  12.40 kPa 34 count */
-       14787,  /*  12.46 kPa 35 count */
-       14760,  /*  12.51 kPa 36 count */
-       14732,  /*  12.56 kPa 37 count */
-       14705,  /*  12.62 kPa 38 count */
-       14678,  /*  12.67 kPa 39 count */
-       14651,  /*  12.73 kPa 40 count */
-       14624,  /*  12.78 kPa 41 count */
-       14597,  /*  12.84 kPa 42 count */
-       14570,  /*  12.89 kPa 43 count */
-       14543,  /*  12.94 kPa 44 count */
-       14517,  /*  13.00 kPa 45 count */
-       14490,  /*  13.05 kPa 46 count */
-       14464,  /*  13.11 kPa 47 count */
-       14438,  /*  13.16 kPa 48 count */
-       14412,  /*  13.22 kPa 49 count */
-       14386,  /*  13.27 kPa 50 count */
-       14360,  /*  13.32 kPa 51 count */
-       14334,  /*  13.38 kPa 52 count */
-       14308,  /*  13.43 kPa 53 count */
-       14283,  /*  13.49 kPa 54 count */
-       14257,  /*  13.54 kPa 55 count */
-       14232,  /*  13.60 kPa 56 count */
-       14207,  /*  13.65 kPa 57 count */
-       14182,  /*  13.70 kPa 58 count */
-       14156,  /*  13.76 kPa 59 count */
-       14132,  /*  13.81 kPa 60 count */
-       14107,  /*  13.87 kPa 61 count */
-       14082,  /*  13.92 kPa 62 count */
-       14057,  /*  13.98 kPa 63 count */
-       14033,  /*  14.03 kPa 64 count */
-       14008,  /*  14.08 kPa 65 count */
-       13984,  /*  14.14 kPa 66 count */
-       13959,  /*  14.19 kPa 67 count */
-       13935,  /*  14.25 kPa 68 count */
-       13911,  /*  14.30 kPa 69 count */
-       13887,  /*  14.36 kPa 70 count */
-       13863,  /*  14.41 kPa 71 count */
-       13839,  /*  14.46 kPa 72 count */
-       13816,  /*  14.52 kPa 73 count */
-       13792,  /*  14.57 kPa 74 count */
-       13768,  /*  14.63 kPa 75 count */
-       13745,  /*  14.68 kPa 76 count */
-       13721,  /*  14.74 kPa 77 count */
-       13698,  /*  14.79 kPa 78 count */
-       13675,  /*  14.84 kPa 79 count */
-       13652,  /*  14.90 kPa 80 count */
-       13629,  /*  14.95 kPa 81 count */
-       13606,  /*  15.01 kPa 82 count */
-       13583,  /*  15.06 kPa 83 count */
-       13560,  /*  15.12 kPa 84 count */
-       13537,  /*  15.17 kPa 85 count */
-       13515,  /*  15.22 kPa 86 count */
-       13492,  /*  15.28 kPa 87 count */
-       13470,  /*  15.33 kPa 88 count */
-       13447,  /*  15.39 kPa 89 count */
-       13425,  /*  15.44 kPa 90 count */
-       13403,  /*  15.50 kPa 91 count */
-       13380,  /*  15.55 kPa 92 count */
-       13358,  /*  15.60 kPa 93 count */
-       13336,  /*  15.66 kPa 94 count */
-       13314,  /*  15.71 kPa 95 count */
-       13292,  /*  15.77 kPa 96 count */
-       13271,  /*  15.82 kPa 97 count */
-       13249,  /*  15.87 kPa 98 count */
-       13227,  /*  15.93 kPa 99 count */
-       13206,  /*  15.98 kPa 100 count */
-       13184,  /*  16.04 kPa 101 count */
-       13163,  /*  16.09 kPa 102 count */
-       13141,  /*  16.15 kPa 103 count */
-       13120,  /*  16.20 kPa 104 count */
-       13099,  /*  16.25 kPa 105 count */
-       13078,  /*  16.31 kPa 106 count */
-       13057,  /*  16.36 kPa 107 count */
-       13036,  /*  16.42 kPa 108 count */
-       13015,  /*  16.47 kPa 109 count */
-       12994,  /*  16.53 kPa 110 count */
-       12973,  /*  16.58 kPa 111 count */
-       12952,  /*  16.63 kPa 112 count */
-       12932,  /*  16.69 kPa 113 count */
-       12911,  /*  16.74 kPa 114 count */
-       12891,  /*  16.80 kPa 115 count */
-       12870,  /*  16.85 kPa 116 count */
-       12850,  /*  16.91 kPa 117 count */
-       12829,  /*  16.96 kPa 118 count */
-       12809,  /*  17.01 kPa 119 count */
-       12789,  /*  17.07 kPa 120 count */
-       12769,  /*  17.12 kPa 121 count */
-       12749,  /*  17.18 kPa 122 count */
-       12729,  /*  17.23 kPa 123 count */
-       12709,  /*  17.29 kPa 124 count */
-       12689,  /*  17.34 kPa 125 count */
-       12669,  /*  17.39 kPa 126 count */
-       12649,  /*  17.45 kPa 127 count */
-       12630,  /*  17.50 kPa 128 count */
-       12610,  /*  17.56 kPa 129 count */
-       12590,  /*  17.61 kPa 130 count */
-       12571,  /*  17.67 kPa 131 count */
-       12551,  /*  17.72 kPa 132 count */
-       12532,  /*  17.77 kPa 133 count */
-       12513,  /*  17.83 kPa 134 count */
-       12493,  /*  17.88 kPa 135 count */
-       12474,  /*  17.94 kPa 136 count */
-       12455,  /*  17.99 kPa 137 count */
-       12436,  /*  18.05 kPa 138 count */
-       12417,  /*  18.10 kPa 139 count */
-       12398,  /*  18.15 kPa 140 count */
-       12379,  /*  18.21 kPa 141 count */
-       12360,  /*  18.26 kPa 142 count */
-       12341,  /*  18.32 kPa 143 count */
-       12323,  /*  18.37 kPa 144 count */
-       12304,  /*  18.43 kPa 145 count */
-       12285,  /*  18.48 kPa 146 count */
-       12267,  /*  18.53 kPa 147 count */
-       12248,  /*  18.59 kPa 148 count */
-       12230,  /*  18.64 kPa 149 count */
-       12211,  /*  18.70 kPa 150 count */
-       12193,  /*  18.75 kPa 151 count */
-       12174,  /*  18.81 kPa 152 count */
-       12156,  /*  18.86 kPa 153 count */
-       12138,  /*  18.91 kPa 154 count */
-       12120,  /*  18.97 kPa 155 count */
-       12102,  /*  19.02 kPa 156 count */
-       12084,  /*  19.08 kPa 157 count */
-       12065,  /*  19.13 kPa 158 count */
-       12048,  /*  19.19 kPa 159 count */
-       12030,  /*  19.24 kPa 160 count */
-       12012,  /*  19.29 kPa 161 count */
-       11994,  /*  19.35 kPa 162 count */
-       11976,  /*  19.40 kPa 163 count */
-       11958,  /*  19.46 kPa 164 count */
-       11941,  /*  19.51 kPa 165 count */
-       11923,  /*  19.57 kPa 166 count */
-       11906,  /*  19.62 kPa 167 count */
-       11888,  /*  19.67 kPa 168 count */
-       11871,  /*  19.73 kPa 169 count */
-       11853,  /*  19.78 kPa 170 count */
-       11836,  /*  19.84 kPa 171 count */
-       11818,  /*  19.89 kPa 172 count */
-       11801,  /*  19.95 kPa 173 count */
-       11784,  /*  20.00 kPa 174 count */
-       11767,  /*  20.05 kPa 175 count */
-       11750,  /*  20.11 kPa 176 count */
-       11733,  /*  20.16 kPa 177 count */
-       11715,  /*  20.22 kPa 178 count */
-       11698,  /*  20.27 kPa 179 count */
-       11682,  /*  20.33 kPa 180 count */
-       11665,  /*  20.38 kPa 181 count */
-       11648,  /*  20.43 kPa 182 count */
-       11631,  /*  20.49 kPa 183 count */
-       11614,  /*  20.54 kPa 184 count */
-       11597,  /*  20.60 kPa 185 count */
-       11581,  /*  20.65 kPa 186 count */
-       11564,  /*  20.71 kPa 187 count */
-       11547,  /*  20.76 kPa 188 count */
-       11531,  /*  20.81 kPa 189 count */
-       11514,  /*  20.87 kPa 190 count */
-       11498,  /*  20.92 kPa 191 count */
-       11481,  /*  20.98 kPa 192 count */
-       11465,  /*  21.03 kPa 193 count */
-       11449,  /*  21.09 kPa 194 count */
-       11432,  /*  21.14 kPa 195 count */
-       11416,  /*  21.19 kPa 196 count */
-       11400,  /*  21.25 kPa 197 count */
-       11384,  /*  21.30 kPa 198 count */
-       11368,  /*  21.36 kPa 199 count */
-       11352,  /*  21.41 kPa 200 count */
-       11336,  /*  21.47 kPa 201 count */
-       11319,  /*  21.52 kPa 202 count */
-       11304,  /*  21.57 kPa 203 count */
-       11288,  /*  21.63 kPa 204 count */
-       11272,  /*  21.68 kPa 205 count */
-       11256,  /*  21.74 kPa 206 count */
-       11240,  /*  21.79 kPa 207 count */
-       11224,  /*  21.85 kPa 208 count */
-       11208,  /*  21.90 kPa 209 count */
-       11193,  /*  21.95 kPa 210 count */
-       11177,  /*  22.01 kPa 211 count */
-       11162,  /*  22.06 kPa 212 count */
-       11146,  /*  22.12 kPa 213 count */
-       11130,  /*  22.17 kPa 214 count */
-       11115,  /*  22.23 kPa 215 count */
-       11099,  /*  22.28 kPa 216 count */
-       11084,  /*  22.33 kPa 217 count */
-       11069,  /*  22.39 kPa 218 count */
-       11053,  /*  22.44 kPa 219 count */
-       11038,  /*  22.50 kPa 220 count */
-       11023,  /*  22.55 kPa 221 count */
-       11007,  /*  22.61 kPa 222 count */
-       10992,  /*  22.66 kPa 223 count */
-       10977,  /*  22.71 kPa 224 count */
-       10962,  /*  22.77 kPa 225 count */
-       10947,  /*  22.82 kPa 226 count */
-       10932,  /*  22.88 kPa 227 count */
-       10917,  /*  22.93 kPa 228 count */
-       10902,  /*  22.99 kPa 229 count */
-       10887,  /*  23.04 kPa 230 count */
-       10872,  /*  23.09 kPa 231 count */
-       10857,  /*  23.15 kPa 232 count */
-       10842,  /*  23.20 kPa 233 count */
-       10827,  /*  23.26 kPa 234 count */
-       10812,  /*  23.31 kPa 235 count */
-       10797,  /*  23.37 kPa 236 count */
-       10782,  /*  23.42 kPa 237 count */
-       10768,  /*  23.47 kPa 238 count */
-       10753,  /*  23.53 kPa 239 count */
-       10738,  /*  23.58 kPa 240 count */
-       10723,  /*  23.64 kPa 241 count */
-       10709,  /*  23.69 kPa 242 count */
-       10694,  /*  23.75 kPa 243 count */
-       10679,  /*  23.80 kPa 244 count */
-       10665,  /*  23.85 kPa 245 count */
-       10650,  /*  23.91 kPa 246 count */
-       10636,  /*  23.96 kPa 247 count */
-       10621,  /*  24.02 kPa 248 count */
-       10607,  /*  24.07 kPa 249 count */
-       10592,  /*  24.13 kPa 250 count */
-       10578,  /*  24.18 kPa 251 count */
-       10563,  /*  24.23 kPa 252 count */
-       10549,  /*  24.29 kPa 253 count */
-       10535,  /*  24.34 kPa 254 count */
-       10520,  /*  24.40 kPa 255 count */
-       10506,  /*  24.45 kPa 256 count */
-       10492,  /*  24.51 kPa 257 count */
-       10478,  /*  24.56 kPa 258 count */
-       10463,  /*  24.61 kPa 259 count */
-       10449,  /*  24.67 kPa 260 count */
-       10435,  /*  24.72 kPa 261 count */
-       10421,  /*  24.78 kPa 262 count */
-       10407,  /*  24.83 kPa 263 count */
-       10393,  /*  24.89 kPa 264 count */
-       10379,  /*  24.94 kPa 265 count */
-       10364,  /*  24.99 kPa 266 count */
-       10350,  /*  25.05 kPa 267 count */
-       10336,  /*  25.10 kPa 268 count */
-       10322,  /*  25.16 kPa 269 count */
-       10309,  /*  25.21 kPa 270 count */
-       10295,  /*  25.27 kPa 271 count */
-       10281,  /*  25.32 kPa 272 count */
-       10267,  /*  25.37 kPa 273 count */
-       10253,  /*  25.43 kPa 274 count */
-       10239,  /*  25.48 kPa 275 count */
-       10225,  /*  25.54 kPa 276 count */
-       10212,  /*  25.59 kPa 277 count */
-       10198,  /*  25.65 kPa 278 count */
-       10184,  /*  25.70 kPa 279 count */
-       10170,  /*  25.75 kPa 280 count */
-       10157,  /*  25.81 kPa 281 count */
-       10143,  /*  25.86 kPa 282 count */
-       10129,  /*  25.92 kPa 283 count */
-       10116,  /*  25.97 kPa 284 count */
-       10102,  /*  26.03 kPa 285 count */
-       10089,  /*  26.08 kPa 286 count */
-       10075,  /*  26.13 kPa 287 count */
-       10062,  /*  26.19 kPa 288 count */
-       10048,  /*  26.24 kPa 289 count */
-       10035,  /*  26.30 kPa 290 count */
-       10021,  /*  26.35 kPa 291 count */
-       10008,  /*  26.41 kPa 292 count */
-       9994,   /*  26.46 kPa 293 count */
-       9981,   /*  26.51 kPa 294 count */
-       9967,   /*  26.57 kPa 295 count */
-       9954,   /*  26.62 kPa 296 count */
-       9941,   /*  26.68 kPa 297 count */
-       9928,   /*  26.73 kPa 298 count */
-       9914,   /*  26.79 kPa 299 count */
-       9901,   /*  26.84 kPa 300 count */
-       9888,   /*  26.89 kPa 301 count */
-       9875,   /*  26.95 kPa 302 count */
-       9861,   /*  27.00 kPa 303 count */
-       9848,   /*  27.06 kPa 304 count */
-       9835,   /*  27.11 kPa 305 count */
-       9822,   /*  27.17 kPa 306 count */
-       9809,   /*  27.22 kPa 307 count */
-       9796,   /*  27.27 kPa 308 count */
-       9783,   /*  27.33 kPa 309 count */
-       9770,   /*  27.38 kPa 310 count */
-       9757,   /*  27.44 kPa 311 count */
-       9744,   /*  27.49 kPa 312 count */
-       9731,   /*  27.55 kPa 313 count */
-       9718,   /*  27.60 kPa 314 count */
-       9705,   /*  27.65 kPa 315 count */
-       9692,   /*  27.71 kPa 316 count */
-       9679,   /*  27.76 kPa 317 count */
-       9666,   /*  27.82 kPa 318 count */
-       9653,   /*  27.87 kPa 319 count */
-       9640,   /*  27.93 kPa 320 count */
-       9627,   /*  27.98 kPa 321 count */
-       9615,   /*  28.03 kPa 322 count */
-       9602,   /*  28.09 kPa 323 count */
-       9589,   /*  28.14 kPa 324 count */
-       9576,   /*  28.20 kPa 325 count */
-       9564,   /*  28.25 kPa 326 count */
-       9551,   /*  28.31 kPa 327 count */
-       9538,   /*  28.36 kPa 328 count */
-       9526,   /*  28.41 kPa 329 count */
-       9513,   /*  28.47 kPa 330 count */
-       9500,   /*  28.52 kPa 331 count */
-       9488,   /*  28.58 kPa 332 count */
-       9475,   /*  28.63 kPa 333 count */
-       9463,   /*  28.69 kPa 334 count */
-       9450,   /*  28.74 kPa 335 count */
-       9438,   /*  28.79 kPa 336 count */
-       9425,   /*  28.85 kPa 337 count */
-       9413,   /*  28.90 kPa 338 count */
-       9400,   /*  28.96 kPa 339 count */
-       9388,   /*  29.01 kPa 340 count */
-       9375,   /*  29.07 kPa 341 count */
-       9363,   /*  29.12 kPa 342 count */
-       9350,   /*  29.17 kPa 343 count */
-       9338,   /*  29.23 kPa 344 count */
-       9326,   /*  29.28 kPa 345 count */
-       9313,   /*  29.34 kPa 346 count */
-       9301,   /*  29.39 kPa 347 count */
-       9289,   /*  29.44 kPa 348 count */
-       9276,   /*  29.50 kPa 349 count */
-       9264,   /*  29.55 kPa 350 count */
-       9252,   /*  29.61 kPa 351 count */
-       9240,   /*  29.66 kPa 352 count */
-       9227,   /*  29.72 kPa 353 count */
-       9215,   /*  29.77 kPa 354 count */
-       9203,   /*  29.82 kPa 355 count */
-       9191,   /*  29.88 kPa 356 count */
-       9179,   /*  29.93 kPa 357 count */
-       9167,   /*  29.99 kPa 358 count */
-       9155,   /*  30.04 kPa 359 count */
-       9142,   /*  30.10 kPa 360 count */
-       9130,   /*  30.15 kPa 361 count */
-       9118,   /*  30.20 kPa 362 count */
-       9106,   /*  30.26 kPa 363 count */
-       9094,   /*  30.31 kPa 364 count */
-       9082,   /*  30.37 kPa 365 count */
-       9070,   /*  30.42 kPa 366 count */
-       9058,   /*  30.48 kPa 367 count */
-       9046,   /*  30.53 kPa 368 count */
-       9035,   /*  30.58 kPa 369 count */
-       9023,   /*  30.64 kPa 370 count */
-       9011,   /*  30.69 kPa 371 count */
-       8999,   /*  30.75 kPa 372 count */
-       8987,   /*  30.80 kPa 373 count */
-       8975,   /*  30.86 kPa 374 count */
-       8963,   /*  30.91 kPa 375 count */
-       8952,   /*  30.96 kPa 376 count */
-       8940,   /*  31.02 kPa 377 count */
-       8928,   /*  31.07 kPa 378 count */
-       8916,   /*  31.13 kPa 379 count */
-       8904,   /*  31.18 kPa 380 count */
-       8893,   /*  31.24 kPa 381 count */
-       8881,   /*  31.29 kPa 382 count */
-       8869,   /*  31.34 kPa 383 count */
-       8858,   /*  31.40 kPa 384 count */
-       8846,   /*  31.45 kPa 385 count */
-       8834,   /*  31.51 kPa 386 count */
-       8823,   /*  31.56 kPa 387 count */
-       8811,   /*  31.62 kPa 388 count */
-       8800,   /*  31.67 kPa 389 count */
-       8788,   /*  31.72 kPa 390 count */
-       8776,   /*  31.78 kPa 391 count */
-       8765,   /*  31.83 kPa 392 count */
-       8753,   /*  31.89 kPa 393 count */
-       8742,   /*  31.94 kPa 394 count */
-       8730,   /*  32.00 kPa 395 count */
-       8719,   /*  32.05 kPa 396 count */
-       8707,   /*  32.10 kPa 397 count */
-       8696,   /*  32.16 kPa 398 count */
-       8684,   /*  32.21 kPa 399 count */
-       8673,   /*  32.27 kPa 400 count */
-       8662,   /*  32.32 kPa 401 count */
-       8650,   /*  32.38 kPa 402 count */
-       8639,   /*  32.43 kPa 403 count */
-       8628,   /*  32.48 kPa 404 count */
-       8616,   /*  32.54 kPa 405 count */
-       8605,   /*  32.59 kPa 406 count */
-       8594,   /*  32.65 kPa 407 count */
-       8582,   /*  32.70 kPa 408 count */
-       8571,   /*  32.76 kPa 409 count */
-       8560,   /*  32.81 kPa 410 count */
-       8548,   /*  32.86 kPa 411 count */
-       8537,   /*  32.92 kPa 412 count */
-       8526,   /*  32.97 kPa 413 count */
-       8515,   /*  33.03 kPa 414 count */
-       8504,   /*  33.08 kPa 415 count */
-       8492,   /*  33.14 kPa 416 count */
-       8481,   /*  33.19 kPa 417 count */
-       8470,   /*  33.24 kPa 418 count */
-       8459,   /*  33.30 kPa 419 count */
-       8448,   /*  33.35 kPa 420 count */
-       8437,   /*  33.41 kPa 421 count */
-       8426,   /*  33.46 kPa 422 count */
-       8415,   /*  33.52 kPa 423 count */
-       8403,   /*  33.57 kPa 424 count */
-       8392,   /*  33.62 kPa 425 count */
-       8381,   /*  33.68 kPa 426 count */
-       8370,   /*  33.73 kPa 427 count */
-       8359,   /*  33.79 kPa 428 count */
-       8348,   /*  33.84 kPa 429 count */
-       8337,   /*  33.90 kPa 430 count */
-       8326,   /*  33.95 kPa 431 count */
-       8316,   /*  34.00 kPa 432 count */
-       8305,   /*  34.06 kPa 433 count */
-       8294,   /*  34.11 kPa 434 count */
-       8283,   /*  34.17 kPa 435 count */
-       8272,   /*  34.22 kPa 436 count */
-       8261,   /*  34.28 kPa 437 count */
-       8250,   /*  34.33 kPa 438 count */
-       8239,   /*  34.38 kPa 439 count */
-       8228,   /*  34.44 kPa 440 count */
-       8218,   /*  34.49 kPa 441 count */
-       8207,   /*  34.55 kPa 442 count */
-       8196,   /*  34.60 kPa 443 count */
-       8185,   /*  34.66 kPa 444 count */
-       8175,   /*  34.71 kPa 445 count */
-       8164,   /*  34.76 kPa 446 count */
-       8153,   /*  34.82 kPa 447 count */
-       8142,   /*  34.87 kPa 448 count */
-       8132,   /*  34.93 kPa 449 count */
-       8121,   /*  34.98 kPa 450 count */
-       8110,   /*  35.04 kPa 451 count */
-       8100,   /*  35.09 kPa 452 count */
-       8089,   /*  35.14 kPa 453 count */
-       8078,   /*  35.20 kPa 454 count */
-       8068,   /*  35.25 kPa 455 count */
-       8057,   /*  35.31 kPa 456 count */
-       8046,   /*  35.36 kPa 457 count */
-       8036,   /*  35.42 kPa 458 count */
-       8025,   /*  35.47 kPa 459 count */
-       8015,   /*  35.52 kPa 460 count */
-       8004,   /*  35.58 kPa 461 count */
-       7994,   /*  35.63 kPa 462 count */
-       7983,   /*  35.69 kPa 463 count */
-       7973,   /*  35.74 kPa 464 count */
-       7962,   /*  35.80 kPa 465 count */
-       7952,   /*  35.85 kPa 466 count */
-       7941,   /*  35.90 kPa 467 count */
-       7931,   /*  35.96 kPa 468 count */
-       7920,   /*  36.01 kPa 469 count */
-       7910,   /*  36.07 kPa 470 count */
-       7899,   /*  36.12 kPa 471 count */
-       7889,   /*  36.18 kPa 472 count */
-       7879,   /*  36.23 kPa 473 count */
-       7868,   /*  36.28 kPa 474 count */
-       7858,   /*  36.34 kPa 475 count */
-       7847,   /*  36.39 kPa 476 count */
-       7837,   /*  36.45 kPa 477 count */
-       7827,   /*  36.50 kPa 478 count */
-       7816,   /*  36.56 kPa 479 count */
-       7806,   /*  36.61 kPa 480 count */
-       7796,   /*  36.66 kPa 481 count */
-       7785,   /*  36.72 kPa 482 count */
-       7775,   /*  36.77 kPa 483 count */
-       7765,   /*  36.83 kPa 484 count */
-       7755,   /*  36.88 kPa 485 count */
-       7744,   /*  36.94 kPa 486 count */
-       7734,   /*  36.99 kPa 487 count */
-       7724,   /*  37.04 kPa 488 count */
-       7714,   /*  37.10 kPa 489 count */
-       7704,   /*  37.15 kPa 490 count */
-       7693,   /*  37.21 kPa 491 count */
-       7683,   /*  37.26 kPa 492 count */
-       7673,   /*  37.32 kPa 493 count */
-       7663,   /*  37.37 kPa 494 count */
-       7653,   /*  37.42 kPa 495 count */
-       7643,   /*  37.48 kPa 496 count */
-       7633,   /*  37.53 kPa 497 count */
-       7623,   /*  37.59 kPa 498 count */
-       7613,   /*  37.64 kPa 499 count */
-       7602,   /*  37.70 kPa 500 count */
-       7592,   /*  37.75 kPa 501 count */
-       7582,   /*  37.80 kPa 502 count */
-       7572,   /*  37.86 kPa 503 count */
-       7562,   /*  37.91 kPa 504 count */
-       7552,   /*  37.97 kPa 505 count */
-       7542,   /*  38.02 kPa 506 count */
-       7532,   /*  38.08 kPa 507 count */
-       7522,   /*  38.13 kPa 508 count */
-       7512,   /*  38.18 kPa 509 count */
-       7502,   /*  38.24 kPa 510 count */
-       7492,   /*  38.29 kPa 511 count */
-       7483,   /*  38.35 kPa 512 count */
-       7473,   /*  38.40 kPa 513 count */
-       7463,   /*  38.46 kPa 514 count */
-       7453,   /*  38.51 kPa 515 count */
-       7443,   /*  38.56 kPa 516 count */
-       7433,   /*  38.62 kPa 517 count */
-       7423,   /*  38.67 kPa 518 count */
-       7413,   /*  38.73 kPa 519 count */
-       7403,   /*  38.78 kPa 520 count */
-       7394,   /*  38.84 kPa 521 count */
-       7384,   /*  38.89 kPa 522 count */
-       7374,   /*  38.94 kPa 523 count */
-       7364,   /*  39.00 kPa 524 count */
-       7354,   /*  39.05 kPa 525 count */
-       7345,   /*  39.11 kPa 526 count */
-       7335,   /*  39.16 kPa 527 count */
-       7325,   /*  39.22 kPa 528 count */
-       7315,   /*  39.27 kPa 529 count */
-       7306,   /*  39.32 kPa 530 count */
-       7296,   /*  39.38 kPa 531 count */
-       7286,   /*  39.43 kPa 532 count */
-       7277,   /*  39.49 kPa 533 count */
-       7267,   /*  39.54 kPa 534 count */
-       7257,   /*  39.60 kPa 535 count */
-       7248,   /*  39.65 kPa 536 count */
-       7238,   /*  39.70 kPa 537 count */
-       7228,   /*  39.76 kPa 538 count */
-       7219,   /*  39.81 kPa 539 count */
-       7209,   /*  39.87 kPa 540 count */
-       7199,   /*  39.92 kPa 541 count */
-       7190,   /*  39.98 kPa 542 count */
-       7180,   /*  40.03 kPa 543 count */
-       7171,   /*  40.08 kPa 544 count */
-       7161,   /*  40.14 kPa 545 count */
-       7152,   /*  40.19 kPa 546 count */
-       7142,   /*  40.25 kPa 547 count */
-       7132,   /*  40.30 kPa 548 count */
-       7123,   /*  40.36 kPa 549 count */
-       7113,   /*  40.41 kPa 550 count */
-       7104,   /*  40.46 kPa 551 count */
-       7094,   /*  40.52 kPa 552 count */
-       7085,   /*  40.57 kPa 553 count */
-       7075,   /*  40.63 kPa 554 count */
-       7066,   /*  40.68 kPa 555 count */
-       7056,   /*  40.74 kPa 556 count */
-       7047,   /*  40.79 kPa 557 count */
-       7038,   /*  40.84 kPa 558 count */
-       7028,   /*  40.90 kPa 559 count */
-       7019,   /*  40.95 kPa 560 count */
-       7009,   /*  41.01 kPa 561 count */
-       7000,   /*  41.06 kPa 562 count */
-       6991,   /*  41.12 kPa 563 count */
-       6981,   /*  41.17 kPa 564 count */
-       6972,   /*  41.22 kPa 565 count */
-       6962,   /*  41.28 kPa 566 count */
-       6953,   /*  41.33 kPa 567 count */
-       6944,   /*  41.39 kPa 568 count */
-       6934,   /*  41.44 kPa 569 count */
-       6925,   /*  41.50 kPa 570 count */
-       6916,   /*  41.55 kPa 571 count */
-       6907,   /*  41.60 kPa 572 count */
-       6897,   /*  41.66 kPa 573 count */
-       6888,   /*  41.71 kPa 574 count */
-       6879,   /*  41.77 kPa 575 count */
-       6869,   /*  41.82 kPa 576 count */
-       6860,   /*  41.88 kPa 577 count */
-       6851,   /*  41.93 kPa 578 count */
-       6842,   /*  41.98 kPa 579 count */
-       6833,   /*  42.04 kPa 580 count */
-       6823,   /*  42.09 kPa 581 count */
-       6814,   /*  42.15 kPa 582 count */
-       6805,   /*  42.20 kPa 583 count */
-       6796,   /*  42.26 kPa 584 count */
-       6787,   /*  42.31 kPa 585 count */
-       6777,   /*  42.36 kPa 586 count */
-       6768,   /*  42.42 kPa 587 count */
-       6759,   /*  42.47 kPa 588 count */
-       6750,   /*  42.53 kPa 589 count */
-       6741,   /*  42.58 kPa 590 count */
-       6732,   /*  42.64 kPa 591 count */
-       6723,   /*  42.69 kPa 592 count */
-       6714,   /*  42.74 kPa 593 count */
-       6705,   /*  42.80 kPa 594 count */
-       6695,   /*  42.85 kPa 595 count */
-       6686,   /*  42.91 kPa 596 count */
-       6677,   /*  42.96 kPa 597 count */
-       6668,   /*  43.01 kPa 598 count */
-       6659,   /*  43.07 kPa 599 count */
-       6650,   /*  43.12 kPa 600 count */
-       6641,   /*  43.18 kPa 601 count */
-       6632,   /*  43.23 kPa 602 count */
-       6623,   /*  43.29 kPa 603 count */
-       6614,   /*  43.34 kPa 604 count */
-       6605,   /*  43.39 kPa 605 count */
-       6596,   /*  43.45 kPa 606 count */
-       6587,   /*  43.50 kPa 607 count */
-       6578,   /*  43.56 kPa 608 count */
-       6569,   /*  43.61 kPa 609 count */
-       6560,   /*  43.67 kPa 610 count */
-       6552,   /*  43.72 kPa 611 count */
-       6543,   /*  43.77 kPa 612 count */
-       6534,   /*  43.83 kPa 613 count */
-       6525,   /*  43.88 kPa 614 count */
-       6516,   /*  43.94 kPa 615 count */
-       6507,   /*  43.99 kPa 616 count */
-       6498,   /*  44.05 kPa 617 count */
-       6489,   /*  44.10 kPa 618 count */
-       6480,   /*  44.15 kPa 619 count */
-       6472,   /*  44.21 kPa 620 count */
-       6463,   /*  44.26 kPa 621 count */
-       6454,   /*  44.32 kPa 622 count */
-       6445,   /*  44.37 kPa 623 count */
-       6436,   /*  44.43 kPa 624 count */
-       6427,   /*  44.48 kPa 625 count */
-       6419,   /*  44.53 kPa 626 count */
-       6410,   /*  44.59 kPa 627 count */
-       6401,   /*  44.64 kPa 628 count */
-       6392,   /*  44.70 kPa 629 count */
-       6384,   /*  44.75 kPa 630 count */
-       6375,   /*  44.81 kPa 631 count */
-       6366,   /*  44.86 kPa 632 count */
-       6357,   /*  44.91 kPa 633 count */
-       6349,   /*  44.97 kPa 634 count */
-       6340,   /*  45.02 kPa 635 count */
-       6331,   /*  45.08 kPa 636 count */
-       6322,   /*  45.13 kPa 637 count */
-       6314,   /*  45.19 kPa 638 count */
-       6305,   /*  45.24 kPa 639 count */
-       6296,   /*  45.29 kPa 640 count */
-       6288,   /*  45.35 kPa 641 count */
-       6279,   /*  45.40 kPa 642 count */
-       6270,   /*  45.46 kPa 643 count */
-       6262,   /*  45.51 kPa 644 count */
-       6253,   /*  45.57 kPa 645 count */
-       6245,   /*  45.62 kPa 646 count */
-       6236,   /*  45.67 kPa 647 count */
-       6227,   /*  45.73 kPa 648 count */
-       6219,   /*  45.78 kPa 649 count */
-       6210,   /*  45.84 kPa 650 count */
-       6202,   /*  45.89 kPa 651 count */
-       6193,   /*  45.95 kPa 652 count */
-       6184,   /*  46.00 kPa 653 count */
-       6176,   /*  46.05 kPa 654 count */
-       6167,   /*  46.11 kPa 655 count */
-       6159,   /*  46.16 kPa 656 count */
-       6150,   /*  46.22 kPa 657 count */
-       6142,   /*  46.27 kPa 658 count */
-       6133,   /*  46.33 kPa 659 count */
-       6125,   /*  46.38 kPa 660 count */
-       6116,   /*  46.43 kPa 661 count */
-       6108,   /*  46.49 kPa 662 count */
-       6099,   /*  46.54 kPa 663 count */
-       6091,   /*  46.60 kPa 664 count */
-       6082,   /*  46.65 kPa 665 count */
-       6074,   /*  46.71 kPa 666 count */
-       6065,   /*  46.76 kPa 667 count */
-       6057,   /*  46.81 kPa 668 count */
-       6048,   /*  46.87 kPa 669 count */
-       6040,   /*  46.92 kPa 670 count */
-       6032,   /*  46.98 kPa 671 count */
-       6023,   /*  47.03 kPa 672 count */
-       6015,   /*  47.09 kPa 673 count */
-       6006,   /*  47.14 kPa 674 count */
-       5998,   /*  47.19 kPa 675 count */
-       5990,   /*  47.25 kPa 676 count */
-       5981,   /*  47.30 kPa 677 count */
-       5973,   /*  47.36 kPa 678 count */
-       5964,   /*  47.41 kPa 679 count */
-       5956,   /*  47.47 kPa 680 count */
-       5948,   /*  47.52 kPa 681 count */
-       5939,   /*  47.57 kPa 682 count */
-       5931,   /*  47.63 kPa 683 count */
-       5923,   /*  47.68 kPa 684 count */
-       5914,   /*  47.74 kPa 685 count */
-       5906,   /*  47.79 kPa 686 count */
-       5898,   /*  47.85 kPa 687 count */
-       5890,   /*  47.90 kPa 688 count */
-       5881,   /*  47.95 kPa 689 count */
-       5873,   /*  48.01 kPa 690 count */
-       5865,   /*  48.06 kPa 691 count */
-       5856,   /*  48.12 kPa 692 count */
-       5848,   /*  48.17 kPa 693 count */
-       5840,   /*  48.23 kPa 694 count */
-       5832,   /*  48.28 kPa 695 count */
-       5823,   /*  48.33 kPa 696 count */
-       5815,   /*  48.39 kPa 697 count */
-       5807,   /*  48.44 kPa 698 count */
-       5799,   /*  48.50 kPa 699 count */
-       5791,   /*  48.55 kPa 700 count */
-       5782,   /*  48.61 kPa 701 count */
-       5774,   /*  48.66 kPa 702 count */
-       5766,   /*  48.71 kPa 703 count */
-       5758,   /*  48.77 kPa 704 count */
-       5750,   /*  48.82 kPa 705 count */
-       5742,   /*  48.88 kPa 706 count */
-       5733,   /*  48.93 kPa 707 count */
-       5725,   /*  48.99 kPa 708 count */
-       5717,   /*  49.04 kPa 709 count */
-       5709,   /*  49.09 kPa 710 count */
-       5701,   /*  49.15 kPa 711 count */
-       5693,   /*  49.20 kPa 712 count */
-       5685,   /*  49.26 kPa 713 count */
-       5677,   /*  49.31 kPa 714 count */
-       5668,   /*  49.37 kPa 715 count */
-       5660,   /*  49.42 kPa 716 count */
-       5652,   /*  49.47 kPa 717 count */
-       5644,   /*  49.53 kPa 718 count */
-       5636,   /*  49.58 kPa 719 count */
-       5628,   /*  49.64 kPa 720 count */
-       5620,   /*  49.69 kPa 721 count */
-       5612,   /*  49.75 kPa 722 count */
-       5604,   /*  49.80 kPa 723 count */
-       5596,   /*  49.85 kPa 724 count */
-       5588,   /*  49.91 kPa 725 count */
-       5580,   /*  49.96 kPa 726 count */
-       5572,   /*  50.02 kPa 727 count */
-       5564,   /*  50.07 kPa 728 count */
-       5556,   /*  50.13 kPa 729 count */
-       5548,   /*  50.18 kPa 730 count */
-       5540,   /*  50.23 kPa 731 count */
-       5532,   /*  50.29 kPa 732 count */
-       5524,   /*  50.34 kPa 733 count */
-       5516,   /*  50.40 kPa 734 count */
-       5508,   /*  50.45 kPa 735 count */
-       5500,   /*  50.51 kPa 736 count */
-       5492,   /*  50.56 kPa 737 count */
-       5484,   /*  50.61 kPa 738 count */
-       5476,   /*  50.67 kPa 739 count */
-       5468,   /*  50.72 kPa 740 count */
-       5461,   /*  50.78 kPa 741 count */
-       5453,   /*  50.83 kPa 742 count */
-       5445,   /*  50.89 kPa 743 count */
-       5437,   /*  50.94 kPa 744 count */
-       5429,   /*  50.99 kPa 745 count */
-       5421,   /*  51.05 kPa 746 count */
-       5413,   /*  51.10 kPa 747 count */
-       5405,   /*  51.16 kPa 748 count */
-       5398,   /*  51.21 kPa 749 count */
-       5390,   /*  51.27 kPa 750 count */
-       5382,   /*  51.32 kPa 751 count */
-       5374,   /*  51.37 kPa 752 count */
-       5366,   /*  51.43 kPa 753 count */
-       5358,   /*  51.48 kPa 754 count */
-       5351,   /*  51.54 kPa 755 count */
-       5343,   /*  51.59 kPa 756 count */
-       5335,   /*  51.65 kPa 757 count */
-       5327,   /*  51.70 kPa 758 count */
-       5319,   /*  51.75 kPa 759 count */
-       5312,   /*  51.81 kPa 760 count */
-       5304,   /*  51.86 kPa 761 count */
-       5296,   /*  51.92 kPa 762 count */
-       5288,   /*  51.97 kPa 763 count */
-       5281,   /*  52.03 kPa 764 count */
-       5273,   /*  52.08 kPa 765 count */
-       5265,   /*  52.13 kPa 766 count */
-       5257,   /*  52.19 kPa 767 count */
-       5250,   /*  52.24 kPa 768 count */
-       5242,   /*  52.30 kPa 769 count */
-       5234,   /*  52.35 kPa 770 count */
-       5226,   /*  52.41 kPa 771 count */
-       5219,   /*  52.46 kPa 772 count */
-       5211,   /*  52.51 kPa 773 count */
-       5203,   /*  52.57 kPa 774 count */
-       5196,   /*  52.62 kPa 775 count */
-       5188,   /*  52.68 kPa 776 count */
-       5180,   /*  52.73 kPa 777 count */
-       5173,   /*  52.79 kPa 778 count */
-       5165,   /*  52.84 kPa 779 count */
-       5157,   /*  52.89 kPa 780 count */
-       5150,   /*  52.95 kPa 781 count */
-       5142,   /*  53.00 kPa 782 count */
-       5134,   /*  53.06 kPa 783 count */
-       5127,   /*  53.11 kPa 784 count */
-       5119,   /*  53.17 kPa 785 count */
-       5112,   /*  53.22 kPa 786 count */
-       5104,   /*  53.27 kPa 787 count */
-       5096,   /*  53.33 kPa 788 count */
-       5089,   /*  53.38 kPa 789 count */
-       5081,   /*  53.44 kPa 790 count */
-       5074,   /*  53.49 kPa 791 count */
-       5066,   /*  53.55 kPa 792 count */
-       5058,   /*  53.60 kPa 793 count */
-       5051,   /*  53.65 kPa 794 count */
-       5043,   /*  53.71 kPa 795 count */
-       5036,   /*  53.76 kPa 796 count */
-       5028,   /*  53.82 kPa 797 count */
-       5021,   /*  53.87 kPa 798 count */
-       5013,   /*  53.93 kPa 799 count */
-       5006,   /*  53.98 kPa 800 count */
-       4998,   /*  54.03 kPa 801 count */
-       4991,   /*  54.09 kPa 802 count */
-       4983,   /*  54.14 kPa 803 count */
-       4976,   /*  54.20 kPa 804 count */
-       4968,   /*  54.25 kPa 805 count */
-       4961,   /*  54.31 kPa 806 count */
-       4953,   /*  54.36 kPa 807 count */
-       4946,   /*  54.41 kPa 808 count */
-       4938,   /*  54.47 kPa 809 count */
-       4931,   /*  54.52 kPa 810 count */
-       4923,   /*  54.58 kPa 811 count */
-       4916,   /*  54.63 kPa 812 count */
-       4908,   /*  54.69 kPa 813 count */
-       4901,   /*  54.74 kPa 814 count */
-       4893,   /*  54.79 kPa 815 count */
-       4886,   /*  54.85 kPa 816 count */
-       4879,   /*  54.90 kPa 817 count */
-       4871,   /*  54.96 kPa 818 count */
-       4864,   /*  55.01 kPa 819 count */
-       4856,   /*  55.07 kPa 820 count */
-       4849,   /*  55.12 kPa 821 count */
-       4842,   /*  55.17 kPa 822 count */
-       4834,   /*  55.23 kPa 823 count */
-       4827,   /*  55.28 kPa 824 count */
-       4819,   /*  55.34 kPa 825 count */
-       4812,   /*  55.39 kPa 826 count */
-       4805,   /*  55.45 kPa 827 count */
-       4797,   /*  55.50 kPa 828 count */
-       4790,   /*  55.55 kPa 829 count */
-       4783,   /*  55.61 kPa 830 count */
-       4775,   /*  55.66 kPa 831 count */
-       4768,   /*  55.72 kPa 832 count */
-       4761,   /*  55.77 kPa 833 count */
-       4753,   /*  55.83 kPa 834 count */
-       4746,   /*  55.88 kPa 835 count */
-       4739,   /*  55.93 kPa 836 count */
-       4731,   /*  55.99 kPa 837 count */
-       4724,   /*  56.04 kPa 838 count */
-       4717,   /*  56.10 kPa 839 count */
-       4709,   /*  56.15 kPa 840 count */
-       4702,   /*  56.21 kPa 841 count */
-       4695,   /*  56.26 kPa 842 count */
-       4688,   /*  56.31 kPa 843 count */
-       4680,   /*  56.37 kPa 844 count */
-       4673,   /*  56.42 kPa 845 count */
-       4666,   /*  56.48 kPa 846 count */
-       4659,   /*  56.53 kPa 847 count */
-       4651,   /*  56.58 kPa 848 count */
-       4644,   /*  56.64 kPa 849 count */
-       4637,   /*  56.69 kPa 850 count */
-       4630,   /*  56.75 kPa 851 count */
-       4622,   /*  56.80 kPa 852 count */
-       4615,   /*  56.86 kPa 853 count */
-       4608,   /*  56.91 kPa 854 count */
-       4601,   /*  56.96 kPa 855 count */
-       4594,   /*  57.02 kPa 856 count */
-       4586,   /*  57.07 kPa 857 count */
-       4579,   /*  57.13 kPa 858 count */
-       4572,   /*  57.18 kPa 859 count */
-       4565,   /*  57.24 kPa 860 count */
-       4558,   /*  57.29 kPa 861 count */
-       4550,   /*  57.34 kPa 862 count */
-       4543,   /*  57.40 kPa 863 count */
-       4536,   /*  57.45 kPa 864 count */
-       4529,   /*  57.51 kPa 865 count */
-       4522,   /*  57.56 kPa 866 count */
-       4515,   /*  57.62 kPa 867 count */
-       4508,   /*  57.67 kPa 868 count */
-       4500,   /*  57.72 kPa 869 count */
-       4493,   /*  57.78 kPa 870 count */
-       4486,   /*  57.83 kPa 871 count */
-       4479,   /*  57.89 kPa 872 count */
-       4472,   /*  57.94 kPa 873 count */
-       4465,   /*  58.00 kPa 874 count */
-       4458,   /*  58.05 kPa 875 count */
-       4451,   /*  58.10 kPa 876 count */
-       4444,   /*  58.16 kPa 877 count */
-       4437,   /*  58.21 kPa 878 count */
-       4429,   /*  58.27 kPa 879 count */
-       4422,   /*  58.32 kPa 880 count */
-       4415,   /*  58.38 kPa 881 count */
-       4408,   /*  58.43 kPa 882 count */
-       4401,   /*  58.48 kPa 883 count */
-       4394,   /*  58.54 kPa 884 count */
-       4387,   /*  58.59 kPa 885 count */
-       4380,   /*  58.65 kPa 886 count */
-       4373,   /*  58.70 kPa 887 count */
-       4366,   /*  58.76 kPa 888 count */
-       4359,   /*  58.81 kPa 889 count */
-       4352,   /*  58.86 kPa 890 count */
-       4345,   /*  58.92 kPa 891 count */
-       4338,   /*  58.97 kPa 892 count */
-       4331,   /*  59.03 kPa 893 count */
-       4324,   /*  59.08 kPa 894 count */
-       4317,   /*  59.14 kPa 895 count */
-       4310,   /*  59.19 kPa 896 count */
-       4303,   /*  59.24 kPa 897 count */
-       4296,   /*  59.30 kPa 898 count */
-       4289,   /*  59.35 kPa 899 count */
-       4282,   /*  59.41 kPa 900 count */
-       4275,   /*  59.46 kPa 901 count */
-       4268,   /*  59.52 kPa 902 count */
-       4261,   /*  59.57 kPa 903 count */
-       4254,   /*  59.62 kPa 904 count */
-       4247,   /*  59.68 kPa 905 count */
-       4240,   /*  59.73 kPa 906 count */
-       4234,   /*  59.79 kPa 907 count */
-       4227,   /*  59.84 kPa 908 count */
-       4220,   /*  59.90 kPa 909 count */
-       4213,   /*  59.95 kPa 910 count */
-       4206,   /*  60.00 kPa 911 count */
-       4199,   /*  60.06 kPa 912 count */
-       4192,   /*  60.11 kPa 913 count */
-       4185,   /*  60.17 kPa 914 count */
-       4178,   /*  60.22 kPa 915 count */
-       4171,   /*  60.28 kPa 916 count */
-       4164,   /*  60.33 kPa 917 count */
-       4158,   /*  60.38 kPa 918 count */
-       4151,   /*  60.44 kPa 919 count */
-       4144,   /*  60.49 kPa 920 count */
-       4137,   /*  60.55 kPa 921 count */
-       4130,   /*  60.60 kPa 922 count */
-       4123,   /*  60.66 kPa 923 count */
-       4116,   /*  60.71 kPa 924 count */
-       4110,   /*  60.76 kPa 925 count */
-       4103,   /*  60.82 kPa 926 count */
-       4096,   /*  60.87 kPa 927 count */
-       4089,   /*  60.93 kPa 928 count */
-       4082,   /*  60.98 kPa 929 count */
-       4076,   /*  61.04 kPa 930 count */
-       4069,   /*  61.09 kPa 931 count */
-       4062,   /*  61.14 kPa 932 count */
-       4055,   /*  61.20 kPa 933 count */
-       4048,   /*  61.25 kPa 934 count */
-       4042,   /*  61.31 kPa 935 count */
-       4035,   /*  61.36 kPa 936 count */
-       4028,   /*  61.42 kPa 937 count */
-       4021,   /*  61.47 kPa 938 count */
-       4014,   /*  61.52 kPa 939 count */
-       4008,   /*  61.58 kPa 940 count */
-       4001,   /*  61.63 kPa 941 count */
-       3994,   /*  61.69 kPa 942 count */
-       3987,   /*  61.74 kPa 943 count */
-       3981,   /*  61.80 kPa 944 count */
-       3974,   /*  61.85 kPa 945 count */
-       3967,   /*  61.90 kPa 946 count */
-       3960,   /*  61.96 kPa 947 count */
-       3954,   /*  62.01 kPa 948 count */
-       3947,   /*  62.07 kPa 949 count */
-       3940,   /*  62.12 kPa 950 count */
-       3934,   /*  62.18 kPa 951 count */
-       3927,   /*  62.23 kPa 952 count */
-       3920,   /*  62.28 kPa 953 count */
-       3913,   /*  62.34 kPa 954 count */
-       3907,   /*  62.39 kPa 955 count */
-       3900,   /*  62.45 kPa 956 count */
-       3893,   /*  62.50 kPa 957 count */
-       3887,   /*  62.56 kPa 958 count */
-       3880,   /*  62.61 kPa 959 count */
-       3873,   /*  62.66 kPa 960 count */
-       3867,   /*  62.72 kPa 961 count */
-       3860,   /*  62.77 kPa 962 count */
-       3853,   /*  62.83 kPa 963 count */
-       3847,   /*  62.88 kPa 964 count */
-       3840,   /*  62.94 kPa 965 count */
-       3833,   /*  62.99 kPa 966 count */
-       3827,   /*  63.04 kPa 967 count */
-       3820,   /*  63.10 kPa 968 count */
-       3814,   /*  63.15 kPa 969 count */
-       3807,   /*  63.21 kPa 970 count */
-       3800,   /*  63.26 kPa 971 count */
-       3794,   /*  63.32 kPa 972 count */
-       3787,   /*  63.37 kPa 973 count */
-       3780,   /*  63.42 kPa 974 count */
-       3774,   /*  63.48 kPa 975 count */
-       3767,   /*  63.53 kPa 976 count */
-       3761,   /*  63.59 kPa 977 count */
-       3754,   /*  63.64 kPa 978 count */
-       3748,   /*  63.70 kPa 979 count */
-       3741,   /*  63.75 kPa 980 count */
-       3734,   /*  63.80 kPa 981 count */
-       3728,   /*  63.86 kPa 982 count */
-       3721,   /*  63.91 kPa 983 count */
-       3715,   /*  63.97 kPa 984 count */
-       3708,   /*  64.02 kPa 985 count */
-       3702,   /*  64.08 kPa 986 count */
-       3695,   /*  64.13 kPa 987 count */
-       3688,   /*  64.18 kPa 988 count */
-       3682,   /*  64.24 kPa 989 count */
-       3675,   /*  64.29 kPa 990 count */
-       3669,   /*  64.35 kPa 991 count */
-       3662,   /*  64.40 kPa 992 count */
-       3656,   /*  64.46 kPa 993 count */
-       3649,   /*  64.51 kPa 994 count */
-       3643,   /*  64.56 kPa 995 count */
-       3636,   /*  64.62 kPa 996 count */
-       3630,   /*  64.67 kPa 997 count */
-       3623,   /*  64.73 kPa 998 count */
-       3617,   /*  64.78 kPa 999 count */
-       3610,   /*  64.84 kPa 1000 count */
-       3604,   /*  64.89 kPa 1001 count */
-       3597,   /*  64.94 kPa 1002 count */
-       3591,   /*  65.00 kPa 1003 count */
-       3584,   /*  65.05 kPa 1004 count */
-       3578,   /*  65.11 kPa 1005 count */
-       3571,   /*  65.16 kPa 1006 count */
-       3565,   /*  65.22 kPa 1007 count */
-       3559,   /*  65.27 kPa 1008 count */
-       3552,   /*  65.32 kPa 1009 count */
-       3546,   /*  65.38 kPa 1010 count */
-       3539,   /*  65.43 kPa 1011 count */
-       3533,   /*  65.49 kPa 1012 count */
-       3526,   /*  65.54 kPa 1013 count */
-       3520,   /*  65.60 kPa 1014 count */
-       3514,   /*  65.65 kPa 1015 count */
-       3507,   /*  65.70 kPa 1016 count */
-       3501,   /*  65.76 kPa 1017 count */
-       3494,   /*  65.81 kPa 1018 count */
-       3488,   /*  65.87 kPa 1019 count */
-       3481,   /*  65.92 kPa 1020 count */
-       3475,   /*  65.98 kPa 1021 count */
-       3469,   /*  66.03 kPa 1022 count */
-       3462,   /*  66.08 kPa 1023 count */
-       3456,   /*  66.14 kPa 1024 count */
-       3450,   /*  66.19 kPa 1025 count */
-       3443,   /*  66.25 kPa 1026 count */
-       3437,   /*  66.30 kPa 1027 count */
-       3430,   /*  66.36 kPa 1028 count */
-       3424,   /*  66.41 kPa 1029 count */
-       3418,   /*  66.46 kPa 1030 count */
-       3411,   /*  66.52 kPa 1031 count */
-       3405,   /*  66.57 kPa 1032 count */
-       3399,   /*  66.63 kPa 1033 count */
-       3392,   /*  66.68 kPa 1034 count */
-       3386,   /*  66.74 kPa 1035 count */
-       3380,   /*  66.79 kPa 1036 count */
-       3373,   /*  66.84 kPa 1037 count */
-       3367,   /*  66.90 kPa 1038 count */
-       3361,   /*  66.95 kPa 1039 count */
-       3354,   /*  67.01 kPa 1040 count */
-       3348,   /*  67.06 kPa 1041 count */
-       3342,   /*  67.12 kPa 1042 count */
-       3335,   /*  67.17 kPa 1043 count */
-       3329,   /*  67.22 kPa 1044 count */
-       3323,   /*  67.28 kPa 1045 count */
-       3316,   /*  67.33 kPa 1046 count */
-       3310,   /*  67.39 kPa 1047 count */
-       3304,   /*  67.44 kPa 1048 count */
-       3298,   /*  67.50 kPa 1049 count */
-       3291,   /*  67.55 kPa 1050 count */
-       3285,   /*  67.60 kPa 1051 count */
-       3279,   /*  67.66 kPa 1052 count */
-       3273,   /*  67.71 kPa 1053 count */
-       3266,   /*  67.77 kPa 1054 count */
-       3260,   /*  67.82 kPa 1055 count */
-       3254,   /*  67.88 kPa 1056 count */
-       3248,   /*  67.93 kPa 1057 count */
-       3241,   /*  67.98 kPa 1058 count */
-       3235,   /*  68.04 kPa 1059 count */
-       3229,   /*  68.09 kPa 1060 count */
-       3223,   /*  68.15 kPa 1061 count */
-       3216,   /*  68.20 kPa 1062 count */
-       3210,   /*  68.26 kPa 1063 count */
-       3204,   /*  68.31 kPa 1064 count */
-       3198,   /*  68.36 kPa 1065 count */
-       3191,   /*  68.42 kPa 1066 count */
-       3185,   /*  68.47 kPa 1067 count */
-       3179,   /*  68.53 kPa 1068 count */
-       3173,   /*  68.58 kPa 1069 count */
-       3167,   /*  68.64 kPa 1070 count */
-       3160,   /*  68.69 kPa 1071 count */
-       3154,   /*  68.74 kPa 1072 count */
-       3148,   /*  68.80 kPa 1073 count */
-       3142,   /*  68.85 kPa 1074 count */
-       3136,   /*  68.91 kPa 1075 count */
-       3130,   /*  68.96 kPa 1076 count */
-       3123,   /*  69.02 kPa 1077 count */
-       3117,   /*  69.07 kPa 1078 count */
-       3111,   /*  69.12 kPa 1079 count */
-       3105,   /*  69.18 kPa 1080 count */
-       3099,   /*  69.23 kPa 1081 count */
-       3093,   /*  69.29 kPa 1082 count */
-       3087,   /*  69.34 kPa 1083 count */
-       3080,   /*  69.40 kPa 1084 count */
-       3074,   /*  69.45 kPa 1085 count */
-       3068,   /*  69.50 kPa 1086 count */
-       3062,   /*  69.56 kPa 1087 count */
-       3056,   /*  69.61 kPa 1088 count */
-       3050,   /*  69.67 kPa 1089 count */
-       3044,   /*  69.72 kPa 1090 count */
-       3037,   /*  69.78 kPa 1091 count */
-       3031,   /*  69.83 kPa 1092 count */
-       3025,   /*  69.88 kPa 1093 count */
-       3019,   /*  69.94 kPa 1094 count */
-       3013,   /*  69.99 kPa 1095 count */
-       3007,   /*  70.05 kPa 1096 count */
-       3001,   /*  70.10 kPa 1097 count */
-       2995,   /*  70.15 kPa 1098 count */
-       2989,   /*  70.21 kPa 1099 count */
-       2983,   /*  70.26 kPa 1100 count */
-       2977,   /*  70.32 kPa 1101 count */
-       2970,   /*  70.37 kPa 1102 count */
-       2964,   /*  70.43 kPa 1103 count */
-       2958,   /*  70.48 kPa 1104 count */
-       2952,   /*  70.53 kPa 1105 count */
-       2946,   /*  70.59 kPa 1106 count */
-       2940,   /*  70.64 kPa 1107 count */
-       2934,   /*  70.70 kPa 1108 count */
-       2928,   /*  70.75 kPa 1109 count */
-       2922,   /*  70.81 kPa 1110 count */
-       2916,   /*  70.86 kPa 1111 count */
-       2910,   /*  70.91 kPa 1112 count */
-       2904,   /*  70.97 kPa 1113 count */
-       2898,   /*  71.02 kPa 1114 count */
-       2892,   /*  71.08 kPa 1115 count */
-       2886,   /*  71.13 kPa 1116 count */
-       2880,   /*  71.19 kPa 1117 count */
-       2874,   /*  71.24 kPa 1118 count */
-       2868,   /*  71.29 kPa 1119 count */
-       2862,   /*  71.35 kPa 1120 count */
-       2856,   /*  71.40 kPa 1121 count */
-       2850,   /*  71.46 kPa 1122 count */
-       2844,   /*  71.51 kPa 1123 count */
-       2838,   /*  71.57 kPa 1124 count */
-       2832,   /*  71.62 kPa 1125 count */
-       2826,   /*  71.67 kPa 1126 count */
-       2820,   /*  71.73 kPa 1127 count */
-       2814,   /*  71.78 kPa 1128 count */
-       2808,   /*  71.84 kPa 1129 count */
-       2802,   /*  71.89 kPa 1130 count */
-       2796,   /*  71.95 kPa 1131 count */
-       2790,   /*  72.00 kPa 1132 count */
-       2784,   /*  72.05 kPa 1133 count */
-       2778,   /*  72.11 kPa 1134 count */
-       2772,   /*  72.16 kPa 1135 count */
-       2766,   /*  72.22 kPa 1136 count */
-       2760,   /*  72.27 kPa 1137 count */
-       2754,   /*  72.33 kPa 1138 count */
-       2748,   /*  72.38 kPa 1139 count */
-       2743,   /*  72.43 kPa 1140 count */
-       2737,   /*  72.49 kPa 1141 count */
-       2731,   /*  72.54 kPa 1142 count */
-       2725,   /*  72.60 kPa 1143 count */
-       2719,   /*  72.65 kPa 1144 count */
-       2713,   /*  72.71 kPa 1145 count */
-       2707,   /*  72.76 kPa 1146 count */
-       2701,   /*  72.81 kPa 1147 count */
-       2695,   /*  72.87 kPa 1148 count */
-       2689,   /*  72.92 kPa 1149 count */
-       2683,   /*  72.98 kPa 1150 count */
-       2678,   /*  73.03 kPa 1151 count */
-       2672,   /*  73.09 kPa 1152 count */
-       2666,   /*  73.14 kPa 1153 count */
-       2660,   /*  73.19 kPa 1154 count */
-       2654,   /*  73.25 kPa 1155 count */
-       2648,   /*  73.30 kPa 1156 count */
-       2642,   /*  73.36 kPa 1157 count */
-       2636,   /*  73.41 kPa 1158 count */
-       2631,   /*  73.47 kPa 1159 count */
-       2625,   /*  73.52 kPa 1160 count */
-       2619,   /*  73.57 kPa 1161 count */
-       2613,   /*  73.63 kPa 1162 count */
-       2607,   /*  73.68 kPa 1163 count */
-       2601,   /*  73.74 kPa 1164 count */
-       2595,   /*  73.79 kPa 1165 count */
-       2590,   /*  73.85 kPa 1166 count */
-       2584,   /*  73.90 kPa 1167 count */
-       2578,   /*  73.95 kPa 1168 count */
-       2572,   /*  74.01 kPa 1169 count */
-       2566,   /*  74.06 kPa 1170 count */
-       2560,   /*  74.12 kPa 1171 count */
-       2555,   /*  74.17 kPa 1172 count */
-       2549,   /*  74.23 kPa 1173 count */
-       2543,   /*  74.28 kPa 1174 count */
-       2537,   /*  74.33 kPa 1175 count */
-       2531,   /*  74.39 kPa 1176 count */
-       2526,   /*  74.44 kPa 1177 count */
-       2520,   /*  74.50 kPa 1178 count */
-       2514,   /*  74.55 kPa 1179 count */
-       2508,   /*  74.61 kPa 1180 count */
-       2502,   /*  74.66 kPa 1181 count */
-       2497,   /*  74.71 kPa 1182 count */
-       2491,   /*  74.77 kPa 1183 count */
-       2485,   /*  74.82 kPa 1184 count */
-       2479,   /*  74.88 kPa 1185 count */
-       2473,   /*  74.93 kPa 1186 count */
-       2468,   /*  74.99 kPa 1187 count */
-       2462,   /*  75.04 kPa 1188 count */
-       2456,   /*  75.09 kPa 1189 count */
-       2450,   /*  75.15 kPa 1190 count */
-       2445,   /*  75.20 kPa 1191 count */
-       2439,   /*  75.26 kPa 1192 count */
-       2433,   /*  75.31 kPa 1193 count */
-       2427,   /*  75.37 kPa 1194 count */
-       2422,   /*  75.42 kPa 1195 count */
-       2416,   /*  75.47 kPa 1196 count */
-       2410,   /*  75.53 kPa 1197 count */
-       2405,   /*  75.58 kPa 1198 count */
-       2399,   /*  75.64 kPa 1199 count */
-       2393,   /*  75.69 kPa 1200 count */
-       2387,   /*  75.75 kPa 1201 count */
-       2382,   /*  75.80 kPa 1202 count */
-       2376,   /*  75.85 kPa 1203 count */
-       2370,   /*  75.91 kPa 1204 count */
-       2364,   /*  75.96 kPa 1205 count */
-       2359,   /*  76.02 kPa 1206 count */
-       2353,   /*  76.07 kPa 1207 count */
-       2347,   /*  76.13 kPa 1208 count */
-       2342,   /*  76.18 kPa 1209 count */
-       2336,   /*  76.23 kPa 1210 count */
-       2330,   /*  76.29 kPa 1211 count */
-       2325,   /*  76.34 kPa 1212 count */
-       2319,   /*  76.40 kPa 1213 count */
-       2313,   /*  76.45 kPa 1214 count */
-       2308,   /*  76.51 kPa 1215 count */
-       2302,   /*  76.56 kPa 1216 count */
-       2296,   /*  76.61 kPa 1217 count */
-       2291,   /*  76.67 kPa 1218 count */
-       2285,   /*  76.72 kPa 1219 count */
-       2279,   /*  76.78 kPa 1220 count */
-       2274,   /*  76.83 kPa 1221 count */
-       2268,   /*  76.89 kPa 1222 count */
-       2262,   /*  76.94 kPa 1223 count */
-       2257,   /*  76.99 kPa 1224 count */
-       2251,   /*  77.05 kPa 1225 count */
-       2245,   /*  77.10 kPa 1226 count */
-       2240,   /*  77.16 kPa 1227 count */
-       2234,   /*  77.21 kPa 1228 count */
-       2228,   /*  77.27 kPa 1229 count */
-       2223,   /*  77.32 kPa 1230 count */
-       2217,   /*  77.37 kPa 1231 count */
-       2212,   /*  77.43 kPa 1232 count */
-       2206,   /*  77.48 kPa 1233 count */
-       2200,   /*  77.54 kPa 1234 count */
-       2195,   /*  77.59 kPa 1235 count */
-       2189,   /*  77.65 kPa 1236 count */
-       2184,   /*  77.70 kPa 1237 count */
-       2178,   /*  77.75 kPa 1238 count */
-       2172,   /*  77.81 kPa 1239 count */
-       2167,   /*  77.86 kPa 1240 count */
-       2161,   /*  77.92 kPa 1241 count */
-       2156,   /*  77.97 kPa 1242 count */
-       2150,   /*  78.03 kPa 1243 count */
-       2144,   /*  78.08 kPa 1244 count */
-       2139,   /*  78.13 kPa 1245 count */
-       2133,   /*  78.19 kPa 1246 count */
-       2128,   /*  78.24 kPa 1247 count */
-       2122,   /*  78.30 kPa 1248 count */
-       2117,   /*  78.35 kPa 1249 count */
-       2111,   /*  78.41 kPa 1250 count */
-       2105,   /*  78.46 kPa 1251 count */
-       2100,   /*  78.51 kPa 1252 count */
-       2094,   /*  78.57 kPa 1253 count */
-       2089,   /*  78.62 kPa 1254 count */
-       2083,   /*  78.68 kPa 1255 count */
-       2078,   /*  78.73 kPa 1256 count */
-       2072,   /*  78.79 kPa 1257 count */
-       2067,   /*  78.84 kPa 1258 count */
-       2061,   /*  78.89 kPa 1259 count */
-       2056,   /*  78.95 kPa 1260 count */
-       2050,   /*  79.00 kPa 1261 count */
-       2045,   /*  79.06 kPa 1262 count */
-       2039,   /*  79.11 kPa 1263 count */
-       2033,   /*  79.17 kPa 1264 count */
-       2028,   /*  79.22 kPa 1265 count */
-       2022,   /*  79.27 kPa 1266 count */
-       2017,   /*  79.33 kPa 1267 count */
-       2011,   /*  79.38 kPa 1268 count */
-       2006,   /*  79.44 kPa 1269 count */
-       2000,   /*  79.49 kPa 1270 count */
-       1995,   /*  79.55 kPa 1271 count */
-       1989,   /*  79.60 kPa 1272 count */
-       1984,   /*  79.65 kPa 1273 count */
-       1978,   /*  79.71 kPa 1274 count */
-       1973,   /*  79.76 kPa 1275 count */
-       1967,   /*  79.82 kPa 1276 count */
-       1962,   /*  79.87 kPa 1277 count */
-       1957,   /*  79.93 kPa 1278 count */
-       1951,   /*  79.98 kPa 1279 count */
-       1946,   /*  80.03 kPa 1280 count */
-       1940,   /*  80.09 kPa 1281 count */
-       1935,   /*  80.14 kPa 1282 count */
-       1929,   /*  80.20 kPa 1283 count */
-       1924,   /*  80.25 kPa 1284 count */
-       1918,   /*  80.31 kPa 1285 count */
-       1913,   /*  80.36 kPa 1286 count */
-       1907,   /*  80.41 kPa 1287 count */
-       1902,   /*  80.47 kPa 1288 count */
-       1896,   /*  80.52 kPa 1289 count */
-       1891,   /*  80.58 kPa 1290 count */
-       1886,   /*  80.63 kPa 1291 count */
-       1880,   /*  80.69 kPa 1292 count */
-       1875,   /*  80.74 kPa 1293 count */
-       1869,   /*  80.79 kPa 1294 count */
-       1864,   /*  80.85 kPa 1295 count */
-       1858,   /*  80.90 kPa 1296 count */
-       1853,   /*  80.96 kPa 1297 count */
-       1848,   /*  81.01 kPa 1298 count */
-       1842,   /*  81.07 kPa 1299 count */
-       1837,   /*  81.12 kPa 1300 count */
-       1831,   /*  81.17 kPa 1301 count */
-       1826,   /*  81.23 kPa 1302 count */
-       1821,   /*  81.28 kPa 1303 count */
-       1815,   /*  81.34 kPa 1304 count */
-       1810,   /*  81.39 kPa 1305 count */
-       1804,   /*  81.45 kPa 1306 count */
-       1799,   /*  81.50 kPa 1307 count */
-       1794,   /*  81.55 kPa 1308 count */
-       1788,   /*  81.61 kPa 1309 count */
-       1783,   /*  81.66 kPa 1310 count */
-       1777,   /*  81.72 kPa 1311 count */
-       1772,   /*  81.77 kPa 1312 count */
-       1767,   /*  81.83 kPa 1313 count */
-       1761,   /*  81.88 kPa 1314 count */
-       1756,   /*  81.93 kPa 1315 count */
-       1751,   /*  81.99 kPa 1316 count */
-       1745,   /*  82.04 kPa 1317 count */
-       1740,   /*  82.10 kPa 1318 count */
-       1735,   /*  82.15 kPa 1319 count */
-       1729,   /*  82.21 kPa 1320 count */
-       1724,   /*  82.26 kPa 1321 count */
-       1718,   /*  82.31 kPa 1322 count */
-       1713,   /*  82.37 kPa 1323 count */
-       1708,   /*  82.42 kPa 1324 count */
-       1702,   /*  82.48 kPa 1325 count */
-       1697,   /*  82.53 kPa 1326 count */
-       1692,   /*  82.59 kPa 1327 count */
-       1686,   /*  82.64 kPa 1328 count */
-       1681,   /*  82.69 kPa 1329 count */
-       1676,   /*  82.75 kPa 1330 count */
-       1670,   /*  82.80 kPa 1331 count */
-       1665,   /*  82.86 kPa 1332 count */
-       1660,   /*  82.91 kPa 1333 count */
-       1655,   /*  82.97 kPa 1334 count */
-       1649,   /*  83.02 kPa 1335 count */
-       1644,   /*  83.07 kPa 1336 count */
-       1639,   /*  83.13 kPa 1337 count */
-       1633,   /*  83.18 kPa 1338 count */
-       1628,   /*  83.24 kPa 1339 count */
-       1623,   /*  83.29 kPa 1340 count */
-       1617,   /*  83.35 kPa 1341 count */
-       1612,   /*  83.40 kPa 1342 count */
-       1607,   /*  83.45 kPa 1343 count */
-       1602,   /*  83.51 kPa 1344 count */
-       1596,   /*  83.56 kPa 1345 count */
-       1591,   /*  83.62 kPa 1346 count */
-       1586,   /*  83.67 kPa 1347 count */
-       1580,   /*  83.72 kPa 1348 count */
-       1575,   /*  83.78 kPa 1349 count */
-       1570,   /*  83.83 kPa 1350 count */
-       1565,   /*  83.89 kPa 1351 count */
-       1559,   /*  83.94 kPa 1352 count */
-       1554,   /*  84.00 kPa 1353 count */
-       1549,   /*  84.05 kPa 1354 count */
-       1544,   /*  84.10 kPa 1355 count */
-       1538,   /*  84.16 kPa 1356 count */
-       1533,   /*  84.21 kPa 1357 count */
-       1528,   /*  84.27 kPa 1358 count */
-       1523,   /*  84.32 kPa 1359 count */
-       1517,   /*  84.38 kPa 1360 count */
-       1512,   /*  84.43 kPa 1361 count */
-       1507,   /*  84.48 kPa 1362 count */
-       1502,   /*  84.54 kPa 1363 count */
-       1496,   /*  84.59 kPa 1364 count */
-       1491,   /*  84.65 kPa 1365 count */
-       1486,   /*  84.70 kPa 1366 count */
-       1481,   /*  84.76 kPa 1367 count */
-       1475,   /*  84.81 kPa 1368 count */
-       1470,   /*  84.86 kPa 1369 count */
-       1465,   /*  84.92 kPa 1370 count */
-       1460,   /*  84.97 kPa 1371 count */
-       1455,   /*  85.03 kPa 1372 count */
-       1449,   /*  85.08 kPa 1373 count */
-       1444,   /*  85.14 kPa 1374 count */
-       1439,   /*  85.19 kPa 1375 count */
-       1434,   /*  85.24 kPa 1376 count */
-       1429,   /*  85.30 kPa 1377 count */
-       1423,   /*  85.35 kPa 1378 count */
-       1418,   /*  85.41 kPa 1379 count */
-       1413,   /*  85.46 kPa 1380 count */
-       1408,   /*  85.52 kPa 1381 count */
-       1403,   /*  85.57 kPa 1382 count */
-       1398,   /*  85.62 kPa 1383 count */
-       1392,   /*  85.68 kPa 1384 count */
-       1387,   /*  85.73 kPa 1385 count */
-       1382,   /*  85.79 kPa 1386 count */
-       1377,   /*  85.84 kPa 1387 count */
-       1372,   /*  85.90 kPa 1388 count */
-       1366,   /*  85.95 kPa 1389 count */
-       1361,   /*  86.00 kPa 1390 count */
-       1356,   /*  86.06 kPa 1391 count */
-       1351,   /*  86.11 kPa 1392 count */
-       1346,   /*  86.17 kPa 1393 count */
-       1341,   /*  86.22 kPa 1394 count */
-       1336,   /*  86.28 kPa 1395 count */
-       1330,   /*  86.33 kPa 1396 count */
-       1325,   /*  86.38 kPa 1397 count */
-       1320,   /*  86.44 kPa 1398 count */
-       1315,   /*  86.49 kPa 1399 count */
-       1310,   /*  86.55 kPa 1400 count */
-       1305,   /*  86.60 kPa 1401 count */
-       1300,   /*  86.66 kPa 1402 count */
-       1294,   /*  86.71 kPa 1403 count */
-       1289,   /*  86.76 kPa 1404 count */
-       1284,   /*  86.82 kPa 1405 count */
-       1279,   /*  86.87 kPa 1406 count */
-       1274,   /*  86.93 kPa 1407 count */
-       1269,   /*  86.98 kPa 1408 count */
-       1264,   /*  87.04 kPa 1409 count */
-       1259,   /*  87.09 kPa 1410 count */
-       1254,   /*  87.14 kPa 1411 count */
-       1248,   /*  87.20 kPa 1412 count */
-       1243,   /*  87.25 kPa 1413 count */
-       1238,   /*  87.31 kPa 1414 count */
-       1233,   /*  87.36 kPa 1415 count */
-       1228,   /*  87.42 kPa 1416 count */
-       1223,   /*  87.47 kPa 1417 count */
-       1218,   /*  87.52 kPa 1418 count */
-       1213,   /*  87.58 kPa 1419 count */
-       1208,   /*  87.63 kPa 1420 count */
-       1203,   /*  87.69 kPa 1421 count */
-       1198,   /*  87.74 kPa 1422 count */
-       1192,   /*  87.80 kPa 1423 count */
-       1187,   /*  87.85 kPa 1424 count */
-       1182,   /*  87.90 kPa 1425 count */
-       1177,   /*  87.96 kPa 1426 count */
-       1172,   /*  88.01 kPa 1427 count */
-       1167,   /*  88.07 kPa 1428 count */
-       1162,   /*  88.12 kPa 1429 count */
-       1157,   /*  88.18 kPa 1430 count */
-       1152,   /*  88.23 kPa 1431 count */
-       1147,   /*  88.28 kPa 1432 count */
-       1142,   /*  88.34 kPa 1433 count */
-       1137,   /*  88.39 kPa 1434 count */
-       1132,   /*  88.45 kPa 1435 count */
-       1127,   /*  88.50 kPa 1436 count */
-       1122,   /*  88.56 kPa 1437 count */
-       1117,   /*  88.61 kPa 1438 count */
-       1112,   /*  88.66 kPa 1439 count */
-       1107,   /*  88.72 kPa 1440 count */
-       1102,   /*  88.77 kPa 1441 count */
-       1097,   /*  88.83 kPa 1442 count */
-       1091,   /*  88.88 kPa 1443 count */
-       1086,   /*  88.94 kPa 1444 count */
-       1081,   /*  88.99 kPa 1445 count */
-       1076,   /*  89.04 kPa 1446 count */
-       1071,   /*  89.10 kPa 1447 count */
-       1066,   /*  89.15 kPa 1448 count */
-       1061,   /*  89.21 kPa 1449 count */
-       1056,   /*  89.26 kPa 1450 count */
-       1051,   /*  89.32 kPa 1451 count */
-       1046,   /*  89.37 kPa 1452 count */
-       1041,   /*  89.42 kPa 1453 count */
-       1036,   /*  89.48 kPa 1454 count */
-       1031,   /*  89.53 kPa 1455 count */
-       1026,   /*  89.59 kPa 1456 count */
-       1021,   /*  89.64 kPa 1457 count */
-       1016,   /*  89.70 kPa 1458 count */
-       1011,   /*  89.75 kPa 1459 count */
-       1006,   /*  89.80 kPa 1460 count */
-       1001,   /*  89.86 kPa 1461 count */
-       996,    /*  89.91 kPa 1462 count */
-       992,    /*  89.97 kPa 1463 count */
-       987,    /*  90.02 kPa 1464 count */
-       982,    /*  90.08 kPa 1465 count */
-       977,    /*  90.13 kPa 1466 count */
-       972,    /*  90.18 kPa 1467 count */
-       967,    /*  90.24 kPa 1468 count */
-       962,    /*  90.29 kPa 1469 count */
-       957,    /*  90.35 kPa 1470 count */
-       952,    /*  90.40 kPa 1471 count */
-       947,    /*  90.46 kPa 1472 count */
-       942,    /*  90.51 kPa 1473 count */
-       937,    /*  90.56 kPa 1474 count */
-       932,    /*  90.62 kPa 1475 count */
-       927,    /*  90.67 kPa 1476 count */
-       922,    /*  90.73 kPa 1477 count */
-       917,    /*  90.78 kPa 1478 count */
-       912,    /*  90.84 kPa 1479 count */
-       907,    /*  90.89 kPa 1480 count */
-       902,    /*  90.94 kPa 1481 count */
-       897,    /*  91.00 kPa 1482 count */
-       892,    /*  91.05 kPa 1483 count */
-       888,    /*  91.11 kPa 1484 count */
-       883,    /*  91.16 kPa 1485 count */
-       878,    /*  91.22 kPa 1486 count */
-       873,    /*  91.27 kPa 1487 count */
-       868,    /*  91.32 kPa 1488 count */
-       863,    /*  91.38 kPa 1489 count */
-       858,    /*  91.43 kPa 1490 count */
-       853,    /*  91.49 kPa 1491 count */
-       848,    /*  91.54 kPa 1492 count */
-       843,    /*  91.60 kPa 1493 count */
-       838,    /*  91.65 kPa 1494 count */
-       834,    /*  91.70 kPa 1495 count */
-       829,    /*  91.76 kPa 1496 count */
-       824,    /*  91.81 kPa 1497 count */
-       819,    /*  91.87 kPa 1498 count */
-       814,    /*  91.92 kPa 1499 count */
-       809,    /*  91.98 kPa 1500 count */
-       804,    /*  92.03 kPa 1501 count */
-       799,    /*  92.08 kPa 1502 count */
-       794,    /*  92.14 kPa 1503 count */
-       790,    /*  92.19 kPa 1504 count */
-       785,    /*  92.25 kPa 1505 count */
-       780,    /*  92.30 kPa 1506 count */
-       775,    /*  92.36 kPa 1507 count */
-       770,    /*  92.41 kPa 1508 count */
-       765,    /*  92.46 kPa 1509 count */
-       760,    /*  92.52 kPa 1510 count */
-       755,    /*  92.57 kPa 1511 count */
-       751,    /*  92.63 kPa 1512 count */
-       746,    /*  92.68 kPa 1513 count */
-       741,    /*  92.74 kPa 1514 count */
-       736,    /*  92.79 kPa 1515 count */
-       731,    /*  92.84 kPa 1516 count */
-       726,    /*  92.90 kPa 1517 count */
-       721,    /*  92.95 kPa 1518 count */
-       717,    /*  93.01 kPa 1519 count */
-       712,    /*  93.06 kPa 1520 count */
-       707,    /*  93.12 kPa 1521 count */
-       702,    /*  93.17 kPa 1522 count */
-       697,    /*  93.22 kPa 1523 count */
-       692,    /*  93.28 kPa 1524 count */
-       688,    /*  93.33 kPa 1525 count */
-       683,    /*  93.39 kPa 1526 count */
-       678,    /*  93.44 kPa 1527 count */
-       673,    /*  93.50 kPa 1528 count */
-       668,    /*  93.55 kPa 1529 count */
-       664,    /*  93.60 kPa 1530 count */
-       659,    /*  93.66 kPa 1531 count */
-       654,    /*  93.71 kPa 1532 count */
-       649,    /*  93.77 kPa 1533 count */
-       644,    /*  93.82 kPa 1534 count */
-       639,    /*  93.88 kPa 1535 count */
-       635,    /*  93.93 kPa 1536 count */
-       630,    /*  93.98 kPa 1537 count */
-       625,    /*  94.04 kPa 1538 count */
-       620,    /*  94.09 kPa 1539 count */
-       615,    /*  94.15 kPa 1540 count */
-       611,    /*  94.20 kPa 1541 count */
-       606,    /*  94.26 kPa 1542 count */
-       601,    /*  94.31 kPa 1543 count */
-       596,    /*  94.36 kPa 1544 count */
-       591,    /*  94.42 kPa 1545 count */
-       587,    /*  94.47 kPa 1546 count */
-       582,    /*  94.53 kPa 1547 count */
-       577,    /*  94.58 kPa 1548 count */
-       572,    /*  94.64 kPa 1549 count */
-       568,    /*  94.69 kPa 1550 count */
-       563,    /*  94.74 kPa 1551 count */
-       558,    /*  94.80 kPa 1552 count */
-       553,    /*  94.85 kPa 1553 count */
-       549,    /*  94.91 kPa 1554 count */
-       544,    /*  94.96 kPa 1555 count */
-       539,    /*  95.02 kPa 1556 count */
-       534,    /*  95.07 kPa 1557 count */
-       529,    /*  95.12 kPa 1558 count */
-       525,    /*  95.18 kPa 1559 count */
-       520,    /*  95.23 kPa 1560 count */
-       515,    /*  95.29 kPa 1561 count */
-       510,    /*  95.34 kPa 1562 count */
-       506,    /*  95.40 kPa 1563 count */
-       501,    /*  95.45 kPa 1564 count */
-       496,    /*  95.50 kPa 1565 count */
-       492,    /*  95.56 kPa 1566 count */
-       487,    /*  95.61 kPa 1567 count */
-       482,    /*  95.67 kPa 1568 count */
-       477,    /*  95.72 kPa 1569 count */
-       473,    /*  95.78 kPa 1570 count */
-       468,    /*  95.83 kPa 1571 count */
-       463,    /*  95.88 kPa 1572 count */
-       458,    /*  95.94 kPa 1573 count */
-       454,    /*  95.99 kPa 1574 count */
-       449,    /*  96.05 kPa 1575 count */
-       444,    /*  96.10 kPa 1576 count */
-       440,    /*  96.16 kPa 1577 count */
-       435,    /*  96.21 kPa 1578 count */
-       430,    /*  96.26 kPa 1579 count */
-       425,    /*  96.32 kPa 1580 count */
-       421,    /*  96.37 kPa 1581 count */
-       416,    /*  96.43 kPa 1582 count */
-       411,    /*  96.48 kPa 1583 count */
-       407,    /*  96.54 kPa 1584 count */
-       402,    /*  96.59 kPa 1585 count */
-       397,    /*  96.64 kPa 1586 count */
-       392,    /*  96.70 kPa 1587 count */
-       388,    /*  96.75 kPa 1588 count */
-       383,    /*  96.81 kPa 1589 count */
-       378,    /*  96.86 kPa 1590 count */
-       374,    /*  96.91 kPa 1591 count */
-       369,    /*  96.97 kPa 1592 count */
-       364,    /*  97.02 kPa 1593 count */
-       360,    /*  97.08 kPa 1594 count */
-       355,    /*  97.13 kPa 1595 count */
-       350,    /*  97.19 kPa 1596 count */
-       346,    /*  97.24 kPa 1597 count */
-       341,    /*  97.29 kPa 1598 count */
-       336,    /*  97.35 kPa 1599 count */
-       332,    /*  97.40 kPa 1600 count */
-       327,    /*  97.46 kPa 1601 count */
-       322,    /*  97.51 kPa 1602 count */
-       318,    /*  97.57 kPa 1603 count */
-       313,    /*  97.62 kPa 1604 count */
-       308,    /*  97.67 kPa 1605 count */
-       304,    /*  97.73 kPa 1606 count */
-       299,    /*  97.78 kPa 1607 count */
-       294,    /*  97.84 kPa 1608 count */
-       290,    /*  97.89 kPa 1609 count */
-       285,    /*  97.95 kPa 1610 count */
-       280,    /*  98.00 kPa 1611 count */
-       276,    /*  98.05 kPa 1612 count */
-       271,    /*  98.11 kPa 1613 count */
-       267,    /*  98.16 kPa 1614 count */
-       262,    /*  98.22 kPa 1615 count */
-       257,    /*  98.27 kPa 1616 count */
-       253,    /*  98.33 kPa 1617 count */
-       248,    /*  98.38 kPa 1618 count */
-       243,    /*  98.43 kPa 1619 count */
-       239,    /*  98.49 kPa 1620 count */
-       234,    /*  98.54 kPa 1621 count */
-       230,    /*  98.60 kPa 1622 count */
-       225,    /*  98.65 kPa 1623 count */
-       220,    /*  98.71 kPa 1624 count */
-       216,    /*  98.76 kPa 1625 count */
-       211,    /*  98.81 kPa 1626 count */
-       206,    /*  98.87 kPa 1627 count */
-       202,    /*  98.92 kPa 1628 count */
-       197,    /*  98.98 kPa 1629 count */
-       193,    /*  99.03 kPa 1630 count */
-       188,    /*  99.09 kPa 1631 count */
-       183,    /*  99.14 kPa 1632 count */
-       179,    /*  99.19 kPa 1633 count */
-       174,    /*  99.25 kPa 1634 count */
-       170,    /*  99.30 kPa 1635 count */
-       165,    /*  99.36 kPa 1636 count */
-       160,    /*  99.41 kPa 1637 count */
-       156,    /*  99.47 kPa 1638 count */
-       151,    /*  99.52 kPa 1639 count */
-       147,    /*  99.57 kPa 1640 count */
-       142,    /*  99.63 kPa 1641 count */
-       138,    /*  99.68 kPa 1642 count */
-       133,    /*  99.74 kPa 1643 count */
-       128,    /*  99.79 kPa 1644 count */
-       124,    /*  99.85 kPa 1645 count */
-       119,    /*  99.90 kPa 1646 count */
-       115,    /*  99.95 kPa 1647 count */
-       110,    /* 100.01 kPa 1648 count */
-       106,    /* 100.06 kPa 1649 count */
-       101,    /* 100.12 kPa 1650 count */
-       96,     /* 100.17 kPa 1651 count */
-       92,     /* 100.23 kPa 1652 count */
-       87,     /* 100.28 kPa 1653 count */
-       83,     /* 100.33 kPa 1654 count */
-       78,     /* 100.39 kPa 1655 count */
-       74,     /* 100.44 kPa 1656 count */
-       69,     /* 100.50 kPa 1657 count */
-       65,     /* 100.55 kPa 1658 count */
-       60,     /* 100.61 kPa 1659 count */
-       55,     /* 100.66 kPa 1660 count */
-       51,     /* 100.71 kPa 1661 count */
-       46,     /* 100.77 kPa 1662 count */
-       42,     /* 100.82 kPa 1663 count */
-       37,     /* 100.88 kPa 1664 count */
-       33,     /* 100.93 kPa 1665 count */
-       28,     /* 100.99 kPa 1666 count */
-       24,     /* 101.04 kPa 1667 count */
-       19,     /* 101.09 kPa 1668 count */
-       15,     /* 101.15 kPa 1669 count */
-       10,     /* 101.20 kPa 1670 count */
-       6,      /* 101.26 kPa 1671 count */
-       1,      /* 101.31 kPa 1672 count */
-       -3,     /* 101.37 kPa 1673 count */
-       -8,     /* 101.42 kPa 1674 count */
-       -12,    /* 101.47 kPa 1675 count */
-       -17,    /* 101.53 kPa 1676 count */
-       -21,    /* 101.58 kPa 1677 count */
-       -26,    /* 101.64 kPa 1678 count */
-       -30,    /* 101.69 kPa 1679 count */
-       -35,    /* 101.75 kPa 1680 count */
-       -39,    /* 101.80 kPa 1681 count */
-       -44,    /* 101.85 kPa 1682 count */
-       -48,    /* 101.91 kPa 1683 count */
-       -53,    /* 101.96 kPa 1684 count */
-       -57,    /* 102.02 kPa 1685 count */
-       -62,    /* 102.07 kPa 1686 count */
-       -66,    /* 102.13 kPa 1687 count */
-       -71,    /* 102.18 kPa 1688 count */
-       -75,    /* 102.23 kPa 1689 count */
-       -80,    /* 102.29 kPa 1690 count */
-       -84,    /* 102.34 kPa 1691 count */
-       -89,    /* 102.40 kPa 1692 count */
-       -93,    /* 102.45 kPa 1693 count */
-       -98,    /* 102.51 kPa 1694 count */
-       -102,   /* 102.56 kPa 1695 count */
-       -107,   /* 102.61 kPa 1696 count */
-       -111,   /* 102.67 kPa 1697 count */
-       -116,   /* 102.72 kPa 1698 count */
-       -120,   /* 102.78 kPa 1699 count */
-       -125,   /* 102.83 kPa 1700 count */
-       -129,   /* 102.89 kPa 1701 count */
-       -134,   /* 102.94 kPa 1702 count */
-       -138,   /* 102.99 kPa 1703 count */
-       -143,   /* 103.05 kPa 1704 count */
-       -147,   /* 103.10 kPa 1705 count */
-       -151,   /* 103.16 kPa 1706 count */
-       -156,   /* 103.21 kPa 1707 count */
-       -160,   /* 103.27 kPa 1708 count */
-       -165,   /* 103.32 kPa 1709 count */
-       -169,   /* 103.37 kPa 1710 count */
-       -174,   /* 103.43 kPa 1711 count */
-       -178,   /* 103.48 kPa 1712 count */
-       -183,   /* 103.54 kPa 1713 count */
-       -187,   /* 103.59 kPa 1714 count */
-       -191,   /* 103.65 kPa 1715 count */
-       -196,   /* 103.70 kPa 1716 count */
-       -200,   /* 103.75 kPa 1717 count */
-       -205,   /* 103.81 kPa 1718 count */
-       -209,   /* 103.86 kPa 1719 count */
-       -214,   /* 103.92 kPa 1720 count */
-       -218,   /* 103.97 kPa 1721 count */
-       -222,   /* 104.03 kPa 1722 count */
-       -227,   /* 104.08 kPa 1723 count */
-       -231,   /* 104.13 kPa 1724 count */
-       -236,   /* 104.19 kPa 1725 count */
-       -240,   /* 104.24 kPa 1726 count */
-       -245,   /* 104.30 kPa 1727 count */
-       -249,   /* 104.35 kPa 1728 count */
-       -253,   /* 104.41 kPa 1729 count */
-       -258,   /* 104.46 kPa 1730 count */
-       -262,   /* 104.51 kPa 1731 count */
-       -267,   /* 104.57 kPa 1732 count */
-       -271,   /* 104.62 kPa 1733 count */
-       -275,   /* 104.68 kPa 1734 count */
-       -280,   /* 104.73 kPa 1735 count */
-       -284,   /* 104.79 kPa 1736 count */
-       -289,   /* 104.84 kPa 1737 count */
-       -293,   /* 104.89 kPa 1738 count */
-       -297,   /* 104.95 kPa 1739 count */
-       -302,   /* 105.00 kPa 1740 count */
-       -306,   /* 105.06 kPa 1741 count */
-       -311,   /* 105.11 kPa 1742 count */
-       -315,   /* 105.17 kPa 1743 count */
-       -319,   /* 105.22 kPa 1744 count */
-       -324,   /* 105.27 kPa 1745 count */
-       -328,   /* 105.33 kPa 1746 count */
-       -332,   /* 105.38 kPa 1747 count */
-       -337,   /* 105.44 kPa 1748 count */
-       -341,   /* 105.49 kPa 1749 count */
-       -346,   /* 105.55 kPa 1750 count */
-       -350,   /* 105.60 kPa 1751 count */
-       -354,   /* 105.65 kPa 1752 count */
-       -359,   /* 105.71 kPa 1753 count */
-       -363,   /* 105.76 kPa 1754 count */
-       -367,   /* 105.82 kPa 1755 count */
-       -372,   /* 105.87 kPa 1756 count */
-       -376,   /* 105.93 kPa 1757 count */
-       -380,   /* 105.98 kPa 1758 count */
-       -385,   /* 106.03 kPa 1759 count */
-       -389,   /* 106.09 kPa 1760 count */
-       -394,   /* 106.14 kPa 1761 count */
-       -398,   /* 106.20 kPa 1762 count */
-       -402,   /* 106.25 kPa 1763 count */
-       -407,   /* 106.31 kPa 1764 count */
-       -411,   /* 106.36 kPa 1765 count */
-       -415,   /* 106.41 kPa 1766 count */
-       -420,   /* 106.47 kPa 1767 count */
-       -424,   /* 106.52 kPa 1768 count */
-       -428,   /* 106.58 kPa 1769 count */
-       -433,   /* 106.63 kPa 1770 count */
-       -437,   /* 106.69 kPa 1771 count */
-       -441,   /* 106.74 kPa 1772 count */
-       -446,   /* 106.79 kPa 1773 count */
-       -450,   /* 106.85 kPa 1774 count */
-       -454,   /* 106.90 kPa 1775 count */
-       -459,   /* 106.96 kPa 1776 count */
-       -463,   /* 107.01 kPa 1777 count */
-       -467,   /* 107.07 kPa 1778 count */
-       -472,   /* 107.12 kPa 1779 count */
-       -476,   /* 107.17 kPa 1780 count */
-       -480,   /* 107.23 kPa 1781 count */
-       -485,   /* 107.28 kPa 1782 count */
-       -489,   /* 107.34 kPa 1783 count */
-       -493,   /* 107.39 kPa 1784 count */
-       -497,   /* 107.45 kPa 1785 count */
-       -502,   /* 107.50 kPa 1786 count */
-       -506,   /* 107.55 kPa 1787 count */
-       -510,   /* 107.61 kPa 1788 count */
-       -515,   /* 107.66 kPa 1789 count */
-       -519,   /* 107.72 kPa 1790 count */
-       -523,   /* 107.77 kPa 1791 count */
-       -528,   /* 107.83 kPa 1792 count */
-       -532,   /* 107.88 kPa 1793 count */
-       -536,   /* 107.93 kPa 1794 count */
-       -540,   /* 107.99 kPa 1795 count */
-       -545,   /* 108.04 kPa 1796 count */
-       -549,   /* 108.10 kPa 1797 count */
-       -553,   /* 108.15 kPa 1798 count */
-       -558,   /* 108.21 kPa 1799 count */
-       -562,   /* 108.26 kPa 1800 count */
-       -566,   /* 108.31 kPa 1801 count */
-       -570,   /* 108.37 kPa 1802 count */
-       -575,   /* 108.42 kPa 1803 count */
-       -579,   /* 108.48 kPa 1804 count */
-       -583,   /* 108.53 kPa 1805 count */
-       -588,   /* 108.59 kPa 1806 count */
-       -592,   /* 108.64 kPa 1807 count */
-       -596,   /* 108.69 kPa 1808 count */
-       -600,   /* 108.75 kPa 1809 count */
-       -605,   /* 108.80 kPa 1810 count */
-       -609,   /* 108.86 kPa 1811 count */
-       -613,   /* 108.91 kPa 1812 count */
-       -617,   /* 108.97 kPa 1813 count */
-       -622,   /* 109.02 kPa 1814 count */
-       -626,   /* 109.07 kPa 1815 count */
-       -630,   /* 109.13 kPa 1816 count */
-       -634,   /* 109.18 kPa 1817 count */
-       -639,   /* 109.24 kPa 1818 count */
-       -643,   /* 109.29 kPa 1819 count */
-       -647,   /* 109.35 kPa 1820 count */
-       -651,   /* 109.40 kPa 1821 count */
-       -656,   /* 109.45 kPa 1822 count */
-       -660,   /* 109.51 kPa 1823 count */
-       -664,   /* 109.56 kPa 1824 count */
-       -668,   /* 109.62 kPa 1825 count */
-       -673,   /* 109.67 kPa 1826 count */
-       -677,   /* 109.73 kPa 1827 count */
-       -681,   /* 109.78 kPa 1828 count */
-       -685,   /* 109.83 kPa 1829 count */
-       -690,   /* 109.89 kPa 1830 count */
-       -694,   /* 109.94 kPa 1831 count */
-       -698,   /* 110.00 kPa 1832 count */
-       -702,   /* 110.05 kPa 1833 count */
-       -706,   /* 110.11 kPa 1834 count */
-       -711,   /* 110.16 kPa 1835 count */
-       -715,   /* 110.21 kPa 1836 count */
-       -719,   /* 110.27 kPa 1837 count */
-       -723,   /* 110.32 kPa 1838 count */
-       -728,   /* 110.38 kPa 1839 count */
-       -732,   /* 110.43 kPa 1840 count */
-       -736,   /* 110.48 kPa 1841 count */
-       -740,   /* 110.54 kPa 1842 count */
-       -744,   /* 110.59 kPa 1843 count */
-       -749,   /* 110.65 kPa 1844 count */
-       -753,   /* 110.70 kPa 1845 count */
-       -757,   /* 110.76 kPa 1846 count */
-       -761,   /* 110.81 kPa 1847 count */
-       -765,   /* 110.86 kPa 1848 count */
-       -770,   /* 110.92 kPa 1849 count */
-       -774,   /* 110.97 kPa 1850 count */
-       -778,   /* 111.03 kPa 1851 count */
-       -782,   /* 111.08 kPa 1852 count */
-       -786,   /* 111.14 kPa 1853 count */
-       -791,   /* 111.19 kPa 1854 count */
-       -795,   /* 111.24 kPa 1855 count */
-       -799,   /* 111.30 kPa 1856 count */
-       -803,   /* 111.35 kPa 1857 count */
-       -807,   /* 111.41 kPa 1858 count */
-       -812,   /* 111.46 kPa 1859 count */
-       -816,   /* 111.52 kPa 1860 count */
-       -820,   /* 111.57 kPa 1861 count */
-       -824,   /* 111.62 kPa 1862 count */
-       -828,   /* 111.68 kPa 1863 count */
-       -832,   /* 111.73 kPa 1864 count */
-       -837,   /* 111.79 kPa 1865 count */
-       -841,   /* 111.84 kPa 1866 count */
-       -845,   /* 111.90 kPa 1867 count */
-       -849,   /* 111.95 kPa 1868 count */
-       -853,   /* 112.00 kPa 1869 count */
-       -857,   /* 112.06 kPa 1870 count */
-       -862,   /* 112.11 kPa 1871 count */
-       -866,   /* 112.17 kPa 1872 count */
-       -870,   /* 112.22 kPa 1873 count */
-       -874,   /* 112.28 kPa 1874 count */
-       -878,   /* 112.33 kPa 1875 count */
-       -882,   /* 112.38 kPa 1876 count */
-       -887,   /* 112.44 kPa 1877 count */
-       -891,   /* 112.49 kPa 1878 count */
-       -895,   /* 112.55 kPa 1879 count */
-       -899,   /* 112.60 kPa 1880 count */
-       -903,   /* 112.66 kPa 1881 count */
-       -907,   /* 112.71 kPa 1882 count */
-       -911,   /* 112.76 kPa 1883 count */
-       -916,   /* 112.82 kPa 1884 count */
-       -920,   /* 112.87 kPa 1885 count */
-       -924,   /* 112.93 kPa 1886 count */
-       -928,   /* 112.98 kPa 1887 count */
-       -932,   /* 113.04 kPa 1888 count */
-       -936,   /* 113.09 kPa 1889 count */
-       -940,   /* 113.14 kPa 1890 count */
-       -945,   /* 113.20 kPa 1891 count */
-       -949,   /* 113.25 kPa 1892 count */
-       -953,   /* 113.31 kPa 1893 count */
-       -957,   /* 113.36 kPa 1894 count */
-       -961,   /* 113.42 kPa 1895 count */
-       -965,   /* 113.47 kPa 1896 count */
-       -969,   /* 113.52 kPa 1897 count */
-       -973,   /* 113.58 kPa 1898 count */
-       -978,   /* 113.63 kPa 1899 count */
-       -982,   /* 113.69 kPa 1900 count */
-       -986,   /* 113.74 kPa 1901 count */
-       -990,   /* 113.80 kPa 1902 count */
-       -994,   /* 113.85 kPa 1903 count */
-       -998,   /* 113.90 kPa 1904 count */
-       -1002,  /* 113.96 kPa 1905 count */
-       -1006,  /* 114.01 kPa 1906 count */
-       -1010,  /* 114.07 kPa 1907 count */
-       -1015,  /* 114.12 kPa 1908 count */
-       -1019,  /* 114.18 kPa 1909 count */
-       -1023,  /* 114.23 kPa 1910 count */
-       -1027,  /* 114.28 kPa 1911 count */
-       -1031,  /* 114.34 kPa 1912 count */
-       -1035,  /* 114.39 kPa 1913 count */
-       -1039,  /* 114.45 kPa 1914 count */
-       -1043,  /* 114.50 kPa 1915 count */
-       -1047,  /* 114.56 kPa 1916 count */
-       -1051,  /* 114.61 kPa 1917 count */
-       -1056,  /* 114.66 kPa 1918 count */
-       -1060,  /* 114.72 kPa 1919 count */
-       -1064,  /* 114.77 kPa 1920 count */
-       -1068,  /* 114.83 kPa 1921 count */
-       -1072,  /* 114.88 kPa 1922 count */
-       -1076,  /* 114.94 kPa 1923 count */
-       -1080,  /* 114.99 kPa 1924 count */
-       -1084,  /* 115.04 kPa 1925 count */
-       -1088,  /* 115.10 kPa 1926 count */
-       -1092,  /* 115.15 kPa 1927 count */
-       -1096,  /* 115.21 kPa 1928 count */
-       -1100,  /* 115.26 kPa 1929 count */
-       -1104,  /* 115.32 kPa 1930 count */
-       -1109,  /* 115.37 kPa 1931 count */
-       -1113,  /* 115.42 kPa 1932 count */
-       -1117,  /* 115.48 kPa 1933 count */
-       -1121,  /* 115.53 kPa 1934 count */
-       -1125,  /* 115.59 kPa 1935 count */
-       -1129,  /* 115.64 kPa 1936 count */
-       -1133,  /* 115.70 kPa 1937 count */
-       -1137,  /* 115.75 kPa 1938 count */
-       -1141,  /* 115.80 kPa 1939 count */
-       -1145,  /* 115.86 kPa 1940 count */
-       -1149,  /* 115.91 kPa 1941 count */
-       -1153,  /* 115.97 kPa 1942 count */
-       -1157,  /* 116.02 kPa 1943 count */
-       -1161,  /* 116.08 kPa 1944 count */
-       -1165,  /* 116.13 kPa 1945 count */
-       -1169,  /* 116.18 kPa 1946 count */
-       -1173,  /* 116.24 kPa 1947 count */
-       -1177,  /* 116.29 kPa 1948 count */
-       -1182,  /* 116.35 kPa 1949 count */
-       -1186,  /* 116.40 kPa 1950 count */
-       -1190,  /* 116.46 kPa 1951 count */
-       -1194,  /* 116.51 kPa 1952 count */
-       -1198,  /* 116.56 kPa 1953 count */
-       -1202,  /* 116.62 kPa 1954 count */
-       -1206,  /* 116.67 kPa 1955 count */
-       -1210,  /* 116.73 kPa 1956 count */
-       -1214,  /* 116.78 kPa 1957 count */
-       -1218,  /* 116.84 kPa 1958 count */
-       -1222,  /* 116.89 kPa 1959 count */
-       -1226,  /* 116.94 kPa 1960 count */
-       -1230,  /* 117.00 kPa 1961 count */
-       -1234,  /* 117.05 kPa 1962 count */
-       -1238,  /* 117.11 kPa 1963 count */
-       -1242,  /* 117.16 kPa 1964 count */
-       -1246,  /* 117.22 kPa 1965 count */
-       -1250,  /* 117.27 kPa 1966 count */
-       -1254,  /* 117.32 kPa 1967 count */
-       -1258,  /* 117.38 kPa 1968 count */
-       -1262,  /* 117.43 kPa 1969 count */
-       -1266,  /* 117.49 kPa 1970 count */
-       -1270,  /* 117.54 kPa 1971 count */
-       -1274,  /* 117.60 kPa 1972 count */
-       -1278,  /* 117.65 kPa 1973 count */
-       -1282,  /* 117.70 kPa 1974 count */
-       -1286,  /* 117.76 kPa 1975 count */
-       -1290,  /* 117.81 kPa 1976 count */
-       -1294,  /* 117.87 kPa 1977 count */
-       -1298,  /* 117.92 kPa 1978 count */
-       -1302,  /* 117.98 kPa 1979 count */
-       -1306,  /* 118.03 kPa 1980 count */
-       -1310,  /* 118.08 kPa 1981 count */
-       -1314,  /* 118.14 kPa 1982 count */
-       -1318,  /* 118.19 kPa 1983 count */
-       -1322,  /* 118.25 kPa 1984 count */
-       -1326,  /* 118.30 kPa 1985 count */
-       -1330,  /* 118.36 kPa 1986 count */
-       -1334,  /* 118.41 kPa 1987 count */
-       -1338,  /* 118.46 kPa 1988 count */
-       -1342,  /* 118.52 kPa 1989 count */
-       -1346,  /* 118.57 kPa 1990 count */
-       -1350,  /* 118.63 kPa 1991 count */
-       -1354,  /* 118.68 kPa 1992 count */
-       -1358,  /* 118.74 kPa 1993 count */
-       -1362,  /* 118.79 kPa 1994 count */
-       -1366,  /* 118.84 kPa 1995 count */
-       -1370,  /* 118.90 kPa 1996 count */
-       -1374,  /* 118.95 kPa 1997 count */
-       -1378,  /* 119.01 kPa 1998 count */
-       -1382,  /* 119.06 kPa 1999 count */
-       -1386,  /* 119.12 kPa 2000 count */
-       -1390,  /* 119.17 kPa 2001 count */
-       -1394,  /* 119.22 kPa 2002 count */
-       -1397,  /* 119.28 kPa 2003 count */
-       -1401,  /* 119.33 kPa 2004 count */
-       -1405,  /* 119.39 kPa 2005 count */
-       -1409,  /* 119.44 kPa 2006 count */
-       -1413,  /* 119.50 kPa 2007 count */
-       -1417,  /* 119.55 kPa 2008 count */
-       -1421,  /* 119.60 kPa 2009 count */
-       -1425,  /* 119.66 kPa 2010 count */
-       -1429,  /* 119.71 kPa 2011 count */
-       -1433,  /* 119.77 kPa 2012 count */
-       -1437,  /* 119.82 kPa 2013 count */
-       -1441,  /* 119.88 kPa 2014 count */
-       -1445,  /* 119.93 kPa 2015 count */
-       -1449,  /* 119.98 kPa 2016 count */
-       -1453,  /* 120.04 kPa 2017 count */
-       -1457,  /* 120.09 kPa 2018 count */
-       -1461,  /* 120.15 kPa 2019 count */
-       -1465,  /* 120.20 kPa 2020 count */
-       -1469,  /* 120.26 kPa 2021 count */
-       -1472,  /* 120.31 kPa 2022 count */
-       -1476,  /* 120.36 kPa 2023 count */
-       -1480,  /* 120.42 kPa 2024 count */
-       -1484,  /* 120.47 kPa 2025 count */
-       -1488,  /* 120.53 kPa 2026 count */
-       -1492,  /* 120.58 kPa 2027 count */
-       -1496,  /* 120.64 kPa 2028 count */
-       -1500,  /* 120.69 kPa 2029 count */
-       -1504,  /* 120.74 kPa 2030 count */
-       -1508,  /* 120.80 kPa 2031 count */
-       -1512,  /* 120.85 kPa 2032 count */
-       -1516,  /* 120.91 kPa 2033 count */
-       -1520,  /* 120.96 kPa 2034 count */
-       -1523,  /* 121.02 kPa 2035 count */
-       -1527,  /* 121.07 kPa 2036 count */
-       -1531,  /* 121.12 kPa 2037 count */
-       -1535,  /* 121.18 kPa 2038 count */
-       -1539,  /* 121.23 kPa 2039 count */
-       -1543,  /* 121.29 kPa 2040 count */
-       -1547,  /* 121.34 kPa 2041 count */
-       -1551,  /* 121.40 kPa 2042 count */
-       -1555,  /* 121.45 kPa 2043 count */
-       -1559,  /* 121.50 kPa 2044 count */
-       -1562,  /* 121.56 kPa 2045 count */
-       -1566,  /* 121.61 kPa 2046 count */
-       -1570,  /* 121.67 kPa 2047 count */
diff --git a/ao-make-product.5c b/ao-make-product.5c
deleted file mode 100644 (file)
index 933032d..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/bin/sh
-
-autoimport ParseArgs;
-
-void
-write_ucs2(string a, string description)
-{
-       int len = String::length(a);
-
-       printf("/* %s */\n", description);
-       printf("#define AO_%s_LEN 0x%02x\n", description, len * 2 + 2);
-       printf("#define AO_%s_STRING \"%s\"\n", description, a);
-       printf("#define AO_%s_UCS2", description);
-       for (int i = 0; i < len; i++) {
-               int     c = a[i];
-               if (i > 0)
-                       printf(",");
-               if (0x20 <= c && c < 128)
-                       printf(" '%c', 0", c);
-               else
-                       printf(" LE_WORD(0x%04x),", c);
-       }
-       printf("\n\n");
-}
-
-void
-write_string(string a, string description)
-{
-       printf ("/* %s */\n", description);
-       printf ("#define AO_%s_STRING \"%s\"\n", description, a);
-}
-
-void
-write_int(int a, string description)
-{
-       printf ("/* %s */\n", description);
-       printf ("#define AO_%s_NUMBER %d\n\n", description, a);
-}
-
-string manufacturer = "altusmetrum.org";
-string product = "TeleMetrum";
-string version = "0.0";
-int serial = 1;
-int user_argind = 0;
-
-argdesc argd = {
-       .args = {
-               {
-                       .var = { .arg_string = &manufacturer },
-                       .abbr = 'm',
-                       .name = "manufacturer",
-                       .expr_name = "manf",
-                       .desc = "Manufacturer name." },
-               {
-                       .var = { .arg_string = &product },
-                       .abbr = 'p',
-                       .name = "product",
-                       .expr_name = "prod",
-                       .desc = "Product name." },
-               {
-                       .var = { .arg_int = &serial },
-                       .abbr = 's',
-                       .name = "serial",
-                       .expr_name = "number",
-                       .desc = "Serial number." },
-               {
-                       .var = { .arg_string = &version },
-                       .abbr = 'v',
-                       .name = "version",
-                       .expr_name = "string",
-                       .desc = "Program version." },
-       },
-       .prog_name = "usb descriptors",
-};
-
-void
-main()
-{
-       string[dim(argv)-1] nargv = {[n] = argv[n+1]};
-       parseargs(&argd, &nargv);
-       write_ucs2(manufacturer, "iManufacturer");
-       write_ucs2(product, "iProduct");
-       write_ucs2(sprintf("%06d", serial), "iSerial");
-       write_int(serial, "iSerial");
-       write_string(version, "iVersion");
-}
-
-main();
diff --git a/ao.h b/ao.h
deleted file mode 100644 (file)
index c4cb5bf..0000000
--- a/ao.h
+++ /dev/null
@@ -1,926 +0,0 @@
-/*
- * Copyright Â© 2009 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_H_
-#define _AO_H_
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include "cc1111.h"
-
-#define TRUE 1
-#define FALSE 0
-
-/* Convert a __data pointer into an __xdata pointer */
-#define DATA_TO_XDATA(a)       ((void __xdata *) ((uint8_t) (a) | 0xff00))
-
-/* Stack runs from above the allocated __data space to 0xfe, which avoids
- * writing to 0xff as that triggers the stack overflow indicator
- */
-#define AO_STACK_START 0x80
-#define AO_STACK_END   0xfe
-#define AO_STACK_SIZE  (AO_STACK_END - AO_STACK_START + 1)
-
-/* An AltOS task */
-struct ao_task {
-       __xdata void *wchan;            /* current wait channel (NULL if running) */
-       uint8_t stack_count;            /* amount of saved stack */
-       uint8_t task_id;                /* index in the task array */
-       __code char *name;              /* task name */
-       uint8_t stack[AO_STACK_SIZE];   /* saved stack */
-};
-
-extern __xdata struct ao_task *__data ao_cur_task;
-
-#define AO_NUM_TASKS           16      /* maximum number of tasks */
-#define AO_NO_TASK             0       /* no task id */
-
-/*
- ao_task.c
- */
-
-/* Suspend the current task until wchan is awoken */
-void
-ao_sleep(__xdata void *wchan);
-
-/* Wake all tasks sleeping on wchan */
-void
-ao_wakeup(__xdata void *wchan);
-
-/* Yield the processor to another task */
-void
-ao_yield(void) _naked;
-
-/* Add a task to the run queue */
-void
-ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name) __reentrant;
-
-/* Dump task info to console */
-void
-ao_task_info(void);
-
-/* Start the scheduler. This will not return */
-void
-ao_start_scheduler(void);
-
-/*
- * ao_panic.c
- */
-
-#define AO_PANIC_NO_TASK       1       /* AO_NUM_TASKS is not large enough */
-#define AO_PANIC_DMA           2       /* Attempt to start DMA while active */
-#define AO_PANIC_MUTEX         3       /* Mis-using mutex API */
-#define AO_PANIC_EE            4       /* Mis-using eeprom API */
-#define AO_PANIC_LOG           5       /* Failing to read/write log data */
-#define AO_PANIC_CMD           6       /* Too many command sets registered */
-
-/* Stop the operating system, beeping and blinking the reason */
-void
-ao_panic(uint8_t reason);
-
-/*
- * ao_timer.c
- */
-
-/* Our timer runs at 100Hz */
-#define AO_MS_TO_TICKS(ms)     ((ms) / 10)
-#define AO_SEC_TO_TICKS(s)     ((s) * 100)
-
-/* Returns the current time in ticks */
-uint16_t
-ao_time(void);
-
-/* Suspend the current task until ticks time has passed */
-void
-ao_delay(uint16_t ticks);
-
-/* Set the ADC interval */
-void
-ao_timer_set_adc_interval(uint8_t interval) __critical;
-
-/* Timer interrupt */
-void
-ao_timer_isr(void) interrupt 9;
-
-/* Initialize the timer */
-void
-ao_timer_init(void);
-
-/*
- * ao_adc.c
- */
-
-#define AO_ADC_RING    64
-#define ao_adc_ring_next(n)    (((n) + 1) & (AO_ADC_RING - 1))
-#define ao_adc_ring_prev(n)    (((n) - 1) & (AO_ADC_RING - 1))
-
-/*
- * One set of samples read from the A/D converter
- */
-struct ao_adc {
-       uint16_t        tick;           /* tick when the sample was read */
-       int16_t         accel;          /* accelerometer */
-       int16_t         pres;           /* pressure sensor */
-       int16_t         temp;           /* temperature sensor */
-       int16_t         v_batt;         /* battery voltage */
-       int16_t         sense_d;        /* drogue continuity sense */
-       int16_t         sense_m;        /* main continuity sense */
-};
-
-/*
- * A/D data is stored in a ring, with the next sample to be written
- * at ao_adc_head
- */
-extern volatile __xdata struct ao_adc  ao_adc_ring[AO_ADC_RING];
-extern volatile __data uint8_t         ao_adc_head;
-
-/* Trigger a conversion sequence (called from the timer interrupt) */
-void
-ao_adc_poll(void);
-
-/* Suspend the current task until another A/D sample is converted */
-void
-ao_adc_sleep(void);
-
-/* Get a copy of the last complete A/D sample set */
-void
-ao_adc_get(__xdata struct ao_adc *packet);
-
-/* The A/D interrupt handler */
-#if !AO_NO_ADC_ISR
-void
-ao_adc_isr(void) interrupt 1;
-#endif
-
-/* Initialize the A/D converter */
-void
-ao_adc_init(void);
-
-/*
- * ao_beep.c
- */
-
-/*
- * Various pre-defined beep frequencies
- *
- * frequency = 1/2 (24e6/32) / beep
- */
-
-#define AO_BEEP_LOW    150     /* 2500Hz */
-#define AO_BEEP_MID    94      /* 3989Hz */
-#define AO_BEEP_HIGH   75      /* 5000Hz */
-#define AO_BEEP_OFF    0       /* off */
-
-#define AO_BEEP_g      240     /* 1562.5Hz */
-#define AO_BEEP_gs     227     /* 1652Hz (1655Hz) */
-#define AO_BEEP_aa     214     /* 1752Hz (1754Hz) */
-#define AO_BEEP_bbf    202     /* 1856Hz (1858Hz) */
-#define AO_BEEP_bb     190     /* 1974Hz (1969Hz) */
-#define AO_BEEP_cc     180     /* 2083Hz (2086Hz) */
-#define AO_BEEP_ccs    170     /* 2205Hz (2210Hz) */
-#define AO_BEEP_dd     160     /* 2344Hz (2341Hz) */
-#define AO_BEEP_eef    151     /* 2483Hz (2480Hz) */
-#define AO_BEEP_ee     143     /* 2622Hz (2628Hz) */
-#define AO_BEEP_ff     135     /* 2778Hz (2784Hz) */
-#define AO_BEEP_ffs    127     /* 2953Hz (2950Hz) */
-#define AO_BEEP_gg     120     /* 3125Hz */
-#define AO_BEEP_ggs    113     /* 3319Hz (3311Hz) */
-#define AO_BEEP_aaa    107     /* 3504Hz (3508Hz) */
-#define AO_BEEP_bbbf   101     /* 3713Hz (3716Hz) */
-#define AO_BEEP_bbb    95      /* 3947Hz (3937Hz) */
-#define AO_BEEP_ccc    90      /* 4167Hz (4171Hz) */
-#define AO_BEEP_cccs   85      /* 4412Hz (4419Hz) */
-#define AO_BEEP_ddd    80      /* 4688Hz (4682Hz) */
-#define AO_BEEP_eeef   76      /* 4934Hz (4961Hz) */
-#define AO_BEEP_eee    71      /* 5282Hz (5256Hz) */
-#define AO_BEEP_fff    67      /* 5597Hz (5568Hz) */
-#define AO_BEEP_fffs   64      /* 5859Hz (5899Hz) */
-#define AO_BEEP_ggg    60      /* 6250Hz */
-
-/* Set the beeper to the specified tone */
-void
-ao_beep(uint8_t beep);
-
-/* Turn on the beeper for the specified time */
-void
-ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant;
-
-/* Initialize the beeper */
-void
-ao_beep_init(void);
-
-/*
- * ao_led.c
- */
-
-#define AO_LED_NONE    0
-#define AO_LED_GREEN   1
-#define AO_LED_RED     2
-
-/* Turn on the specified LEDs */
-void
-ao_led_on(uint8_t colors);
-
-/* Turn off the specified LEDs */
-void
-ao_led_off(uint8_t colors);
-
-/* Set all of the LEDs to the specified state */
-void
-ao_led_set(uint8_t colors);
-
-/* Toggle the specified LEDs */
-void
-ao_led_toggle(uint8_t colors);
-
-/* Turn on the specified LEDs for the indicated interval */
-void
-ao_led_for(uint8_t colors, uint16_t ticks) __reentrant;
-
-/* Initialize the LEDs */
-void
-ao_led_init(uint8_t enable);
-
-/*
- * ao_usb.c
- */
-
-/* Put one character to the USB output queue */
-void
-ao_usb_putchar(char c);
-
-/* Get one character from the USB input queue */
-char
-ao_usb_getchar(void);
-
-/* Flush the USB output queue */
-void
-ao_usb_flush(void);
-
-/* USB interrupt handler */
-void
-ao_usb_isr(void) interrupt 6;
-
-/* Enable the USB controller */
-void
-ao_usb_enable(void);
-
-/* Disable the USB controller */
-void
-ao_usb_disable(void);
-
-/* Initialize the USB system */
-void
-ao_usb_init(void);
-
-/*
- * ao_cmd.c
- */
-
-enum ao_cmd_status {
-       ao_cmd_success = 0,
-       ao_cmd_lex_error = 1,
-       ao_cmd_syntax_error = 2,
-};
-
-extern __xdata uint16_t ao_cmd_lex_i;
-extern __xdata char    ao_cmd_lex_c;
-extern __xdata enum ao_cmd_status ao_cmd_status;
-
-void
-ao_cmd_lex(void);
-
-void
-ao_cmd_put8(uint8_t v);
-
-void
-ao_cmd_put16(uint16_t v);
-
-void
-ao_cmd_white(void);
-
-void
-ao_cmd_hex(void);
-
-void
-ao_cmd_decimal(void);
-
-struct ao_cmds {
-       char            cmd;
-       void            (*func)(void);
-       const char      *help;
-};
-
-void
-ao_cmd_register(__code struct ao_cmds *cmds);
-
-void
-ao_cmd_init(void);
-
-/*
- * ao_dma.c
- */
-
-/* Allocate a DMA channel. the 'done' parameter will be set to 1
- * when the dma is finished and will be used to wakeup any waiters
- */
-uint8_t
-ao_dma_alloc(__xdata uint8_t * done);
-
-/* Setup a DMA channel */
-void
-ao_dma_set_transfer(uint8_t id,
-                   void __xdata *srcaddr,
-                   void __xdata *dstaddr,
-                   uint16_t count,
-                   uint8_t cfg0,
-                   uint8_t cfg1);
-
-/* Start a DMA channel */
-void
-ao_dma_start(uint8_t id);
-
-/* Manually trigger a DMA channel */
-void
-ao_dma_trigger(uint8_t id);
-
-/* Abort a running DMA transfer */
-void
-ao_dma_abort(uint8_t id);
-
-/* DMA interrupt routine */
-void
-ao_dma_isr(void) interrupt 8;
-
-/*
- * ao_mutex.c
- */
-
-void
-ao_mutex_get(__xdata uint8_t *ao_mutex) __reentrant;
-
-void
-ao_mutex_put(__xdata uint8_t *ao_mutex) __reentrant;
-
-/*
- * ao_ee.c
- */
-
-/*
- * We reserve the last block on the device for
- * configuration space. Writes and reads in this
- * area return errors.
- */
-
-#define AO_EE_BLOCK_SIZE       ((uint16_t) (256))
-#define AO_EE_DEVICE_SIZE      ((uint32_t) 128 * (uint32_t) 1024)
-#define AO_EE_DATA_SIZE                (AO_EE_DEVICE_SIZE - (uint32_t) AO_EE_BLOCK_SIZE)
-#define AO_EE_CONFIG_BLOCK     ((uint16_t) (AO_EE_DATA_SIZE / AO_EE_BLOCK_SIZE))
-
-void
-ao_ee_flush(void) __reentrant;
-
-/* Write to the eeprom */
-uint8_t
-ao_ee_write(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant;
-
-/* Read from the eeprom */
-uint8_t
-ao_ee_read(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant;
-
-/* Write the config block (at the end of the eeprom) */
-uint8_t
-ao_ee_write_config(uint8_t *buf, uint16_t len) __reentrant;
-
-/* Read the config block (at the end of the eeprom) */
-uint8_t
-ao_ee_read_config(uint8_t *buf, uint16_t len) __reentrant;
-
-/* Initialize the EEPROM code */
-void
-ao_ee_init(void);
-
-/*
- * ao_log.c
- */
-
-/* Structure containing GPS position, either lat or lon */
-
-struct ao_gps_pos {
-       uint8_t degrees;
-       uint8_t minutes;
-       uint16_t minutes_fraction;      /* in units of 1/10000 minutes */
-};
-
-/*
- * The data log is recorded in the eeprom as a sequence
- * of data packets.
- *
- * Each packet starts with a 4-byte header that has the
- * packet type, the packet checksum and the tick count. Then
- * they all contain 2 16 bit values which hold packet-specific
- * data.
- *
- * For each flight, the first packet
- * is FLIGHT packet, indicating the serial number of the
- * device and a unique number marking the number of flights
- * recorded by this device.
- *
- * During flight, data from the accelerometer and barometer
- * are recorded in SENSOR packets, using the raw 16-bit values
- * read from the A/D converter.
- *
- * Also during flight, but at a lower rate, the deployment
- * sensors are recorded in DEPLOY packets. The goal here is to
- * detect failure in the deployment circuits.
- *
- * STATE packets hold state transitions as the flight computer
- * transitions through different stages of the flight.
- */
-#define AO_LOG_FLIGHT          'F'
-#define AO_LOG_SENSOR          'A'
-#define AO_LOG_TEMP_VOLT       'T'
-#define AO_LOG_DEPLOY          'D'
-#define AO_LOG_STATE           'S'
-#define AO_LOG_GPS_TIME                'G'
-#define AO_LOG_GPS_LAT         'N'
-#define AO_LOG_GPS_LON         'W'
-#define AO_LOG_GPS_ALT         'H'
-
-#define AO_LOG_POS_NONE                (~0UL)
-
-struct ao_log_record {
-       char                    type;
-       uint8_t                 csum;
-       uint16_t                tick;
-       union {
-               struct {
-                       int16_t         ground_accel;
-                       uint16_t        flight;
-               } flight;
-               struct {
-                       int16_t         accel;
-                       int16_t         pres;
-               } sensor;
-               struct {
-                       int16_t         temp;
-                       int16_t         v_batt;
-               } temp_volt;
-               struct {
-                       int16_t         drogue;
-                       int16_t         main;
-               } deploy;
-               struct {
-                       uint16_t        state;
-                       uint16_t        reason;
-               } state;
-               struct {
-                       uint8_t         hour;
-                       uint8_t         minute;
-                       uint8_t         second;
-                       uint8_t         flags;
-               } gps_time;
-               struct ao_gps_pos gps_latitude;
-               struct ao_gps_pos gps_longitude;
-               struct {
-                       int16_t         altitude;
-                       uint16_t        unused;
-               } gps_altitude;
-               struct {
-                       uint16_t        d0;
-                       uint16_t        d1;
-               } anon;
-       } u;
-};
-
-/* Write a record to the eeprom log */
-void
-ao_log_data(struct ao_log_record *log);
-
-/* Flush the log */
-void
-ao_log_flush(void);
-
-/* Log dumping API:
- * ao_log_dump_first() - get first log record
- * ao_log_dump_next()  - get next log record
- */
-extern __xdata struct ao_log_record ao_log_dump;
-
-/* Retrieve first log record for the current flight */
-uint8_t
-ao_log_dump_first(void);
-
-/* return next log record for the current flight */
-uint8_t
-ao_log_dump_next(void);
-
-/* Logging thread main routine */
-void
-ao_log(void);
-
-/* Start logging to eeprom */
-void
-ao_log_start(void);
-
-/* Stop logging */
-void
-ao_log_stop(void);
-
-/* Initialize the logging system */
-void
-ao_log_init(void);
-
-/*
- * ao_flight.c
- */
-
-enum ao_flight_state {
-       ao_flight_startup = 0,
-       ao_flight_idle = 1,
-       ao_flight_launchpad = 2,
-       ao_flight_boost = 3,
-       ao_flight_coast = 4,
-       ao_flight_apogee = 5,
-       ao_flight_drogue = 6,
-       ao_flight_main = 7,
-       ao_flight_landed = 8,
-       ao_flight_invalid = 9
-};
-
-extern __xdata struct ao_adc           ao_flight_data;
-extern __pdata enum ao_flight_state    ao_flight_state;
-extern __pdata uint16_t                        ao_flight_tick;
-extern __pdata int16_t                 ao_flight_accel;
-extern __pdata int16_t                 ao_flight_pres;
-extern __pdata int32_t                 ao_flight_vel;
-extern __pdata int16_t                 ao_ground_pres;
-extern __pdata int16_t                 ao_ground_accel;
-extern __pdata int16_t                 ao_min_pres;
-extern __pdata uint16_t                        ao_launch_time;
-
-/* Flight thread */
-void
-ao_flight(void);
-
-/* Initialize flight thread */
-void
-ao_flight_init(void);
-
-/*
- * ao_report.c
- */
-
-void
-ao_report_init(void);
-
-/*
- * ao_convert.c
- *
- * Given raw data, convert to SI units
- */
-
-/* pressure from the sensor to altitude in meters */
-int16_t
-ao_pres_to_altitude(int16_t pres) __reentrant;
-
-int16_t
-ao_altitude_to_pres(int16_t alt) __reentrant;
-
-int16_t
-ao_temp_to_dC(int16_t temp) __reentrant;
-
-/*
- * ao_dbg.c
- *
- * debug another telemetrum board
- */
-
-/* Send a byte to the dbg target */
-void
-ao_dbg_send_byte(uint8_t byte);
-
-/* Receive a byte from the dbg target */
-uint8_t
-ao_dbg_recv_byte(void);
-
-/* Start a bulk transfer to/from dbg target memory */
-void
-ao_dbg_start_transfer(uint16_t addr);
-
-/* End a bulk transfer to/from dbg target memory */
-void
-ao_dbg_end_transfer(void);
-
-/* Write a byte to dbg target memory */
-void
-ao_dbg_write_byte(uint8_t byte);
-
-/* Read a byte from dbg target memory */
-uint8_t
-ao_dbg_read_byte(void);
-
-/* Enable dbg mode, switching use of the pins */
-void
-ao_dbg_debug_mode(void);
-
-/* Reset the dbg target */
-void
-ao_dbg_reset(void);
-
-void
-ao_dbg_init(void);
-
-/*
- * ao_serial.c
- */
-
-#if !AO_NO_SERIAL_ISR
-void
-ao_serial_rx1_isr(void) interrupt 3;
-
-void
-ao_serial_tx1_isr(void) interrupt 14;
-#endif
-
-char
-ao_serial_getchar(void) __critical;
-
-void
-ao_serial_putchar(char c) __critical;
-
-void
-ao_serial_init(void);
-
-/*
- * ao_gps.c
- */
-
-#define AO_GPS_NUM_SAT_MASK    (0xf << 0)
-#define AO_GPS_NUM_SAT_SHIFT   (0)
-
-#define AO_GPS_VALID           (1 << 4)
-#define AO_GPS_LONGITUDE_MASK  (1 << 5)
-#define AO_GPS_LONGITUDE_EAST  (0 << 5)
-#define AO_GPS_LONGITUDE_WEST  (1 << 5)
-
-#define AO_GPS_LATITUDE_MASK   (1 << 6)
-#define AO_GPS_LATITUDE_NORTH  (0 << 6)
-#define AO_GPS_LATITUDE_SOUTH  (1 << 6)
-
-struct ao_gps_data {
-       uint8_t                 hour;
-       uint8_t                 minute;
-       uint8_t                 second;
-       uint8_t                 flags;
-       struct ao_gps_pos       latitude;
-       struct ao_gps_pos       longitude;
-       int16_t                 altitude;
-};
-
-extern __xdata uint8_t ao_gps_mutex;
-extern __xdata struct ao_gps_data ao_gps_data;
-
-void
-ao_gps(void);
-
-void
-ao_gps_print(__xdata struct ao_gps_data *gps_data);
-
-void
-ao_gps_init(void);
-
-/*
- * ao_gps_report.c
- */
-
-void
-ao_gps_report(void);
-
-void
-ao_gps_report_init(void);
-
-/*
- * ao_telemetry.c
- */
-
-#define AO_MAX_CALLSIGN                8
-
-struct ao_telemetry {
-       uint8_t                 addr;
-       uint8_t                 flight_state;
-       int16_t                 flight_accel;
-       int16_t                 ground_accel;
-       int32_t                 flight_vel;
-       int16_t                 flight_pres;
-       int16_t                 ground_pres;
-       struct ao_adc           adc;
-       struct ao_gps_data      gps;
-       char                    callsign[AO_MAX_CALLSIGN];
-};
-
-/* Set delay between telemetry reports (0 to disable) */
-
-#define AO_TELEMETRY_INTERVAL_PAD      AO_MS_TO_TICKS(1000)
-#define AO_TELEMETRY_INTERVAL_FLIGHT   AO_MS_TO_TICKS(50)
-#define AO_TELEMETRY_INTERVAL_RECOVER  AO_MS_TO_TICKS(1000)
-
-void
-ao_telemetry_set_interval(uint16_t interval);
-
-void
-ao_telemetry_init(void);
-
-/*
- * ao_radio.c
- */
-
-void
-ao_radio_send(__xdata struct ao_telemetry *telemetry) __reentrant;
-
-struct ao_radio_recv {
-       struct ao_telemetry     telemetry;
-       int8_t                  rssi;
-       uint8_t                 status;
-};
-
-void
-ao_radio_recv(__xdata struct ao_radio_recv *recv) __reentrant;
-
-void
-ao_radio_init(void);
-
-/*
- * ao_monitor.c
- */
-
-extern const char const * const ao_state_names[];
-
-void
-ao_monitor(void);
-
-void
-ao_set_monitor(uint8_t monitoring);
-
-void
-ao_monitor_init(uint8_t led, uint8_t monitoring) __reentrant;
-
-/*
- * ao_stdio.c
- */
-
-void
-flush(void);
-
-/*
- * ao_ignite.c
- */
-
-enum ao_igniter {
-       ao_igniter_drogue = 0,
-       ao_igniter_main = 1
-};
-
-void
-ao_ignite(enum ao_igniter igniter);
-
-enum ao_igniter_status {
-       ao_igniter_unknown,     /* unknown status (ambiguous voltage) */
-       ao_igniter_ready,       /* continuity detected */
-       ao_igniter_active,      /* igniter firing */
-       ao_igniter_open,        /* open circuit detected */
-};
-
-enum ao_igniter_status
-ao_igniter_status(enum ao_igniter igniter);
-
-void
-ao_igniter_init(void);
-
-/*
- * ao_config.c
- */
-
-#define AO_CONFIG_MAJOR        1
-#define AO_CONFIG_MINOR        0
-
-struct ao_config {
-       uint8_t         major;
-       uint8_t         minor;
-       uint16_t        main_deploy;
-       int16_t         accel_zero_g;
-       uint8_t         radio_channel;
-       char            callsign[AO_MAX_CALLSIGN + 1];
-};
-
-extern __xdata struct ao_config ao_config;
-
-void
-ao_config_get(void);
-
-void
-ao_config_init(void);
-
-/*
- * ao_rssi.c
- */
-
-void
-ao_rssi_set(int rssi_value);
-
-void
-ao_rssi_init(uint8_t rssi_led);
-
-/*
- * ao_product.c
- *
- * values which need to be defined for
- * each instance of a product
- */
-
-extern const uint8_t ao_usb_descriptors [];
-extern const uint16_t ao_serial_number;
-extern const char ao_version[];
-extern const char ao_manufacturer[];
-extern const char ao_product[];
-
-/*
- * Fifos
- */
-
-#define AO_FIFO_SIZE   32
-
-struct ao_fifo {
-       uint8_t insert;
-       uint8_t remove;
-       char    fifo[AO_FIFO_SIZE];
-};
-
-#define ao_fifo_insert(f,c) do { \
-       (f).fifo[(f).insert] = (c); \
-       (f).insert = ((f).insert + 1) & (AO_FIFO_SIZE-1); \
-} while(0)
-
-#define ao_fifo_remove(f,c) do {\
-       c = (f).fifo[(f).remove]; \
-       (f).remove = ((f).remove + 1) & (AO_FIFO_SIZE-1); \
-} while(0)
-
-#define ao_fifo_full(f)                ((((f).insert + 1) & (AO_FIFO_SIZE-1)) == (f).remove)
-#define ao_fifo_empty(f)       ((f).insert == (f).remove)
-
-/*
- * ao_packet.c
- *
- * Packet-based command interface
- */
-
-#define AO_PACKET_MAX  32
-#define AO_PACKET_WIN  256
-
-#define AO_PACKET_FIN  (1 << 0)
-#define AO_PACKET_SYN  (1 << 1)
-#define AO_PACKET_RST  (1 << 2)
-#define AO_PACKET_ACK  (1 << 3)
-
-struct ao_packet {
-       uint8_t         addr;
-       uint8_t         flags;
-       uint16_t        seq;
-       uint16_t        ack;
-       uint16_t        window;
-       uint8_t         len;
-       uint8_t         d[AO_PACKET_MAX];
-};
-
-uint8_t
-ao_packet_connect(uint8_t dest);
-
-uint8_t
-ao_packet_accept(void);
-
-int
-ao_packet_send(uint8_t *data, int len);
-
-int
-ao_packet_recv(uint8_t *data, int len);
-
-void
-ao_packet_init(void);
-
-#endif /* _AO_H_ */
diff --git a/ao_adc.c b/ao_adc.c
deleted file mode 100644 (file)
index bef6bb7..0000000
--- a/ao_adc.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-volatile __xdata struct ao_adc ao_adc_ring[AO_ADC_RING];
-volatile __data uint8_t                ao_adc_head;
-
-void
-ao_adc_poll(void)
-{
-       ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | 0;
-}
-
-void
-ao_adc_sleep(void)
-{
-       ao_sleep(&ao_adc_ring);
-}
-
-void
-ao_adc_get(__xdata struct ao_adc *packet)
-{
-       uint8_t i = ao_adc_ring_prev(ao_adc_head);
-       memcpy(packet, &ao_adc_ring[i], sizeof (struct ao_adc));
-}
-
-void
-ao_adc_isr(void) interrupt 1
-{
-       uint8_t sequence;
-       uint8_t __xdata *a;
-       
-       sequence = (ADCCON2 & ADCCON2_SCH_MASK) >> ADCCON2_SCH_SHIFT;
-       a = (uint8_t __xdata *) (&ao_adc_ring[ao_adc_head].accel + sequence);
-       a[0] = ADCL;
-       a[1] = ADCH;
-       if (sequence < 5) {
-               /* start next channel conversion */
-               ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | (sequence + 1);
-       } else {
-               /* record this conversion series */
-               ao_adc_ring[ao_adc_head].tick = ao_time();
-               ao_adc_head = ao_adc_ring_next(ao_adc_head);
-               ao_wakeup(ao_adc_ring);
-       }
-}
-
-static void
-ao_adc_dump(void)
-{
-       __xdata struct ao_adc   packet;
-       ao_adc_get(&packet);
-       printf("tick: %5u accel: %4d pres: %4d temp: %4d batt: %4d drogue: %4d main: %4d\n",
-              packet.tick, packet.accel >> 4, packet.pres >> 4, packet.temp >> 4,
-              packet.v_batt >> 4, packet.sense_d >> 4, packet.sense_m >> 4);
-}
-
-__code struct ao_cmds ao_adc_cmds[] = {
-       { 'a',  ao_adc_dump,    "a                                  Display current ADC values" },
-       { 0,    ao_adc_dump, NULL },
-};
-
-void
-ao_adc_init(void)
-{
-       ADCCFG = ((1 << 0) |    /* acceleration */
-                 (1 << 1) |    /* pressure */
-                 (1 << 2) |    /* temperature */
-                 (1 << 3) |    /* battery voltage */
-                 (1 << 4) |    /* drogue sense */
-                 (1 << 5));    /* main sense */
-       
-       /* enable interrupts */
-       ADCIF = 0;
-       IEN0 |= IEN0_ADCIE;
-       ao_cmd_register(&ao_adc_cmds[0]);
-}
-
diff --git a/ao_adc_fake.c b/ao_adc_fake.c
deleted file mode 100644 (file)
index 6ca88d4..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-volatile __xdata struct ao_adc ao_adc_ring[AO_ADC_RING];
-volatile __data uint8_t                ao_adc_head;
-
-/* Stub for systems which have no ADC */
-void
-ao_adc_poll(void)
-{
-}
diff --git a/ao_beep.c b/ao_beep.c
deleted file mode 100644 (file)
index 3642f4c..0000000
--- a/ao_beep.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-void
-ao_beep(uint8_t beep)
-{
-       if (beep == 0) {
-               P2_0 = 0;
-               P2SEL = (P2SEL & ~P2SEL_SELP2_0_MASK) | P2SEL_SELP2_0_GPIO;
-               T4CTL = 0;
-       } else {
-               P2SEL = (P2SEL & ~P2SEL_SELP2_0_MASK) | P2SEL_SELP2_0_PERIPHERAL;
-               T4CC0 = beep;
-               T4CTL = TxCTL_DIV_32 | TxCTL_MODE_MODULO | TxCTL_START;
-       }
-}
-
-void
-ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant
-{
-       ao_beep(beep);
-       ao_delay(ticks);
-       ao_beep(0);
-}
-
-void
-ao_beep_init(void)
-{
-       /* Our beeper is on P2_0, which is hooked to timer 4 using
-        * configuration alternative 2
-        */
-       P2_0 = 0;
-       P2SEL = (P2SEL & ~P2SEL_SELP2_0_MASK) | P2SEL_SELP2_0_GPIO;
-       PERCFG = (PERCFG & ~PERCFG_T4CFG_ALT_MASK) | PERCFG_T4CFG_ALT_2;
-       T4CCTL0 = TxCCTLy_CMP_TOGGLE|TxCCTLy_CMP_MODE_ENABLE;
-}
diff --git a/ao_cmd.c b/ao_cmd.c
deleted file mode 100644 (file)
index 827545d..0000000
--- a/ao_cmd.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-__xdata uint16_t ao_cmd_lex_i;
-__xdata char   ao_cmd_lex_c;
-__xdata enum ao_cmd_status ao_cmd_status;
-static __xdata uint8_t lex_echo;
-
-#define CMD_LEN        32
-
-static __xdata char    cmd_line[CMD_LEN];
-static __xdata uint8_t cmd_len;
-static __xdata uint8_t cmd_i;
-
-static void
-put_string(char *s)
-{
-       __xdata char    c;
-       while (c = *s++)
-               putchar(c);
-}
-
-static void
-readline(void)
-{
-       __xdata char c;
-       if (lex_echo)
-               put_string("> ");
-       cmd_len = 0;
-       for (;;) {
-               flush();
-               c = getchar();
-               /* backspace/delete */
-               if (c == '\010' || c == '\177') {
-                       if (cmd_len != 0) {
-                               if (lex_echo)
-                                       put_string("\010 \010");
-                               --cmd_len;
-                       }
-                       continue;
-               }
-
-               /* ^U */
-               if (c == '\025') {
-                       while (cmd_len != 0) {
-                               if (lex_echo)
-                                       put_string("\010 \010");
-                               --cmd_len;
-                       }
-                       continue;
-               }
-
-               /* map CR to NL */
-               if (c == '\r')
-                       c = '\n';
-               
-               if (c == '\n') {
-                       if (lex_echo)
-                               putchar('\n');
-                       break;
-               }
-
-               if (cmd_len >= CMD_LEN - 2) {
-                       if (lex_echo)
-                               putchar('\007');
-                       continue;
-               }
-               cmd_line[cmd_len++] = c;
-               if (lex_echo)
-                       putchar(c);
-       }
-       cmd_line[cmd_len++] = '\n';
-       cmd_line[cmd_len++] = '\0';
-       cmd_i = 0;
-}
-
-void
-ao_cmd_lex(void)
-{
-       ao_cmd_lex_c = '\n';
-       if (cmd_i < cmd_len)
-               ao_cmd_lex_c = cmd_line[cmd_i++];
-}
-
-static void
-putnibble(uint8_t v)
-{
-       if (v < 10)
-               putchar(v + '0');
-       else
-               putchar(v + ('a' - 10));
-}
-
-void
-ao_cmd_put16(uint16_t v)
-{
-       int8_t i;
-       for (i = 3; i >= 0; i--)
-               putnibble((v >> (i << 2)) & 0xf);
-}
-
-void
-ao_cmd_put8(uint8_t v)
-{
-       putnibble((v >> 4) & 0xf);
-       putnibble(v & 0xf);
-}
-
-void
-ao_cmd_white(void)
-{
-       while (ao_cmd_lex_c == ' ' || ao_cmd_lex_c == '\t')
-               ao_cmd_lex();
-}
-
-void
-ao_cmd_hex(void)
-{
-       __xdata uint8_t r = ao_cmd_lex_error;
-       
-       ao_cmd_lex_i = 0;
-       ao_cmd_white();
-       for(;;) {
-               if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9')
-                       ao_cmd_lex_i = (ao_cmd_lex_i << 4) | (ao_cmd_lex_c - '0');
-               else if ('a' <= ao_cmd_lex_c && ao_cmd_lex_c <= 'f')
-                       ao_cmd_lex_i = (ao_cmd_lex_i << 4) | (ao_cmd_lex_c - 'a' + 10);
-               else if ('A' <= ao_cmd_lex_c && ao_cmd_lex_c <= 'F')
-                       ao_cmd_lex_i = (ao_cmd_lex_i << 4) | (ao_cmd_lex_c - 'A' + 10);
-               else
-                       break;
-               r = ao_cmd_success;
-               ao_cmd_lex();
-       }
-       if (r != ao_cmd_success)
-               ao_cmd_status = r;
-}
-
-void
-ao_cmd_decimal(void)
-{
-       __xdata uint8_t r = ao_cmd_lex_error;
-       
-       ao_cmd_lex_i = 0;
-       ao_cmd_white();
-       for(;;) {
-               if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9')
-                       ao_cmd_lex_i = (ao_cmd_lex_i * 10) + (ao_cmd_lex_c - '0');
-               else
-                       break;
-               r = ao_cmd_success;
-               ao_cmd_lex();
-       }
-       if (r != ao_cmd_success)
-               ao_cmd_status = r;
-}
-
-static void
-eol(void)
-{
-       while (ao_cmd_lex_c != '\n')
-               ao_cmd_lex();
-}
-
-static void
-dump(void)
-{
-       __xdata uint16_t c;
-       __xdata uint8_t * __xdata start, * __xdata end;
-
-       ao_cmd_hex();
-       start = (uint8_t __xdata *) ao_cmd_lex_i;
-       ao_cmd_hex();
-       end = (uint8_t __xdata *) ao_cmd_lex_i;
-       if (ao_cmd_status != ao_cmd_success)
-               return;
-       c = 0;
-       while (start <= end) {
-               if ((c & 7) == 0) {
-                       if (c)
-                               putchar('\n');
-                       ao_cmd_put16((uint16_t) start);
-               }
-               putchar(' ');
-               ao_cmd_put8(*start);
-               ++c;
-               start++;
-       }
-       putchar('\n');
-}
-
-static void
-echo(void)
-{
-       ao_cmd_hex();
-       lex_echo = ao_cmd_lex_i != 0;
-}
-
-static void
-version(void)
-{
-       printf("manufacturer     %s\n", ao_manufacturer);
-       printf("product          %s\n", ao_product);
-       printf("serial-number    %u\n", ao_serial_number);
-       printf("software-version %s\n", ao_version);
-}
-
-static const char help_txt[] = "All numbers are in hex";
-
-#define NUM_CMDS       11
-
-static __code struct ao_cmds   *__xdata (ao_cmds[NUM_CMDS]);
-static __xdata uint8_t         ao_ncmds;
-
-static void
-help(void)
-{
-       __xdata uint8_t cmds;
-       __xdata uint8_t cmd;
-       __code struct ao_cmds * __xdata cs;
-       puts(help_txt);
-       for (cmds = 0; cmds < ao_ncmds; cmds++) {
-               cs = ao_cmds[cmds];
-               for (cmd = 0; cs[cmd].cmd != '\0'; cmd++)
-                       puts(cs[cmd].help);
-       }
-}
-
-static void
-report(void)
-{
-       switch(ao_cmd_status) {
-       case ao_cmd_lex_error:
-       case ao_cmd_syntax_error:
-               puts("Syntax error");
-               ao_cmd_status = 0;
-               break;
-       }
-}
-
-void
-ao_cmd_register(__code struct ao_cmds *cmds)
-{
-       if (ao_ncmds >= NUM_CMDS)
-               ao_panic(AO_PANIC_CMD);
-       ao_cmds[ao_ncmds++] = cmds;
-}
-
-void
-ao_cmd(void *parameters)
-{
-       __xdata char    c;
-       __xdata uint8_t cmd, cmds;
-       __code struct ao_cmds * __xdata cs;
-       void (*__xdata func)(void);
-       (void) parameters;
-
-       lex_echo = 1;
-       for (;;) {
-               readline();
-               ao_cmd_lex();
-               ao_cmd_white();
-               c = ao_cmd_lex_c;
-               ao_cmd_lex();
-               if (c == '\r' || c == '\n')
-                       continue;
-               func = (void (*)(void)) NULL;
-               for (cmds = 0; cmds < ao_ncmds; cmds++) {
-                       cs = ao_cmds[cmds];
-                       for (cmd = 0; cs[cmd].cmd != '\0'; cmd++)
-                               if (cs[cmd].cmd == c) {
-                                       func = cs[cmd].func;
-                                       break;
-                               }
-                       if (func)
-                               break;
-               }
-               if (func)
-                       (*func)();
-               else
-                       ao_cmd_status = ao_cmd_syntax_error;
-               report();
-       }
-}
-
-__xdata struct ao_task ao_cmd_task;
-
-__code struct ao_cmds  ao_base_cmds[] = {
-       { '?', help,            "?                                  Print this message" },
-       { 'T', ao_task_info,    "T                                  Show task states" },
-       { 'E', echo,            "E <0 off, 1 on>                    Set command echo mode" },
-       { 'd', dump,            "d <start> <end>                    Dump memory" },
-       { 'v', version,         "v                                  Show version" },
-       { 0,    help,   NULL },
-};
-
-void
-ao_cmd_init(void)
-{
-       ao_cmd_register(&ao_base_cmds[0]);
-       ao_add_task(&ao_cmd_task, ao_cmd, "cmd");
-}
diff --git a/ao_config.c b/ao_config.c
deleted file mode 100644 (file)
index 657c7a8..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-__xdata struct ao_config ao_config;
-__xdata uint8_t ao_config_loaded;
-__xdata uint8_t ao_config_dirty;
-__xdata uint8_t ao_config_mutex;
-
-#define AO_CONFIG_DEFAULT_MAIN_DEPLOY  250
-#define AO_CONFIG_DEFAULT_RADIO_CHANNEL        0
-#define AO_CONFIG_DEFAULT_CALLSIGN     "KD7SQG"
-#define AO_CONFIG_DEFAULT_ACCEL_ZERO_G 16000
-
-static void
-_ao_config_put(void)
-{
-       ao_ee_write_config((uint8_t *) &ao_config, sizeof (ao_config));
-}
-
-static void
-_ao_config_get(void)
-{
-       if (ao_config_loaded)
-               return;
-       ao_ee_read_config((uint8_t *) &ao_config, sizeof (ao_config));
-       if (ao_config.major != AO_CONFIG_MAJOR) {
-               ao_config.major = AO_CONFIG_MAJOR;
-               ao_config.minor = AO_CONFIG_MINOR;
-               ao_config.main_deploy = AO_CONFIG_DEFAULT_MAIN_DEPLOY;
-               ao_config.radio_channel = AO_CONFIG_DEFAULT_RADIO_CHANNEL;
-               ao_config.accel_zero_g = AO_CONFIG_DEFAULT_ACCEL_ZERO_G;
-               memset(&ao_config.callsign, '\0', sizeof (ao_config.callsign));
-               memcpy(&ao_config.callsign, AO_CONFIG_DEFAULT_CALLSIGN,
-                      sizeof(AO_CONFIG_DEFAULT_CALLSIGN) - 1);
-               ao_config_dirty = 1;
-       }
-       /* deal with minor version issues here, at 0 we haven't any */
-       ao_config_loaded = 1;
-}
-
-void
-ao_config_get(void)
-{
-       ao_mutex_get(&ao_config_mutex);
-       _ao_config_get();
-       ao_mutex_put(&ao_config_mutex);
-}
-
-void
-ao_config_callsign_show(void)
-{
-       printf ("Callsign: \"%s\"\n", ao_config.callsign);
-}
-
-void
-ao_config_callsign_set(void) __reentrant
-{
-       uint8_t c;
-       char callsign[AO_MAX_CALLSIGN + 1];
-
-       ao_cmd_white();
-       c = 0;
-       while (ao_cmd_lex_c != '\n') {
-               if (c < AO_MAX_CALLSIGN)
-                       callsign[c++] = ao_cmd_lex_c;
-               else
-                       ao_cmd_status = ao_cmd_lex_error;
-               ao_cmd_lex();
-       }
-       if (ao_cmd_status != ao_cmd_success)
-               return;
-       ao_mutex_get(&ao_config_mutex);
-       _ao_config_get();
-       while (c < AO_MAX_CALLSIGN + 1)
-               callsign[c++] = '\0';
-       memcpy(&ao_config.callsign, &callsign,
-              AO_MAX_CALLSIGN + 1);
-       ao_config_dirty = 1;
-       ao_mutex_put(&ao_config_mutex);
-       ao_config_callsign_show();
-}
-
-void
-ao_config_radio_channel_show(void) __reentrant
-{
-       uint32_t        freq = 434550L + ao_config.radio_channel * 100L;
-       uint16_t        mhz = freq / 1000L;
-       uint16_t        khz = freq % 1000L;
-
-       printf("Radio channel: %d (%d.%03dMHz)\n",
-              ao_config.radio_channel, mhz, khz);
-}
-
-void
-ao_config_radio_channel_set(void) __reentrant
-{
-       ao_cmd_decimal();
-       if (ao_cmd_status != ao_cmd_success)
-               return;
-       ao_mutex_get(&ao_config_mutex);
-       _ao_config_get();
-       ao_config.radio_channel = ao_cmd_lex_i;
-       ao_config_dirty = 1;
-       ao_mutex_put(&ao_config_mutex);
-       ao_config_radio_channel_show();
-}
-
-void
-ao_config_main_deploy_show(void) __reentrant
-{
-       printf("Main deploy set to %d meters (%d feet)\n",
-              ao_config.main_deploy,
-              (int16_t) ((int32_t) ao_config.main_deploy * 328 / 100));
-}
-
-void
-ao_config_main_deploy_set(void) __reentrant
-{
-       ao_cmd_decimal();
-       if (ao_cmd_status != ao_cmd_success)
-               return;
-       ao_mutex_get(&ao_config_mutex);
-       _ao_config_get();
-       ao_config.main_deploy = ao_cmd_lex_i;
-       ao_config_dirty = 1;
-       ao_mutex_put(&ao_config_mutex);
-       ao_config_main_deploy_show();
-}
-
-void
-ao_config_accel_zero_g_show(void) __reentrant
-{
-       printf("Accel zero g point set to %d\n",
-              ao_config.accel_zero_g);
-}
-
-#define ZERO_G_SAMPLES 1000
-
-static int16_t
-ao_config_accel_zero_g_auto(void) __reentrant
-{
-       uint16_t        i;
-       int32_t         accel_total;
-       uint8_t         cal_adc_ring;
-
-       puts("Calibrating accelerometer..."); flush();
-       i = ZERO_G_SAMPLES;
-       accel_total = 0;
-       cal_adc_ring = ao_adc_head;
-       while (i) {
-               ao_sleep(&ao_adc_ring);
-               while (i && cal_adc_ring != ao_adc_head) {
-                       accel_total += (int32_t) ao_adc_ring[cal_adc_ring].accel;
-                       cal_adc_ring = ao_adc_ring_next(cal_adc_ring);
-                       i--;
-               }
-       }
-       return (int16_t) (accel_total / ZERO_G_SAMPLES);
-}
-void
-ao_config_accel_zero_g_set(void) __reentrant
-{
-       ao_cmd_decimal();
-       if (ao_cmd_status != ao_cmd_success)
-               return;
-       if (ao_cmd_lex_i == 0)
-               ao_cmd_lex_i = ao_config_accel_zero_g_auto();
-       ao_mutex_get(&ao_config_mutex);
-       _ao_config_get();
-       ao_config.accel_zero_g = ao_cmd_lex_i;
-       ao_config_dirty = 1;
-       ao_mutex_put(&ao_config_mutex);
-       ao_config_accel_zero_g_show();
-}
-
-struct ao_config_var {
-       char            cmd;
-       void            (*set)(void) __reentrant;
-       void            (*show)(void) __reentrant;
-       const char      *help;
-};
-
-void
-ao_config_help(void) __reentrant;
-
-void
-ao_config_show(void) __reentrant;
-
-void
-ao_config_write(void) __reentrant;
-
-__code struct ao_config_var ao_config_vars[] = {
-       { 'm',  ao_config_main_deploy_set,      ao_config_main_deploy_show,
-               "m <meters>  Set height above launch for main deploy (in meters)" },
-       { 'a',  ao_config_accel_zero_g_set,     ao_config_accel_zero_g_show,
-               "a <value>   Set accelerometer zero g point (0 for auto)" },
-       { 'r',  ao_config_radio_channel_set,    ao_config_radio_channel_show,
-               "r <channel> Set radio channel (freq = 434.550 + channel * .1)" },
-       { 'c',  ao_config_callsign_set,         ao_config_callsign_show,
-               "c <call>    Set callsign broadcast in each packet (8 char max)" },
-       { 's',  ao_config_show,                 ao_config_show,
-               "s           Show current config values" },
-       { 'w',  ao_config_write,                ao_config_write,
-               "w           Write current values to eeprom" },
-       { '?',  ao_config_help,                 ao_config_help,
-               "?           Show available config variables" },
-       { 0,    ao_config_main_deploy_set,      ao_config_main_deploy_show,
-               NULL },
-};
-
-void
-ao_config_set(void)
-{
-       char    c;
-       uint8_t cmd;
-       void (*__xdata func)(void) __reentrant;
-
-       ao_cmd_white();
-       c = ao_cmd_lex_c;
-       ao_cmd_lex();
-       func = 0;
-       for (cmd = 0; ao_config_vars[cmd].cmd != '\0'; cmd++)
-               if (ao_config_vars[cmd].cmd == c) {
-                       func = ao_config_vars[cmd].set;
-                       break;
-               }
-       if (func)
-               (*func)();
-       else
-               ao_cmd_status = ao_cmd_syntax_error;
-}
-
-void
-ao_config_help(void) __reentrant
-{
-       uint8_t cmd;
-       for (cmd = 0; ao_config_vars[cmd].cmd != '\0'; cmd++)
-               puts (ao_config_vars[cmd].help);
-}
-
-void
-ao_config_show(void) __reentrant
-{
-       uint8_t cmd;
-       for (cmd = 0; ao_config_vars[cmd].cmd != '\0'; cmd++)
-               if (ao_config_vars[cmd].show != ao_config_vars[cmd].set)
-                       (*ao_config_vars[cmd].show)();
-}
-
-void
-ao_config_write(void) __reentrant
-{
-       ao_mutex_get(&ao_config_mutex);
-       if (ao_config_dirty) {
-               _ao_config_put();
-               ao_config_dirty = 0;
-               printf("Saved\n");
-       }
-       ao_mutex_put(&ao_config_mutex);
-}
-
-__code struct ao_cmds ao_config_cmds[] = {
-       { 'c',  ao_config_set,  "c <var> <value>                    Set config variable (? for help, s to show)" },
-       { '\0', ao_config_set, NULL },
-};
-
-void
-ao_config_init(void)
-{
-       ao_cmd_register(&ao_config_cmds[0]);
-}
diff --git a/ao_convert.c b/ao_convert.c
deleted file mode 100644 (file)
index 57ed737..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-static const int16_t altitude_table[2048] = {
-#include "altitude.h"
-};
-
-int16_t
-ao_pres_to_altitude(int16_t pres) __reentrant
-{
-       pres = pres >> 4;
-       if (pres < 0) pres = 0;
-       if (pres > 2047) pres = 2047;
-       return altitude_table[pres];
-}
-
-int16_t
-ao_altitude_to_pres(int16_t alt) __reentrant
-{
-       int16_t pres;
-
-       for (pres = 0; pres < 2047; pres++)
-               if (altitude_table[pres] <= alt)
-                       break;
-       return pres << 4;
-}
-
-static __xdata uint8_t ao_temp_mutex;
-
-int16_t
-ao_temp_to_dC(int16_t temp) __reentrant
-{
-       int16_t ret;
-
-       ao_mutex_get(&ao_temp_mutex);
-       ret = (int16_t) ((temp >> 4) * 3300L / 2047L) - 500;
-       ao_mutex_put(&ao_temp_mutex);
-       return ret;
-}
diff --git a/ao_dbg.c b/ao_dbg.c
deleted file mode 100644 (file)
index 8a11a44..0000000
--- a/ao_dbg.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-#define 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)
-
-static void
-ao_dbg_send_bits(uint8_t msk, uint8_t val)
-{
-       P0 = (P0 & ~msk) | (val & msk);
-       _asm
-               nop
-               nop
-       _endasm;
-}
-
-void
-ao_dbg_send_byte(uint8_t byte)
-{
-       __xdata uint8_t b, d;
-
-       P0 |= DBG_DATA;
-       P0DIR |= DBG_DATA;
-       for (b = 0; b < 8; b++) {
-               d = 0;
-               if (byte & 0x80)
-                       d = DBG_DATA;
-               byte <<= 1;
-               ao_dbg_send_bits(DBG_CLOCK|DBG_DATA, DBG_CLOCK|d);
-               ao_dbg_send_bits(DBG_CLOCK|DBG_DATA,     0    |d);
-       }
-       P0DIR &= ~DBG_DATA;
-}
-
-uint8_t
-ao_dbg_recv_byte(void)
-{
-       __xdata uint8_t byte, b;
-
-       byte = 0;
-       for (b = 0; b < 8; b++) {
-               byte = byte << 1;
-               ao_dbg_send_bits(DBG_CLOCK, DBG_CLOCK);
-               if (DBG_DATA_PIN)
-                       byte |= 1;
-               ao_dbg_send_bits(DBG_CLOCK, 0);
-       }
-       return byte;
-}
-
-/* 8051 instructions
- */
-#define NOP                    0x00
-#define MOV_direct_data                0x75
-#define LJMP                   0x02
-#define MOV_Rn_data(n)         (0x78 | (n))
-#define DJNZ_Rn_rel(n)         (0xd8 | (n))
-#define MOV_A_direct           0xe5
-#define MOV_direct1_direct2    0x85
-#define MOV_direct_A           0xf5
-#define MOV_DPTR_data16                0x90
-#define MOV_A_data             0x74
-#define MOVX_atDPTR_A          0xf0
-#define MOVX_A_atDPTR          0xe0
-#define INC_DPTR               0xa3
-#define TRAP                   0xa5
-#define SJMP                   0x80
-#define JB                     0x20
-
-#define DEBUG_INSTR(l)         (0x54 | (l))
-
-#define SFR_PSW                        0xD0
-#define SFR_DPL0               0x82
-#define SFR_DPH0               0x83
-#define SFR_DPL1               0x84
-#define SFR_DPH1               0x85
-
-__xdata uint8_t        save_acc;
-__xdata uint8_t save_psw;
-__xdata uint8_t save_dpl0;
-__xdata uint8_t save_dph0;
-__xdata uint8_t save_dpl1;
-__xdata uint8_t save_dph1;
-
-static uint8_t
-ao_dbg_inst1(uint8_t a) __reentrant
-{
-       ao_dbg_send_byte(DEBUG_INSTR(1));
-       ao_dbg_send_byte(a);
-       return ao_dbg_recv_byte();
-}
-
-static uint8_t
-ao_dbg_inst2(uint8_t a, uint8_t b) __reentrant
-{
-       ao_dbg_send_byte(DEBUG_INSTR(2));
-       ao_dbg_send_byte(a);
-       ao_dbg_send_byte(b);
-       return ao_dbg_recv_byte();
-}
-
-static uint8_t
-ao_dbg_inst3(uint8_t a, uint8_t b, uint8_t c) __reentrant
-{
-       ao_dbg_send_byte(DEBUG_INSTR(3));
-       ao_dbg_send_byte(a);
-       ao_dbg_send_byte(b);
-       ao_dbg_send_byte(c);
-       return ao_dbg_recv_byte();
-}
-
-void
-ao_dbg_start_transfer(uint16_t addr)
-{
-       save_acc  = ao_dbg_inst1(NOP);
-       save_psw  = ao_dbg_inst2(MOV_A_direct, SFR_PSW);
-       save_dpl0 = ao_dbg_inst2(MOV_A_direct, SFR_DPL0);
-       save_dph0 = ao_dbg_inst2(MOV_A_direct, SFR_DPH0);
-       save_dpl1 = ao_dbg_inst2(MOV_A_direct, SFR_DPL1);
-       save_dph1 = ao_dbg_inst2(MOV_A_direct, SFR_DPH1);
-       ao_dbg_inst3(MOV_DPTR_data16, addr >> 8, addr);
-}
-
-void
-ao_dbg_end_transfer(void)
-{
-       ao_dbg_inst3(MOV_direct_data, SFR_DPL0, save_dpl0);
-       ao_dbg_inst3(MOV_direct_data, SFR_DPH0, save_dph0);
-       ao_dbg_inst3(MOV_direct_data, SFR_DPL1, save_dpl1);
-       ao_dbg_inst3(MOV_direct_data, SFR_DPH1, save_dph1);
-       ao_dbg_inst3(MOV_direct_data, SFR_PSW, save_psw);
-       ao_dbg_inst2(MOV_A_data, save_acc);
-}
-
-void
-ao_dbg_write_byte(uint8_t byte)
-{
-       ao_dbg_inst2(MOV_A_data, byte);
-       ao_dbg_inst1(MOVX_atDPTR_A);
-       ao_dbg_inst1(INC_DPTR);
-}
-
-uint8_t
-ao_dbg_read_byte(void)
-{
-       ao_dbg_inst1(MOVX_A_atDPTR);
-       return ao_dbg_inst1(INC_DPTR);
-}
-
-static void
-ao_dbg_set_pins(void)
-{
-       /* Disable peripheral use of P0 */
-       ADCCFG = 0;
-       P0SEL = 0;
-       
-       
-       /* make P0_4 tri-state */
-       P0INP = DBG_DATA;
-       P2INP &= ~(P2INP_PDUP0_PULL_DOWN);
-       
-       /* Raise RESET_N and CLOCK */
-       P0 = DBG_RESET_N | DBG_CLOCK;
-
-       /* RESET_N and CLOCK are outputs now */
-       P0DIR = DBG_RESET_N | DBG_CLOCK;
-}
-
-static void
-ao_dbg_long_delay(void)
-{
-       uint8_t n;
-
-       for (n = 0; n < 20; n++)
-               _asm nop _endasm;
-}
-
-void
-ao_dbg_debug_mode(void)
-{
-       ao_dbg_set_pins();
-       ao_dbg_long_delay();
-       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N);
-       ao_dbg_long_delay();
-       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N,     0    |DBG_DATA|    0    );
-       ao_dbg_long_delay();
-       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
-       ao_dbg_long_delay();
-       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N,     0    |DBG_DATA|    0    );
-       ao_dbg_long_delay();
-       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
-       ao_dbg_long_delay();
-       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N,     0    |DBG_DATA|DBG_RESET_N);
-       ao_dbg_long_delay();
-}
-
-void
-ao_dbg_reset(void)
-{
-       ao_dbg_set_pins();
-       ao_dbg_long_delay();
-       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N);
-       ao_dbg_long_delay();
-       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
-       ao_dbg_long_delay();
-       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
-       ao_dbg_long_delay();
-       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
-       ao_dbg_long_delay();
-       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
-       ao_dbg_long_delay();
-       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N);
-       ao_dbg_long_delay();
-}
-
-static void
-debug_enable(void)
-{
-       ao_dbg_debug_mode();
-}
-
-static void
-debug_reset(void)
-{
-       ao_dbg_reset();
-}
-
-static void
-debug_put(void)
-{
-       for (;;) {
-               ao_cmd_white ();
-               if (ao_cmd_lex_c == '\n')
-                       break;
-               ao_cmd_hex();
-               if (ao_cmd_status != ao_cmd_success)
-                       break;
-               ao_dbg_send_byte(ao_cmd_lex_i);
-       }
-}
-
-static void
-debug_get(void)
-{
-       __xdata uint16_t count;
-       __xdata uint16_t i;
-       __xdata uint8_t byte;
-       ao_cmd_hex();
-       if (ao_cmd_status != ao_cmd_success)
-               return;
-       count = ao_cmd_lex_i;
-       if (count > 256) {
-               ao_cmd_status = ao_cmd_syntax_error;
-               return;
-       }
-       for (i = 0; i < count; i++) {
-               if (i && (i & 7) == 0)
-                       putchar('\n');
-               byte = ao_dbg_recv_byte();
-               ao_cmd_put8(byte);
-               putchar(' ');
-       }
-       putchar('\n');
-}
-
-static uint8_t
-getnibble(void)
-{
-       __xdata char    c;
-
-       c = getchar();
-       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);
-       ao_cmd_status = ao_cmd_lex_error;
-       return 0;
-}
-
-static void
-debug_input(void)
-{
-       __xdata uint16_t count;
-       __xdata uint16_t addr;
-       __xdata uint8_t b;
-       __xdata uint8_t i;
-
-       ao_cmd_hex();
-       count = ao_cmd_lex_i;
-       ao_cmd_hex();
-       addr = ao_cmd_lex_i;
-       if (ao_cmd_status != ao_cmd_success)
-               return;
-       ao_dbg_start_transfer(addr);
-       i = 0;
-       while (count--) {
-               if (!(i++ & 7))
-                       putchar('\n');
-               b = ao_dbg_read_byte();
-               ao_cmd_put8(b);
-       }
-       ao_dbg_end_transfer();
-       putchar('\n');
-}
-
-static void
-debug_output(void)
-{
-       __xdata uint16_t count;
-       __xdata uint16_t addr;
-       __xdata uint8_t b;
-
-       ao_cmd_hex();
-       count = ao_cmd_lex_i;
-       ao_cmd_hex();
-       addr = ao_cmd_lex_i;
-       if (ao_cmd_status != ao_cmd_success)
-               return;
-       ao_dbg_start_transfer(addr);
-       while (count--) {
-               b = getnibble() << 4;
-               b |= getnibble();
-               if (ao_cmd_status != ao_cmd_success)
-                       return;
-               ao_dbg_write_byte(b);
-       }
-       ao_dbg_end_transfer();
-}
-
-__code struct ao_cmds ao_dbg_cmds[7] = {
-       { 'D',  debug_enable,   "D                                  Enable debug mode" },
-       { 'G',  debug_get,      "G <count>                          Get data from debug port" },
-       { 'I',  debug_input,    "I <count> <addr>                   Input <count> bytes to target at <addr>" },
-       { 'O',  debug_output,   "O <count> <addr>                   Output <count> bytes to target at <addr>" },
-       { 'P',  debug_put,      "P <byte> ...                       Put data to debug port" },
-       { 'R',  debug_reset,    "R                                  Reset target" },
-       { 0, debug_reset,       0 },
-};
-
-void
-ao_dbg_init(void)
-{
-       ao_cmd_register(&ao_dbg_cmds[0]);
-}
diff --git a/ao_dma.c b/ao_dma.c
deleted file mode 100644 (file)
index 8d96cc4..0000000
--- a/ao_dma.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-#define NUM_DMA        5
-
-/*
- * The config address for DMA0 is programmed
- * separately from that of DMA1-4, but for simplicity, 
- * we make them all contiguous.
- */
-
-static __xdata struct cc_dma_channel ao_dma_config[NUM_DMA];
-static __xdata uint8_t * __xdata ao_dma_done[NUM_DMA];
-static __data uint8_t ao_next_dma;
-
-uint8_t
-ao_dma_alloc(__xdata uint8_t *done)
-{
-       uint8_t id;
-
-       if (ao_next_dma == NUM_DMA)
-               ao_panic(AO_PANIC_DMA);
-       id = ao_next_dma++;
-       ao_dma_done[id] = done;
-
-       /* When the first dma object is allocated, set up the DMA
-        * controller
-        */
-       if (id == 0) {
-               DMAIRQ = 0;
-               DMAIF = 0;
-               IEN1 |= IEN1_DMAIE;
-       } 
-
-       return id;
-}
-
-void
-ao_dma_set_transfer(uint8_t id,
-                   void __xdata *srcaddr,
-                   void __xdata *dstaddr,
-                   uint16_t count,
-                   uint8_t cfg0,
-                   uint8_t cfg1)
-{
-       if (DMAARM & (1 << id))
-               ao_panic(AO_PANIC_DMA);
-       ao_dma_config[id].src_high = ((uint16_t) srcaddr) >> 8;
-       ao_dma_config[id].src_low = ((uint16_t) srcaddr);
-       ao_dma_config[id].dst_high = ((uint16_t) dstaddr) >> 8;
-       ao_dma_config[id].dst_low = ((uint16_t) dstaddr);
-       ao_dma_config[id].len_high = count >> 8;
-       ao_dma_config[id].len_low = count;
-       ao_dma_config[id].cfg0 = cfg0;
-       ao_dma_config[id].cfg1 = cfg1 | DMA_CFG1_IRQMASK;
-       if (id == 0) {
-               DMA0CFGH = ((uint16_t) (&ao_dma_config[0])) >> 8;
-               DMA0CFGL = ((uint16_t) (&ao_dma_config[0]));
-       } else {
-               DMA1CFGH = ((uint16_t) (&ao_dma_config[1])) >> 8;
-               DMA1CFGL = ((uint16_t) (&ao_dma_config[1]));
-       }
-}
-
-#define nop()  _asm nop _endasm;
-
-void
-ao_dma_start(uint8_t id)
-{
-       uint8_t mask = (1 << id);
-       DMAIRQ &= ~mask;
-       DMAARM = 0x80 | mask;
-       nop(); nop(); nop(); nop();
-       nop(); nop(); nop(); nop();
-       *(ao_dma_done[id]) = 0;
-       DMAARM = mask;
-       nop(); nop(); nop(); nop();
-       nop(); nop(); nop(); nop();
-       nop();
-}
-
-void
-ao_dma_trigger(uint8_t id)
-{
-       DMAREQ |= (1 << id);
-}
-
-void
-ao_dma_abort(uint8_t id)
-{
-       uint8_t mask = (1 << id);
-       DMAARM = 0x80 | mask;
-       DMAIRQ &= ~mask;
-}
-
-void
-ao_dma_isr(void) interrupt 8
-{
-       uint8_t id, mask;
-       
-       /* Find the first DMA channel which is done */
-       mask = 1;
-       for (id = 0; id < ao_next_dma; id++) {
-               if (DMAIRQ & mask) {
-                       /* Clear CPU interrupt flag */
-                       DMAIF = 0;
-                       /* Clear the completed ID */
-                       DMAIRQ = ~mask;
-                       *(ao_dma_done[id]) = 1;
-                       ao_wakeup(ao_dma_done[id]);
-                       break;
-               }
-               mask <<= 1;
-       }
-}
diff --git a/ao_ee.c b/ao_ee.c
deleted file mode 100644 (file)
index a0f2e23..0000000
--- a/ao_ee.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-#include "25lc1024.h"
-
-/*
- * Using SPI on USART 0, with P1_2 as the chip select
- */
-
-#define EE_CS          P1_2
-#define EE_CS_INDEX    2
-
-__xdata uint8_t ao_ee_dma_in_done;
-__xdata uint8_t ao_ee_dma_out_done;
-__xdata uint8_t ao_ee_mutex;
-
-uint8_t        ao_ee_dma_out_id;
-uint8_t ao_ee_dma_in_id;
-
-static __xdata uint8_t ao_ee_const = 0xff;
-
-#define ao_ee_delay() do { \
-       _asm nop _endasm; \
-       _asm nop _endasm; \
-       _asm nop _endasm; \
-} while(0)
-
-void ao_ee_cs_low(void)
-{
-       ao_ee_delay();
-       EE_CS = 0;
-       ao_ee_delay();
-}
-
-void ao_ee_cs_high(void)
-{
-       ao_ee_delay();
-       EE_CS = 1;
-       ao_ee_delay();
-}
-
-/* Send bytes over SPI.
- *
- * This sets up two DMA engines, one writing the data and another reading
- * bytes coming back.  We use the bytes coming back to tell when the transfer
- * is complete, as the transmit register is double buffered and hence signals
- * completion one byte before the transfer is actually complete
- */
-static void
-ao_ee_send(void __xdata *block, uint16_t len)
-{
-       ao_dma_set_transfer(ao_ee_dma_in_id,
-                           &U0DBUFXADDR,
-                           &ao_ee_const,
-                           len,
-                           DMA_CFG0_WORDSIZE_8 |
-                           DMA_CFG0_TMODE_SINGLE |
-                           DMA_CFG0_TRIGGER_URX0,
-                           DMA_CFG1_SRCINC_0 |
-                           DMA_CFG1_DESTINC_0 |
-                           DMA_CFG1_PRIORITY_NORMAL);
-
-       ao_dma_set_transfer(ao_ee_dma_out_id,
-                           block,
-                           &U0DBUFXADDR,
-                           len,
-                           DMA_CFG0_WORDSIZE_8 |
-                           DMA_CFG0_TMODE_SINGLE |
-                           DMA_CFG0_TRIGGER_UTX0,
-                           DMA_CFG1_SRCINC_1 |
-                           DMA_CFG1_DESTINC_0 |
-                           DMA_CFG1_PRIORITY_NORMAL);
-
-       ao_dma_start(ao_ee_dma_in_id);
-       ao_dma_start(ao_ee_dma_out_id);
-       ao_dma_trigger(ao_ee_dma_out_id);
-       __critical while (!ao_ee_dma_in_done)
-               ao_sleep(&ao_ee_dma_in_done);
-}
-
-/* Receive bytes over SPI.
- *
- * This sets up tow DMA engines, one reading the data and another
- * writing constant values to the SPI transmitter as that is what
- * clocks the data coming in.
- */
-static void
-ao_ee_recv(void __xdata *block, uint16_t len)
-{
-       ao_dma_set_transfer(ao_ee_dma_in_id,
-                           &U0DBUFXADDR,
-                           block,
-                           len,
-                           DMA_CFG0_WORDSIZE_8 |
-                           DMA_CFG0_TMODE_SINGLE |
-                           DMA_CFG0_TRIGGER_URX0,
-                           DMA_CFG1_SRCINC_0 |
-                           DMA_CFG1_DESTINC_1 |
-                           DMA_CFG1_PRIORITY_NORMAL);
-
-       ao_dma_set_transfer(ao_ee_dma_out_id,
-                           &ao_ee_const,
-                           &U0DBUFXADDR,
-                           len,
-                           DMA_CFG0_WORDSIZE_8 |
-                           DMA_CFG0_TMODE_SINGLE |
-                           DMA_CFG0_TRIGGER_UTX0,
-                           DMA_CFG1_SRCINC_0 |
-                           DMA_CFG1_DESTINC_0 |
-                           DMA_CFG1_PRIORITY_NORMAL);
-
-       ao_dma_start(ao_ee_dma_in_id);
-       ao_dma_start(ao_ee_dma_out_id);
-       ao_dma_trigger(ao_ee_dma_out_id);
-       __critical while (!ao_ee_dma_in_done)
-               ao_sleep(&ao_ee_dma_in_done);
-}
-
-#define EE_BLOCK       256
-
-struct ao_ee_instruction {
-       uint8_t instruction;
-       uint8_t address[3];
-} __xdata ao_ee_instruction;
-
-static void
-ao_ee_write_enable(void)
-{
-       ao_ee_cs_low();
-       ao_ee_instruction.instruction = EE_WREN;
-       ao_ee_send(&ao_ee_instruction, 1);
-       ao_ee_cs_high();
-}
-
-static uint8_t
-ao_ee_rdsr(void)
-{
-       ao_ee_cs_low();
-       ao_ee_instruction.instruction = EE_RDSR;
-       ao_ee_send(&ao_ee_instruction, 1);
-       ao_ee_recv(&ao_ee_instruction, 1);
-       ao_ee_cs_high();
-       return ao_ee_instruction.instruction;
-}
-
-static void
-ao_ee_wrsr(uint8_t status)
-{
-       ao_ee_cs_low();
-       ao_ee_instruction.instruction = EE_WRSR;
-       ao_ee_instruction.address[0] = status;
-       ao_ee_send(&ao_ee_instruction, 2);
-       ao_ee_cs_high();
-}
-
-#define EE_BLOCK_NONE  0xffff
-
-static __xdata uint8_t ao_ee_data[EE_BLOCK];
-static __pdata uint16_t ao_ee_block = EE_BLOCK_NONE;
-static __pdata uint8_t ao_ee_block_dirty;
-
-/* Write the current block to the EEPROM */
-static void
-ao_ee_write_block(void)
-{
-       uint8_t status;
-
-       status = ao_ee_rdsr();
-       if (status & (EE_STATUS_BP0|EE_STATUS_BP1|EE_STATUS_WPEN)) {
-               status &= ~(EE_STATUS_BP0|EE_STATUS_BP1|EE_STATUS_WPEN);
-               ao_ee_wrsr(status);
-       }
-       ao_ee_write_enable();
-       ao_ee_cs_low();
-       ao_ee_instruction.instruction = EE_WRITE;
-       ao_ee_instruction.address[0] = ao_ee_block >> 8;
-       ao_ee_instruction.address[1] = ao_ee_block;
-       ao_ee_instruction.address[2] = 0;
-       ao_ee_send(&ao_ee_instruction, 4);
-       ao_ee_send(ao_ee_data, EE_BLOCK);
-       ao_ee_cs_high();
-       for (;;) {
-               uint8_t status = ao_ee_rdsr();
-               if ((status & EE_STATUS_WIP) == 0)
-                       break;
-       }
-}
-
-/* Read the current block from the EEPROM */
-static void
-ao_ee_read_block(void)
-{
-       ao_ee_cs_low();
-       ao_ee_instruction.instruction = EE_READ;
-       ao_ee_instruction.address[0] = ao_ee_block >> 8;
-       ao_ee_instruction.address[1] = ao_ee_block;
-       ao_ee_instruction.address[2] = 0;
-       ao_ee_send(&ao_ee_instruction, 4);
-       ao_ee_recv(ao_ee_data, EE_BLOCK);
-       ao_ee_cs_high();
-}
-       
-static void
-ao_ee_flush_internal(void)
-{
-       if (ao_ee_block_dirty) {
-               ao_ee_write_block();
-               ao_ee_block_dirty = 0;
-       }
-}
-       
-static void
-ao_ee_fill(uint16_t block)
-{
-       if (block != ao_ee_block) {
-               ao_ee_flush_internal();
-               ao_ee_block = block;
-               ao_ee_read_block();
-       }
-}
-
-uint8_t
-ao_ee_write(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant
-{
-       uint16_t block;
-       uint16_t this_len;
-       uint8_t this_off;
-       
-       if (pos >= AO_EE_DATA_SIZE || pos + len > AO_EE_DATA_SIZE)
-               return 0;
-       while (len) {
-               
-               /* Compute portion of transfer within
-                * a single block
-                */
-               this_off = pos;
-               this_len = 256 - (uint16_t) this_off;
-               block = (uint16_t) (pos >> 8);
-               if (this_len > len)
-                       this_len = len;
-               if (this_len & 0xff00)
-                       ao_panic(AO_PANIC_EE);
-
-               /* Transfer the data */
-               ao_mutex_get(&ao_ee_mutex); {
-                       if (this_len != 256)
-                               ao_ee_fill(block);
-                       else {
-                               ao_ee_flush_internal();
-                               ao_ee_block = block;
-                       }
-                       memcpy(ao_ee_data + this_off, buf, this_len);
-                       ao_ee_block_dirty = 1;
-               } ao_mutex_put(&ao_ee_mutex);
-
-               /* See how much is left */
-               buf += this_len;
-               len -= this_len;
-       }
-       return 1;
-}
-
-uint8_t
-ao_ee_read(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant
-{
-       uint16_t block;
-       uint16_t this_len;
-       uint8_t this_off;
-       
-       if (pos >= AO_EE_DATA_SIZE || pos + len > AO_EE_DATA_SIZE)
-               return 0;
-       while (len) {
-               
-               /* Compute portion of transfer within
-                * a single block
-                */
-               this_off = pos;
-               this_len = 256 - (uint16_t) this_off;
-               block = (uint16_t) (pos >> 8);
-               if (this_len > len)
-                       this_len = len;
-               if (this_len & 0xff00)
-                       ao_panic(AO_PANIC_EE);
-
-               /* Transfer the data */
-               ao_mutex_get(&ao_ee_mutex); {
-                       ao_ee_fill(block);
-                       memcpy(buf, ao_ee_data + this_off, this_len);
-               } ao_mutex_put(&ao_ee_mutex);
-
-               /* See how much is left */
-               buf += this_len;
-               len -= this_len;
-       }
-       return 1;
-}
-
-void
-ao_ee_flush(void) __reentrant
-{
-       ao_mutex_get(&ao_ee_mutex); {
-               ao_ee_flush_internal();
-       } ao_mutex_put(&ao_ee_mutex);
-}
-
-/*
- * Read/write the config block, which is in
- * the last block of the ao_eeprom
- */
-uint8_t
-ao_ee_write_config(uint8_t *buf, uint16_t len) __reentrant
-{
-       if (len > AO_EE_BLOCK_SIZE)
-               return 0;
-       ao_mutex_get(&ao_ee_mutex); {
-               ao_ee_fill(AO_EE_CONFIG_BLOCK);
-               memcpy(ao_ee_data, buf, len);
-               ao_ee_block_dirty = 1;
-               ao_ee_flush_internal();
-       } ao_mutex_put(&ao_ee_mutex);
-       return 1;
-}
-
-uint8_t
-ao_ee_read_config(uint8_t *buf, uint16_t len) __reentrant
-{
-       if (len > AO_EE_BLOCK_SIZE)
-               return 0;
-       ao_mutex_get(&ao_ee_mutex); {
-               ao_ee_fill(AO_EE_CONFIG_BLOCK);
-               memcpy(buf, ao_ee_data, len);
-       } ao_mutex_put(&ao_ee_mutex);
-       return 1;
-}
-
-static void
-ee_dump(void)
-{
-       __xdata uint8_t b;
-       __xdata uint16_t block;
-       __xdata uint8_t i;
-       
-       ao_cmd_hex();
-       block = ao_cmd_lex_i;
-       if (ao_cmd_status != ao_cmd_success)
-               return;
-       i = 0;
-       do {
-               if ((i & 7) == 0) {
-                       if (i)
-                               putchar('\n');
-                       ao_cmd_put16((uint16_t) i);
-               }
-               putchar(' ');
-               ao_ee_read(((uint32_t) block << 8) | i, &b, 1);
-               ao_cmd_put8(b);
-               ++i;
-       } while (i != 0);
-       putchar('\n');
-}
-
-static void
-ee_store(void)
-{
-       __xdata uint16_t block;
-       __xdata uint8_t i;
-       __xdata uint16_t len;
-       __xdata uint8_t b;
-       __xdata uint32_t addr;
-
-       ao_cmd_hex();
-       block = ao_cmd_lex_i;
-       ao_cmd_hex();
-       i = ao_cmd_lex_i;
-       addr = ((uint32_t) block << 8) | i;
-       ao_cmd_hex();
-       len = ao_cmd_lex_i;
-       if (ao_cmd_status != ao_cmd_success)
-               return;
-       while (len--) {
-               ao_cmd_hex();
-               if (ao_cmd_status != ao_cmd_success)
-                       return;
-               b = ao_cmd_lex_i;
-               ao_ee_write(addr, &b, 1);
-               addr++;
-       }
-       ao_ee_flush();  
-}
-
-__code struct ao_cmds ao_ee_cmds[] = {
-       { 'e', ee_dump,         "e <block>                          Dump a block of EEPROM data" },
-       { 'w', ee_store,        "w <block> <start> <len> <data> ... Write data to EEPROM" },
-       { 0,   ee_store, NULL },
-};
-
-/*
- * To initialize the chip, set up the CS line and
- * the SPI interface
- */
-void
-ao_ee_init(void)
-{
-       /* set up CS */
-       EE_CS = 1;
-       P1DIR |= (1 << EE_CS_INDEX);
-       P1SEL &= ~(1 << EE_CS_INDEX);
-
-       /* Set up the USART pin assignment */
-       PERCFG = (PERCFG & ~PERCFG_U0CFG_ALT_MASK) | PERCFG_U0CFG_ALT_2;
-
-       /* Ensure that USART0 takes precidence over USART1 for pins that
-        * they share
-        */
-       P2SEL = (P2SEL & ~P2SEL_PRI3P1_MASK) | P2SEL_PRI3P1_USART0;
-
-       /* Make the SPI pins be controlled by the USART peripheral */
-       P1SEL |= ((1 << 5) | (1 << 4) | (1 << 3));
-
-       /* Set up OUT DMA */
-       ao_ee_dma_out_id = ao_dma_alloc(&ao_ee_dma_out_done);
-
-       /* Set up IN DMA */
-       ao_ee_dma_in_id = ao_dma_alloc(&ao_ee_dma_in_done);
-
-       /* Set up the USART.
-        *
-        * SPI master mode
-        */
-       U0CSR = (UxCSR_MODE_SPI | UxCSR_RE | UxCSR_MASTER);
-
-       /* Set the baud rate and signal parameters
-        *
-        * The cc1111 is limited to a 24/8 MHz SPI clock,
-        * while the 25LC1024 is limited to 20MHz. So,
-        * use the 3MHz clock (BAUD_E 17, BAUD_M 0)
-        */
-       U0BAUD = 0;
-       U0GCR = (UxGCR_CPOL_NEGATIVE |
-                UxGCR_CPHA_FIRST_EDGE |
-                UxGCR_ORDER_MSB |
-                (17 << UxGCR_BAUD_E_SHIFT));
-       ao_cmd_register(&ao_ee_cmds[0]);
-}
diff --git a/ao_ee_fake.c b/ao_ee_fake.c
deleted file mode 100644 (file)
index b0c1d61..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-/*
- * For hardware without eeprom, the config code still
- * wants to call these functions
- */
-uint8_t
-ao_ee_write_config(uint8_t *buf, uint16_t len) __reentrant
-{
-       (void) buf;
-       (void) len;
-       return 1;
-}
-
-uint8_t
-ao_ee_read_config(uint8_t *buf, uint16_t len) __reentrant
-{
-       memset(buf, '\0', len);
-       return 1;
-}
diff --git a/ao_flight.c b/ao_flight.c
deleted file mode 100644 (file)
index c0f5683..0000000
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright Â© 2009 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_FLIGHT_TEST
-#include "ao.h"
-#endif
-
-/* Main flight thread. */
-
-__pdata enum ao_flight_state   ao_flight_state;        /* current flight state */
-__pdata uint16_t               ao_flight_tick;         /* time of last data */
-__pdata uint16_t               ao_flight_prev_tick;    /* time of previous data */
-__pdata int16_t                        ao_flight_accel;        /* filtered acceleration */
-__pdata int16_t                        ao_flight_pres;         /* filtered pressure */
-__pdata int16_t                        ao_ground_pres;         /* startup pressure */
-__pdata int16_t                        ao_ground_accel;        /* startup acceleration */
-__pdata int16_t                        ao_min_pres;            /* minimum recorded pressure */
-__pdata uint16_t               ao_launch_tick;         /* time of launch detect */
-__pdata int16_t                        ao_main_pres;           /* pressure to eject main */
-
-/*
- * track min/max data over a long interval to detect
- * resting
- */
-__pdata uint16_t               ao_interval_end;
-__pdata int16_t                        ao_interval_cur_min_accel;
-__pdata int16_t                        ao_interval_cur_max_accel;
-__pdata int16_t                        ao_interval_cur_min_pres;
-__pdata int16_t                        ao_interval_cur_max_pres;
-__pdata int16_t                        ao_interval_min_accel;
-__pdata int16_t                        ao_interval_max_accel;
-__pdata int16_t                        ao_interval_min_pres;
-__pdata int16_t                        ao_interval_max_pres;
-
-__data uint8_t ao_flight_adc;
-__pdata int16_t ao_raw_accel, ao_raw_accel_prev, ao_raw_pres;
-
-/* Accelerometer calibration
- *
- * We're sampling the accelerometer through a resistor divider which
- * consists of 5k and 10k resistors. This multiplies the values by 2/3.
- * That goes into the cc1111 A/D converter, which is running at 11 bits
- * of precision with the bits in the MSB of the 16 bit value. Only positive
- * values are used, so values should range from 0-32752 for 0-3.3V. The
- * specs say we should see 40mV/g (uncalibrated), multiply by 2/3 for what
- * the A/D converter sees (26.67 mV/g). We should see 32752/3300 counts/mV,
- * for a final computation of:
- *
- * 26.67 mV/g * 32767/3300 counts/mV = 264.8 counts/g
- *
- * Zero g was measured at 16000 (we would expect 16384).
- * Note that this value is only require to tell if the
- * rocket is standing upright. Once that is determined,
- * the value of the accelerometer is averaged for 100 samples
- * to find the resting accelerometer value, which is used
- * for all further flight computations
- */
-
-#define GRAVITY 9.80665
-/* convert m/s to velocity count */
-#define VEL_MPS_TO_COUNT(mps) ((int32_t) (((mps) / GRAVITY) * ACCEL_G * 100))
-
-#define ACCEL_G                265
-#define ACCEL_ZERO_G   16000
-#define ACCEL_NOSE_UP  (ACCEL_G * 2 /3)
-#define ACCEL_BOOST    ACCEL_G * 2
-#define ACCEL_INT_LAND (ACCEL_G / 10)
-#define ACCEL_VEL_LAND VEL_MPS_TO_COUNT(10)
-#define ACCEL_VEL_MACH VEL_MPS_TO_COUNT(200)
-#define ACCEL_VEL_APOGEE       VEL_MPS_TO_COUNT(2)
-#define ACCEL_VEL_MAIN VEL_MPS_TO_COUNT(100)
-#define ACCEL_VEL_BOOST        VEL_MPS_TO_COUNT(5)
-
-/*
- * Barometer calibration
- *
- * We directly sample the barometer. The specs say:
- *
- * Pressure range: 15-115 kPa
- * Voltage at 115kPa: 2.82
- * Output scale: 27mV/kPa
- *
- * If we want to detect launch with the barometer, we need
- * a large enough bump to not be fooled by noise. At typical
- * launch elevations (0-2000m), a 200Pa pressure change cooresponds
- * to about a 20m elevation change. This is 5.4mV, or about 3LSB.
- * As all of our calculations are done in 16 bits, we'll actually see a change
- * of 16 times this though
- *
- * 27 mV/kPa * 32767 / 3300 counts/mV = 268.1 counts/kPa
- */
-
-#define BARO_kPa       268
-#define BARO_LAUNCH    (BARO_kPa / 5)  /* .2kPa, or about 20m */
-#define BARO_APOGEE    (BARO_kPa / 10) /* .1kPa, or about 10m */
-#define BARO_COAST     (BARO_kPa * 5)  /* 5kpa, or about 500m */
-#define BARO_MAIN      (BARO_kPa)      /* 1kPa, or about 100m */
-#define BARO_INT_LAND  (BARO_kPa / 20) /* .05kPa, or about 5m */
-#define BARO_LAND      (BARO_kPa * 10) /* 10kPa or about 1000m */
-
-/* We also have a clock, which can be used to sanity check things in
- * case of other failures
- */
-
-#define BOOST_TICKS_MAX        AO_SEC_TO_TICKS(15)
-
-/* This value is scaled in a weird way. It's a running total of accelerometer
- * readings minus the ground accelerometer reading. That means it measures
- * velocity, and quite accurately too. As it gets updated 100 times a second,
- * it's scaled by 100
- */
-__pdata int32_t        ao_flight_vel;
-__pdata int32_t ao_min_vel;
-__pdata int32_t        ao_old_vel;
-__pdata int16_t ao_old_vel_tick;
-__xdata int32_t ao_raw_accel_sum, ao_raw_pres_sum;
-
-/* Landing is detected by getting constant readings from both pressure and accelerometer
- * for a fairly long time (AO_INTERVAL_TICKS)
- */
-#define AO_INTERVAL_TICKS      AO_SEC_TO_TICKS(20)
-
-#define abs(a) ((a) < 0 ? -(a) : (a))
-
-void
-ao_flight(void)
-{
-       __pdata static uint16_t nsamples = 0;
-
-       ao_flight_adc = ao_adc_head;
-       ao_raw_accel_prev = 0;
-       ao_raw_accel = 0;
-       ao_raw_pres = 0;
-       ao_flight_tick = 0;
-       for (;;) {
-               ao_sleep(&ao_adc_ring);
-               while (ao_flight_adc != ao_adc_head) {
-                       __pdata uint8_t ticks;
-                       __pdata int16_t ao_vel_change;
-                       ao_flight_prev_tick = ao_flight_tick;
-
-                       /* Capture a sample */
-                       ao_raw_accel = ao_adc_ring[ao_flight_adc].accel;
-                       ao_raw_pres = ao_adc_ring[ao_flight_adc].pres;
-                       ao_flight_tick = ao_adc_ring[ao_flight_adc].tick;
-
-                       ao_flight_accel -= ao_flight_accel >> 4;
-                       ao_flight_accel += ao_raw_accel >> 4;
-                       ao_flight_pres -= ao_flight_pres >> 4;
-                       ao_flight_pres += ao_raw_pres >> 4;
-                       /* Update velocity
-                        *
-                        * The accelerometer is mounted so that
-                        * acceleration yields negative values
-                        * while deceleration yields positive values,
-                        * so subtract instead of add.
-                        */
-                       ticks = ao_flight_tick - ao_flight_prev_tick;
-                       ao_vel_change = (((ao_raw_accel >> 1) + (ao_raw_accel_prev >> 1)) - ao_ground_accel);
-                       ao_raw_accel_prev = ao_raw_accel;
-
-                       /* one is a common interval */
-                       if (ticks == 1)
-                               ao_flight_vel -= (int32_t) ao_vel_change;
-                       else
-                               ao_flight_vel -= (int32_t) ao_vel_change * (int32_t) ticks;
-
-                       ao_flight_adc = ao_adc_ring_next(ao_flight_adc);
-               }
-
-               if (ao_flight_pres < ao_min_pres)
-                       ao_min_pres = ao_flight_pres;
-               if (ao_flight_vel >= 0) {
-                       if (ao_flight_vel < ao_min_vel)
-                           ao_min_vel = ao_flight_vel;
-               } else {
-                       if (-ao_flight_vel < ao_min_vel)
-                           ao_min_vel = -ao_flight_vel;
-               }
-
-               switch (ao_flight_state) {
-               case ao_flight_startup:
-
-                       /* startup state:
-                        *
-                        * Collect 1000 samples of acceleration and pressure
-                        * data and average them to find the resting values
-                        */
-                       if (nsamples < 1000) {
-                               ao_raw_accel_sum += ao_raw_accel;
-                               ao_raw_pres_sum += ao_raw_pres;
-                               ++nsamples;
-                               continue;
-                       }
-                       ao_ground_accel = (ao_raw_accel_sum / nsamples);
-                       ao_ground_pres = (ao_raw_pres_sum / nsamples);
-                       ao_min_pres = ao_ground_pres;
-                       ao_config_get();
-                       ao_main_pres = ao_altitude_to_pres(ao_pres_to_altitude(ao_ground_pres) + ao_config.main_deploy);
-                       ao_flight_vel = 0;
-                       ao_min_vel = 0;
-                       ao_old_vel = ao_flight_vel;
-                       ao_old_vel_tick = ao_flight_tick;
-
-                       /* Go to launchpad state if the nose is pointing up */
-                       ao_config_get();
-                       if (ao_flight_accel < ao_config.accel_zero_g - ACCEL_NOSE_UP) {
-
-                               /* Disable the USB controller in flight mode
-                                * to save power
-                                */
-                               ao_usb_disable();
-
-                               /* Turn on telemetry system
-                                */
-                               ao_telemetry_set_interval(AO_TELEMETRY_INTERVAL_PAD);
-
-                               ao_flight_state = ao_flight_launchpad;
-                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
-                       } else {
-                               ao_flight_state = ao_flight_idle;
-
-                               /* Turn on the Green LED in idle mode
-                                */
-                               ao_led_on(AO_LED_GREEN);
-                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
-                       }
-                       /* signal successful initialization by turning off the LED */
-                       ao_led_off(AO_LED_RED);
-                       break;
-               case ao_flight_launchpad:
-
-                       /* Trim velocity
-                        *
-                        * Once a second, remove any velocity from
-                        * a second ago
-                        */
-                       if ((int16_t) (ao_flight_tick - ao_old_vel_tick) >= AO_SEC_TO_TICKS(1)) {
-                               ao_old_vel_tick = ao_flight_tick;
-                               ao_flight_vel -= ao_old_vel;
-                               ao_old_vel = ao_flight_vel;
-                       }
-                       /* pad to boost:
-                        *
-                        * accelerometer: > 2g AND velocity > 5m/s
-                        *             OR
-                        * barometer: > 20m vertical motion
-                        *
-                        * The accelerometer should always detect motion before
-                        * the barometer, but we use both to make sure this
-                        * transition is detected
-                        */
-                       if ((ao_flight_accel < ao_ground_accel - ACCEL_BOOST &&
-                            ao_flight_vel > ACCEL_VEL_BOOST) ||
-                           ao_flight_pres < ao_ground_pres - BARO_LAUNCH)
-                       {
-                               ao_flight_state = ao_flight_boost;
-                               ao_launch_tick = ao_flight_tick;
-
-                               /* start logging data */
-                               ao_log_start();
-
-                               /* Increase telemetry rate */
-                               ao_telemetry_set_interval(AO_TELEMETRY_INTERVAL_FLIGHT);
-
-                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
-                               break;
-                       }
-                       break;
-               case ao_flight_boost:
-
-                       /* boost to coast:
-                        *
-                        * accelerometer: start to fall at > 1/4 G
-                        *              OR
-                        * time: boost for more than 15 seconds
-                        *
-                        * Detects motor burn out by the switch from acceleration to
-                        * deceleration, or by waiting until the maximum burn duration
-                        * (15 seconds) has past.
-                        */
-                       if (ao_flight_accel > ao_ground_accel + (ACCEL_G >> 2) ||
-                           (int16_t) (ao_flight_tick - ao_launch_tick) > BOOST_TICKS_MAX)
-                       {
-                               ao_flight_state = ao_flight_coast;
-                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
-                               break;
-                       }
-                       break;
-               case ao_flight_coast:
-
-                       /* coast to apogee detect:
-                        *
-                        * accelerometer: integrated velocity < 200 m/s
-                        *               OR
-                        * barometer: fall at least 500m from max altitude
-                        *
-                        * This extra state is required to avoid mis-detecting
-                        * apogee due to mach transitions.
-                        *
-                        * XXX this is essentially a single-detector test
-                        * as the 500m altitude change would likely result
-                        * in a loss of the rocket. More data on precisely
-                        * how big a pressure change the mach transition
-                        * generates would be useful here.
-                        */
-                       if (ao_flight_vel < ACCEL_VEL_MACH ||
-                           ao_flight_pres > ao_min_pres + BARO_COAST)
-                       {
-                               /* set min velocity to current velocity for
-                                * apogee detect
-                                */
-                               ao_min_vel = abs(ao_flight_vel);
-                               ao_flight_state = ao_flight_apogee;
-                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
-                       }
-                       break;
-               case ao_flight_apogee:
-
-                       /* apogee detect to drogue deploy:
-                        *
-                        * accelerometer: abs(velocity) > min_velocity + 2m/s
-                        *               OR
-                        * barometer: fall at least 10m
-                        *
-                        * If the barometer saturates because the flight
-                        * goes over its measuring range (about 53k'),
-                        * requiring a 10m fall will avoid prematurely
-                        * detecting apogee; the accelerometer will take
-                        * over in that case and the integrated velocity
-                        * measurement should suffice to find apogee
-                        */
-                       if (/* abs(ao_flight_vel) > ao_min_vel + ACCEL_VEL_APOGEE || */
-                           ao_flight_pres > ao_min_pres + BARO_APOGEE)
-                       {
-                               /* ignite the drogue charge */
-                               ao_ignite(ao_igniter_drogue);
-
-                               /* slow down the telemetry system */
-                               ao_telemetry_set_interval(AO_TELEMETRY_INTERVAL_RECOVER);
-
-                               /* slow down the ADC sample rate */
-                               ao_timer_set_adc_interval(10);
-
-                               /*
-                                * Start recording min/max accel and pres for a while
-                                * to figure out when the rocket has landed
-                                */
-                               /* Set the 'last' limits to max range to prevent
-                                * early resting detection
-                                */
-                               ao_interval_min_accel = 0;
-                               ao_interval_max_accel = 0x7fff;
-                               ao_interval_min_pres = 0;
-                               ao_interval_max_pres = 0x7fff;
-
-                               /* initialize interval values */
-                               ao_interval_end = ao_flight_tick + AO_INTERVAL_TICKS;
-
-                               ao_interval_cur_min_pres = ao_interval_cur_max_pres = ao_flight_pres;
-                               ao_interval_cur_min_accel = ao_interval_cur_max_accel = ao_flight_accel;
-
-                               /* and enter drogue state */
-                               ao_flight_state = ao_flight_drogue;
-                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
-                       }
-
-                       break;
-               case ao_flight_drogue:
-
-                       /* drogue to main deploy:
-                        *
-                        * barometer: reach main deploy altitude
-                        *
-                        * Would like to use the accelerometer for this test, but
-                        * the orientation of the flight computer is unknown after
-                        * drogue deploy, so we ignore it. Could also detect
-                        * high descent rate using the pressure sensor to
-                        * recognize drogue deploy failure and eject the main
-                        * at that point. Perhaps also use the drogue sense lines
-                        * to notice continutity?
-                        */
-                       if (ao_flight_pres >= ao_main_pres)
-                       {
-                               ao_ignite(ao_igniter_main);
-                               ao_flight_state = ao_flight_main;
-                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
-                       }
-
-                       /* fall through... */
-               case ao_flight_main:
-
-                       /* drogue/main to land:
-                        *
-                        * accelerometer: value stable
-                        *                           AND
-                        * barometer: altitude stable and within 1000m of the launch altitude
-                        */
-
-                       if (ao_flight_pres < ao_interval_cur_min_pres)
-                               ao_interval_cur_min_pres = ao_flight_pres;
-                       if (ao_flight_pres > ao_interval_cur_max_pres)
-                               ao_interval_cur_max_pres = ao_flight_pres;
-                       if (ao_flight_accel < ao_interval_cur_min_accel)
-                               ao_interval_cur_min_accel = ao_flight_accel;
-                       if (ao_flight_accel > ao_interval_cur_max_accel)
-                               ao_interval_cur_max_accel = ao_flight_accel;
-
-                       if ((int16_t) (ao_flight_tick - ao_interval_end) >= 0) {
-                               ao_interval_max_pres = ao_interval_cur_max_pres;
-                               ao_interval_min_pres = ao_interval_cur_min_pres;
-                               ao_interval_max_accel = ao_interval_cur_max_accel;
-                               ao_interval_min_accel = ao_interval_cur_min_accel;
-                               ao_interval_end = ao_flight_tick + AO_INTERVAL_TICKS;
-                               ao_interval_cur_min_pres = ao_interval_cur_max_pres = ao_flight_pres;
-                               ao_interval_cur_min_accel = ao_interval_cur_max_accel = ao_flight_accel;
-                       }
-
-                       if ((uint16_t) (ao_interval_max_accel - ao_interval_min_accel) < (uint16_t) ACCEL_INT_LAND &&
-                           ao_flight_pres > ao_ground_pres - BARO_LAND &&
-                           (uint16_t) (ao_interval_max_pres - ao_interval_min_pres) < (uint16_t) BARO_INT_LAND)
-                       {
-                               ao_flight_state = ao_flight_landed;
-
-                               /* turn off the ADC capture */
-                               ao_timer_set_adc_interval(0);
-
-                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
-                       }
-                       break;
-               case ao_flight_landed:
-                       break;
-               }
-       }
-}
-
-#define AO_ACCEL_COUNT_TO_MSS(count)   ((count) / 27)
-#define AO_VEL_COUNT_TO_MS(count)      ((int16_t) ((count) / 2700))
-
-static void
-ao_flight_status(void)
-{
-       printf("STATE: %7s accel: %d speed: %d altitude: %d main: %d\n",
-              ao_state_names[ao_flight_state],
-              AO_ACCEL_COUNT_TO_MSS(ACCEL_ZERO_G - ao_flight_accel),
-              AO_VEL_COUNT_TO_MS(ao_flight_vel),
-              ao_pres_to_altitude(ao_flight_pres),
-              ao_pres_to_altitude(ao_main_pres));
-}
-
-static __xdata struct ao_task  flight_task;
-
-__code struct ao_cmds ao_flight_cmds[] = {
-       { 'f', ao_flight_status,        "f                                  Display current flight state" },
-       { 0, ao_flight_status, NULL }
-};
-
-void
-ao_flight_init(void)
-{
-       ao_flight_state = ao_flight_startup;
-       ao_interval_min_accel = 0;
-       ao_interval_max_accel = 0x7fff;
-       ao_interval_min_pres = 0;
-       ao_interval_max_pres = 0x7fff;
-       ao_interval_end = AO_INTERVAL_TICKS;
-
-       ao_add_task(&flight_task, ao_flight, "flight");
-       ao_cmd_register(&ao_flight_cmds[0]);
-}
diff --git a/ao_flight_test.c b/ao_flight_test.c
deleted file mode 100644 (file)
index f4731aa..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#define _GNU_SOURCE
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define AO_ADC_RING    64
-#define ao_adc_ring_next(n)    (((n) + 1) & (AO_ADC_RING - 1))
-#define ao_adc_ring_prev(n)    (((n) - 1) & (AO_ADC_RING - 1))
-
-/*
- * One set of samples read from the A/D converter
- */
-struct ao_adc {
-       uint16_t        tick;           /* tick when the sample was read */
-       int16_t         accel;          /* accelerometer */
-       int16_t         pres;           /* pressure sensor */
-       int16_t         temp;           /* temperature sensor */
-       int16_t         v_batt;         /* battery voltage */
-       int16_t         sense_d;        /* drogue continuity sense */
-       int16_t         sense_m;        /* main continuity sense */
-};
-
-#define __pdata
-#define __data
-#define __xdata
-#define __code
-#define __reentrant
-
-enum ao_flight_state {
-       ao_flight_startup = 0,
-       ao_flight_idle = 1,
-       ao_flight_launchpad = 2,
-       ao_flight_boost = 3,
-       ao_flight_coast = 4,
-       ao_flight_apogee = 5,
-       ao_flight_drogue = 6,
-       ao_flight_main = 7,
-       ao_flight_landed = 8,
-       ao_flight_invalid = 9
-};
-
-struct ao_adc ao_adc_ring[AO_ADC_RING];
-uint8_t ao_adc_head;
-
-#define ao_led_on(l)
-#define ao_led_off(l)
-#define ao_timer_set_adc_interval(i)
-#define ao_wakeup(wchan) ao_dump_state()
-#define ao_cmd_register(c)
-#define ao_usb_disable()
-#define ao_telemetry_set_interval(x)
-
-enum ao_igniter {
-       ao_igniter_drogue = 0,
-       ao_igniter_main = 1
-};
-
-void
-ao_ignite(enum ao_igniter igniter)
-{
-       printf ("ignite %s\n", igniter == ao_igniter_drogue ? "drogue" : "main");
-}
-
-struct ao_task {
-       int dummy;
-};
-
-#define ao_add_task(t,f,n)
-
-#define ao_log_start()
-#define ao_log_stop()
-
-#define AO_MS_TO_TICKS(ms)     ((ms) / 10)
-#define AO_SEC_TO_TICKS(s)     ((s) * 100)
-
-#define AO_FLIGHT_TEST
-
-struct ao_adc ao_adc_static;
-
-FILE *emulator_in;
-
-void
-ao_dump_state(void);
-
-void
-ao_sleep(void *wchan);
-
-const char const * const ao_state_names[] = {
-       "startup", "idle", "pad", "boost", "coast",
-       "apogee", "drogue", "main", "landed", "invalid"
-};
-
-struct ao_cmds {
-       char            cmd;
-       void            (*func)(void);
-       const char      *help;
-};
-
-
-static int16_t altitude_table[2048] = {
-#include "altitude.h"
-};
-
-int16_t
-ao_pres_to_altitude(int16_t pres) __reentrant
-{
-       pres = pres >> 4;
-       if (pres < 0) pres = 0;
-       if (pres > 2047) pres = 2047;
-       return altitude_table[pres];
-}
-
-int16_t
-ao_altitude_to_pres(int16_t alt) __reentrant
-{
-       int16_t pres;
-
-       for (pres = 0; pres < 2047; pres++)
-               if (altitude_table[pres] <= alt)
-                       break;
-       return pres << 4;
-}
-
-struct ao_config {
-       uint16_t        main_deploy;
-       int16_t         accel_zero_g;
-};
-
-#define ao_config_get()
-
-struct ao_config ao_config = { 250, 16000 };
-
-#include "ao_flight.c"
-
-void
-ao_insert(void)
-{
-       ao_adc_ring[ao_adc_head] = ao_adc_static;
-       ao_adc_head = ao_adc_ring_next(ao_adc_head);
-       if (ao_flight_state != ao_flight_startup) {
-               printf("time %g accel %d pres %d\n",
-                      (double) ao_adc_static.tick / 100,
-                      ao_adc_static.accel,
-                      ao_adc_static.pres);
-       }
-}
-
-static int     ao_records_read = 0;
-static int     ao_eof_read = 0;
-static int     ao_flight_ground_accel;
-static int     ao_flight_started = 0;
-
-void
-ao_sleep(void *wchan)
-{
-       ao_dump_state();
-       if (wchan == &ao_adc_ring) {
-               char            type;
-               uint16_t        tick;
-               uint16_t        a, b;
-               int             ret;
-               char            line[1024];
-               char            *saveptr;
-               char            *l;
-               char            *words[64];
-               int             nword;
-
-               for (;;) {
-                       if (ao_records_read > 2 && ao_flight_state == ao_flight_startup)
-                       {
-                               ao_adc_static.accel = ao_flight_ground_accel;
-                               ao_insert();
-                               return;
-                       }
-
-                       if (!fgets(line, sizeof (line), emulator_in)) {
-                               if (++ao_eof_read >= 1000) {
-                                       printf ("no more data, exiting simulation\n");
-                                       exit(0);
-                               }
-                               ao_adc_static.tick += 10;
-                               ao_insert();
-                               return;
-                       }
-                       l = line;
-                       for (nword = 0; nword < 64; nword++) {
-                               words[nword] = strtok_r(l, " \t\n", &saveptr);
-                               l = NULL;
-                               if (words[nword] == NULL)
-                                       break;
-                       }
-                       if (nword == 4) {
-                               type = words[0][0];
-                               tick = strtoul(words[1], NULL, 16);
-                               a = strtoul(words[2], NULL, 16);
-                               b = strtoul(words[2], NULL, 16);
-                       } else if (nword >= 36 && strcmp(words[0], "CALL") == 0) {
-                               tick = atoi(words[10]);
-                               if (!ao_flight_started) {
-                                       type = 'F';
-                                       a = atoi(words[26]);
-                                       ao_flight_started = 1;
-                               } else {
-                                       type = 'A';
-                                       a = atoi(words[12]);
-                                       b = atoi(words[14]);
-                               }
-                       }
-                       if (type != 'F' && !ao_flight_started)
-                               continue;
-
-                       switch (type) {
-                       case 'F':
-                               ao_flight_ground_accel = a;
-                               ao_flight_started = 1;
-                               break;
-                       case 'S':
-                               break;
-                       case 'A':
-                               ao_adc_static.tick = tick;
-                               ao_adc_static.accel = a;
-                               ao_adc_static.pres = b;
-                               ao_records_read++;
-                               ao_insert();
-                               return;
-                       case 'T':
-                               ao_adc_static.tick = tick;
-                               ao_adc_static.temp = a;
-                               ao_adc_static.v_batt = b;
-                               break;
-                       case 'D':
-                       case 'G':
-                       case 'N':
-                       case 'W':
-                       case 'H':
-                               break;
-                       }
-               }
-
-       }
-}
-#define COUNTS_PER_G 264.8
-
-void
-ao_dump_state(void)
-{
-       if (ao_flight_state == ao_flight_startup)
-               return;
-       printf ("\t\t\t\t\t%s accel %g vel %g alt %d main %d\n",
-               ao_state_names[ao_flight_state],
-               (ao_ground_accel - ao_flight_accel) / COUNTS_PER_G * GRAVITY,
-               (double) ao_flight_vel / 100 / COUNTS_PER_G * GRAVITY,
-               ao_pres_to_altitude(ao_flight_pres) - ao_pres_to_altitude(ao_ground_pres),
-               ao_pres_to_altitude(ao_main_pres) - ao_pres_to_altitude(ao_ground_pres));
-       if (ao_flight_state == ao_flight_landed)
-               exit(0);
-}
-
-int
-main (int argc, char **argv)
-{
-       emulator_in = fopen (argv[1], "r");
-       if (!emulator_in) {
-               perror(argv[1]);
-               exit(1);
-       }
-       ao_flight_init();
-       ao_flight();
-}
diff --git a/ao_gps.c b/ao_gps.c
deleted file mode 100644 (file)
index e5a5a88..0000000
--- a/ao_gps.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-#define AO_GPS_LEADER          6
-
-static const char ao_gps_header[] = "GPGGA,";
-__xdata uint8_t ao_gps_mutex;
-static __xdata char ao_gps_char;
-static __xdata uint8_t ao_gps_cksum;
-static __xdata uint8_t ao_gps_error;
-
-__xdata struct ao_gps_data     ao_gps_data;
-static __xdata struct ao_gps_data      ao_gps_next;
-
-const char ao_gps_config[] =
-       "$PSRF103,00,00,01,01*25\r\n"   /* GGA 1 per sec */
-       "$PSRF103,01,00,00,01*25\r\n"   /* GLL disable */
-       "$PSRF103,02,00,00,01*26\r\n"   /* GSA disable */
-       "$PSRF103,03,00,00,01*27\r\n"   /* GSV disable */
-       "$PSRF103,04,00,00,01*20\r\n"   /* RMC disable */
-       "$PSRF103,05,00,00,01*21\r\n";  /* VTG disable */
-
-static void
-ao_gps_lexchar(void)
-{
-       if (ao_gps_error)
-               ao_gps_char = '\n';
-       else 
-               ao_gps_char = ao_serial_getchar();
-       ao_gps_cksum ^= ao_gps_char;
-}
-
-void
-ao_gps_skip(void)
-{
-       while (ao_gps_char >= '0')
-               ao_gps_lexchar();
-}
-
-void
-ao_gps_skip_field(void)
-{
-       while (ao_gps_char != ',' && ao_gps_char != '*' && ao_gps_char != '\n')
-               ao_gps_lexchar();
-}
-
-void
-ao_gps_skip_sep(void)
-{
-       while (ao_gps_char == ',' || ao_gps_char == '.' || ao_gps_char == '*')
-               ao_gps_lexchar();
-}
-
-__xdata static uint8_t ao_gps_num_width;
-
-static int16_t
-ao_gps_decimal(uint8_t max_width)
-{
-       int16_t v;
-       __xdata uint8_t neg = 0;
-       
-       ao_gps_skip_sep();
-       if (ao_gps_char == '-') {
-               neg = 1;
-               ao_gps_lexchar();
-       }
-       v = 0;
-       ao_gps_num_width = 0;
-       while (ao_gps_num_width < max_width) {
-               if (ao_gps_char < '0' || '9' < ao_gps_char)
-                       break;
-               v = v * (int16_t) 10 + ao_gps_char - '0';
-               ao_gps_num_width++;
-               ao_gps_lexchar();
-       }
-       if (neg)
-               v = -v;
-       return v;
-}
-
-static uint8_t
-ao_gps_hex(uint8_t max_width)
-{
-       uint8_t v, d;
-
-       ao_gps_skip_sep();
-       v = 0;
-       ao_gps_num_width = 0;
-       while (ao_gps_num_width < max_width) {
-               if ('0' <= ao_gps_char && ao_gps_char <= '9')
-                       d = ao_gps_char - '0';
-               else if ('A' <= ao_gps_char && ao_gps_char <= 'F')
-                       d = ao_gps_char - 'A' + 10;
-               else if ('a' <= ao_gps_char && ao_gps_char <= 'f')
-                       d = ao_gps_char - 'a' + 10;
-               else
-                       break;
-               v = (v << 4) | d;
-               ao_gps_num_width++;
-               ao_gps_lexchar();
-       }
-       return v;
-}
-
-static void
-ao_gps_parse_pos(__xdata struct ao_gps_pos * pos, uint8_t deg_width) __reentrant
-{
-       pos->degrees = ao_gps_decimal(deg_width);
-       pos->minutes = ao_gps_decimal(2);
-       if (ao_gps_char == '.') {
-               pos->minutes_fraction = ao_gps_decimal(4);
-               while (ao_gps_num_width < 4) {
-                       pos->minutes_fraction *= 10;
-                       ao_gps_num_width++;
-               }
-       } else {
-               pos->minutes_fraction = 0;
-               if (ao_gps_char != ',')
-                       ao_gps_error = 1;
-       }
-}
-
-static void
-ao_gps_parse_flag(char yes_c, uint8_t yes, char no_c, uint8_t no) __reentrant
-{
-       ao_gps_skip_sep();
-       if (ao_gps_char == yes_c)
-               ao_gps_next.flags |= yes;
-       else if (ao_gps_char == no_c)
-               ao_gps_next.flags |= no;
-       else
-               ao_gps_error = 1;
-       ao_gps_lexchar();
-}
-
-
-void
-ao_gps(void) __reentrant
-{
-       char    c;
-       uint8_t i;
-
-       for (i = 0; (c = ao_gps_config[i]); i++)
-               ao_serial_putchar(c);
-       for (;;) {
-               /* Locate the begining of the next record */
-               for (;;) {
-                       c = ao_serial_getchar();
-                       if (c == '$')
-                               break;
-               }
-
-               ao_gps_cksum = 0;
-               ao_gps_error = 0;
-               
-               /* Skip anything other than GGA */
-               for (i = 0; i < AO_GPS_LEADER; i++) {
-                       ao_gps_lexchar();
-                       if (ao_gps_char != ao_gps_header[i])
-                               break;
-               }
-               if (i != AO_GPS_LEADER)
-                       continue;
-
-               /* Now read the data into the gps data record
-                *
-                * $GPGGA,025149.000,4528.1723,N,12244.2480,W,1,05,2.0,103.5,M,-19.5,M,,0000*66
-                *  
-                * Essential fix data
-                * 
-                *         025149.000   time (02:51:49.000 GMT)
-                *         4528.1723,N  Latitude 45°28.1723' N
-                *         12244.2480,W Longitude 122°44.2480' W
-                *         1            Fix quality:
-                *                                 0 = invalid
-                *                                 1 = GPS fix (SPS)
-                *                                 2 = DGPS fix
-                *                                 3 = PPS fix
-                *                                 4 = Real Time Kinematic
-                *                                 5 = Float RTK
-                *                                 6 = estimated (dead reckoning)
-                *                                 7 = Manual input mode
-                *                                 8 = Simulation mode
-                *         05           Number of satellites (5)
-                *         2.0          Horizontal dilution
-                *         103.5,M              Altitude, 103.5M above msl
-                *         -19.5,M              Height of geoid above WGS84 ellipsoid
-                *         ?            time in seconds since last DGPS update
-                *         0000         DGPS station ID
-                *         *66          checksum
-                */
-
-               ao_gps_next.flags = 0;
-               ao_gps_next.hour = ao_gps_decimal(2);
-               ao_gps_next.minute = ao_gps_decimal(2);
-               ao_gps_next.second = ao_gps_decimal(2);
-               ao_gps_skip_field();    /* skip seconds fraction */
-               
-               ao_gps_parse_pos(&ao_gps_next.latitude, 2);
-               ao_gps_parse_flag('N', AO_GPS_LATITUDE_NORTH, 'S', AO_GPS_LATITUDE_SOUTH);
-               ao_gps_parse_pos(&ao_gps_next.longitude, 3);
-               ao_gps_parse_flag('W', AO_GPS_LONGITUDE_WEST, 'E', AO_GPS_LONGITUDE_EAST);
-               
-               i = ao_gps_decimal(0xff);
-               if (i == 1)
-                       ao_gps_next.flags |= AO_GPS_VALID;
-               
-               i = ao_gps_decimal(0xff) << AO_GPS_NUM_SAT_SHIFT;
-               if (i > AO_GPS_NUM_SAT_MASK)
-                       i = AO_GPS_NUM_SAT_MASK;
-               ao_gps_next.flags |= i;
-               
-               ao_gps_lexchar();
-               ao_gps_skip_field();    /* Horizontal dilution */
-               
-               ao_gps_next.altitude = ao_gps_decimal(0xff);
-               ao_gps_skip_field();    /* skip any fractional portion */
-               
-               /* Skip remaining fields */
-               while (ao_gps_char != '*' && ao_gps_char != '\n' && ao_gps_char != '\r') {
-                       ao_gps_lexchar();
-                       ao_gps_skip_field();
-               }
-               if (ao_gps_char == '*') {
-                       uint8_t cksum = ao_gps_cksum ^ '*';
-                       if (cksum != ao_gps_hex(2))
-                               ao_gps_error = 1;
-               } else 
-                       ao_gps_error = 1;
-               if (!ao_gps_error) {
-                       ao_mutex_get(&ao_gps_mutex);
-                       memcpy(&ao_gps_data, &ao_gps_next, sizeof (struct ao_gps_data));
-                       ao_mutex_put(&ao_gps_mutex);
-                       ao_wakeup(&ao_gps_data);
-               }
-       }
-}
-
-__xdata struct ao_task ao_gps_task;
-
-static void
-gps_dump(void) __reentrant
-{
-       ao_mutex_get(&ao_gps_mutex);
-       ao_gps_print(&ao_gps_data);
-       ao_mutex_put(&ao_gps_mutex);
-}
-
-__code struct ao_cmds ao_gps_cmds[] = {
-       { 'g', gps_dump,        "g                                  Display current GPS values" },
-       { 0, gps_dump, NULL },
-};
-
-void
-ao_gps_init(void)
-{
-       ao_add_task(&ao_gps_task, ao_gps, "gps");
-       ao_cmd_register(&ao_gps_cmds[0]);
-}
diff --git a/ao_gps_print.c b/ao_gps_print.c
deleted file mode 100644 (file)
index 8cadd31..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-void
-ao_gps_print(__xdata struct ao_gps_data *gps_data) __reentrant
-{
-       printf("GPS %2d sat",
-              (gps_data->flags & AO_GPS_NUM_SAT_MASK) >> AO_GPS_NUM_SAT_SHIFT);;
-       if (gps_data->flags & AO_GPS_VALID) {
-               printf(" %2d:%02d:%02d %2d°%2d.%04d'%c %2d°%2d.%04d'%c %5dm\n",
-                      gps_data->hour,
-                      gps_data->minute,
-                      gps_data->second,
-                      gps_data->latitude.degrees,
-                      gps_data->latitude.minutes,
-                      gps_data->latitude.minutes_fraction,
-                      (gps_data->flags & AO_GPS_LATITUDE_MASK) == AO_GPS_LATITUDE_NORTH ?
-                      'N' : 'S',
-                      gps_data->longitude.degrees,
-                      gps_data->longitude.minutes,
-                      gps_data->longitude.minutes_fraction,
-                      (gps_data->flags & AO_GPS_LONGITUDE_MASK) == AO_GPS_LONGITUDE_WEST ?
-                      'W' : 'E',
-                      gps_data->altitude,
-                      (gps_data->flags & AO_GPS_NUM_SAT_MASK) >> AO_GPS_NUM_SAT_SHIFT);
-       } else {
-               printf(" unlocked\n");
-       }
-}
-
diff --git a/ao_gps_report.c b/ao_gps_report.c
deleted file mode 100644 (file)
index 1b5402a..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-void
-ao_gps_report(void)
-{
-       static __xdata struct ao_log_record     gps_log;
-       static __xdata struct ao_gps_data       gps_data;
-
-       for (;;) {
-               ao_sleep(&ao_gps_data);
-               ao_mutex_get(&ao_gps_mutex);
-               memcpy(&gps_data, &ao_gps_data, sizeof (struct ao_gps_data));
-               ao_mutex_put(&ao_gps_mutex);
-
-               if (!(gps_data.flags & AO_GPS_VALID))
-                       continue;
-
-               gps_log.tick = ao_time();
-               gps_log.type = AO_LOG_GPS_TIME;
-               gps_log.u.gps_time.hour = gps_data.hour;
-               gps_log.u.gps_time.minute = gps_data.minute;
-               gps_log.u.gps_time.second = gps_data.second;
-               gps_log.u.gps_time.flags = gps_data.flags;
-               ao_log_data(&gps_log);
-               gps_log.type = AO_LOG_GPS_LAT;
-               gps_log.u.gps_latitude.degrees = gps_data.latitude.degrees;
-               gps_log.u.gps_latitude.minutes = gps_data.latitude.minutes;
-               gps_log.u.gps_latitude.minutes_fraction = gps_data.latitude.minutes_fraction;
-               ao_log_data(&gps_log);
-               gps_log.type = AO_LOG_GPS_LON;
-               gps_log.u.gps_longitude.degrees = gps_data.longitude.degrees;
-               gps_log.u.gps_longitude.minutes = gps_data.longitude.minutes;
-               gps_log.u.gps_longitude.minutes_fraction = gps_data.longitude.minutes_fraction;
-               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;
-               ao_log_data(&gps_log);
-       }
-}
-
-__xdata struct ao_task ao_gps_report_task;
-
-void
-ao_gps_report_init(void)
-{
-       ao_add_task(&ao_gps_report_task, ao_gps_report, "gps_report");
-}
diff --git a/ao_ignite.c b/ao_ignite.c
deleted file mode 100644 (file)
index be29152..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-#define AO_IGNITER_DROGUE      P2_3
-#define AO_IGNITER_MAIN                P2_4
-#define AO_IGNITER_DIR         P2DIR
-#define AO_IGNITER_DROGUE_BIT  (1 << 3)
-#define AO_IGNITER_MAIN_BIT    (1 << 4)
-
-/* test these values with real igniters */
-#define AO_IGNITER_OPEN                1000
-#define AO_IGNITER_CLOSED      7000
-#define AO_IGNITER_FIRE_TIME   AO_MS_TO_TICKS(500)
-#define AO_IGNITER_CHARGE_TIME AO_MS_TO_TICKS(2000)
-
-struct ao_ignition {
-       uint8_t request;
-       uint8_t fired;
-       uint8_t firing;
-};
-
-__xdata struct ao_ignition ao_ignition[2];
-
-void
-ao_ignite(enum ao_igniter igniter) __critical
-{
-       ao_ignition[igniter].request = 1;
-       ao_wakeup(&ao_ignition[0]);
-}
-
-enum ao_igniter_status
-ao_igniter_status(enum ao_igniter igniter)
-{
-       __xdata struct ao_adc adc;
-       __xdata int16_t value;
-       __xdata uint8_t request, firing, fired;
-
-       __critical {
-               ao_adc_sleep();
-               ao_adc_get(&adc);
-               request = ao_ignition[igniter].request;
-               fired = ao_ignition[igniter].fired;
-               firing = ao_ignition[igniter].firing;
-       }
-       if (firing || (request && !fired))
-               return ao_igniter_active;
-
-       value = (AO_IGNITER_CLOSED>>1);
-       switch (igniter) {
-       case ao_igniter_drogue:
-               value = adc.sense_d;
-               break;
-       case ao_igniter_main:
-               value = adc.sense_m;
-               break;
-       }
-       if (value < AO_IGNITER_OPEN)
-               return ao_igniter_open;
-       else if (value > AO_IGNITER_CLOSED)
-               return ao_igniter_ready;
-       else
-               return ao_igniter_unknown;
-}
-
-void
-ao_igniter_fire(enum ao_igniter igniter) __critical
-{
-       ao_ignition[igniter].firing = 1;
-       switch (igniter) {
-       case ao_igniter_drogue:
-               AO_IGNITER_DROGUE = 1;
-               ao_delay(AO_IGNITER_FIRE_TIME);
-               AO_IGNITER_DROGUE = 0;
-               break;
-       case ao_igniter_main:
-               AO_IGNITER_MAIN = 1;
-               ao_delay(AO_IGNITER_FIRE_TIME);
-               AO_IGNITER_MAIN = 0;
-               break;
-       }
-       ao_ignition[igniter].firing = 0;
-}
-
-void
-ao_igniter(void)
-{
-       __xdata enum ao_ignter igniter;
-       __xdata enum ao_igniter_status status;
-
-       for (;;) {
-               ao_sleep(&ao_ignition);
-               for (igniter = ao_igniter_drogue; igniter <= ao_igniter_main; igniter++) {
-                       if (ao_ignition[igniter].request && !ao_ignition[igniter].fired) {
-                               ao_igniter_fire(igniter);
-                               ao_delay(AO_IGNITER_CHARGE_TIME);
-                               status = ao_igniter_status(igniter);
-                               if (status == ao_igniter_open)
-                                       ao_ignition[igniter].fired = 1;
-                       }
-               }
-       }
-}
-
-static uint8_t
-ao_match_word(__code char *word)
-{
-       while (*word) {
-               if (ao_cmd_lex_c != *word) {
-                       ao_cmd_status = ao_cmd_syntax_error;
-                       return 0;
-               }
-               word++;
-               ao_cmd_lex();
-       }
-       return 1;
-}
-
-void
-ao_ignite_manual(void)
-{
-       ao_cmd_white();
-       if (!ao_match_word("DoIt"))
-               return;
-       ao_cmd_white();
-       if (ao_cmd_lex_c == 'm') {
-               if(ao_match_word("main"))
-                       ao_igniter_fire(ao_igniter_main);
-       } else {
-               if(ao_match_word("drogue"))
-                       ao_igniter_fire(ao_igniter_drogue);
-       }
-}
-
-static __code char *igniter_status_names[] = {
-       "unknown", "ready", "active", "open"
-};
-
-void
-ao_ignite_print_status(enum ao_igniter igniter, __code char *name) __reentrant
-{
-       enum ao_igniter_status status = ao_igniter_status(igniter);
-       printf("Igniter: %6s Status: %s\n",
-              name,
-              igniter_status_names[status]);
-}
-
-void
-ao_ignite_test(void)
-{
-       ao_ignite_print_status(ao_igniter_drogue, "drogue");
-       ao_ignite_print_status(ao_igniter_main, "main");
-}
-
-__code struct ao_cmds ao_ignite_cmds[] = {
-       { 'i',  ao_ignite_manual,       "i <key> {main|drogue}              Fire igniter. <key> is doit with D&I" },
-       { 't',  ao_ignite_test,         "t                                  Test igniter continuity" },
-       { 0,    ao_ignite_manual,       NULL },
-};
-
-__xdata struct ao_task ao_igniter_task;
-
-void
-ao_igniter_init(void)
-{
-       AO_IGNITER_DROGUE = 0;
-       AO_IGNITER_MAIN = 0;
-       AO_IGNITER_DIR |= AO_IGNITER_DROGUE_BIT | AO_IGNITER_MAIN_BIT;
-       ao_cmd_register(&ao_ignite_cmds[0]);
-       ao_add_task(&ao_igniter_task, ao_igniter, "igniter");
-}
diff --git a/ao_led.c b/ao_led.c
deleted file mode 100644 (file)
index 6c698b4..0000000
--- a/ao_led.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-#define AO_LED_ALL     (AO_LED_GREEN|AO_LED_RED)
-
-__pdata uint8_t ao_led_enable;
-
-void
-ao_led_on(uint8_t colors)
-{
-       P1 |= (colors & ao_led_enable);
-}
-
-void
-ao_led_off(uint8_t colors)
-{
-       P1 &= ~(colors & ao_led_enable);
-}
-
-void
-ao_led_set(uint8_t colors)
-{
-       P1 = (P1 & ~(ao_led_enable)) | (colors & ao_led_enable);
-}
-
-void
-ao_led_toggle(uint8_t colors)
-{
-       P1 ^= (colors & ao_led_enable);
-}
-
-void
-ao_led_for(uint8_t colors, uint16_t ticks) __reentrant
-{
-       ao_led_on(colors);
-       ao_delay(ticks);
-       ao_led_off(colors);
-}
-
-void
-ao_led_init(uint8_t enable)
-{
-       ao_led_enable = enable;
-       P1SEL &= ~enable;
-       P1 &= ~enable;
-       P1DIR |= enable;
-}
diff --git a/ao_log.c b/ao_log.c
deleted file mode 100644 (file)
index 7284121..0000000
--- a/ao_log.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-static __pdata uint32_t        ao_log_current_pos;
-static __pdata uint32_t        ao_log_start_pos;
-static __xdata uint8_t ao_log_running;
-static __xdata uint8_t ao_log_mutex;
-
-static uint8_t
-ao_log_csum(uint8_t *b)
-{
-       uint8_t sum = 0x5a;
-       uint8_t i;
-
-       for (i = 0; i < sizeof (struct ao_log_record); i++)
-               sum += *b++;
-       return -sum;
-}
-
-void
-ao_log_data(struct ao_log_record *log)
-{
-       /* set checksum */
-       log->csum = 0;
-       log->csum = ao_log_csum((uint8_t *) log);
-       ao_mutex_get(&ao_log_mutex); {
-               if (ao_log_running) {
-                       ao_ee_write(ao_log_current_pos,
-                                   (uint8_t *) log,
-                                   sizeof (struct ao_log_record));
-                       ao_log_current_pos += sizeof (struct ao_log_record);
-                       if (ao_log_current_pos >= AO_EE_DATA_SIZE)
-                               ao_log_current_pos = 0;
-                       if (ao_log_current_pos == ao_log_start_pos)
-                               ao_log_running = 0;
-               }
-       } ao_mutex_put(&ao_log_mutex);
-}
-
-void
-ao_log_flush(void)
-{
-       ao_ee_flush();
-}
-
-__xdata struct ao_log_record ao_log_dump;
-static __xdata uint16_t ao_log_dump_flight;
-static __xdata uint32_t ao_log_dump_pos;
-
-static uint8_t
-ao_log_dump_check_data(void)
-{
-       if (ao_log_csum((uint8_t *) &ao_log_dump) != 0)
-               return 0;
-       return 1;
-}
-
-static uint8_t
-ao_log_dump_scan(void)
-{
-       if (!ao_ee_read(0, (uint8_t *) &ao_log_dump, sizeof (struct ao_log_record)))
-               ao_panic(AO_PANIC_LOG);
-       if (ao_log_dump_check_data() && ao_log_dump.type == AO_LOG_FLIGHT) {
-               ao_log_dump_flight = ao_log_dump.u.flight.flight;
-               return 1;
-       } else {
-               ao_log_dump_flight = 0;
-               return 0;
-       }
-}
-
-uint8_t
-ao_log_dump_first(void)
-{
-       ao_log_dump_pos = 0;
-       if (!ao_log_dump_scan())
-               return 0;
-       return 1;
-}
-
-uint8_t
-ao_log_dump_next(void)
-{
-       ao_log_dump_pos += sizeof (struct ao_log_record);
-       if (ao_log_dump_pos >= AO_EE_DEVICE_SIZE)
-               return 0;
-       if (!ao_ee_read(ao_log_dump_pos, (uint8_t *) &ao_log_dump,
-                       sizeof (struct ao_log_record)))
-               return 0;
-       return ao_log_dump_check_data();
-}
-
-__xdata uint8_t        ao_log_adc_pos;
-__xdata enum flight_state ao_log_state;
-
-void
-ao_log(void)
-{
-       static __xdata struct ao_log_record     log;
-       
-       ao_log_dump_scan();
-
-       while (!ao_log_running)
-               ao_sleep(&ao_log_running);
-       
-       log.type = AO_LOG_FLIGHT;
-       log.tick = ao_flight_tick;
-       log.u.flight.ground_accel = ao_ground_accel;
-       log.u.flight.flight = ao_log_dump_flight + 1;
-       ao_log_data(&log);
-
-       /* Write the whole contents of the ring to the log
-        * when starting up.
-        */
-       ao_log_adc_pos = ao_adc_ring_next(ao_adc_head);
-       for (;;) {
-               /* Write samples to EEPROM */
-               while (ao_log_adc_pos != ao_adc_head) {
-                       log.type = AO_LOG_SENSOR;
-                       log.tick = ao_adc_ring[ao_log_adc_pos].tick;
-                       log.u.sensor.accel = ao_adc_ring[ao_log_adc_pos].accel;
-                       log.u.sensor.pres = ao_adc_ring[ao_log_adc_pos].pres;
-                       ao_log_data(&log);
-                       if ((ao_log_adc_pos & 0x1f) == 0) {
-                               log.type = AO_LOG_TEMP_VOLT;
-                               log.tick = ao_adc_ring[ao_log_adc_pos].tick;
-                               log.u.temp_volt.temp = ao_adc_ring[ao_log_adc_pos].temp;
-                               log.u.temp_volt.v_batt = ao_adc_ring[ao_log_adc_pos].v_batt;
-                               ao_log_data(&log);
-                               log.type = AO_LOG_DEPLOY;
-                               log.tick = ao_adc_ring[ao_log_adc_pos].tick;
-                               log.u.deploy.drogue = ao_adc_ring[ao_log_adc_pos].sense_d;
-                               log.u.deploy.main = ao_adc_ring[ao_log_adc_pos].sense_m;
-                               ao_log_data(&log);
-                       }
-                       ao_log_adc_pos = ao_adc_ring_next(ao_log_adc_pos);
-               }
-               /* Write state change to EEPROM */
-               if (ao_flight_state != ao_log_state) {
-                       ao_log_state = ao_flight_state;
-                       log.type = AO_LOG_STATE;
-                       log.tick = ao_flight_tick;
-                       log.u.state.state = ao_log_state;
-                       log.u.state.reason = 0;
-                       ao_log_data(&log);
-
-                       if (ao_log_state == ao_flight_landed)
-                               ao_log_stop();
-               }
-               
-               /* Wait for a while */
-               ao_delay(AO_MS_TO_TICKS(100));
-
-               /* Stop logging when told to */
-               while (!ao_log_running)
-                       ao_sleep(&ao_log_running);
-       }
-}
-
-void
-ao_log_start(void)
-{
-       /* start logging */
-       ao_log_running = 1;
-       ao_wakeup(&ao_log_running);
-}
-
-void
-ao_log_stop(void)
-{
-       ao_log_running = 0;
-       ao_log_flush();
-}
-
-static void
-dump_log(void)
-{
-       uint8_t more;
-
-       for (more = ao_log_dump_first(); more; more = ao_log_dump_next()) {
-               printf("%c %4x %4x %4x\n",
-                      ao_log_dump.type,
-                      ao_log_dump.tick,
-                      ao_log_dump.u.anon.d0,
-                      ao_log_dump.u.anon.d1);
-               if (ao_log_dump.type == AO_LOG_STATE &&
-                   ao_log_dump.u.state.state == ao_flight_landed)
-                       break;
-       }
-       printf("end\n");
-}
-
-__code struct ao_cmds ao_log_cmds[] = {
-       { 'l',  dump_log,               "l                                  Dump last flight log" },
-       { 0, dump_log, NULL },
-};
-
-static __xdata struct ao_task ao_log_task;
-
-void
-ao_log_init(void)
-{
-       ao_log_running = 0;
-
-       /* For now, just log the flight starting at the begining of eeprom */
-       ao_log_start_pos = 0;
-       ao_log_current_pos = ao_log_start_pos;
-       ao_log_state = ao_flight_invalid;
-
-       /* Create a task to log events to eeprom */
-       ao_add_task(&ao_log_task, ao_log, "log");
-       ao_cmd_register(&ao_log_cmds[0]);
-}
diff --git a/ao_main.c b/ao_main.c
deleted file mode 100644 (file)
index 1f7a829..0000000
--- a/ao_main.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-void
-main(void)
-{
-       CLKCON = 0;
-       while (!(SLEEP & SLEEP_XOSC_STB))
-               ;
-
-       /* Turn on the red LED until the system is stable */
-       ao_led_init();
-       ao_led_on(AO_LED_RED);
-
-       ao_timer_init();
-       ao_adc_init();
-       ao_beep_init();
-       ao_cmd_init();
-       ao_ee_init();
-       ao_flight_init();
-       ao_log_init();
-       ao_report_init();
-       ao_usb_init();
-       ao_serial_init();
-       ao_gps_init();
-       ao_telemetry_init();
-       ao_radio_init();
-       ao_start_scheduler();
-}
diff --git a/ao_monitor.c b/ao_monitor.c
deleted file mode 100644 (file)
index 5997d42..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-__xdata uint8_t ao_monitoring;
-__pdata uint8_t ao_monitor_led;
-
-void
-ao_monitor(void)
-{
-       __xdata struct ao_radio_recv recv;
-       __xdata char callsign[AO_MAX_CALLSIGN+1];
-       uint8_t state;
-
-       for (;;) {
-               __critical while (!ao_monitoring)
-                       ao_sleep(&ao_monitoring);
-               ao_radio_recv(&recv);
-               state = recv.telemetry.flight_state;
-               memcpy(callsign, recv.telemetry.callsign, AO_MAX_CALLSIGN);
-               if (state > ao_flight_invalid)
-                       state = ao_flight_invalid;
-               if (recv.status & PKT_APPEND_STATUS_1_CRC_OK) {
-                       printf ("CALL %s SERIAL %3d RSSI %4d STATUS %02x STATE %7s ",
-                               callsign,
-                               recv.telemetry.addr,
-                               (int) recv.rssi - 74, recv.status,
-                               ao_state_names[state]);
-                       printf("%5u a: %5d p: %5d t: %5d v: %5d d: %5d m: %5d fa: %5d ga: %d fv: %7ld fp: %5d gp: %5d ",
-                              recv.telemetry.adc.tick,
-                              recv.telemetry.adc.accel,
-                              recv.telemetry.adc.pres,
-                              recv.telemetry.adc.temp,
-                              recv.telemetry.adc.v_batt,
-                              recv.telemetry.adc.sense_d,
-                              recv.telemetry.adc.sense_m,
-                              recv.telemetry.flight_accel,
-                              recv.telemetry.ground_accel,
-                              recv.telemetry.flight_vel,
-                              recv.telemetry.flight_pres,
-                              recv.telemetry.ground_pres);
-                       ao_gps_print(&recv.telemetry.gps);
-                       ao_rssi_set((int) recv.rssi - 74);
-               } else {
-                       printf("CRC INVALID RSSI %3d\n", (int) recv.rssi - 74);
-               }
-               ao_usb_flush();
-               ao_led_toggle(ao_monitor_led);
-       }
-}
-
-__xdata struct ao_task ao_monitor_task;
-
-void
-ao_set_monitor(uint8_t monitoring)
-{
-       ao_monitoring = monitoring;
-       ao_wakeup(&ao_monitoring);
-}
-
-static void
-set_monitor(void)
-{
-       ao_cmd_hex();
-       ao_set_monitor(ao_cmd_lex_i != 0);
-}
-
-__code struct ao_cmds ao_monitor_cmds[] = {
-       { 'm',  set_monitor,    "m <0 off, 1 on>                    Enable/disable radio monitoring" },
-       { 0,    set_monitor,    NULL },
-};
-
-void
-ao_monitor_init(uint8_t monitor_led, uint8_t monitoring) __reentrant
-{
-       ao_monitor_led = monitor_led;
-       ao_monitoring = monitoring;
-       ao_cmd_register(&ao_monitor_cmds[0]);
-       ao_add_task(&ao_monitor_task, ao_monitor, "monitor");
-}
diff --git a/ao_mutex.c b/ao_mutex.c
deleted file mode 100644 (file)
index 8212a51..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-void
-ao_mutex_get(__xdata uint8_t *mutex) __reentrant
-{
-       if (*mutex == ao_cur_task->task_id)
-               ao_panic(AO_PANIC_MUTEX);
-       __critical {
-               while (*mutex) 
-                       ao_sleep(mutex);
-               *mutex = ao_cur_task->task_id;
-       }
-}
-
-void
-ao_mutex_put(__xdata uint8_t *mutex) __reentrant
-{
-       if (*mutex != ao_cur_task->task_id)
-               ao_panic(AO_PANIC_MUTEX);
-       __critical {
-               *mutex = 0;
-               ao_wakeup(mutex);
-       }
-}
diff --git a/ao_panic.c b/ao_panic.c
deleted file mode 100644 (file)
index f6ecc38..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-static void
-ao_panic_delay(uint8_t n)
-{
-       uint8_t i = 0, j = 0;
-
-       while (n--)
-               while (--j)
-                       while (--i)
-                               _asm nop _endasm;
-}
-
-void
-ao_panic(uint8_t reason)
-{
-       uint8_t n;
-       
-       __critical for (;;) {
-               ao_panic_delay(20);
-               for (n = 0; n < 5; n++) {
-                       ao_led_on(AO_LED_RED);
-                       ao_beep(AO_BEEP_HIGH);
-                       ao_panic_delay(1);
-                       ao_led_off(AO_LED_RED);
-                       ao_beep(AO_BEEP_LOW);
-                       ao_panic_delay(1);
-               }
-               ao_beep(AO_BEEP_OFF);
-               ao_panic_delay(2);
-#pragma disable_warning 126
-               for (n = 0; n < reason; n++) {
-                       ao_led_on(AO_LED_RED);
-                       ao_beep(AO_BEEP_MID);
-                       ao_panic_delay(10);
-                       ao_led_off(AO_LED_RED);
-                       ao_beep(AO_BEEP_OFF);
-                       ao_panic_delay(10);
-               }
-       }
-}
diff --git a/ao_product.c b/ao_product.c
deleted file mode 100644 (file)
index b42e62c..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-#include "ao_usb.h"
-#include PRODUCT_DEFS
-
-/* Defines which mark this particular AltOS product */
-
-const uint16_t ao_serial_number = AO_iSerial_NUMBER;
-const char ao_version[] = AO_iVersion_STRING;
-const char ao_manufacturer[] = AO_iManufacturer_STRING;
-const char ao_product[] = AO_iProduct_STRING;
-
-#define LE_WORD(x)    ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8))
-
-/* USB descriptors in one giant block of bytes */
-const uint8_t ao_usb_descriptors [] =
-{
-       /* Device descriptor */
-       0x12,
-       AO_USB_DESC_DEVICE,
-       LE_WORD(0x0110),        /*  bcdUSB */
-       0x02,                   /*  bDeviceClass */
-       0x00,                   /*  bDeviceSubClass */
-       0x00,                   /*  bDeviceProtocol */
-       AO_USB_CONTROL_SIZE,    /*  bMaxPacketSize */
-       LE_WORD(0xFFFE),        /*  idVendor */
-       LE_WORD(0x000A),        /*  idProduct */
-       LE_WORD(0x0100),        /*  bcdDevice */
-       0x01,                   /*  iManufacturer */
-       0x02,                   /*  iProduct */
-       0x03,                   /*  iSerialNumber */
-       0x01,                   /*  bNumConfigurations */
-
-       /* Configuration descriptor */
-       0x09,
-       AO_USB_DESC_CONFIGURATION,
-       LE_WORD(67),            /*  wTotalLength */
-       0x02,                   /*  bNumInterfaces */
-       0x01,                   /*  bConfigurationValue */
-       0x00,                   /*  iConfiguration */
-       0xC0,                   /*  bmAttributes */
-       0x32,                   /*  bMaxPower */
-
-       /* Control class interface */
-       0x09,
-       AO_USB_DESC_INTERFACE,
-       0x00,                   /*  bInterfaceNumber */
-       0x00,                   /*  bAlternateSetting */
-       0x01,                   /*  bNumEndPoints */
-       0x02,                   /*  bInterfaceClass */
-       0x02,                   /*  bInterfaceSubClass */
-       0x01,                   /*  bInterfaceProtocol, linux requires value of 1 for the cdc_acm module */
-       0x00,                   /*  iInterface */
-
-       /* Header functional descriptor */
-       0x05,
-       CS_INTERFACE,
-       0x00,                   /*  bDescriptor SubType Header */
-       LE_WORD(0x0110),        /*  CDC version 1.1 */
-
-       /* Call management functional descriptor */
-       0x05,
-       CS_INTERFACE,
-       0x01,                   /* bDescriptor SubType Call Management */
-       0x01,                   /* bmCapabilities = device handles call management */
-       0x01,                   /* bDataInterface call management interface number */
-
-       /* ACM functional descriptor */
-       0x04,
-       CS_INTERFACE,
-       0x02,                   /* bDescriptor SubType Abstract Control Management */
-       0x02,                   /* bmCapabilities = D1 (Set_line_Coding, Set_Control_Line_State, Get_Line_Coding and Serial_State) */
-
-       /* Union functional descriptor */
-       0x05,
-       CS_INTERFACE,
-       0x06,                   /* bDescriptor SubType Union Functional descriptor */
-       0x00,                   /* bMasterInterface */
-       0x01,                   /* bSlaveInterface0 */
-
-       /* Notification EP */
-       0x07,
-       AO_USB_DESC_ENDPOINT,
-       AO_USB_INT_EP|0x80,     /* bEndpointAddress */
-       0x03,                   /* bmAttributes = intr */
-       LE_WORD(8),             /* wMaxPacketSize */
-       0x0A,                   /* bInterval */
-
-       /* Data class interface descriptor */
-       0x09,
-       AO_USB_DESC_INTERFACE,
-       0x01,                   /* bInterfaceNumber */
-       0x00,                   /* bAlternateSetting */
-       0x02,                   /* bNumEndPoints */
-       0x0A,                   /* bInterfaceClass = data */
-       0x00,                   /* bInterfaceSubClass */
-       0x00,                   /* bInterfaceProtocol */
-       0x00,                   /* iInterface */
-
-       /* Data EP OUT */
-       0x07,
-       AO_USB_DESC_ENDPOINT,
-       AO_USB_OUT_EP,          /* bEndpointAddress */
-       0x02,                   /* bmAttributes = bulk */
-       LE_WORD(AO_USB_OUT_SIZE),/* wMaxPacketSize */
-       0x00,                   /* bInterval */
-
-       /* Data EP in */
-       0x07,
-       AO_USB_DESC_ENDPOINT,
-       AO_USB_IN_EP|0x80,      /* bEndpointAddress */
-       0x02,                   /* bmAttributes = bulk */
-       LE_WORD(AO_USB_IN_SIZE),/* wMaxPacketSize */
-       0x00,                   /* bInterval */
-
-       /* String descriptors */
-       0x04,
-       AO_USB_DESC_STRING,
-       LE_WORD(0x0409),
-
-       /* iManufacturer */
-       AO_iManufacturer_LEN,
-       AO_USB_DESC_STRING,
-       AO_iManufacturer_UCS2,
-
-       /* iProduct */
-       AO_iProduct_LEN,
-       AO_USB_DESC_STRING,
-       AO_iProduct_UCS2,
-
-       /* iSerial */
-       AO_iSerial_LEN,
-       AO_USB_DESC_STRING,
-       AO_iSerial_UCS2,
-
-       /* Terminating zero */
-       0
-};
diff --git a/ao_radio.c b/ao_radio.c
deleted file mode 100644 (file)
index e090fe7..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-/* Values from SmartRF® Studio for:
- *
- * Deviation:  20.507812 kHz
- * Datarate:   38.360596 kBaud
- * Modulation: GFSK
- * RF Freq:    434.549927 MHz
- * Channel:    99.975586 kHz
- * Channel:    0
- * RX filter:  93.75 kHz
- */
-
-/*
- * For 434.550MHz, the frequency value is:
- *
- * 434.550e6 / (24e6 / 2**16) = 1186611.2
- */
-
-#define FREQ_CONTROL   1186611
-
-/*
- * For IF freq of 140.62kHz, the IF value is:
- *
- * 140.62e3 / (24e6 / 2**10) = 6
- */
-
-#define IF_FREQ_CONTROL        6
-
-/*
- * For channel bandwidth of 93.75 kHz, the CHANBW_E and CHANBW_M values are
- *
- * BW = 24e6 / (8 * (4 + M) * 2 ** E)
- *
- * So, M = 0 and E = 3
- */
-
-#define CHANBW_M       0
-#define CHANBW_E       3
-
-/*
- * For a symbol rate of 38360kBaud, the DRATE_E and DRATE_M values are:
- *
- * R = (256 + M) * 2** E * 24e6 / 2**28
- *
- * So M is 163 and E is 10
- */
-
-#define DRATE_E                10
-#define DRATE_M                163
-
-/*
- * For a channel deviation of 20.5kHz, the DEVIATION_E and DEVIATION_M values are:
- *
- * F = 24e6/2**17 * (8 + DEVIATION_M) * 2**DEVIATION_E
- *
- * So M is 6 and E is 3
- */
-
-#define DEVIATION_M    6
-#define DEVIATION_E    3
-
-/* This are from the table for 433MHz */
-
-#define RF_POWER_M30_DBM       0x12
-#define RF_POWER_M20_DBM       0x0e
-#define RF_POWER_M15_DBM       0x1d
-#define RF_POWER_M10_DBM       0x34
-#define RF_POWER_M5_DBM                0x2c
-#define RF_POWER_0_DBM         0x60
-#define RF_POWER_5_DBM         0x84
-#define RF_POWER_7_DBM         0xc8
-#define RF_POWER_10_DBM                0xc0
-
-#define RF_POWER               RF_POWER_10_DBM
-
-static __code uint8_t radio_setup[] = {
-       RF_PA_TABLE7_OFF,       RF_POWER,
-       RF_PA_TABLE6_OFF,       RF_POWER,
-       RF_PA_TABLE5_OFF,       RF_POWER,
-       RF_PA_TABLE4_OFF,       RF_POWER,
-       RF_PA_TABLE3_OFF,       RF_POWER,
-       RF_PA_TABLE2_OFF,       RF_POWER,
-       RF_PA_TABLE1_OFF,       RF_POWER,
-       RF_PA_TABLE0_OFF,       RF_POWER,
-
-       RF_FREQ2_OFF,           (FREQ_CONTROL >> 16) & 0xff,
-       RF_FREQ1_OFF,           (FREQ_CONTROL >> 8) & 0xff,
-       RF_FREQ0_OFF,           (FREQ_CONTROL >> 0) & 0xff,
-
-       RF_FSCTRL1_OFF,         (IF_FREQ_CONTROL << RF_FSCTRL1_FREQ_IF_SHIFT),
-       RF_FSCTRL0_OFF,         (0 << RF_FSCTRL0_FREQOFF_SHIFT),
-
-       RF_MDMCFG4_OFF,         ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
-                                (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) |
-                                (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)),
-       RF_MDMCFG3_OFF,         (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
-       RF_MDMCFG2_OFF,         (RF_MDMCFG2_DEM_DCFILT_OFF |
-                                RF_MDMCFG2_MOD_FORMAT_GFSK |
-                                RF_MDMCFG2_SYNC_MODE_15_16_THRES),
-       RF_MDMCFG1_OFF,         (RF_MDMCFG1_FEC_EN |
-                                RF_MDMCFG1_NUM_PREAMBLE_4 |
-                                (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)),
-       RF_MDMCFG0_OFF,         (17 << RF_MDMCFG0_CHANSPC_M_SHIFT),
-
-       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
-        */
-       RF_FREND0_OFF,          ((1 << RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT) |
-                                (0 << RF_FREND0_PA_POWER_SHIFT)),
-
-       RF_FREND1_OFF,          ((1 << RF_FREND1_LNA_CURRENT_SHIFT) |
-                                (1 << RF_FREND1_LNA2MIX_CURRENT_SHIFT) |
-                                (1 << RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT) |
-                                (2 << RF_FREND1_MIX_CURRENT_SHIFT)),
-
-       RF_FSCAL3_OFF,          0xE9,
-       RF_FSCAL2_OFF,          0x0A,
-       RF_FSCAL1_OFF,          0x00,
-       RF_FSCAL0_OFF,          0x1F,
-
-       RF_TEST2_OFF,           0x88,
-       RF_TEST1_OFF,           0x31,
-       RF_TEST0_OFF,           0x09,
-
-       /* default sync values */
-       RF_SYNC1_OFF,           0xD3,
-       RF_SYNC0_OFF,           0x91,
-
-       /* max packet length */
-       RF_PKTLEN_OFF,          sizeof (struct ao_telemetry),
-
-       RF_PKTCTRL1_OFF,        ((1 << PKTCTRL1_PQT_SHIFT)|
-                                PKTCTRL1_APPEND_STATUS|
-                                PKTCTRL1_ADR_CHK_NONE),
-       RF_PKTCTRL0_OFF,        (RF_PKTCTRL0_WHITE_DATA|
-                                RF_PKTCTRL0_PKT_FORMAT_NORMAL|
-                                RF_PKTCTRL0_CRC_EN|
-                                RF_PKTCTRL0_LENGTH_CONFIG_FIXED),
-       RF_ADDR_OFF,            0x00,
-       RF_MCSM2_OFF,           (RF_MCSM2_RX_TIME_END_OF_PACKET),
-       RF_MCSM1_OFF,           (RF_MCSM1_CCA_MODE_RSSI_BELOW_UNLESS_RECEIVING|
-                                RF_MCSM1_RXOFF_MODE_IDLE|
-                                RF_MCSM1_TXOFF_MODE_IDLE),
-       RF_MCSM0_OFF,           (RF_MCSM0_FS_AUTOCAL_FROM_IDLE|
-                                RF_MCSM0_MAGIC_3|
-                                RF_MCSM0_CLOSE_IN_RX_0DB),
-       RF_FOCCFG_OFF,          (RF_FOCCFG_FOC_PRE_K_3K,
-                                RF_FOCCFG_FOC_POST_K_PRE_K,
-                                RF_FOCCFG_FOC_LIMIT_BW_OVER_4),
-       RF_BSCFG_OFF,           (RF_BSCFG_BS_PRE_K_2K|
-                                RF_BSCFG_BS_PRE_KP_3KP|
-                                RF_BSCFG_BS_POST_KI_PRE_KI|
-                                RF_BSCFG_BS_POST_KP_PRE_KP|
-                                RF_BSCFG_BS_LIMIT_0),
-       RF_AGCCTRL2_OFF,        0x43,
-       RF_AGCCTRL1_OFF,        0x40,
-       RF_AGCCTRL0_OFF,        0x91,
-
-       RF_IOCFG2_OFF,          0x00,
-       RF_IOCFG1_OFF,          0x00,
-       RF_IOCFG0_OFF,          0x00,
-};
-
-
-static __code uint8_t telemetry_setup[] = {
-       RF_MDMCFG4_OFF,         ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
-                                (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) |
-                                (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)),
-       RF_MDMCFG3_OFF,         (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
-       RF_MDMCFG2_OFF,         (RF_MDMCFG2_DEM_DCFILT_OFF |
-                                RF_MDMCFG2_MOD_FORMAT_GFSK |
-                                RF_MDMCFG2_SYNC_MODE_15_16_THRES),
-       RF_MDMCFG1_OFF,         (RF_MDMCFG1_FEC_EN |
-                                RF_MDMCFG1_NUM_PREAMBLE_4 |
-                                (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)),
-
-       RF_DEVIATN_OFF,         ((DEVIATION_E << RF_DEVIATN_DEVIATION_E_SHIFT) |
-                                (DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)),
-
-       /* max packet length */
-       RF_PKTLEN_OFF,          sizeof (struct ao_telemetry),
-       RF_PKTCTRL1_OFF,        ((1 << PKTCTRL1_PQT_SHIFT)|
-                                PKTCTRL1_APPEND_STATUS|
-                                PKTCTRL1_ADR_CHK_NONE),
-       RF_PKTCTRL0_OFF,        (RF_PKTCTRL0_WHITE_DATA|
-                                RF_PKTCTRL0_PKT_FORMAT_NORMAL|
-                                RF_PKTCTRL0_CRC_EN|
-                                RF_PKTCTRL0_LENGTH_CONFIG_FIXED),
-};
-
-__xdata uint8_t        ao_radio_dma;
-__xdata uint8_t ao_radio_dma_done;
-__xdata uint8_t ao_radio_mutex;
-
-static void
-ao_radio_idle(void)
-{
-       if (RF_MARCSTATE != RF_MARCSTATE_IDLE)
-       {
-               RFST = RFST_SIDLE;
-               do {
-                       ao_yield();
-               } while (RF_MARCSTATE != RF_MARCSTATE_IDLE);
-       }
-}
-
-void
-ao_radio_send(__xdata struct ao_telemetry *telemetry) __reentrant
-{
-       ao_config_get();
-       ao_mutex_get(&ao_radio_mutex);
-       ao_radio_idle();
-       RF_CHANNR = ao_config.radio_channel;
-       ao_dma_set_transfer(ao_radio_dma,
-                           telemetry,
-                           &RFDXADDR,
-                           sizeof (struct ao_telemetry),
-                           DMA_CFG0_WORDSIZE_8 |
-                           DMA_CFG0_TMODE_SINGLE |
-                           DMA_CFG0_TRIGGER_RADIO,
-                           DMA_CFG1_SRCINC_1 |
-                           DMA_CFG1_DESTINC_0 |
-                           DMA_CFG1_PRIORITY_HIGH);
-       ao_dma_start(ao_radio_dma);
-       RFST = RFST_STX;
-       __critical while (!ao_radio_dma_done)
-               ao_sleep(&ao_radio_dma_done);
-       ao_mutex_put(&ao_radio_mutex);
-}
-
-void
-ao_radio_recv(__xdata struct ao_radio_recv *radio) __reentrant
-{
-       ao_config_get();
-       ao_mutex_get(&ao_radio_mutex);
-       ao_radio_idle();
-       RF_CHANNR = ao_config.radio_channel;
-       ao_dma_set_transfer(ao_radio_dma,
-                           &RFDXADDR,
-                           radio,
-                           sizeof (struct ao_radio_recv),
-                           DMA_CFG0_WORDSIZE_8 |
-                           DMA_CFG0_TMODE_SINGLE |
-                           DMA_CFG0_TRIGGER_RADIO,
-                           DMA_CFG1_SRCINC_0 |
-                           DMA_CFG1_DESTINC_1 |
-                           DMA_CFG1_PRIORITY_HIGH);
-       ao_dma_start(ao_radio_dma);
-       RFST = RFST_SRX;
-       __critical while (!ao_radio_dma_done)
-               ao_sleep(&ao_radio_dma_done);
-       ao_mutex_put(&ao_radio_mutex);
-}
-
-void
-ao_radio_init(void)
-{
-       uint8_t i;
-       for (i = 0; i < sizeof (radio_setup); i += 2)
-               RF[radio_setup[i]] = radio_setup[i+1];
-       ao_radio_dma_done = 1;
-       ao_radio_dma = ao_dma_alloc(&ao_radio_dma_done);
-}
-
diff --git a/ao_report.c b/ao_report.c
deleted file mode 100644 (file)
index e52b292..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-static const char * __xdata flight_reports[] = {
-       "...",          /* startup, 'S' */
-       "..",           /* idle 'I' */
-       ".--.",         /* launchpad 'P' */
-       "-...",         /* boost 'B' */
-       "-.-.",         /* coast 'C' */
-       ".-",           /* apogee 'A' */
-       "-..",          /* drogue 'D' */
-       "--",           /* main 'M' */
-       ".-..",         /* landed 'L' */
-       ".-.-.-",       /* invalid */
-};
-
-#if 1
-#define signal(time)   ao_beep_for(AO_BEEP_MID, time)
-#else
-#define signal(time)   ao_led_for(AO_LED_RED, time)
-#endif
-#define pause(time)    ao_delay(time)
-
-static __xdata enum ao_flight_state ao_report_state;
-
-static void
-ao_report_beep(void) __reentrant
-{
-       char *r = flight_reports[ao_flight_state];
-       char c;
-
-       if (!r)
-               return;
-       while (c = *r++) {
-               if (c == '.')
-                       signal(AO_MS_TO_TICKS(200));
-               else
-                       signal(AO_MS_TO_TICKS(600));
-               pause(AO_MS_TO_TICKS(200));
-       }
-       pause(AO_MS_TO_TICKS(400));
-}
-
-static void
-ao_report_digit(uint8_t digit) __reentrant
-{
-       if (!digit) {
-               signal(AO_MS_TO_TICKS(500));
-               pause(AO_MS_TO_TICKS(200));
-       } else {
-               while (digit--) {
-                       signal(AO_MS_TO_TICKS(200));
-                       pause(AO_MS_TO_TICKS(200));
-               }
-       }
-       pause(AO_MS_TO_TICKS(300));
-}
-
-static void
-ao_report_altitude(void)
-{
-       __xdata int16_t agl = ao_pres_to_altitude(ao_min_pres) - ao_pres_to_altitude(ao_ground_pres);
-       __xdata uint8_t digits[10];
-       __xdata uint8_t ndigits, i;
-
-       if (agl < 0)
-               agl = 0;
-       ndigits = 0;
-       do {
-               digits[ndigits++] = agl % 10;
-               agl /= 10;
-       } while (agl);
-
-       for (;;) {
-               ao_report_beep();
-               i = ndigits;
-               do
-                       ao_report_digit(digits[--i]);
-               while (i != 0);
-               pause(AO_SEC_TO_TICKS(5));
-       }
-}
-
-void
-ao_report(void)
-{
-       ao_report_state = ao_flight_state;
-       for(;;) {
-               if (ao_flight_state == ao_flight_landed)
-                       ao_report_altitude();
-               ao_report_beep();
-               __critical {
-                       while (ao_report_state == ao_flight_state)
-                               ao_sleep(DATA_TO_XDATA(&ao_flight_state));
-                       ao_report_state = ao_flight_state;
-               }
-       }
-}
-
-static __xdata struct ao_task ao_report_task;
-
-void
-ao_report_init(void)
-{
-       ao_add_task(&ao_report_task, ao_report, "report");
-}
diff --git a/ao_rssi.c b/ao_rssi.c
deleted file mode 100644 (file)
index 6912b9a..0000000
--- a/ao_rssi.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-static __xdata volatile uint16_t       ao_rssi_time;
-static __xdata volatile uint16_t       ao_rssi_delay;
-static __xdata uint8_t                 ao_rssi_led;
-
-void
-ao_rssi(void)
-{
-       for (;;) {
-               while ((int16_t) (ao_time() - ao_rssi_time) > AO_SEC_TO_TICKS(3))
-                       ao_sleep(&ao_rssi_time);
-               ao_led_for(ao_rssi_led, AO_MS_TO_TICKS(100));
-               ao_delay(ao_rssi_delay);
-       }
-}
-
-void
-ao_rssi_set(int rssi_value)
-{
-       if (rssi_value > 0)
-               rssi_value = 0;
-       ao_rssi_delay = AO_MS_TO_TICKS((-rssi_value) * 5);
-       ao_rssi_time = ao_time();
-       ao_wakeup(&ao_rssi_time);
-}
-
-__xdata struct ao_task ao_rssi_task;
-
-void
-ao_rssi_init(uint8_t rssi_led)
-{
-       ao_rssi_led = rssi_led;
-       ao_rssi_delay = 0;
-       ao_add_task(&ao_rssi_task, ao_rssi, "rssi");
-}
diff --git a/ao_serial.c b/ao_serial.c
deleted file mode 100644 (file)
index ce11694..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-volatile __xdata struct ao_fifo        ao_usart1_rx_fifo;
-volatile __xdata struct ao_fifo        ao_usart1_tx_fifo;
-
-void
-ao_serial_rx1_isr(void) interrupt 3
-{
-       if (!ao_fifo_full(ao_usart1_rx_fifo))
-               ao_fifo_insert(ao_usart1_rx_fifo, U1DBUF);
-       ao_wakeup(&ao_usart1_rx_fifo);
-}
-
-static __xdata uint8_t ao_serial_tx1_started;
-
-static void
-ao_serial_tx1_start(void)
-{
-       if (!ao_fifo_empty(ao_usart1_tx_fifo) &&
-           !ao_serial_tx1_started)
-       {
-               ao_serial_tx1_started = 1;
-               ao_fifo_remove(ao_usart1_tx_fifo, U1DBUF);
-       }
-}
-
-void
-ao_serial_tx1_isr(void) interrupt 14
-{
-       UTX1IF = 0;
-       ao_serial_tx1_started = 0;
-       ao_serial_tx1_start();
-       ao_wakeup(&ao_usart1_tx_fifo);
-}
-
-char
-ao_serial_getchar(void) __critical
-{
-       char    c;
-       while (ao_fifo_empty(ao_usart1_rx_fifo))
-               ao_sleep(&ao_usart1_rx_fifo);
-       ao_fifo_remove(ao_usart1_rx_fifo, c);
-       return c;
-}
-
-void
-ao_serial_putchar(char c) __critical
-{
-       while (ao_fifo_full(ao_usart1_tx_fifo))
-               ao_sleep(&ao_usart1_tx_fifo);
-       ao_fifo_insert(ao_usart1_tx_fifo, c);
-       ao_serial_tx1_start();
-}
-
-static void
-send_serial(void)
-{
-       ao_cmd_white();
-       while (ao_cmd_lex_c != '\n') {
-               ao_serial_putchar(ao_cmd_lex_c);
-               ao_cmd_lex();
-       }
-}
-
-__code struct ao_cmds ao_serial_cmds[] = {
-       { 'S', send_serial,             "S <data>                           Send data to serial line" },
-       { 0, send_serial, NULL },
-};
-
-void
-ao_serial_init(void)
-{
-       /* Set up the USART pin assignment */
-       PERCFG = (PERCFG & ~PERCFG_U1CFG_ALT_MASK) | PERCFG_U1CFG_ALT_2;
-
-       /* ee has already set the P2SEL bits */
-
-       /* Make the USART pins be controlled by the USART */
-       P1SEL |= (1 << 6) | (1 << 7);
-
-       /* UART mode with receiver enabled */
-       U1CSR = (UxCSR_MODE_UART | UxCSR_RE);
-
-       /* Pick a 4800 baud rate */
-       U1BAUD = 163;                           /* 4800 */
-       U1GCR = 7 << UxGCR_BAUD_E_SHIFT;        /* 4800 */
-
-       /* Reasonable serial parameters */
-       U1UCR = (UxUCR_FLUSH |
-                UxUCR_FLOW_DISABLE |
-                UxUCR_D9_ODD_PARITY |
-                UxUCR_BIT9_8_BITS |
-                UxUCR_PARITY_DISABLE |
-                UxUCR_SPB_1_STOP_BIT |
-                UxUCR_STOP_HIGH |
-                UxUCR_START_LOW);
-
-       IEN0 |= IEN0_URX1IE;
-       IEN2 |= IEN2_UTX1IE;
-
-       ao_cmd_register(&ao_serial_cmds[0]);
-}
diff --git a/ao_state.c b/ao_state.c
deleted file mode 100644 (file)
index 96b4c1a..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-const char const * const ao_state_names[] = {
-       "startup", "idle", "pad", "boost", "coast",
-       "apogee", "drogue", "main", "landed", "invalid"
-};
diff --git a/ao_stdio.c b/ao_stdio.c
deleted file mode 100644 (file)
index fb8ce09..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-/*
- * Basic I/O functions to support SDCC stdio package
- */
-
-void
-putchar(char c)
-{
-       if (c == '\n')
-               ao_usb_putchar('\r');
-       ao_usb_putchar(c);
-}
-
-void
-flush(void)
-{
-       ao_usb_flush();
-}
-
-char
-getchar(void)
-{
-       return ao_usb_getchar();
-}
diff --git a/ao_task.c b/ao_task.c
deleted file mode 100644 (file)
index 06c279e..0000000
--- a/ao_task.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-#define AO_NO_TASK_INDEX       0xff
-
-__xdata struct ao_task * __xdata ao_tasks[AO_NUM_TASKS];
-__data uint8_t ao_num_tasks;
-__data uint8_t ao_cur_task_index;
-__xdata struct ao_task *__data ao_cur_task;
-
-void
-ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name) __reentrant
-{
-       uint8_t __xdata *stack;
-       if (ao_num_tasks == AO_NUM_TASKS)
-               ao_panic(AO_PANIC_NO_TASK);
-       ao_tasks[ao_num_tasks++] = task;
-       task->task_id = ao_num_tasks;
-       task->name = name;
-       /*
-        * Construct a stack frame so that it will 'return'
-        * to the start of the task
-        */
-       stack = task->stack;
-       
-       *stack++ = ((uint16_t) start);
-       *stack++ = ((uint16_t) start) >> 8;
-       
-       /* and the stuff saved by ao_switch */
-       *stack++ = 0;           /* acc */
-       *stack++ = 0x80;        /* IE */
-       *stack++ = 0;           /* DPL */
-       *stack++ = 0;           /* DPH */
-       *stack++ = 0;           /* B */
-       *stack++ = 0;           /* R2 */
-       *stack++ = 0;           /* R3 */
-       *stack++ = 0;           /* R4 */
-       *stack++ = 0;           /* R5 */
-       *stack++ = 0;           /* R6 */
-       *stack++ = 0;           /* R7 */
-       *stack++ = 0;           /* R0 */
-       *stack++ = 0;           /* R1 */
-       *stack++ = 0;           /* PSW */
-       *stack++ = 0;           /* BP */
-       task->stack_count = stack - task->stack;
-       task->wchan = NULL;
-}
-
-/* Task switching function. This must not use any stack variables */
-void
-ao_yield(void) _naked
-{
-
-       /* Save current context */
-       _asm
-               /* Push ACC first, as when restoring the context it must be restored
-                * last (it is used to set the IE register). */
-               push    ACC
-               /* Store the IE register then enable interrupts. */
-               push    _IEN0
-               setb    _EA
-               push    DPL
-               push    DPH
-               push    b
-               push    ar2
-               push    ar3
-               push    ar4
-               push    ar5
-               push    ar6
-               push    ar7
-               push    ar0
-               push    ar1
-               push    PSW
-       _endasm;
-       PSW = 0;
-       _asm
-               push    _bp
-       _endasm;
-       
-       if (ao_cur_task_index != AO_NO_TASK_INDEX)
-       {
-               uint8_t stack_len;
-               __data uint8_t *stack_ptr;
-               __xdata uint8_t *save_ptr;
-               /* Save the current stack */
-               stack_len = SP - (AO_STACK_START - 1);
-               ao_cur_task->stack_count = stack_len;
-               stack_ptr = (uint8_t __data *) AO_STACK_START;
-               save_ptr = (uint8_t __xdata *) ao_cur_task->stack;
-               do
-                       *save_ptr++ = *stack_ptr++;
-               while (--stack_len);
-       }
-       
-       /* Empty the stack; might as well let interrupts have the whole thing */
-       SP = AO_STACK_START - 1;
-
-       /* Find a task to run. If there isn't any runnable task,
-        * this loop will run forever, which is just fine
-        */
-       {
-               __pdata uint8_t ao_next_task_index = ao_cur_task_index;
-               for (;;) {
-                       ++ao_next_task_index;
-                       if (ao_next_task_index == ao_num_tasks)
-                               ao_next_task_index = 0;
-
-                       ao_cur_task = ao_tasks[ao_next_task_index];
-                       if (ao_cur_task->wchan == NULL) {
-                               ao_cur_task_index = ao_next_task_index;
-                               break;
-                       }
-
-                       /* Enter lower power mode when there isn't anything to do */
-                       if (ao_next_task_index == ao_cur_task_index)
-                               PCON = PCON_IDLE;
-               }
-       }
-
-       {
-               uint8_t stack_len;
-               __data uint8_t *stack_ptr;
-               __xdata uint8_t *save_ptr;
-
-               /* Restore the old stack */
-               stack_len = ao_cur_task->stack_count;
-               SP = AO_STACK_START - 1 + stack_len;
-       
-               stack_ptr = (uint8_t __data *) AO_STACK_START;
-               save_ptr = (uint8_t __xdata *) ao_cur_task->stack;
-               do
-                       *stack_ptr++ = *save_ptr++;
-               while (--stack_len);
-       }
-
-       _asm
-               pop             _bp
-               pop             PSW
-               pop             ar1
-               pop             ar0
-               pop             ar7
-               pop             ar6
-               pop             ar5
-               pop             ar4
-               pop             ar3
-               pop             ar2
-               pop             b
-               pop             DPH
-               pop             DPL
-               /* The next byte of the stack is the IE register.  Only the global
-               enable bit forms part of the task context.  Pop off the IE then set
-               the global enable bit to match that of the stored IE register. */
-               pop             ACC
-               JB              ACC.7,0098$
-               CLR             _EA
-               LJMP    0099$
-       0098$:
-               SETB            _EA
-       0099$:
-               /* Finally pop off the ACC, which was the first register saved. */
-               pop             ACC
-               ret
-       _endasm;
-}
-
-void
-ao_sleep(__xdata void *wchan)
-{
-       __critical {
-               ao_cur_task->wchan = wchan;
-       }
-       ao_yield();
-}
-
-void
-ao_wakeup(__xdata void *wchan)
-{
-       uint8_t i;
-
-       for (i = 0; i < ao_num_tasks; i++)
-               if (ao_tasks[i]->wchan == wchan)
-                       ao_tasks[i]->wchan = NULL;
-}
-
-void
-ao_task_info(void)
-{
-       uint8_t i;
-       uint8_t pc_loc;
-       __xdata struct ao_task *task;
-
-       for (i = 0; i < ao_num_tasks; i++) {
-               task = ao_tasks[i];
-               pc_loc = task->stack_count - 17;
-               printf("%12s: wchan %04x pc %04x\n",
-                      task->name,
-                      (int16_t) task->wchan,
-                      (task->stack[pc_loc]) | (task->stack[pc_loc+1] << 8));
-       }
-}
-
-void
-ao_start_scheduler(void)
-{
-       ao_cur_task_index = AO_NO_TASK_INDEX;
-       ao_cur_task = NULL;
-       ao_yield();
-}
diff --git a/ao_teledongle.c b/ao_teledongle.c
deleted file mode 100644 (file)
index 67fe761..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#define AO_NO_SERIAL_ISR 1
-#define AO_NO_ADC_ISR 1
-#include "ao.h"
-
-void
-main(void)
-{
-       CLKCON = 0;
-       while (!(SLEEP & SLEEP_XOSC_STB))
-               ;
-       
-       /* Turn on the LED until the system is stable */
-       ao_led_init(AO_LED_RED|AO_LED_GREEN);
-       ao_led_on(AO_LED_RED);
-       ao_timer_init();
-       ao_cmd_init();
-       ao_usb_init();
-       ao_monitor_init(AO_LED_GREEN, TRUE);
-       ao_rssi_init(AO_LED_RED);
-       ao_radio_init();
-       ao_dbg_init();
-       ao_config_init();
-       ao_start_scheduler();
-}
diff --git a/ao_telemetrum.c b/ao_telemetrum.c
deleted file mode 100644 (file)
index a680ce1..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-void
-main(void)
-{
-       CLKCON = 0;
-       while (!(SLEEP & SLEEP_XOSC_STB))
-               ;
-
-       /* Turn on the red LED until the system is stable */
-       ao_led_init(AO_LED_RED|AO_LED_GREEN);
-       ao_led_on(AO_LED_RED);
-
-       ao_timer_init();
-       ao_adc_init();
-       ao_beep_init();
-       ao_cmd_init();
-       ao_ee_init();
-       ao_flight_init();
-       ao_log_init();
-       ao_report_init();
-       ao_usb_init();
-       ao_serial_init();
-       ao_gps_init();
-       ao_gps_report_init();
-       ao_telemetry_init();
-       ao_radio_init();
-       ao_igniter_init();
-       ao_dbg_init();
-       ao_config_init();
-       ao_start_scheduler();
-}
diff --git a/ao_telemetry.c b/ao_telemetry.c
deleted file mode 100644 (file)
index 463bcd9..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-__xdata uint16_t ao_telemetry_interval = 0;
-
-void
-ao_telemetry(void)
-{
-       static __xdata struct ao_telemetry telemetry;
-
-       ao_config_get();
-       memcpy(telemetry.callsign, ao_config.callsign, AO_MAX_CALLSIGN);
-       telemetry.addr = ao_serial_number;
-       for (;;) {
-               while (ao_telemetry_interval == 0)
-                       ao_sleep(&ao_telemetry_interval);
-               telemetry.flight_state = ao_flight_state;
-               telemetry.flight_accel = ao_flight_accel;
-               telemetry.ground_accel = ao_ground_accel;
-               telemetry.flight_vel = ao_flight_vel;
-               telemetry.flight_pres = ao_flight_pres;
-               telemetry.ground_pres = ao_ground_pres;
-               ao_adc_get(&telemetry.adc);
-               ao_mutex_get(&ao_gps_mutex);
-               memcpy(&telemetry.gps, &ao_gps_data, sizeof (struct ao_gps_data));
-               ao_mutex_put(&ao_gps_mutex);
-               ao_radio_send(&telemetry);
-               ao_delay(ao_telemetry_interval);
-       }
-}
-
-void
-ao_telemetry_set_interval(uint16_t interval)
-{
-       ao_telemetry_interval = interval;
-       ao_wakeup(&ao_telemetry_interval);
-}
-
-__xdata struct ao_task ao_telemetry_task;
-
-void
-ao_telemetry_init()
-{
-       ao_add_task(&ao_telemetry_task, ao_telemetry, "telemetry");
-}
diff --git a/ao_teleterra.c b/ao_teleterra.c
deleted file mode 100644 (file)
index ad3e2d9..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#define AO_NO_ADC_ISR 1
-#include "ao.h"
-
-void
-main(void)
-{
-       CLKCON = 0;
-       while (!(SLEEP & SLEEP_XOSC_STB))
-               ;
-
-       /* Turn on the red LED until the system is stable */
-       ao_led_init(AO_LED_RED|AO_LED_GREEN);
-       ao_led_on(AO_LED_RED);
-       ao_timer_init();
-       ao_beep_init();
-       ao_cmd_init();
-       ao_usb_init();
-       ao_serial_init();
-       ao_gps_init();
-       ao_monitor_init(AO_LED_GREEN, TRUE);
-       ao_radio_init();
-       ao_dbg_init();
-       ao_config_init();
-       ao_start_scheduler();
-}
diff --git a/ao_test.c b/ao_test.c
deleted file mode 100644 (file)
index 6d005ff..0000000
--- a/ao_test.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-struct ao_task __xdata blink_0_task;
-struct ao_task __xdata blink_1_task;
-struct ao_task __xdata wakeup_task;
-struct ao_task __xdata beep_task;
-struct ao_task __xdata echo_task;
-
-void delay(int n) __reentrant
-{
-       uint8_t j = 0;
-       while (--n)
-               while (--j)
-                       ao_yield();
-}
-
-static __xdata uint8_t blink_chan;
-
-void
-blink_0(void)
-{
-       uint8_t b = 0;
-       for (;;) {
-               b = 1 - b;
-               if (b)
-                       ao_led_on(AO_LED_GREEN);
-               else
-                       ao_led_off(AO_LED_GREEN);
-               ao_sleep(&blink_chan);
-       }
-}
-
-void
-blink_1(void)
-{
-       static __xdata struct ao_adc adc;
-
-       for (;;) {
-               ao_sleep(&ao_adc_ring);
-               ao_adc_get(&adc);
-               if (adc.accel < 15900)
-                       ao_led_on(AO_LED_RED);
-               else
-                       ao_led_off(AO_LED_RED);
-       }
-}
-
-void
-wakeup(void)
-{
-       for (;;) {
-               ao_delay(AO_MS_TO_TICKS(100));
-               ao_wakeup(&blink_chan);
-       }
-}
-
-void
-beep(void)
-{
-       static __xdata struct ao_adc adc;
-
-       for (;;) {
-               ao_delay(AO_SEC_TO_TICKS(1));
-               ao_adc_get(&adc);
-               if (adc.temp > 7400)
-                       ao_beep_for(AO_BEEP_LOW, AO_MS_TO_TICKS(50));
-       }
-}
-
-void
-echo(void)
-{
-       char    c;
-       for (;;) {
-               ao_usb_flush();
-               c = ao_usb_getchar();
-               ao_usb_putchar(c);
-               if (c == '\r')
-                       ao_usb_putchar('\n');
-       }
-}
-
-void
-main(void)
-{
-       CLKCON = 0;
-       while (!(SLEEP & SLEEP_XOSC_STB))
-               ;
-
-//     ao_add_task(&blink_0_task, blink_0);
-//     ao_add_task(&blink_1_task, blink_1);
-//     ao_add_task(&wakeup_task, wakeup);
-//     ao_add_task(&beep_task, beep);
-       ao_add_task(&echo_task, echo);
-       ao_timer_init();
-       ao_adc_init();
-       ao_beep_init();
-       ao_led_init();
-       ao_usb_init();
-       
-       ao_start_scheduler();
-}
diff --git a/ao_tidongle.c b/ao_tidongle.c
deleted file mode 100644 (file)
index b068d04..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#define AO_NO_SERIAL_ISR 1
-#define AO_NO_ADC_ISR 1
-#include "ao.h"
-
-void
-main(void)
-{
-       CLKCON = 0;
-       while (!(SLEEP & SLEEP_XOSC_STB))
-               ;
-       
-       /* Turn on the LED until the system is stable */
-       ao_led_init(AO_LED_RED);
-       ao_led_on(AO_LED_RED);
-       ao_timer_init();
-       ao_cmd_init();
-       ao_usb_init();
-       ao_monitor_init(AO_LED_RED, TRUE);
-       ao_rssi_init(AO_LED_RED);
-       ao_radio_init();
-       ao_dbg_init();
-       ao_config_init();
-       /* Bring up the USB link */
-       P1DIR |= 1;
-       P1 |= 1;
-       ao_start_scheduler();
-}
diff --git a/ao_timer.c b/ao_timer.c
deleted file mode 100644 (file)
index a6a7646..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-
-static volatile __data uint16_t ao_tick_count;
-
-uint16_t ao_time(void) __critical
-{
-       return ao_tick_count;
-}
-
-void
-ao_delay(uint16_t ticks)
-{
-       uint16_t until = ao_time() + ticks;
-
-       while ((int16_t) (until - ao_time()) > 0)
-               ao_sleep(DATA_TO_XDATA(&ao_tick_count));
-}
-
-#define T1_CLOCK_DIVISOR       8       /* 24e6/8 = 3e6 */
-#define T1_SAMPLE_TIME         30000   /* 3e6/30000 = 100 */
-
-volatile __data uint8_t        ao_adc_interval = 1;
-volatile __data uint8_t        ao_adc_count;
-
-void ao_timer_isr(void) interrupt 9
-{
-       ++ao_tick_count;
-       if (++ao_adc_count == ao_adc_interval) {
-               ao_adc_count = 0;
-               ao_adc_poll();
-       }
-       ao_wakeup(DATA_TO_XDATA(&ao_tick_count));
-}
-
-void
-ao_timer_set_adc_interval(uint8_t interval) __critical
-{
-       ao_adc_interval = interval;
-       ao_adc_count = 0;
-}
-
-void
-ao_timer_init(void)
-{
-       /* NOTE:  This uses a timer only present on cc1111 architecture. */
-
-       /* disable timer 1 */
-       T1CTL = 0;
-
-       /* set the sample rate */
-       T1CC0H = T1_SAMPLE_TIME >> 8;
-       T1CC0L = (uint8_t) T1_SAMPLE_TIME;
-
-       T1CCTL0 = T1CCTL_MODE_COMPARE;
-       T1CCTL1 = 0;
-       T1CCTL2 = 0;
-
-       /* clear timer value */
-       T1CNTL = 0;
-
-       /* enable overflow interrupt */
-       OVFIM = 1;
-       /* enable timer 1 interrupt */
-       T1IE = 1;
-
-       /* enable timer 1 in module mode, dividing by 8 */
-       T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_8;
-}
-
diff --git a/ao_usb.c b/ao_usb.c
deleted file mode 100644 (file)
index 315eea0..0000000
--- a/ao_usb.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "ao.h"
-#include "ao_usb.h"
-
-struct ao_task __xdata ao_usb_task;
-
-static __xdata uint16_t        ao_usb_in_bytes;
-static __xdata uint16_t        ao_usb_out_bytes;
-static __xdata uint8_t ao_usb_iif;
-static __xdata uint8_t ao_usb_running;
-
-static void
-ao_usb_set_interrupts(void)
-{
-       /* IN interrupts on the control an IN endpoints */
-       USBIIE = (1 << AO_USB_CONTROL_EP) | (1 << AO_USB_IN_EP);
-
-       /* OUT interrupts on the OUT endpoint */
-       USBOIE = (1 << AO_USB_OUT_EP);
-
-       /* Only care about reset */
-       USBCIE = USBCIE_RSTIE;
-}
-
-/* This interrupt is shared with port 2, 
- * so when we hook that up, fix this
- */
-void
-ao_usb_isr(void) interrupt 6
-{
-       USBIF = 0;
-       ao_usb_iif |= USBIIF;
-       if (ao_usb_iif & 1)
-               ao_wakeup(&ao_usb_task);
-       if (ao_usb_iif & (1 << AO_USB_IN_EP))
-               ao_wakeup(&ao_usb_in_bytes);
-
-       if (USBOIF & (1 << AO_USB_OUT_EP))
-               ao_wakeup(&ao_usb_out_bytes);
-
-       if (USBCIF & USBCIF_RSTIF)
-               ao_usb_set_interrupts();
-}
-
-struct ao_usb_setup {
-       uint8_t         dir_type_recip;
-       uint8_t         request;
-       uint16_t        value;
-       uint16_t        index;
-       uint16_t        length;
-} __xdata ao_usb_setup;
-
-__xdata uint8_t ao_usb_ep0_state;
-uint8_t * __xdata ao_usb_ep0_in_data;
-__xdata uint8_t ao_usb_ep0_in_len;
-__xdata uint8_t        ao_usb_ep0_in_buf[2];
-__xdata uint8_t ao_usb_ep0_out_len;
-__xdata uint8_t *__data ao_usb_ep0_out_data;
-__xdata uint8_t ao_usb_configuration;
-
-/* Send an IN data packet */
-static void
-ao_usb_ep0_flush(void)
-{
-       __xdata uint8_t this_len;
-       __xdata uint8_t cs0;
-       
-       USBINDEX = 0;
-       cs0 = USBCS0;
-       if (cs0 & USBCS0_INPKT_RDY)
-               ao_panic(0);
-
-       this_len = ao_usb_ep0_in_len;
-       if (this_len > AO_USB_CONTROL_SIZE)
-               this_len = AO_USB_CONTROL_SIZE;
-       cs0 = USBCS0_INPKT_RDY;
-       if (this_len != AO_USB_CONTROL_SIZE) {
-               cs0 = USBCS0_INPKT_RDY | USBCS0_DATA_END;
-               ao_usb_ep0_state = AO_USB_EP0_IDLE;
-       }
-       ao_usb_ep0_in_len -= this_len;
-       while (this_len--)
-               USBFIFO[0] = *ao_usb_ep0_in_data++;
-       USBINDEX = 0;
-       USBCS0 = cs0;
-}
-
-__xdata static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
-
-/* Walk through the list of descriptors and find a match
- */
-static void
-ao_usb_get_descriptor(uint16_t value)
-{
-       const uint8_t           *__xdata descriptor;
-       __xdata uint8_t         type = value >> 8;
-       __xdata uint8_t         index = value;
-
-       descriptor = ao_usb_descriptors;
-       while (descriptor[0] != 0) {
-               if (descriptor[1] == type && index-- == 0) {
-                       if (type == AO_USB_DESC_CONFIGURATION)
-                               ao_usb_ep0_in_len = descriptor[2];
-                       else
-                               ao_usb_ep0_in_len = descriptor[0];
-                       ao_usb_ep0_in_data = descriptor;
-                       break;
-               }
-               descriptor += descriptor[0];
-       }
-}
-
-/* Read data from the ep0 OUT fifo
- */
-static void
-ao_usb_ep0_fill(void)
-{
-       __xdata uint8_t len;
-       
-       USBINDEX = 0;
-       len = USBCNT0;
-       if (len > ao_usb_ep0_out_len)
-               len = ao_usb_ep0_out_len;
-       ao_usb_ep0_out_len -= len;
-       while (len--)
-               *ao_usb_ep0_out_data++ = USBFIFO[0];
-}
-
-void
-ao_usb_ep0_queue_byte(uint8_t a)
-{
-       ao_usb_ep0_in_buf[ao_usb_ep0_in_len++] = a;
-}
-
-void
-ao_usb_set_address(uint8_t address)
-{
-       ao_usb_running = 1;
-       USBADDR = address | 0x80;
-       while (USBADDR & 0x80)
-               ;
-}
-
-static void
-ao_usb_set_configuration(void)
-{
-       /* Set the IN max packet size, double buffered */
-       USBINDEX = AO_USB_IN_EP;
-       USBMAXI = AO_USB_IN_SIZE >> 3;
-       USBCSIH |= USBCSIH_IN_DBL_BUF;
-
-       /* Set the OUT max packet size, double buffered */
-       USBINDEX = AO_USB_OUT_EP;
-       USBMAXO = AO_USB_OUT_SIZE >> 3;
-       USBCSOH = USBCSOH_OUT_DBL_BUF;
-}
-
-static void
-ao_usb_ep0_setup(void)
-{
-       /* Pull the setup packet out of the fifo */
-       ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_setup;
-       ao_usb_ep0_out_len = 8;
-       ao_usb_ep0_fill();
-       if (ao_usb_ep0_out_len != 0)
-               return;
-
-       /* Figure out how to ACK the setup packet */
-       if (ao_usb_setup.dir_type_recip & AO_USB_DIR_IN) {
-               if (ao_usb_setup.length)
-                       ao_usb_ep0_state = AO_USB_EP0_DATA_IN;
-               else
-                       ao_usb_ep0_state = AO_USB_EP0_IDLE;
-       } else {
-               if (ao_usb_setup.length)
-                       ao_usb_ep0_state = AO_USB_EP0_DATA_OUT;
-               else
-                       ao_usb_ep0_state = AO_USB_EP0_IDLE;
-       }
-       USBINDEX = 0;
-       if (ao_usb_ep0_state == AO_USB_EP0_IDLE)
-               USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END;
-       else
-               USBCS0 = USBCS0_CLR_OUTPKT_RDY;
-       
-       ao_usb_ep0_in_data = ao_usb_ep0_in_buf;
-       ao_usb_ep0_in_len = 0;
-       switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_TYPE_MASK) {
-       case AO_USB_TYPE_STANDARD:
-               switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_RECIP_MASK) {
-               case AO_USB_RECIP_DEVICE:
-                       switch(ao_usb_setup.request) {
-                       case AO_USB_REQ_GET_STATUS:
-                               ao_usb_ep0_queue_byte(0);
-                               ao_usb_ep0_queue_byte(0);
-                               break;
-                       case AO_USB_REQ_SET_ADDRESS:
-                               ao_usb_set_address(ao_usb_setup.value);
-                               break;
-                       case AO_USB_REQ_GET_DESCRIPTOR:
-                               ao_usb_get_descriptor(ao_usb_setup.value);
-                               break;
-                       case AO_USB_REQ_GET_CONFIGURATION:
-                               ao_usb_ep0_queue_byte(ao_usb_configuration);
-                               break;
-                       case AO_USB_REQ_SET_CONFIGURATION:
-                               ao_usb_configuration = ao_usb_setup.value;
-                               ao_usb_set_configuration();
-                               break;
-                       }
-                       break;
-               case AO_USB_RECIP_INTERFACE:
-                       #pragma disable_warning 110
-                       switch(ao_usb_setup.request) {
-                       case AO_USB_REQ_GET_STATUS:
-                               ao_usb_ep0_queue_byte(0);
-                               ao_usb_ep0_queue_byte(0);
-                               break;
-                       case AO_USB_REQ_GET_INTERFACE:
-                               ao_usb_ep0_queue_byte(0);
-                               break;
-                       case AO_USB_REQ_SET_INTERFACE:
-                               break;
-                       }
-                       break;
-               case AO_USB_RECIP_ENDPOINT:
-                       switch(ao_usb_setup.request) {
-                       case AO_USB_REQ_GET_STATUS:
-                               ao_usb_ep0_queue_byte(0);
-                               ao_usb_ep0_queue_byte(0);
-                               break;
-                       }
-                       break;
-               }
-               break;
-       case AO_USB_TYPE_CLASS:
-               switch (ao_usb_setup.request) {
-               case SET_LINE_CODING:
-                       ao_usb_ep0_out_len = 7;
-                       ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_line_coding;
-                       break;
-               case GET_LINE_CODING:
-                       ao_usb_ep0_in_len = 7;
-                       ao_usb_ep0_in_data = (uint8_t *) &ao_usb_line_coding;
-                       break;
-               case SET_CONTROL_LINE_STATE:
-                       break;
-               }
-               break;
-       }
-       if (ao_usb_ep0_state != AO_USB_EP0_DATA_OUT) {
-               if (ao_usb_setup.length < ao_usb_ep0_in_len)
-                       ao_usb_ep0_in_len = ao_usb_setup.length;
-               ao_usb_ep0_flush();
-       }
-}
-
-/* End point 0 receives all of the control messages. */
-static void
-ao_usb_ep0(void)
-{
-       __xdata uint8_t cs0;
-
-       ao_usb_ep0_state = AO_USB_EP0_IDLE;
-       for (;;) {
-               __critical for (;;) {
-                       if (ao_usb_iif & 1) {
-                               ao_usb_iif &= ~1;
-                               break;
-                       }
-                       ao_sleep(&ao_usb_task);
-               }
-               USBINDEX = 0;
-               cs0 = USBCS0;
-               if (cs0 & USBCS0_SETUP_END) {
-                       ao_usb_ep0_state = AO_USB_EP0_IDLE;
-                       USBCS0 = USBCS0_CLR_SETUP_END;
-               }
-               if (cs0 & USBCS0_SENT_STALL) {
-                       ao_usb_ep0_state = AO_USB_EP0_IDLE;
-                       USBCS0 &= ~USBCS0_SENT_STALL;
-               }
-               if (ao_usb_ep0_state == AO_USB_EP0_DATA_IN &&
-                   (cs0 & USBCS0_INPKT_RDY) == 0)
-               {
-                       ao_usb_ep0_flush();
-               }
-               if (cs0 & USBCS0_OUTPKT_RDY) {
-                       switch (ao_usb_ep0_state) {
-                       case AO_USB_EP0_IDLE:
-                               ao_usb_ep0_setup();
-                               break;
-                       case AO_USB_EP0_DATA_OUT:
-                               ao_usb_ep0_fill();
-                               if (ao_usb_ep0_out_len == 0)
-                                       ao_usb_ep0_state = AO_USB_EP0_IDLE;
-                               USBINDEX = 0;
-                               if (ao_usb_ep0_state == AO_USB_EP0_IDLE)
-                                       USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END;
-                               else
-                                       USBCS0 = USBCS0_CLR_OUTPKT_RDY;
-                               break;
-                       }
-               }
-       }
-}
-
-void
-ao_usb_flush(void) __critical
-{
-       if (ao_usb_in_bytes) {
-               USBINDEX = AO_USB_IN_EP;
-               USBCSIL |= USBCSIL_INPKT_RDY;
-               ao_usb_in_bytes = 0;
-       }
-}
-
-void
-ao_usb_putchar(char c) __critical
-{
-       if (!ao_usb_running)
-               return;
-       for (;;) {
-               USBINDEX = AO_USB_IN_EP;
-               if ((USBCSIL & USBCSIL_INPKT_RDY) == 0)
-                       break;
-               ao_sleep(&ao_usb_in_bytes);
-       }
-       USBFIFO[AO_USB_IN_EP << 1] = c;
-       if (++ao_usb_in_bytes == AO_USB_IN_SIZE) {
-               USBINDEX = AO_USB_IN_EP;
-               USBCSIL |= USBCSIL_INPKT_RDY;
-               ao_usb_in_bytes = 0;
-       }
-}
-
-char
-ao_usb_getchar(void) __critical
-{
-       __xdata char    c;
-       while (ao_usb_out_bytes == 0) {
-               for (;;) {
-                       USBINDEX = AO_USB_OUT_EP;
-                       if ((USBCSOL & USBCSOL_OUTPKT_RDY) != 0)
-                               break;
-                       ao_sleep(&ao_usb_out_bytes);
-               }
-               ao_usb_out_bytes = (USBCNTH << 8) | USBCNTL;
-       }
-       --ao_usb_out_bytes;
-       c = USBFIFO[AO_USB_OUT_EP << 1];
-       if (ao_usb_out_bytes == 0) {
-               USBINDEX = AO_USB_OUT_EP;
-               USBCSOL &= ~USBCSOL_OUTPKT_RDY;
-       }
-       return c;
-}
-
-void
-ao_usb_enable(void)
-{
-       /* Turn on the USB controller */
-       SLEEP |= SLEEP_USB_EN;
-
-       ao_usb_set_configuration();
-       
-       ao_usb_set_interrupts();
-
-       /* enable USB interrupts */
-       IEN2 |= IEN2_USBIE;
-
-       /* Clear any pending interrupts */
-       USBCIF = 0;
-       USBOIF = 0;
-       USBIIF = 0;
-}
-
-void
-ao_usb_disable(void)
-{
-       /* Disable USB interrupts */
-       USBIIE = 0;
-       USBOIE = 0;
-       USBCIE = 0;
-       IEN2 &= ~IEN2_USBIE;
-       
-       /* Clear any pending interrupts */
-       USBCIF = 0;
-       USBOIF = 0;
-       USBIIF = 0;
-
-       /* Turn off the USB controller */
-       SLEEP &= ~SLEEP_USB_EN;
-}
-
-void
-ao_usb_init(void)
-{
-       ao_usb_enable();
-
-       ao_add_task(&ao_usb_task, ao_usb_ep0, "usb");
-}
diff --git a/ao_usb.h b/ao_usb.h
deleted file mode 100644 (file)
index 6633daf..0000000
--- a/ao_usb.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright Â© 2009 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_USB_H_
-#define _AO_USB_H_
-
-#define AO_USB_SETUP_DIR_MASK  (0x01 << 7)
-#define AO_USB_SETUP_TYPE_MASK (0x03 << 5)
-#define AO_USB_SETUP_RECIP_MASK        (0x1f)
-
-#define AO_USB_DIR_OUT                 0
-#define AO_USB_DIR_IN                  (1 << 7)
-
-#define AO_USB_TYPE_STANDARD           0
-#define AO_USB_TYPE_CLASS              (1 << 5)
-#define AO_USB_TYPE_VENDOR             (2 << 5)
-#define AO_USB_TYPE_RESERVED           (3 << 5)
-
-#define AO_USB_RECIP_DEVICE            0
-#define AO_USB_RECIP_INTERFACE         1
-#define AO_USB_RECIP_ENDPOINT          2
-#define AO_USB_RECIP_OTHER             3
-
-/* standard requests */
-#define        AO_USB_REQ_GET_STATUS           0x00
-#define AO_USB_REQ_CLEAR_FEATURE       0x01
-#define AO_USB_REQ_SET_FEATURE         0x03
-#define AO_USB_REQ_SET_ADDRESS         0x05
-#define AO_USB_REQ_GET_DESCRIPTOR      0x06
-#define AO_USB_REQ_SET_DESCRIPTOR      0x07
-#define AO_USB_REQ_GET_CONFIGURATION   0x08
-#define AO_USB_REQ_SET_CONFIGURATION   0x09
-#define AO_USB_REQ_GET_INTERFACE       0x0A
-#define AO_USB_REQ_SET_INTERFACE       0x0B
-#define AO_USB_REQ_SYNCH_FRAME         0x0C
-
-#define AO_USB_DESC_DEVICE             1
-#define AO_USB_DESC_CONFIGURATION      2
-#define AO_USB_DESC_STRING             3
-#define AO_USB_DESC_INTERFACE          4
-#define AO_USB_DESC_ENDPOINT           5
-#define AO_USB_DESC_DEVICE_QUALIFIER   6
-#define AO_USB_DESC_OTHER_SPEED                7
-#define AO_USB_DESC_INTERFACE_POWER    8
-
-#define AO_USB_GET_DESC_TYPE(x)                (((x)>>8)&0xFF)
-#define AO_USB_GET_DESC_INDEX(x)       ((x)&0xFF)
-
-#define AO_USB_CONTROL_EP      0
-#define AO_USB_INT_EP          1
-#define AO_USB_OUT_EP          4
-#define AO_USB_IN_EP           5
-#define AO_USB_CONTROL_SIZE    32
-/*
- * Double buffer IN and OUT EPs, so each
- * gets half of the available space
- *
- * Ah, but USB bulk packets can only come in 8, 16, 32 and 64
- * byte sizes, so we'll use 64 for everything
- */
-#define AO_USB_IN_SIZE         64
-#define AO_USB_OUT_SIZE                64
-
-#define AO_USB_EP0_IDLE                0
-#define AO_USB_EP0_DATA_IN     1
-#define AO_USB_EP0_DATA_OUT    2
-
-#define LE_WORD(x)    ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8))
-
-/* CDC definitions */
-#define CS_INTERFACE      0x24
-#define CS_ENDPOINT       0x25
-
-#define SET_LINE_CODING         0x20
-#define GET_LINE_CODING         0x21
-#define SET_CONTROL_LINE_STATE  0x22
-
-/* Data structure for GET_LINE_CODING / SET_LINE_CODING class requests */
-struct ao_usb_line_coding {
-       uint32_t        rate;
-       uint8_t         char_format;
-       uint8_t         parity;
-       uint8_t         data_bits;
-} ;
-
-#endif /* _AO_USB_H_ */
diff --git a/aoview/Makefile b/aoview/Makefile
deleted file mode 100644 (file)
index 6bf789b..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-VERSION=$(shell git describe)
-MODULES=gtk+-2.0 libglade-2.0 gconf-2.0
-INCLUDES=$(shell pkg-config --cflags $(MODULES)) -I..
-WARN= -Wall -Wpointer-arith -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -fno-strict-aliasing
-CFLAGS=$(INCLUDES) -O0 -g $(WARN) -DAOVIEW_VERSION='"$(VERSION)"'
-LIBS=$(shell pkg-config --libs $(MODULES)) -lm
-
-BIN=/usr/local/bin
-
-SRC = \
-       aoview_main.c \
-       aoview_dev.c \
-       aoview_dev_dialog.c \
-       aoview_serial.c \
-       aoview_monitor.c \
-       aoview_state.c \
-       aoview_convert.c \
-       aoview_log.c \
-       aoview_table.c \
-       aoview_util.c \
-       aoview_file.c \
-       aoview_eeprom.c
-
-INC = \
-       aoview.h
-
-OBJ = \
-       $(SRC:.c=.o)
-
-PROG = aoview
-
-$(PROG): $(OBJ)
-       $(CC) $(CFLAGS) -o $@ $(OBJ) $(LIBS)
-
-$(OBJ): $(INC)
-
-aoview_main.o: aoview_glade.h
-
-clean:
-       rm -f $(OBJ) $(PROG)
-
-install: $(BIN)/aoview
-
-$(BIN)/aoview: aoview
-       install aoview $(BIN)
-
-aoview_glade.h: aoview.glade
-       sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/"/' $< > $@
diff --git a/aoview/Makefile.am b/aoview/Makefile.am
new file mode 100644 (file)
index 0000000..9f67ac4
--- /dev/null
@@ -0,0 +1,28 @@
+VERSION=$(shell git describe)
+AM_CFLAGS=$(AOVIEW_CFLAGS) -I$(top_srcdir)/src -DAOVIEW_VERSION=\"$(VERSION)\"
+
+bin_PROGRAMS=aoview
+
+aoview_LDADD=$(AOVIEW_LIBS)
+
+aoview_SOURCES = \
+       aoview_main.c \
+       aoview_dev.c \
+       aoview_dev_dialog.c \
+       aoview_serial.c \
+       aoview_monitor.c \
+       aoview_state.c \
+       aoview_convert.c \
+       aoview_log.c \
+       aoview_table.c \
+       aoview_util.c \
+       aoview_file.c \
+       aoview_eeprom.c \
+       aoview.h
+
+BUILT_SOURCES = aoview_glade.h
+
+CLEANFILES = aoview_glade.h
+
+aoview_glade.h: aoview.glade
+       sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/"/' $< > $@
index a4bf813d479e3cc0105c44b96c0282046fba07d1..02416647ed6ae4f13815f3992f67bf6429b58ec6 100644 (file)
@@ -18,7 +18,7 @@
 #include "aoview.h"
 
 static int16_t altitude_table[2048] = {
-#include "../altitude.h"
+#include "altitude.h"
 };
 
 int16_t
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..4e8b11b
--- /dev/null
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf --force -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+$srcdir/configure --enable-maintainer-mode "$@"
diff --git a/cc1111.h b/cc1111.h
deleted file mode 100644 (file)
index 4e45146..0000000
--- a/cc1111.h
+++ /dev/null
@@ -1,1214 +0,0 @@
-/*-------------------------------------------------------------------------
-   Register Declarations for the ChipCon CC1111 Processor Range
-
-   Copyright Â© 2008 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.
-
-   Adapted from the Cygnal C8051F12x config file which is:
-   Copyright (C) 2003 - Maarten Brock, sourceforge.brock@dse.nl
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
--------------------------------------------------------------------------*/
-
-#ifndef _CC1111_H_
-#define _CC1111_H_
-#include <cc1110.h>
-#include <stdint.h>
-
-sfr at 0xA8 IEN0;              /* Interrupt Enable 0 Register */
-
-sbit at 0xA8 RFTXRXIE;         /* RF TX/RX done interrupt enable */
-sbit at 0xA9 ADCIE;            /* ADC interrupt enable */
-sbit at 0xAA URX0IE;           /* USART0 RX interrupt enable */
-sbit at 0xAB URX1IE;           /* USART1 RX interrupt enable (shared with I2S RX) */
-sbit at 0xAB I2SRXIE;          /* I2S RX interrupt enable (shared with USART1 RX) */
-sbit at 0xAC ENCIE;            /* AES encryption/decryption interrupt enable */
-sbit at 0xAD STIE;             /* Sleep Timer interrupt enable */
-sbit at 0xAF EA;               /* Enable All */
-
-#define IEN0_EA                        (1 << 7)
-#define IEN0_STIE              (1 << 5)
-#define IEN0_ENCIE             (1 << 4)
-#define IEN0_URX1IE            (1 << 3)
-#define IEN0_I2SRXIE           (1 << 3)
-#define IEN0_URX0IE            (1 << 2)
-#define IEN0_ADCIE             (1 << 1)
-#define IEN0_RFTXRXIE          (1 << 0)
-
-sfr at 0xB8 IEN1;              /* Interrupt Enable 1 Register */
-
-#define IEN1_P0IE              (1 << 5)        /* Port 0 interrupt enable */
-#define IEN1_T4IE              (1 << 4)        /* Timer 4 interrupt enable */
-#define IEN1_T3IE              (1 << 3)        /* Timer 3 interrupt enable */
-#define IEN1_T2IE              (1 << 2)        /* Timer 2 interrupt enable */
-#define IEN1_T1IE              (1 << 1)        /* Timer 1 interrupt enable */
-#define IEN1_DMAIE             (1 << 0)        /* DMA transfer interrupt enable */
-
-/* IEN2 */
-sfr at 0x9A IEN2;              /* Interrupt Enable 2 Register */
-
-#define IEN2_WDTIE             (1 << 5)        /* Watchdog timer interrupt enable */
-#define IEN2_P1IE              (1 << 4)        /* Port 1 interrupt enable */
-#define IEN2_UTX1IE            (1 << 3)        /* USART1 TX interrupt enable */
-#define IEN2_I2STXIE           (1 << 3)        /* I2S TX interrupt enable */
-#define IEN2_UTX0IE            (1 << 2)        /* USART0 TX interrupt enable */
-#define IEN2_P2IE              (1 << 1)        /* Port 2 interrupt enable */
-#define IEN2_USBIE             (1 << 1)        /* USB interrupt enable */
-#define IEN2_RFIE              (1 << 0)        /* RF general interrupt enable */
-
-/* SLEEP 0xBE */
-#define SLEEP_USB_EN           (1 << 7)
-#define SLEEP_XOSC_STB         (1 << 6)
-#define SLEEP_HFRC_STB         (1 << 5)
-#define SLEEP_RST_POWER                (0 << 3)
-#define SLEEP_RST_EXTERNAL     (1 << 3)
-#define SLEEP_RST_WATCHDOG     (2 << 3)
-#define SLEEP_RST_MASK         (3 << 3)
-#define SLEEP_OSC_PD           (1 << 2)
-#define SLEEP_MODE_PM0         (0 << 0)
-#define SLEEP_MODE_PM1         (1 << 0)
-#define SLEEP_MODE_PM2         (2 << 0)
-#define SLEEP_MODE_PM3         (3 << 0)
-#define SLEEP_MODE_MASK                (3 << 0)
-
-/* PCON 0x87 */
-sfr at 0x87 PCON;              /* Power Mode Control Register */
-
-#define PCON_IDLE              (1 << 0)
-
-/*
- * TCON
- */
-sfr at 0x88 TCON;      /* CPU Interrupt Flag 1 */
-
-sbit at 0x8F URX1IF;   /* USART1 RX interrupt flag. Automatically cleared */
-sbit at 0x8F I2SRXIF;  /* I2S RX interrupt flag. Automatically cleared */
-sbit at 0x8D ADCIF;    /* ADC interrupt flag. Automatically cleared */
-sbit at 0x8B URX0IF;   /* USART0 RX interrupt flag. Automatically cleared */
-sbit at 0x89 RFTXRXIF; /* RF TX/RX complete interrupt flag. Automatically cleared */
-
-#define TCON_URX1IF    (1 << 7)
-#define TCON_I2SRXIF   (1 << 7)
-#define TCON_ADCIF     (1 << 5)
-#define TCON_URX0IF    (1 << 3)
-#define TCON_RFTXRXIF  (1 << 1)
-
-/*
- * S0CON
- */
-sfr at 0x98 S0CON;     /* CPU Interrupt Flag 2 */
-
-sbit at 0x98 ENCIF_0;  /* AES interrupt 0. */
-sbit at 0x99 ENCIF_1;  /* AES interrupt 1. */
-
-#define S0CON_ENCIF_1  (1 << 1)
-#define S0CON_ENCIF_0  (1 << 0)
-
-/* 
- * S1CON
- */
-sfr at 0x9B S1CON;     /* CPU Interrupt Flag 3 */
-
-#define S1CON_RFIF_1   (1 << 1)
-#define S1CON_RFIF_0   (1 << 0)
-
-/*
- * IRCON
- */
-sfr at 0xC0 IRCON;     /* CPU Interrupt Flag 4 */
-
-sbit at 0xC0 DMAIF;    /* DMA complete interrupt flag */
-sbit at 0xC1 T1IF;     /* Timer 1 interrupt flag. Automatically cleared */
-sbit at 0xC2 T2IF;     /* Timer 2 interrupt flag. Automatically cleared */
-sbit at 0xC3 T3IF;     /* Timer 3 interrupt flag. Automatically cleared */
-sbit at 0xC4 T4IF;     /* Timer 4 interrupt flag. Automatically cleared */
-sbit at 0xC5 P0IF;     /* Port0 interrupt flag */
-sbit at 0xC7 STIF;     /* Sleep Timer interrupt flag */
-
-#define IRCON_DMAIF    (1 << 0)        /* DMA complete interrupt flag */
-#define IRCON_T1IF     (1 << 1)        /* Timer 1 interrupt flag. Automatically cleared */
-#define IRCON_T2IF     (1 << 2)        /* Timer 2 interrupt flag. Automatically cleared */
-#define IRCON_T3IF     (1 << 3)        /* Timer 3 interrupt flag. Automatically cleared */
-#define IRCON_T4IF     (1 << 4)        /* Timer 4 interrupt flag. Automatically cleared */
-#define IRCON_P0IF     (1 << 5)        /* Port0 interrupt flag */
-#define IRCON_STIF     (1 << 7)        /* Sleep Timer interrupt flag */
-
-/*
- * IRCON2
- */
-sfr at 0xE8 IRCON2;    /* CPU Interrupt Flag 5 */
-
-sbit at 0xE8 USBIF;    /* USB interrupt flag (shared with Port2) */
-sbit at 0xE8 P2IF;     /* Port2 interrupt flag (shared with USB) */
-sbit at 0xE9 UTX0IF;   /* USART0 TX interrupt flag */
-sbit at 0xEA UTX1IF;   /* USART1 TX interrupt flag (shared with I2S TX) */
-sbit at 0xEA I2STXIF;  /* I2S TX interrupt flag (shared with USART1 TX) */
-sbit at 0xEB P1IF;     /* Port1 interrupt flag */
-sbit at 0xEC WDTIF;    /* Watchdog timer interrupt flag */
-
-#define IRCON2_USBIF   (1 << 0)        /* USB interrupt flag (shared with Port2) */
-#define IRCON2_P2IF    (1 << 0)        /* Port2 interrupt flag (shared with USB) */
-#define IRCON2_UTX0IF  (1 << 1)        /* USART0 TX interrupt flag */
-#define IRCON2_UTX1IF  (1 << 2)        /* USART1 TX interrupt flag (shared with I2S TX) */
-#define IRCON2_I2STXIF (1 << 2)        /* I2S TX interrupt flag (shared with USART1 TX) */
-#define IRCON2_P1IF    (1 << 3)        /* Port1 interrupt flag */
-#define IRCON2_WDTIF   (1 << 4)        /* Watchdog timer interrupt flag */
-
-/*
- * IP1 - Interrupt Priority 1
- */
-
-/*
- * Interrupt priority groups:
- *
- * IPG0                RFTXRX          RF              DMA
- * IPG1                ADC             T1              P2INT/USB
- * IPG2                URX0            T2              UTX0
- * IPG3                URX1/I2SRX      T3              UTX1 / I2STX
- * IPG4                ENC             T4              P1INT
- * IPG5                ST              P0INT           WDT
- *
- * Priority = (IP1 << 1) | IP0. Higher priority interrupts served first
- */
-
-sfr at 0xB9 IP1;       /* Interrupt Priority 1 */
-sfr at 0xA9 IP0;       /* Interrupt Priority 0 */
-
-#define IP1_IPG5       (1 << 5)
-#define IP1_IPG4       (1 << 4)
-#define IP1_IPG3       (1 << 3)
-#define IP1_IPG2       (1 << 2)
-#define IP1_IPG1       (1 << 1)
-#define IP1_IPG0       (1 << 0)
-
-#define IP0_IPG5       (1 << 5)
-#define IP0_IPG4       (1 << 4)
-#define IP0_IPG3       (1 << 3)
-#define IP0_IPG2       (1 << 2)
-#define IP0_IPG1       (1 << 1)
-#define IP0_IPG0       (1 << 0)
-
-/*
- * Timer 1
- */
-#define T1CTL_MODE_SUSPENDED   (0 << 0)
-#define T1CTL_MODE_FREE                (1 << 0)
-#define T1CTL_MODE_MODULO      (2 << 0)
-#define T1CTL_MODE_UP_DOWN     (3 << 0)
-#define T1CTL_MODE_MASK                (3 << 0)
-#define T1CTL_DIV_1            (0 << 2)
-#define T1CTL_DIV_8            (1 << 2)
-#define T1CTL_DIV_32           (2 << 2)
-#define T1CTL_DIV_128          (3 << 2)
-#define T1CTL_DIV_MASK         (3 << 2)
-#define T1CTL_OVFIF            (1 << 4)
-#define T1CTL_CH0IF            (1 << 5)
-#define T1CTL_CH1IF            (1 << 6)
-#define T1CTL_CH2IF            (1 << 7)
-
-#define T1CCTL_NO_CAPTURE      (0 << 0)
-#define T1CCTL_CAPTURE_RISING  (1 << 0)
-#define T1CCTL_CAPTURE_FALLING (2 << 0)
-#define T1CCTL_CAPTURE_BOTH    (3 << 0)
-#define T1CCTL_CAPTURE_MASK    (3 << 0)
-
-#define T1CCTL_MODE_CAPTURE    (0 << 2)
-#define T1CCTL_MODE_COMPARE    (1 << 2)
-
-#define T1CTL_CMP_SET          (0 << 3)
-#define T1CTL_CMP_CLEAR                (1 << 3)
-#define T1CTL_CMP_TOGGLE       (2 << 3)
-#define T1CTL_CMP_SET_CLEAR    (3 << 3)
-#define T1CTL_CMP_CLEAR_SET    (4 << 3)
-
-#define T1CTL_IM_DISABLED      (0 << 6)
-#define T1CTL_IM_ENABLED       (1 << 6)
-
-#define T1CTL_CPSEL_NORMAL     (0 << 7)
-#define T1CTL_CPSEL_RF         (1 << 7)
-
-/*
- * Timer 3 and Timer 4
- */
-
-/* Timer count */
-sfr at 0xCA T3CNT;
-sfr at 0xEA T4CNT;
-
-/* Timer control */
-sfr at 0xCB T3CTL;
-sfr at 0xEB T4CTL;
-
-#define TxCTL_DIV_1            (0 << 5)
-#define TxCTL_DIV_2            (1 << 5)
-#define TxCTL_DIV_4            (2 << 5)
-#define TxCTL_DIV_8            (3 << 5)
-#define TxCTL_DIV_16           (4 << 5)
-#define TxCTL_DIV_32           (5 << 5)
-#define TxCTL_DIV_64           (6 << 5)
-#define TxCTL_DIV_128          (7 << 5)
-#define TxCTL_START            (1 << 4)
-#define TxCTL_OVFIM            (1 << 3)
-#define TxCTL_CLR              (1 << 2)
-#define TxCTL_MODE_FREE                (0 << 0)
-#define TxCTL_MODE_DOWN                (1 << 0)
-#define TxCTL_MODE_MODULO      (2 << 0)
-#define TxCTL_MODE_UP_DOWN     (3 << 0)
-
-/* Timer 4 channel 0 compare control */
-
-sfr at 0xCC T3CCTL0;
-sfr at 0xCE T3CCTL1;
-sfr at 0xEC T4CCTL0;
-sfr at 0xEE T4CCTL1;
-
-#define TxCCTLy_IM                     (1 << 6)
-#define TxCCTLy_CMP_SET                        (0 << 3)
-#define TxCCTLy_CMP_CLEAR              (1 << 3)
-#define TxCCTLy_CMP_TOGGLE             (2 << 3)
-#define TxCCTLy_CMP_SET_UP_CLEAR_DOWN  (3 << 3)
-#define TxCCTLy_CMP_CLEAR_UP_SET_DOWN  (4 << 3)
-#define TxCCTLy_CMP_SET_CLEAR_FF       (5 << 3)
-#define TxCCTLy_CMP_CLEAR_SET_00       (6 << 3)
-#define TxCCTLy_CMP_MODE_ENABLE                (1 << 2)
-
-/* Timer compare value */
-sfr at 0xCD T3CC0;
-sfr at 0xCF T3CC1;
-sfr at 0xED T4CC0;
-sfr at 0xEF T4CC1;
-
-/*
- * Peripheral control
- */
-
-sfr at 0xf1 PERCFG;
-#define PERCFG_T1CFG_ALT_1      (0 << 6)
-#define PERCFG_T1CFG_ALT_2      (1 << 6)
-#define PERCFG_T1CFG_ALT_MASK   (1 << 6)
-
-#define PERCFG_T3CFG_ALT_1      (0 << 5)
-#define PERCFG_T3CFG_ALT_2      (1 << 5)
-#define PERCFG_T3CFG_ALT_MASK   (1 << 5)
-
-#define PERCFG_T4CFG_ALT_1      (0 << 4)
-#define PERCFG_T4CFG_ALT_2      (1 << 4)
-#define PERCFG_T4CFG_ALT_MASK   (1 << 4)
-
-#define PERCFG_U1CFG_ALT_1      (0 << 1)
-#define PERCFG_U1CFG_ALT_2      (1 << 1)
-#define PERCFG_U1CFG_ALT_MASK   (1 << 1)
-
-#define PERCFG_U0CFG_ALT_1      (0 << 0)
-#define PERCFG_U0CFG_ALT_2      (1 << 0)
-#define PERCFG_U0CFG_ALT_MASK   (1 << 0)
-
-/* directly addressed USB registers */
-__xdata __at (0xde00) volatile uint8_t USBADDR;
-__xdata __at (0xde01) volatile uint8_t USBPOW;
-__xdata __at (0xde02) volatile uint8_t USBIIF;
-
-__xdata __at (0xde04) volatile uint8_t USBOIF;
-
-__xdata __at (0xde06) volatile uint8_t USBCIF;
-
-# define USBCIF_SOFIF          (1 << 3)
-# define USBCIF_RSTIF          (1 << 2)
-# define USBCIF_RESUMEIF       (1 << 1)
-# define USBCIF_SUSPENDIF      (1 << 0)
-
-__xdata __at (0xde07) volatile uint8_t USBIIE;
-
-__xdata __at (0xde09) volatile uint8_t USBOIE;
-
-__xdata __at (0xde0b) volatile uint8_t USBCIE;
-
-# define USBCIE_SOFIE          (1 << 3)
-# define USBCIE_RSTIE          (1 << 2)
-# define USBCIE_RESUMEIE       (1 << 1)
-# define USBCIE_SUSPENDIE      (1 << 0)
-
-__xdata __at (0xde0c) volatile uint8_t USBFRML;
-__xdata __at (0xde0d) volatile uint8_t USBFRMH;
-__xdata __at (0xde0e) volatile uint8_t USBINDEX;
-
-/* indexed USB registers, must set USBINDEX to 0-5 */
-__xdata __at (0xde10) volatile uint8_t USBMAXI;
-__xdata __at (0xde11) volatile uint8_t USBCS0;
-
-# define USBCS0_CLR_SETUP_END          (1 << 7)
-# define USBCS0_CLR_OUTPKT_RDY         (1 << 6)
-# define USBCS0_SEND_STALL             (1 << 5)
-# define USBCS0_SETUP_END              (1 << 4)
-# define USBCS0_DATA_END               (1 << 3)
-# define USBCS0_SENT_STALL             (1 << 2)
-# define USBCS0_INPKT_RDY              (1 << 1)
-# define USBCS0_OUTPKT_RDY             (1 << 0)
-
-__xdata __at (0xde11) volatile uint8_t USBCSIL;
-
-# define USBCSIL_CLR_DATA_TOG          (1 << 6)
-# define USBCSIL_SENT_STALL            (1 << 5)
-# define USBCSIL_SEND_STALL            (1 << 4)
-# define USBCSIL_FLUSH_PACKET          (1 << 3)
-# define USBCSIL_UNDERRUN              (1 << 2)
-# define USBCSIL_PKT_PRESENT           (1 << 1)
-# define USBCSIL_INPKT_RDY             (1 << 0)
-
-__xdata __at (0xde12) volatile uint8_t USBCSIH;
-
-# define USBCSIH_AUTOSET               (1 << 7)
-# define USBCSIH_ISO                   (1 << 6)
-# define USBCSIH_FORCE_DATA_TOG                (1 << 3)
-# define USBCSIH_IN_DBL_BUF            (1 << 0)
-
-__xdata __at (0xde13) volatile uint8_t USBMAXO;
-__xdata __at (0xde14) volatile uint8_t USBCSOL;
-
-# define USBCSOL_CLR_DATA_TOG          (1 << 7)
-# define USBCSOL_SENT_STALL            (1 << 6)
-# define USBCSOL_SEND_STALL            (1 << 5)
-# define USBCSOL_FLUSH_PACKET          (1 << 4)
-# define USBCSOL_DATA_ERROR            (1 << 3)
-# define USBCSOL_OVERRUN               (1 << 2)
-# define USBCSOL_FIFO_FULL             (1 << 1)
-# define USBCSOL_OUTPKT_RDY            (1 << 0)
-
-__xdata __at (0xde15) volatile uint8_t USBCSOH;
-
-# define USBCSOH_AUTOCLEAR             (1 << 7)
-# define USBCSOH_ISO                   (1 << 6)
-# define USBCSOH_OUT_DBL_BUF           (1 << 0)
-
-__xdata __at (0xde16) volatile uint8_t USBCNT0;
-__xdata __at (0xde16) volatile uint8_t USBCNTL;
-__xdata __at (0xde17) volatile uint8_t USBCNTH;
-
-__xdata __at (0xde20) volatile uint8_t USBFIFO[12];
-
-/* ADC Data register, low and high */
-sfr at 0xBA ADCL;
-sfr at 0xBB ADCH;
-__xdata __at (0xDFBA) volatile uint16_t ADCXDATA;
-
-/* ADC Control Register 1 */
-sfr at 0xB4 ADCCON1;
-
-# define ADCCON1_EOC           (1 << 7)        /* conversion complete */
-# define ADCCON1_ST            (1 << 6)        /* start conversion */
-
-# define ADCCON1_STSEL_MASK    (3 << 4)        /* start select */
-# define ADCCON1_STSEL_EXTERNAL        (0 << 4)        /* P2_0 pin triggers */
-# define ADCCON1_STSEL_FULLSPEED (1 << 4)      /* full speed, no waiting */
-# define ADCCON1_STSEL_TIMER1  (2 << 4)        /* timer 1 channel 0 */
-# define ADCCON1_STSEL_START   (3 << 4)        /* set start bit */
-
-# define ADCCON1_RCTRL_MASK    (3 << 2)        /* random number control */
-# define ADCCON1_RCTRL_COMPLETE        (0 << 2)        /* operation completed */
-# define ADCCON1_RCTRL_CLOCK_LFSR (1 << 2)     /* Clock the LFSR once */
-
-/* ADC Control Register 2 */
-sfr at 0xB5 ADCCON2;
-
-# define ADCCON2_SREF_MASK     (3 << 6)        /* reference voltage */
-# define ADCCON2_SREF_1_25V    (0 << 6)        /* internal 1.25V */
-# define ADCCON2_SREF_EXTERNAL (1 << 6)        /* external on AIN7 cc1110 */
-# define ADCCON2_SREF_VDD      (2 << 6)        /* VDD on the AVDD pin */
-# define ADCCON2_SREF_EXTERNAL_DIFF (3 << 6)   /* external on AIN6-7 cc1110 */
-
-# define ADCCON2_SDIV_MASK     (3 << 4)        /* decimation rate */
-# define ADCCON2_SDIV_64       (0 << 4)        /* 7 bits */
-# define ADCCON2_SDIV_128      (1 << 4)        /* 9 bits */
-# define ADCCON2_SDIV_256      (2 << 4)        /* 10 bits */
-# define ADCCON2_SDIV_512      (3 << 4)        /* 12 bits */
-
-# define ADCCON2_SCH_MASK      (0xf << 0)      /* Sequence channel select */
-# define ADCCON2_SCH_SHIFT     0
-# define ADCCON2_SCH_AIN0      (0 << 0)
-# define ADCCON2_SCH_AIN1      (1 << 0)
-# define ADCCON2_SCH_AIN2      (2 << 0)
-# define ADCCON2_SCH_AIN3      (3 << 0)
-# define ADCCON2_SCH_AIN4      (4 << 0)
-# define ADCCON2_SCH_AIN5      (5 << 0)
-# define ADCCON2_SCH_AIN6      (6 << 0)
-# define ADCCON2_SCH_AIN7      (7 << 0)
-# define ADCCON2_SCH_AIN0_AIN1 (8 << 0)
-# define ADCCON2_SCH_AIN2_AIN3 (9 << 0)
-# define ADCCON2_SCH_AIN4_AIN5 (0xa << 0)
-# define ADCCON2_SCH_AIN6_AIN7 (0xb << 0)
-# define ADCCON2_SCH_GND       (0xc << 0)
-# define ADCCON2_SCH_VREF      (0xd << 0)
-# define ADCCON2_SCH_TEMP      (0xe << 0)
-# define ADCCON2_SCH_VDD_3     (0xf << 0)
-
-
-/* ADC Control Register 3 */
-sfr at 0xB6 ADCCON3;
-
-# define ADCCON3_EREF_MASK     (3 << 6)        /* extra conversion reference */
-# define ADCCON3_EREF_1_25     (0 << 6)        /* internal 1.25V */
-# define ADCCON3_EREF_EXTERNAL (1 << 6)        /* external AIN7 cc1110 */
-# define ADCCON3_EREF_VDD      (2 << 6)        /* VDD on the AVDD pin */
-# define ADCCON3_EREF_EXTERNAL_DIFF (3 << 6)   /* external AIN6-7 cc1110 */
-# define ADCCON3_EDIV_MASK     (3 << 4)        /* extral decimation */
-# define ADCCON3_EDIV_64       (0 << 4)        /* 7 bits */
-# define ADCCON3_EDIV_128      (1 << 4)        /* 9 bits */
-# define ADCCON3_EDIV_256      (2 << 4)        /* 10 bits */
-# define ADCCON3_EDIV_512      (3 << 4)        /* 12 bits */
-# define ADCCON3_ECH_MASK      (0xf << 0)      /* Sequence channel select */
-# define ADCCON3_ECH_SHIFT     0
-# define ADCCON3_ECH_AIN0      (0 << 0)
-# define ADCCON3_ECH_AIN1      (1 << 0)
-# define ADCCON3_ECH_AIN2      (2 << 0)
-# define ADCCON3_ECH_AIN3      (3 << 0)
-# define ADCCON3_ECH_AIN4      (4 << 0)
-# define ADCCON3_ECH_AIN5      (5 << 0)
-# define ADCCON3_ECH_AIN6      (6 << 0)
-# define ADCCON3_ECH_AIN7      (7 << 0)
-# define ADCCON3_ECH_AIN0_AIN1 (8 << 0)
-# define ADCCON3_ECH_AIN2_AIN3 (9 << 0)
-# define ADCCON3_ECH_AIN4_AIN5 (0xa << 0)
-# define ADCCON3_ECH_AIN6_AIN7 (0xb << 0)
-# define ADCCON3_ECH_GND       (0xc << 0)
-# define ADCCON3_ECH_VREF      (0xd << 0)
-# define ADCCON3_ECH_TEMP      (0xe << 0)
-# define ADCCON3_ECH_VDD_3     (0xf << 0)
-
-/*
- * ADC configuration register, this selects which
- * GPIO pins are to be used as ADC inputs
- */
-sfr at 0xF2 ADCCFG;
-
-/*
- * Pin selectors, these set which pins are
- * using their peripheral function
- */
-sfr at 0xF3 P0SEL;
-sfr at 0xF4 P1SEL;
-sfr at 0xF5 P2SEL;
-
-#define P2SEL_PRI3P1_USART0            (0 << 6)
-#define P2SEL_PRI3P1_USART1            (1 << 6)
-#define P2SEL_PRI3P1_MASK              (1 << 6)
-#define P2SEL_PRI2P1_USART1            (0 << 5)
-#define P2SEL_PRI2P1_TIMER3            (1 << 5)
-#define P2SEL_PRI1P1_TIMER1            (0 << 4)
-#define P2SEL_PRI1P1_TIMER4            (1 << 4)
-#define P2SEL_PRI0P1_USART0            (0 << 3)
-#define P2SEL_PRI0P1_TIMER1            (1 << 3)
-#define P2SEL_SELP2_4_GPIO             (0 << 2)
-#define P2SEL_SELP2_4_PERIPHERAL       (1 << 2)
-#define P2SEL_SELP2_3_GPIO             (0 << 1)
-#define P2SEL_SELP2_3_PERIPHERAL       (1 << 1)
-#define P2SEL_SELP2_0_GPIO             (0 << 0)
-#define P2SEL_SELP2_0_PERIPHERAL       (1 << 0)
-#define P2SEL_SELP2_0_MASK             (1 << 0)
-
-/*
- * For pins used as GPIOs, these set which are used as outputs
- */
-sfr at 0xFD P0DIR;
-sfr at 0xFE P1DIR;
-sfr at 0xFF P2DIR;
-
-sfr at 0x8F P0INP;
-
-/* Select between tri-state and pull up/down
- * for pins P0_0 - P0_7.
- */
-#define P0INP_MDP0_7_PULL      (0 << 7)
-#define P0INP_MDP0_7_TRISTATE  (1 << 7)
-#define P0INP_MDP0_6_PULL      (0 << 6)
-#define P0INP_MDP0_6_TRISTATE  (1 << 6)
-#define P0INP_MDP0_5_PULL      (0 << 5)
-#define P0INP_MDP0_5_TRISTATE  (1 << 5)
-#define P0INP_MDP0_4_PULL      (0 << 4)
-#define P0INP_MDP0_4_TRISTATE  (1 << 4)
-#define P0INP_MDP0_3_PULL      (0 << 3)
-#define P0INP_MDP0_3_TRISTATE  (1 << 3)
-#define P0INP_MDP0_2_PULL      (0 << 2)
-#define P0INP_MDP0_2_TRISTATE  (1 << 2)
-#define P0INP_MDP0_1_PULL      (0 << 1)
-#define P0INP_MDP0_1_TRISTATE  (1 << 1)
-#define P0INP_MDP0_0_PULL      (0 << 0)
-#define P0INP_MDP0_0_TRISTATE  (1 << 0)
-
-sfr at 0xF6 P1INP;
-
-/* Select between tri-state and pull up/down
- * for pins P1_2 - P1_7. Pins P1_0 and P1_1 are
- * always tri-stated
- */
-#define P1INP_MDP1_7_PULL      (0 << 7)
-#define P1INP_MDP1_7_TRISTATE  (1 << 7)
-#define P1INP_MDP1_6_PULL      (0 << 6)
-#define P1INP_MDP1_6_TRISTATE  (1 << 6)
-#define P1INP_MDP1_5_PULL      (0 << 5)
-#define P1INP_MDP1_5_TRISTATE  (1 << 5)
-#define P1INP_MDP1_4_PULL      (0 << 4)
-#define P1INP_MDP1_4_TRISTATE  (1 << 4)
-#define P1INP_MDP1_3_PULL      (0 << 3)
-#define P1INP_MDP1_3_TRISTATE  (1 << 3)
-#define P1INP_MDP1_2_PULL      (0 << 2)
-#define P1INP_MDP1_2_TRISTATE  (1 << 2)
-
-sfr at 0xF7 P2INP;
-/* P2INP has three extra bits which are used to choose
- * between pull-up and pull-down when they are not tri-stated
- */
-#define P2INP_PDUP2_PULL_UP    (0 << 7)
-#define P2INP_PDUP2_PULL_DOWN  (1 << 7)
-#define P2INP_PDUP1_PULL_UP    (0 << 6)
-#define P2INP_PDUP1_PULL_DOWN  (1 << 6)
-#define P2INP_PDUP0_PULL_UP    (0 << 5)
-#define P2INP_PDUP0_PULL_DOWN  (1 << 5)
-
-/* For the P2 pins, choose between tri-state and pull up/down
- * mode
- */
-#define P2INP_MDP2_4_PULL      (0 << 4)
-#define P2INP_MDP2_4_TRISTATE  (1 << 4)
-#define P2INP_MDP2_3_PULL      (0 << 3)
-#define P2INP_MDP2_3_TRISTATE  (1 << 3)
-#define P2INP_MDP2_2_PULL      (0 << 2)
-#define P2INP_MDP2_2_TRISTATE  (1 << 2)
-#define P2INP_MDP2_1_PULL      (0 << 1)
-#define P2INP_MDP2_1_TRISTATE  (1 << 1)
-#define P2INP_MDP2_0_PULL      (0 << 0)
-#define P2INP_MDP2_0_TRISTATE  (1 << 0)
-
-/* GPIO interrupt status flags */
-sfr at 0x89 P0IFG;
-sfr at 0x8A P1IFG;
-sfr at 0x8B P2IFG;
-
-#define P0IFG_USB_RESUME       (1 << 7)
-
-/* GPIO pins */
-sfr at 0x80 P0;
-
-sbit at 0x80 P0_0;
-sbit at 0x81 P0_1;
-sbit at 0x82 P0_2;
-sbit at 0x83 P0_3;
-sbit at 0x84 P0_4;
-sbit at 0x85 P0_5;
-sbit at 0x86 P0_6;
-sbit at 0x87 P0_7;
-
-sfr at 0x90 P1;
-
-sbit at 0x90 P1_0;
-sbit at 0x91 P1_1;
-sbit at 0x92 P1_2;
-sbit at 0x93 P1_3;
-sbit at 0x94 P1_4;
-sbit at 0x95 P1_5;
-sbit at 0x96 P1_6;
-sbit at 0x97 P1_7;
-
-sfr at 0xa0 P2;
-
-sbit at 0xa0 P2_0;
-sbit at 0xa1 P2_1;
-sbit at 0xa2 P2_2;
-sbit at 0xa3 P2_3;
-sbit at 0xa4 P2_4;
-sbit at 0xa5 P2_5;
-sbit at 0xa6 P2_6;
-sbit at 0xa7 P2_7;
-
-/* DMA controller */
-struct cc_dma_channel {
-       uint8_t src_high;
-       uint8_t src_low;
-       uint8_t dst_high;
-       uint8_t dst_low;
-       uint8_t len_high;
-       uint8_t len_low;
-       uint8_t cfg0;
-       uint8_t cfg1;
-};
-
-# define DMA_LEN_HIGH_VLEN_MASK                (7 << 5)
-# define DMA_LEN_HIGH_VLEN_LEN         (0 << 5)
-# define DMA_LEN_HIGH_VLEN_PLUS_1      (1 << 5)
-# define DMA_LEN_HIGH_VLEN             (2 << 5)
-# define DMA_LEN_HIGH_VLEN_PLUS_2      (3 << 5)
-# define DMA_LEN_HIGH_VLEN_PLUS_3      (4 << 5)
-# define DMA_LEN_HIGH_MASK             (0x1f)
-
-# define DMA_CFG0_WORDSIZE_8           (0 << 7)
-# define DMA_CFG0_WORDSIZE_16          (1 << 7)
-# define DMA_CFG0_TMODE_MASK           (3 << 5)
-# define DMA_CFG0_TMODE_SINGLE         (0 << 5)
-# define DMA_CFG0_TMODE_BLOCK          (1 << 5)
-# define DMA_CFG0_TMODE_REPEATED_SINGLE        (2 << 5)
-# define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5)
-
-/*
- * DMA triggers
- */
-# define DMA_CFG0_TRIGGER_NONE         0
-# define DMA_CFG0_TRIGGER_PREV         1
-# define DMA_CFG0_TRIGGER_T1_CH0       2
-# define DMA_CFG0_TRIGGER_T1_CH1       3
-# define DMA_CFG0_TRIGGER_T1_CH2       4
-# define DMA_CFG0_TRIGGER_T2_OVFL      6
-# define DMA_CFG0_TRIGGER_T3_CH0       7
-# define DMA_CFG0_TRIGGER_T3_CH1       8
-# define DMA_CFG0_TRIGGER_T4_CH0       9
-# define DMA_CFG0_TRIGGER_T4_CH1       10
-# define DMA_CFG0_TRIGGER_IOC_0                12
-# define DMA_CFG0_TRIGGER_IOC_1                13
-# define DMA_CFG0_TRIGGER_URX0         14
-# define DMA_CFG0_TRIGGER_UTX0         15
-# define DMA_CFG0_TRIGGER_URX1         16
-# define DMA_CFG0_TRIGGER_UTX1         17
-# define DMA_CFG0_TRIGGER_FLASH                18
-# define DMA_CFG0_TRIGGER_RADIO                19
-# define DMA_CFG0_TRIGGER_ADC_CHALL    20
-# define DMA_CFG0_TRIGGER_ADC_CH0      21
-# define DMA_CFG0_TRIGGER_ADC_CH1      22
-# define DMA_CFG0_TRIGGER_ADC_CH2      23
-# define DMA_CFG0_TRIGGER_ADC_CH3      24
-# define DMA_CFG0_TRIGGER_ADC_CH4      25
-# define DMA_CFG0_TRIGGER_ADC_CH5      26
-# define DMA_CFG0_TRIGGER_ADC_CH6      27
-# define DMA_CFG0_TRIGGER_I2SRX                27
-# define DMA_CFG0_TRIGGER_ADC_CH7      28
-# define DMA_CFG0_TRIGGER_I2STX                28
-# define DMA_CFG0_TRIGGER_ENC_DW       29
-# define DMA_CFG0_TRIGGER_DNC_UP       30
-
-# define DMA_CFG1_SRCINC_MASK          (3 << 6)
-# define DMA_CFG1_SRCINC_0             (0 << 6)
-# define DMA_CFG1_SRCINC_1             (1 << 6)
-# define DMA_CFG1_SRCINC_2             (2 << 6)
-# define DMA_CFG1_SRCINC_MINUS_1       (3 << 6)
-
-# define DMA_CFG1_DESTINC_MASK         (3 << 4)
-# define DMA_CFG1_DESTINC_0            (0 << 4)
-# define DMA_CFG1_DESTINC_1            (1 << 4)
-# define DMA_CFG1_DESTINC_2            (2 << 4)
-# define DMA_CFG1_DESTINC_MINUS_1      (3 << 4)
-
-# define DMA_CFG1_IRQMASK              (1 << 3)
-# define DMA_CFG1_M8                   (1 << 2)
-
-# define DMA_CFG1_PRIORITY_MASK                (3 << 0)
-# define DMA_CFG1_PRIORITY_LOW         (0 << 0)
-# define DMA_CFG1_PRIORITY_NORMAL      (1 << 0)
-# define DMA_CFG1_PRIORITY_HIGH                (2 << 0)
-
-/*
- * DMAARM - DMA Channel Arm
- */
-
-sfr at 0xD6 DMAARM;
-
-# define DMAARM_ABORT                  (1 << 7)
-# define DMAARM_DMAARM4                        (1 << 4)
-# define DMAARM_DMAARM3                        (1 << 3)
-# define DMAARM_DMAARM2                        (1 << 2)
-# define DMAARM_DMAARM1                        (1 << 1)
-# define DMAARM_DMAARM0                        (1 << 0)
-
-/*
- * DMAREQ - DMA Channel Start Request and Status
- */
-
-sfr at 0xD7 DMAREQ;
-
-# define DMAREQ_DMAREQ4                        (1 << 4)
-# define DMAREQ_DMAREQ3                        (1 << 3)
-# define DMAREQ_DMAREQ2                        (1 << 2)
-# define DMAREQ_DMAREQ1                        (1 << 1)
-# define DMAREQ_DMAREQ0                        (1 << 0)
-
-/*
- * DMA configuration 0 address
- */
-
-sfr at 0xD5 DMA0CFGH;
-sfr at 0xD4 DMA0CFGL;
-
-/*
- * DMA configuration 1-4 address
- */
-
-sfr at 0xD3 DMA1CFGH;
-sfr at 0xD2 DMA1CFGL;
-
-/*
- * DMAIRQ - DMA Interrupt Flag
- */
-
-sfr at 0xD1 DMAIRQ;
-
-# define DMAIRQ_DMAIF4                 (1 << 4)
-# define DMAIRQ_DMAIF3                 (1 << 3)
-# define DMAIRQ_DMAIF2                 (1 << 2)
-# define DMAIRQ_DMAIF1                 (1 << 1)
-# define DMAIRQ_DMAIF0                 (1 << 0)
-
-/*
- * UART registers
- */
-
-/* USART config/status registers */
-sfr at 0x86 U0CSR;
-sfr at 0xF8 U1CSR;
-
-# define UxCSR_MODE_UART               (1 << 7)
-# define UxCSR_MODE_SPI                        (0 << 7)
-# define UxCSR_RE                      (1 << 6)
-# define UxCSR_SLAVE                   (1 << 5)
-# define UxCSR_MASTER                  (0 << 5)
-# define UxCSR_FE                      (1 << 4)
-# define UxCSR_ERR                     (1 << 3)
-# define UxCSR_RX_BYTE                 (1 << 2)
-# define UxCSR_TX_BYTE                 (1 << 1)
-# define UxCSR_ACTIVE                  (1 << 0)
-
-/* UART configuration registers */
-sfr at 0xc4 U0UCR;
-sfr at 0xfb U1UCR;
-
-# define UxUCR_FLUSH                    (1 << 7)
-# define UxUCR_FLOW_DISABLE             (0 << 6)
-# define UxUCR_FLOW_ENABLE              (1 << 6)
-# define UxUCR_D9_EVEN_PARITY           (0 << 5)
-# define UxUCR_D9_ODD_PARITY            (1 << 5)
-# define UxUCR_BIT9_8_BITS              (0 << 4)
-# define UxUCR_BIT9_9_BITS              (1 << 4)
-# define UxUCR_PARITY_DISABLE           (0 << 3)
-# define UxUCR_PARITY_ENABLE            (1 << 3)
-# define UxUCR_SPB_1_STOP_BIT           (0 << 2)
-# define UxUCR_SPB_2_STOP_BITS          (1 << 2)
-# define UxUCR_STOP_LOW                 (0 << 1)
-# define UxUCR_STOP_HIGH                (1 << 1)
-# define UxUCR_START_LOW                (0 << 0)
-# define UxUCR_START_HIGH               (1 << 0)
-
-/* USART General configuration registers (mostly SPI) */
-sfr at 0xc5 U0GCR;
-sfr at 0xfc U1GCR;
-
-# define UxGCR_CPOL_NEGATIVE           (0 << 7)
-# define UxGCR_CPOL_POSITIVE           (1 << 7)
-# define UxGCR_CPHA_FIRST_EDGE         (0 << 6)
-# define UxGCR_CPHA_SECOND_EDGE                (1 << 6)
-# define UxGCR_ORDER_LSB               (0 << 5)
-# define UxGCR_ORDER_MSB               (1 << 5)
-# define UxGCR_BAUD_E_MASK             (0x1f)
-# define UxGCR_BAUD_E_SHIFT            0
-
-/* USART data registers */
-sfr at 0xc1 U0DBUF;
-__xdata __at (0xDFC1) volatile uint8_t U0DBUFXADDR;
-sfr at 0xf9 U1DBUF;
-__xdata __at (0xDFF9) volatile uint8_t U1DBUFXADDR;
-
-/* USART baud rate registers, M value */
-sfr at 0xc2 U0BAUD;
-sfr at 0xfa U1BAUD;
-
-/* Radio */
-
-sfr at 0xD9 RFD;
-__xdata at (0xDFD9) volatile uint8_t RFDXADDR;
-
-sfr at 0xE9 RFIF;
-#define RFIF_IM_TXUNF  (1 << 7)
-#define RFIF_IM_RXOVF  (1 << 6)
-#define RFIF_IM_TIMEOUT        (1 << 5)
-#define RFIF_IM_DONE   (1 << 4)
-#define RFIF_IM_CS     (1 << 3)
-#define RFIF_IM_PQT    (1 << 2)
-#define RFIF_IM_CCA    (1 << 1)
-#define RFIF_IM_SFD    (1 << 0)
-
-sfr at 0xE1 RFST;
-
-#define RFST_SFSTXON   0x00
-#define RFST_SCAL      0x01
-#define RFST_SRX       0x02
-#define RFST_STX       0x03
-#define RFST_SIDLE     0x04
-
-__xdata __at (0xdf00) uint8_t RF[0x3c];
-
-__xdata __at (0xdf2f) uint8_t RF_IOCFG2;
-#define RF_IOCFG2_OFF  0x2f
-
-__xdata __at (0xdf30) uint8_t RF_IOCFG1;
-#define RF_IOCFG1_OFF  0x30
-
-__xdata __at (0xdf31) uint8_t RF_IOCFG0;
-#define RF_IOCFG0_OFF  0x31
-
-__xdata __at (0xdf00) uint8_t RF_SYNC1;
-#define RF_SYNC1_OFF   0x00
-
-__xdata __at (0xdf01) uint8_t RF_SYNC0;
-#define RF_SYNC0_OFF   0x01
-
-__xdata __at (0xdf02) uint8_t RF_PKTLEN;
-#define RF_PKTLEN_OFF  0x02
-
-__xdata __at (0xdf03) uint8_t RF_PKTCTRL1;
-#define RF_PKTCTRL1_OFF        0x03
-#define PKTCTRL1_PQT_MASK                      (0x7 << 5)
-#define PKTCTRL1_PQT_SHIFT                     5
-#define PKTCTRL1_APPEND_STATUS                 (1 << 2)
-#define PKTCTRL1_ADR_CHK_NONE                  (0 << 0)
-#define PKTCTRL1_ADR_CHK_NO_BROADCAST          (1 << 0)
-#define PKTCTRL1_ADR_CHK_00_BROADCAST          (2 << 0)
-#define PKTCTRL1_ADR_CHK_00_FF_BROADCAST       (3 << 0)
-
-/* If APPEND_STATUS is used, two bytes will be added to the packet data */
-#define PKT_APPEND_STATUS_0_RSSI_MASK          (0xff)
-#define PKT_APPEND_STATUS_0_RSSI_SHIFT         0
-#define PKT_APPEND_STATUS_1_CRC_OK             (1 << 7)
-#define PKT_APPEND_STATUS_1_LQI_MASK           (0x7f)
-#define PKT_APPEND_STATUS_1_LQI_SHIFT          0
-
-__xdata __at (0xdf04) uint8_t RF_PKTCTRL0;
-#define RF_PKTCTRL0_OFF        0x04
-#define RF_PKTCTRL0_WHITE_DATA                 (1 << 6)
-#define RF_PKTCTRL0_PKT_FORMAT_NORMAL          (0 << 4)
-#define RF_PKTCTRL0_PKT_FORMAT_RANDOM          (2 << 4)
-#define RF_PKTCTRL0_CRC_EN                     (1 << 2)
-#define RF_PKTCTRL0_LENGTH_CONFIG_FIXED                (0 << 0)
-#define RF_PKTCTRL0_LENGTH_CONFIG_VARIABLE     (1 << 0)
-
-__xdata __at (0xdf05) uint8_t RF_ADDR;
-#define RF_ADDR_OFF    0x05
-
-__xdata __at (0xdf06) uint8_t RF_CHANNR;
-#define RF_CHANNR_OFF  0x06
-
-__xdata __at (0xdf07) uint8_t RF_FSCTRL1;
-#define RF_FSCTRL1_OFF 0x07
-
-#define RF_FSCTRL1_FREQ_IF_SHIFT       (0)
-
-__xdata __at (0xdf08) uint8_t RF_FSCTRL0;
-#define RF_FSCTRL0_OFF 0x08
-
-#define RF_FSCTRL0_FREQOFF_SHIFT       (0)
-
-__xdata __at (0xdf09) uint8_t RF_FREQ2;
-#define RF_FREQ2_OFF   0x09
-
-__xdata __at (0xdf0a) uint8_t RF_FREQ1;
-#define RF_FREQ1_OFF   0x0a
-
-__xdata __at (0xdf0b) uint8_t RF_FREQ0;
-#define RF_FREQ0_OFF   0x0b
-
-__xdata __at (0xdf0c) uint8_t RF_MDMCFG4;
-#define RF_MDMCFG4_OFF 0x0c
-
-#define RF_MDMCFG4_CHANBW_E_SHIFT      6
-#define RF_MDMCFG4_CHANBW_M_SHIFT      4
-#define RF_MDMCFG4_DRATE_E_SHIFT       0
-
-__xdata __at (0xdf0d) uint8_t RF_MDMCFG3;
-#define RF_MDMCFG3_OFF 0x0d
-
-#define RF_MDMCFG3_DRATE_M_SHIFT       0
-
-__xdata __at (0xdf0e) uint8_t RF_MDMCFG2;
-#define RF_MDMCFG2_OFF 0x0e
-
-#define RF_MDMCFG2_DEM_DCFILT_OFF      (1 << 7)
-#define RF_MDMCFG2_DEM_DCFILT_ON       (0 << 7)
-
-#define RF_MDMCFG2_MOD_FORMAT_MASK     (7 << 4)
-#define RF_MDMCFG2_MOD_FORMAT_2_FSK    (0 << 4)
-#define RF_MDMCFG2_MOD_FORMAT_GFSK     (1 << 4)
-#define RF_MDMCFG2_MOD_FORMAT_ASK_OOK  (3 << 4)
-#define RF_MDMCFG2_MOD_FORMAT_MSK      (7 << 4)
-
-#define RF_MDMCFG2_MANCHESTER_EN       (1 << 3)
-
-#define RF_MDMCFG2_SYNC_MODE_MASK              (0x7 << 0)
-#define RF_MDMCFG2_SYNC_MODE_NONE              (0x0 << 0)
-#define RF_MDMCFG2_SYNC_MODE_15_16             (0x1 << 0)
-#define RF_MDMCFG2_SYNC_MODE_16_16             (0x2 << 0)
-#define RF_MDMCFG2_SYNC_MODE_30_32             (0x3 << 0)
-#define RF_MDMCFG2_SYNC_MODE_NONE_THRES                (0x4 << 0)
-#define RF_MDMCFG2_SYNC_MODE_15_16_THRES       (0x5 << 0)
-#define RF_MDMCFG2_SYNC_MODE_16_16_THRES       (0x6 << 0)
-#define RF_MDMCFG2_SYNC_MODE_30_32_THRES       (0x7 << 0)
-
-__xdata __at (0xdf0f) uint8_t RF_MDMCFG1;
-#define RF_MDMCFG1_OFF 0x0f
-
-#define RF_MDMCFG1_FEC_EN                      (1 << 7)
-#define RF_MDMCFG1_FEC_DIS                     (0 << 7)
-
-#define RF_MDMCFG1_NUM_PREAMBLE_MASK           (7 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_2              (0 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_3              (1 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_4              (2 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_6              (3 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_8              (4 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_12             (5 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_16             (6 << 4)
-#define RF_MDMCFG1_NUM_PREAMBLE_24             (7 << 4)
-
-#define RF_MDMCFG1_CHANSPC_E_MASK              (3 << 0)
-#define RF_MDMCFG1_CHANSPC_E_SHIFT             (0)
-
-__xdata __at (0xdf10) uint8_t RF_MDMCFG0;
-#define RF_MDMCFG0_OFF 0x10
-
-#define RF_MDMCFG0_CHANSPC_M_SHIFT             (0)
-
-__xdata __at (0xdf11) uint8_t RF_DEVIATN;
-#define RF_DEVIATN_OFF 0x11
-
-#define RF_DEVIATN_DEVIATION_E_SHIFT           4
-#define RF_DEVIATN_DEVIATION_M_SHIFT           0
-
-__xdata __at (0xdf12) uint8_t RF_MCSM2;
-#define RF_MCSM2_OFF   0x12
-#define RF_MCSM2_RX_TIME_RSSI                  (1 << 4)
-#define RF_MCSM2_RX_TIME_QUAL                  (1 << 3)
-#define RF_MCSM2_RX_TIME_MASK                  (0x7)
-#define RF_MCSM2_RX_TIME_SHIFT                 0
-#define RF_MCSM2_RX_TIME_END_OF_PACKET         (7)
-
-__xdata __at (0xdf13) uint8_t RF_MCSM1;
-#define RF_MCSM1_OFF   0x13
-#define RF_MCSM1_CCA_MODE_ALWAYS                       (0 << 4)
-#define RF_MCSM1_CCA_MODE_RSSI_BELOW                   (1 << 4)
-#define RF_MCSM1_CCA_MODE_UNLESS_RECEIVING             (2 << 4)
-#define RF_MCSM1_CCA_MODE_RSSI_BELOW_UNLESS_RECEIVING  (3 << 4)
-#define RF_MCSM1_RXOFF_MODE_IDLE                       (0 << 2)
-#define RF_MCSM1_RXOFF_MODE_FSTXON                     (1 << 2)
-#define RF_MCSM1_RXOFF_MODE_TX                         (2 << 2)
-#define RF_MCSM1_RXOFF_MODE_RX                         (3 << 2)
-#define RF_MCSM1_TXOFF_MODE_IDLE                       (0 << 0)
-#define RF_MCSM1_TXOFF_MODE_FSTXON                     (1 << 0)
-#define RF_MCSM1_TXOFF_MODE_TX                         (2 << 0)
-#define RF_MCSM1_TXOFF_MODE_RX                         (3 << 0)
-
-__xdata __at (0xdf14) uint8_t RF_MCSM0;
-#define RF_MCSM0_OFF   0x14
-#define RF_MCSM0_FS_AUTOCAL_NEVER              (0 << 4)
-#define RF_MCSM0_FS_AUTOCAL_FROM_IDLE          (1 << 4)
-#define RF_MCSM0_FS_AUTOCAL_TO_IDLE            (2 << 4)
-#define RF_MCSM0_FS_AUTOCAL_TO_IDLE_EVERY_4    (3 << 4)
-#define RF_MCSM0_MAGIC_3                       (1 << 3)
-#define RF_MCSM0_MAGIC_2                       (1 << 2)
-#define RF_MCSM0_CLOSE_IN_RX_0DB               (0 << 0)
-#define RF_MCSM0_CLOSE_IN_RX_6DB               (1 << 0)
-#define RF_MCSM0_CLOSE_IN_RX_12DB              (2 << 0)
-#define RF_MCSM0_CLOSE_IN_RX_18DB              (3 << 0)
-
-__xdata __at (0xdf15) uint8_t RF_FOCCFG;
-#define RF_FOCCFG_OFF  0x15
-#define RF_FOCCFG_FOC_BS_CS_GATE               (1 << 5)
-#define RF_FOCCFG_FOC_PRE_K_1K                 (0 << 3)
-#define RF_FOCCFG_FOC_PRE_K_2K                 (1 << 3)
-#define RF_FOCCFG_FOC_PRE_K_3K                 (2 << 3)
-#define RF_FOCCFG_FOC_PRE_K_4K                 (3 << 3)
-#define RF_FOCCFG_FOC_POST_K_PRE_K             (0 << 2)
-#define RF_FOCCFG_FOC_POST_K_PRE_K_OVER_2      (1 << 2)
-#define RF_FOCCFG_FOC_LIMIT_0                  (0 << 0)
-#define RF_FOCCFG_FOC_LIMIT_BW_OVER_8          (1 << 0)
-#define RF_FOCCFG_FOC_LIMIT_BW_OVER_4          (2 << 0)
-#define RF_FOCCFG_FOC_LIMIT_BW_OVER_2          (3 << 0)
-
-__xdata __at (0xdf16) uint8_t RF_BSCFG;
-#define RF_BSCFG_OFF   0x16
-#define RF_BSCFG_BS_PRE_K_1K                   (0 << 6)
-#define RF_BSCFG_BS_PRE_K_2K                   (1 << 6)
-#define RF_BSCFG_BS_PRE_K_3K                   (2 << 6)
-#define RF_BSCFG_BS_PRE_K_4K                   (3 << 6)
-#define RF_BSCFG_BS_PRE_KP_1KP                 (0 << 4)
-#define RF_BSCFG_BS_PRE_KP_2KP                 (1 << 4)
-#define RF_BSCFG_BS_PRE_KP_3KP                 (2 << 4)
-#define RF_BSCFG_BS_PRE_KP_4KP                 (3 << 4)
-#define RF_BSCFG_BS_POST_KI_PRE_KI             (0 << 3)
-#define RF_BSCFG_BS_POST_KI_PRE_KI_OVER_2      (1 << 3)
-#define RF_BSCFG_BS_POST_KP_PRE_KP             (0 << 2)
-#define RF_BSCFG_BS_POST_KP_PRE_KP_OVER_2      (1 << 2)
-#define RF_BSCFG_BS_LIMIT_0                    (0 << 0)
-#define RF_BSCFG_BS_LIMIT_3_125                        (1 << 0)
-#define RF_BSCFG_BS_LIMIT_6_25                 (2 << 0)
-#define RF_BSCFG_BS_LIMIT_12_5                 (3 << 0)
-
-__xdata __at (0xdf17) uint8_t RF_AGCCTRL2;
-#define RF_AGCCTRL2_OFF        0x17
-
-__xdata __at (0xdf18) uint8_t RF_AGCCTRL1;
-#define RF_AGCCTRL1_OFF        0x18
-
-__xdata __at (0xdf19) uint8_t RF_AGCCTRL0;
-#define RF_AGCCTRL0_OFF        0x19
-
-__xdata __at (0xdf1a) uint8_t RF_FREND1;
-#define RF_FREND1_OFF  0x1a
-
-#define RF_FREND1_LNA_CURRENT_SHIFT            6
-#define RF_FREND1_LNA2MIX_CURRENT_SHIFT                4
-#define RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT   2
-#define RF_FREND1_MIX_CURRENT_SHIFT            0
-
-__xdata __at (0xdf1b) uint8_t RF_FREND0;
-#define RF_FREND0_OFF  0x1b
-
-#define RF_FREND0_LODIV_BUF_CURRENT_TX_MASK    (0x3 << 4)
-#define RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT   4
-#define RF_FREND0_PA_POWER_MASK                        (0x7)
-#define RF_FREND0_PA_POWER_SHIFT               0
-
-__xdata __at (0xdf1c) uint8_t RF_FSCAL3;
-#define RF_FSCAL3_OFF  0x1c
-
-__xdata __at (0xdf1d) uint8_t RF_FSCAL2;
-#define RF_FSCAL2_OFF  0x1d
-
-__xdata __at (0xdf1e) uint8_t RF_FSCAL1;
-#define RF_FSCAL1_OFF  0x1e
-
-__xdata __at (0xdf1f) uint8_t RF_FSCAL0;
-#define RF_FSCAL0_OFF  0x1f
-
-__xdata __at (0xdf23) uint8_t RF_TEST2;
-#define RF_TEST2_OFF   0x23
-
-#define RF_TEST2_NORMAL_MAGIC          0x88
-#define RF_TEST2_RX_LOW_DATA_RATE_MAGIC        0x81
-
-__xdata __at (0xdf24) uint8_t RF_TEST1;
-#define RF_TEST1_OFF   0x24
-
-#define RF_TEST1_TX_MAGIC              0x31
-#define RF_TEST1_RX_LOW_DATA_RATE_MAGIC        0x35
-
-__xdata __at (0xdf25) uint8_t RF_TEST0;
-#define RF_TEST0_OFF   0x25
-
-#define RF_TEST0_7_2_MASK              (0xfc)
-#define RF_TEST0_VCO_SEL_CAL_EN                (1 << 1)
-#define RF_TEST0_0_MASK                        (1)
-
-/* These are undocumented, and must be computed
- * using the provided tool.
- */
-__xdata __at (0xdf27) uint8_t RF_PA_TABLE7;
-#define RF_PA_TABLE7_OFF       0x27
-
-__xdata __at (0xdf28) uint8_t RF_PA_TABLE6;
-#define RF_PA_TABLE6_OFF       0x28
-
-__xdata __at (0xdf29) uint8_t RF_PA_TABLE5;
-#define RF_PA_TABLE5_OFF       0x29
-
-__xdata __at (0xdf2a) uint8_t RF_PA_TABLE4;
-#define RF_PA_TABLE4_OFF       0x2a
-
-__xdata __at (0xdf2b) uint8_t RF_PA_TABLE3;
-#define RF_PA_TABLE3_OFF       0x2b
-
-__xdata __at (0xdf2c) uint8_t RF_PA_TABLE2;
-#define RF_PA_TABLE2_OFF       0x2c
-
-__xdata __at (0xdf2d) uint8_t RF_PA_TABLE1;
-#define RF_PA_TABLE1_OFF       0x2d
-
-__xdata __at (0xdf2e) uint8_t RF_PA_TABLE0;
-#define RF_PA_TABLE0_OFF       0x2e
-
-__xdata __at (0xdf36) uint8_t RF_PARTNUM;
-#define RF_PARTNUM_OFF 0x36
-
-__xdata __at (0xdf37) uint8_t RF_VERSION;
-#define RF_VERSION_OFF 0x37
-
-__xdata __at (0xdf38) uint8_t RF_FREQEST;
-#define RF_FREQEST_OFF 0x38
-
-__xdata __at (0xdf39) uint8_t RF_LQI;
-#define RF_LQI_OFF     0x39
-
-#define RF_LQI_CRC_OK                  (1 << 7)
-#define RF_LQI_LQI_EST_MASK            (0x7f)
-
-__xdata __at (0xdf3a) uint8_t RF_RSSI;
-#define RF_RSSI_OFF    0x3a
-
-__xdata __at (0xdf3b) uint8_t RF_MARCSTATE;
-#define RF_MARCSTATE_OFF       0x3b
-
-#define RF_MARCSTATE_MASK              0x1f
-#define RF_MARCSTATE_SLEEP             0x00
-#define RF_MARCSTATE_IDLE              0x01
-#define RF_MARCSTATE_VCOON_MC          0x03
-#define RF_MARCSTATE_REGON_MC          0x04
-#define RF_MARCSTATE_MANCAL            0x05
-#define RF_MARCSTATE_VCOON             0x06
-#define RF_MARCSTATE_REGON             0x07
-#define RF_MARCSTATE_STARTCAL          0x08
-#define RF_MARCSTATE_BWBOOST           0x09
-#define RF_MARCSTATE_FS_LOCK           0x0a
-#define RF_MARCSTATE_IFADCON           0x0b
-#define RF_MARCSTATE_ENDCAL            0x0c
-#define RF_MARCSTATE_RX                        0x0d
-#define RF_MARCSTATE_RX_END            0x0e
-#define RF_MARCSTATE_RX_RST            0x0f
-#define RF_MARCSTATE_TXRX_SWITCH       0x10
-#define RF_MARCSTATE_RX_OVERFLOW       0x11
-#define RF_MARCSTATE_FSTXON            0x12
-#define RF_MARCSTATE_TX                        0x13
-#define RF_MARCSTATE_TX_END            0x14
-#define RF_MARCSTATE_RXTX_SWITCH       0x15
-#define RF_MARCSTATE_TX_UNDERFLOW      0x16
-
-
-__xdata __at (0xdf3c) uint8_t RF_PKTSTATUS;
-#define RF_PKTSTATUS_OFF       0x3c
-
-#define RF_PKTSTATUS_CRC_OK            (1 << 7)
-#define RF_PKTSTATUS_CS                        (1 << 6)
-#define RF_PKTSTATUS_PQT_REACHED       (1 << 5)
-#define RF_PKTSTATUS_CCA               (1 << 4)
-#define RF_PKTSTATUS_SFD               (1 << 3)
-
-__xdata __at (0xdf3d) uint8_t RF_VCO_VC_DAC;
-#define RF_VCO_VC_DAC_OFF      0x3d
-
-#endif
diff --git a/check-stack b/check-stack
deleted file mode 100755 (executable)
index 82680b8..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-HEADER=$1
-MEM=$2
-
-HEADER_STACK=`awk '/#define AO_STACK_START/ {print $3}' $HEADER | nickle`
-MEM_STACK=`awk '/Stack starts at/ {print $4}' $MEM | nickle`
-
-if [ "$HEADER_STACK" -lt "$MEM_STACK" ]; then
-       MIN=0x`nickle -e "$MEM_STACK # 16"`
-       echo "Set AO_STACK_START to at least $MIN"
-       exit 1
-else
-       exit 0
-fi
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..0419489
--- /dev/null
@@ -0,0 +1,58 @@
+dnl
+dnl  Copyright Â© 2008 Keith Packard <keithp@keithp.com>
+dnl
+dnl  This program is free software; you can redistribute it and/or modify
+dnl  it under the terms of the GNU General Public License as published by
+dnl  the Free Software Foundation; either version 2 of the License, or
+dnl  (at your option) any later version.
+dnl
+dnl  This program is distributed in the hope that it will be useful, but
+dnl  WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl  General Public License for more details.
+dnl
+dnl  You should have received a copy of the GNU General Public License along
+dnl  with this program; if not, write to the Free Software Foundation, Inc.,
+dnl  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+dnl
+dnl Process this file with autoconf to create configure.
+
+AC_INIT(aoview)
+
+AM_INIT_AUTOMAKE(aoview, 0.1)
+AM_MAINTAINER_MODE
+
+dnl ==========================================================================
+
+AM_CONFIG_HEADER(config.h)
+
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_RANLIB
+PKG_PROG_PKG_CONFIG
+
+CFLAGS="-g"
+WARN_CFLAGS=""
+if test "x$GCC" = "xyes"; then
+       WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \
+       -Wmissing-prototypes -Wmissing-declarations \
+       -Wnested-externs -fno-strict-aliasing"
+       AC_DEFINE_UNQUOTED(HAVE_WARNING_CPP_DIRECTIVE,1,
+       [Can use #warning in C files])
+fi
+AC_SUBST(WARN_CFLAGS)
+
+dnl ==========================================================================
+
+AM_CONDITIONAL(CROSS_COMPILING, test $cross_compiling = yes)
+
+dnl ==========================================================================
+
+
+PKG_CHECK_MODULES([AOVIEW], [gtk+-2.0 libglade-2.0 gconf-2.0])
+
+AC_OUTPUT([
+Makefile
+aoview/Makefile
+])
diff --git a/gps-cksum b/gps-cksum
deleted file mode 100755 (executable)
index a08153b..0000000
--- a/gps-cksum
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env nickle
-
-int checksum(string a)
-{
-       int     c = 0;
-       for (int i = 0; i < String::length(a); i++)
-               c ^= a[i];
-       return c;
-}
-
-void main()
-{
-       for (int i = 1; i < dim(argv); i++)
-               printf ("$%s*%02x\n", argv[i], checksum(argv[i]));
-}
-
-main();
diff --git a/make-altitude b/make-altitude
deleted file mode 100644 (file)
index ddfab5f..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-#!/usr/bin/nickle -f
-/*
- * Pressure Sensor Model, version 1.1
- *
- * written by Holly Grimes
- *
- * Uses the International Standard Atmosphere as described in
- *   "A Quick Derivation relating altitude to air pressure" (version 1.03)
- *    from the Portland State Aerospace Society, except that the atmosphere
- *    is divided into layers with each layer having a different lapse rate.
- *
- * Lapse rate data for each layer was obtained from Wikipedia on Sept. 1, 2007
- *    at site <http://en.wikipedia.org/wiki/International_Standard_Atmosphere
- *
- * Height measurements use the local tangent plane.  The postive z-direction is up.
- *
- * All measurements are given in SI units (Kelvin, Pascal, meter, meters/second^2).
- *   The lapse rate is given in Kelvin/meter, the gas constant for air is given
- *   in Joules/(kilogram-Kelvin).
- */
-
-const real GRAVITATIONAL_ACCELERATION = -9.80665;
-const real AIR_GAS_CONSTANT = 287.053;
-const int NUMBER_OF_LAYERS = 7;
-const real MAXIMUM_ALTITUDE = 84852;
-const real MINIMUM_PRESSURE = 0.3734;
-const real LAYER0_BASE_TEMPERATURE = 288.15;
-const real LAYER0_BASE_PRESSURE = 101325;
-
-/* lapse rate and base altitude for each layer in the atmosphere */
-const real[NUMBER_OF_LAYERS] lapse_rate = {
-       -0.0065, 0.0, 0.001, 0.0028, 0.0, -0.0028, -0.002
-};
-const int[NUMBER_OF_LAYERS] base_altitude = {
-       0, 11000, 20000, 32000, 47000, 51000, 71000
-};
-
-
-/* outputs atmospheric pressure associated with the given altitude. altitudes
-   are measured with respect to the mean sea level */
-real altitude_to_pressure(real altitude) {
-   real base_temperature = LAYER0_BASE_TEMPERATURE;
-   real base_pressure = LAYER0_BASE_PRESSURE;
-
-   real pressure;
-   real base; /* base for function to determine pressure */
-   real exponent; /* exponent for function to determine pressure */
-   int layer_number; /* identifies layer in the atmosphere */
-   int delta_z; /* difference between two altitudes */
-   
-   if (altitude > MAXIMUM_ALTITUDE) /* FIX ME: use sensor data to improve model */
-      return 0;
-
-   /* calculate the base temperature and pressure for the atmospheric layer
-      associated with the inputted altitude */
-   for(layer_number = 0; layer_number < NUMBER_OF_LAYERS - 1 && altitude > base_altitude[layer_number + 1]; layer_number++) {
-      delta_z = base_altitude[layer_number + 1] - base_altitude[layer_number];
-      if (lapse_rate[layer_number] == 0.0) {
-         exponent = GRAVITATIONAL_ACCELERATION * delta_z 
-              / AIR_GAS_CONSTANT / base_temperature;
-         base_pressure *= exp(exponent);
-      }
-      else {
-         base = (lapse_rate[layer_number] * delta_z / base_temperature) + 1.0;
-         exponent = GRAVITATIONAL_ACCELERATION / 
-              (AIR_GAS_CONSTANT * lapse_rate[layer_number]);
-         base_pressure *= pow(base, exponent);
-      }
-      base_temperature += delta_z * lapse_rate[layer_number];
-   }
-
-   /* calculate the pressure at the inputted altitude */
-   delta_z = altitude - base_altitude[layer_number];
-   if (lapse_rate[layer_number] == 0.0) {
-      exponent = GRAVITATIONAL_ACCELERATION * delta_z 
-           / AIR_GAS_CONSTANT / base_temperature;
-      pressure = base_pressure * exp(exponent);
-   }
-   else {
-      base = (lapse_rate[layer_number] * delta_z / base_temperature) + 1.0;
-      exponent = GRAVITATIONAL_ACCELERATION /
-           (AIR_GAS_CONSTANT * lapse_rate[layer_number]);
-      pressure = base_pressure * pow(base, exponent);
-   } 
-
-   return pressure;
-}
-
-
-/* outputs the altitude associated with the given pressure. the altitude
-   returned is measured with respect to the mean sea level */
-real pressure_to_altitude(real pressure) {
-
-   real next_base_temperature = LAYER0_BASE_TEMPERATURE;
-   real next_base_pressure = LAYER0_BASE_PRESSURE;
-
-   real altitude;
-   real base_pressure;
-   real base_temperature;
-   real base; /* base for function to determine base pressure of next layer */
-   real exponent; /* exponent for function to determine base pressure
-                             of next layer */
-   real coefficient;
-   int layer_number; /* identifies layer in the atmosphere */
-   int delta_z; /* difference between two altitudes */
-
-   if (pressure < 0)  /* illegal pressure */
-      return -1;
-   if (pressure < MINIMUM_PRESSURE) /* FIX ME: use sensor data to improve model */
-      return MAXIMUM_ALTITUDE;
-
-   /* calculate the base temperature and pressure for the atmospheric layer
-      associated with the inputted pressure. */
-   layer_number = -1;
-   do {
-      layer_number++;
-      base_pressure = next_base_pressure;
-      base_temperature = next_base_temperature;
-      delta_z = base_altitude[layer_number + 1] - base_altitude[layer_number];
-      if (lapse_rate[layer_number] == 0.0) {
-         exponent = GRAVITATIONAL_ACCELERATION * delta_z 
-              / AIR_GAS_CONSTANT / base_temperature;
-         next_base_pressure *= exp(exponent);
-      }
-      else {
-         base = (lapse_rate[layer_number] * delta_z / base_temperature) + 1.0;
-         exponent = GRAVITATIONAL_ACCELERATION / 
-              (AIR_GAS_CONSTANT * lapse_rate[layer_number]);
-         next_base_pressure *= pow(base, exponent);
-      }
-      next_base_temperature += delta_z * lapse_rate[layer_number];
-   }
-   while(layer_number < NUMBER_OF_LAYERS - 1 && pressure < next_base_pressure);
-
-   /* calculate the altitude associated with the inputted pressure */
-   if (lapse_rate[layer_number] == 0.0) {
-      coefficient = (AIR_GAS_CONSTANT / GRAVITATIONAL_ACCELERATION) 
-                                                    * base_temperature;
-      altitude = base_altitude[layer_number]
-                    + coefficient * log(pressure / base_pressure);
-   }
-   else {
-      base = pressure / base_pressure;
-      exponent = AIR_GAS_CONSTANT * lapse_rate[layer_number] 
-                                       / GRAVITATIONAL_ACCELERATION;
-      coefficient = base_temperature / lapse_rate[layer_number];
-      altitude = base_altitude[layer_number]
-                      + coefficient * (pow(base, exponent) - 1);
-   }
-
-   return altitude;
-}
-
-real feet_to_meters(real feet)
-{
-    return feet * (12 * 2.54 / 100);
-}
-
-real meters_to_feet(real meters)
-{
-    return meters / (12 * 2.54 / 100);
-}
-
-/*
- * Values for our MP3H6115A pressure sensor
- *
- * From the data sheet:
- *
- * Pressure range: 15-115 kPa
- * Voltage at 115kPa: 2.82
- * Output scale: 27mV/kPa
- *
- * 
- * 27 mV/kPa * 2047 / 3300 counts/mV = 16.75 counts/kPa
- * 2.82V * 2047 / 3.3 counts/V = 1749 counts/115 kPa
- */
-
-real counts_per_kPa = 27 * 2047 / 3300;
-real counts_at_101_3kPa = 1674;
-
-real count_to_kPa(real count)
-{
-       return (count / 2047 + 0.095) / 0.009;
-}
-
-for (real count = 0; count <= 2047; count++) {
-       real    kPa = count_to_kPa(count);
-       real    meters = pressure_to_altitude(kPa * 1000);
-       printf ("       %d,     /* %6.2g kPa %d count */\n",
-               floor (meters + 0.5), kPa, count);
-}
diff --git a/src/25lc1024.h b/src/25lc1024.h
new file mode 100644 (file)
index 0000000..44e5238
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright Â© 2009 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.
+ */
+
+/* Defines for the 25LC1024 1Mbit SPI Bus Serial EEPROM */
+
+#ifndef _25LC1024_H_
+#define _25LC1024_H_
+
+#define EE_READ                0x03
+#define EE_WRITE       0x02
+#define EE_WREN                0x06
+#define EE_WRDI                0x04
+#define EE_RDSR                0x05
+#define EE_WRSR                0x01
+#define EE_PE          0x42
+#define EE_SE          0xd8
+#define EE_CE          0xc7
+#define EE_RDID                0xab
+#define EE_DPD         0xb9
+
+#define EE_STATUS_WIP  (1 << 0)
+#define EE_STATUS_WEL  (1 << 1)
+#define EE_STATUS_BP0  (1 << 2)
+#define EE_STATUS_BP1  (1 << 3)
+#define EE_STATUS_WPEN (1 << 7)
+
+#endif /* _25LC1024_H_ */
diff --git a/src/Makefile b/src/Makefile
new file mode 100644 (file)
index 0000000..3928136
--- /dev/null
@@ -0,0 +1,262 @@
+#
+# AltOS build
+#
+#
+CC=sdcc
+
+VERSION=$(shell git describe)
+
+CFLAGS=--model-small --debug --opt-code-speed
+
+LDFLAGS=--out-fmt-ihx --code-loc 0x0000 --code-size 0x8000 \
+       --xram-loc 0xf000 --xram-size 0xda2 --iram-size 0xff
+
+INC = \
+       ao.h \
+       cc1111.h \
+       altitude.h \
+       25lc1024.h
+
+#
+# Common AltOS sources
+#
+ALTOS_SRC = \
+       ao_cmd.c \
+       ao_dbg.c \
+       ao_dma.c \
+       ao_mutex.c \
+       ao_panic.c \
+       ao_task.c \
+       ao_timer.c \
+       _bp.c
+
+#
+# Shared AltOS drivers
+#
+ALTOS_DRIVER_SRC = \
+       ao_beep.c \
+       ao_config.c \
+       ao_led.c \
+       ao_radio.c \
+       ao_stdio.c \
+       ao_usb.c
+
+TELE_COMMON_SRC = \
+       ao_gps_print.c \
+       ao_state.c
+
+#
+# Receiver code
+#
+TELE_RECEIVER_SRC =\
+       ao_monitor.c \
+       ao_rssi.c
+
+#
+# Shared Tele drivers (on TeleMetrum, TeleTerra, TeleDongle)
+#
+
+TELE_DRIVER_SRC = \
+       ao_convert.c \
+       ao_gps.c \
+       ao_serial.c
+
+#
+# Drivers for partially-flled boards (TT, TD and TI)
+#
+TELE_FAKE_SRC = \
+       ao_adc_fake.c \
+       ao_ee_fake.c
+
+#
+# Drivers only on TeleMetrum
+#
+TM_DRIVER_SRC = \
+       ao_adc.c \
+       ao_ee.c \
+       ao_gps_report.c \
+       ao_ignite.c
+
+#
+# Tasks run on TeleMetrum
+#
+TM_TASK_SRC = \
+       ao_flight.c \
+       ao_log.c \
+       ao_report.c \
+       ao_telemetry.c
+
+TM_MAIN_SRC = \
+       ao_telemetrum.c
+
+#
+# All sources for TeleMetrum
+#
+TM_SRC = \
+       $(ALTOS_SRC) \
+       $(ALTOS_DRIVER_SRC) \
+       $(TELE_DRIVER_SRC) \
+       $(TELE_COMMON_SRC) \
+       $(TM_DRIVER_SRC) \
+       $(TM_TASK_SRC) \
+       $(TM_MAIN_SRC)
+
+TI_MAIN_SRC = \
+       ao_tidongle.c
+
+#
+# All sources for the TI debug dongle
+#
+TI_SRC = \
+       $(ALTOS_SRC) \
+       $(ALTOS_DRIVER_SRC) \
+       $(TELE_RECEIVER_SRC) \
+       $(TELE_COMMON_SRC) \
+       $(TELE_FAKE_SRC) \
+       $(TI_MAIN_SRC)
+
+TT_MAIN_SRC = \
+       ao_teleterra.c
+#
+# All sources for TeleTerra
+#
+TT_SRC = \
+       $(ALTOS_SRC) \
+       $(ALTOS_DRIVER_SRC) \
+       $(TELE_RECEIVER_SRC) \
+       $(TELE_DRIVER_SRC) \
+       $(TELE_COMMON_SRC) \
+       $(TELE_FAKE_SRC) \
+       $(TT_MAIN_SRC)
+
+
+#
+# Sources for TeleDongle
+#
+
+TD_MAIN_SRC = \
+       ao_teledongle.c
+
+TD_SRC = \
+       $(ALTOS_SRC) \
+       $(ALTOS_DRIVER_SRC) \
+       $(TELE_RECEIVER_SRC) \
+       $(TELE_COMMON_SRC) \
+       $(TELE_FAKE_SRC) \
+       $(TD_MAIN_SRC)
+
+SRC = \
+       $(ALTOS_SRC) \
+       $(ALTOS_DRIVER_SRC) \
+       $(TELE_DRIVER_SRC) \
+       $(TELE_RECEIVER_SRC) \
+       $(TELE_COMMON_SRC) \
+       $(TELE_FAKE_SRC) \
+       $(TM_DRIVER_SRC) \
+       $(TM_TASK_SRC) \
+       $(TM_MAIN_SRC) \
+       $(TI_MAIN_SRC) \
+       $(TD_MAIN_SRC) \
+       $(TT_MAIN_SRC)
+
+TM_REL=$(TM_SRC:.c=.rel) ao_product-telemetrum.rel
+TI_REL=$(TI_SRC:.c=.rel) ao_product-tidongle.rel
+TT_REL=$(TT_SRC:.c=.rel) ao_product-teleterra.rel
+TD_REL=$(TD_SRC:.c=.rel) ao_product-teledongle.rel
+
+PROD_REL=\
+       ao_product-telemetrum.rel \
+       ao_product-tidongle.rel \
+       ao_product-teleterra.rel \
+       ao_product-teledongle.rel
+
+REL=$(SRC:.c=.rel) $(PROD_REL)
+ADB=$(REL:.rel=.adb)
+ASM=$(REL:.rel=.asm)
+LNK=$(REL:.rel=.lnk)
+LST=$(REL:.rel=.lst)
+RST=$(REL:.rel=.rst)
+SYM=$(REL:.rel=.sym)
+
+PROGS= telemetrum.ihx tidongle.ihx \
+       teleterra.ihx teledongle.ihx
+
+HOST_PROGS=ao_flight_test
+
+PCDB=$(PROGS:.ihx=.cdb)
+PLNK=$(PROGS:.ihx=.lnk)
+PMAP=$(PROGS:.ihx=.map)
+PMEM=$(PROGS:.ihx=.mem)
+PAOM=$(PROGS:.ihx=)
+
+%.rel : %.c $(INC)
+       $(CC) -c $(CFLAGS) -o$*.rel $*.c
+
+all: $(PROGS) $(HOST_PROGS)
+
+telemetrum.ihx: $(TM_REL) Makefile
+       $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(TM_REL)
+       sh check-stack ao.h telemetrum.mem
+
+tidongle.ihx: $(TI_REL) Makefile
+       $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(TI_REL)
+       sh check-stack ao.h tidongle.mem
+
+tidongle.ihx: telemetrum.ihx
+
+teleterra.ihx: $(TT_REL) Makefile
+       $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(TT_REL)
+       sh check-stack ao.h teleterra.mem
+
+teleterra.ihx: tidongle.ihx
+
+teledongle.ihx: $(TD_REL) Makefile
+       $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(TD_REL)
+       sh check-stack ao.h teledongle.mem
+
+teledongle.ihx: teleterra.ihx
+
+altitude.h: make-altitude
+       nickle make-altitude > altitude.h
+
+TELEMETRUM_DEFS=ao-telemetrum.h
+TELETERRA_DEFS=ao-teleterra.h
+TELEDONGLE_DEFS=ao-teledongle.h
+TIDONGLE_DEFS=ao-tidongle.h
+
+ALL_DEFS=$(TELEMETRUM_DEFS) $(TELETERRA_DEFS) \
+       $(TELEDONGLE_DEFS) $(TIDONGLE_DEFS)
+ao_product-telemetrum.rel: ao_product.c $(TELEMETRUM_DEFS)
+       $(CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"$(TELEMETRUM_DEFS)\"' -o$@ ao_product.c
+
+ao_product-teleterra.rel: ao_product.c $(TELETERRA_DEFS)
+       $(CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"$(TELETERRA_DEFS)\"' -o$@ ao_product.c
+
+ao_product-teledongle.rel: ao_product.c $(TELEDONGLE_DEFS)
+       $(CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"$(TELEDONGLE_DEFS)\"' -o$@ ao_product.c
+
+ao_product-tidongle.rel: ao_product.c $(TIDONGLE_DEFS)
+       $(CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"$(TIDONGLE_DEFS)\"' -o$@ ao_product.c
+
+$(TELEMETRUM_DEFS): ao-make-product.5c
+       nickle ao-make-product.5c -m altusmetrum.org -p TeleMetrum -v $(VERSION) > $@
+
+$(TELETERRA_DEFS): ao-make-product.5c
+       nickle ao-make-product.5c -m altusmetrum.org -p TeleTerra -v $(VERSION) > $@
+
+$(TELEDONGLE_DEFS): ao-make-product.5c
+       nickle ao-make-product.5c -m altusmetrum.org -p TeleDongle -v $(VERSION) > $@
+
+$(TIDONGLE_DEFS): ao-make-product.5c
+       nickle ao-make-product.5c -m altusmetrum.org -p TIDongle -v $(VERSION) > $@
+
+clean:
+       rm -f $(ADB) $(ASM) $(LNK) $(LST) $(REL) $(RST) $(SYM)
+       rm -f $(PROGS) $(PCDB) $(PLNK) $(PMAP) $(PMEM) $(PAOM)
+       rm -f $(ALL_DEFS) $(HOST_PROGS)
+       rm -f $(TELEMETRUM_DEFS) $(TELETERRA_DEFS) $(TELEDONGLE_DEFS) $(TIDONGLE_DEFS)
+
+install:
+
+ao_flight_test: ao_flight.c ao_flight_test.c
+       cc -g -o $@ ao_flight_test.c
diff --git a/src/_bp.c b/src/_bp.c
new file mode 100644 (file)
index 0000000..6bf135b
--- /dev/null
+++ b/src/_bp.c
@@ -0,0 +1,26 @@
+/*-------------------------------------------------------------------------
+
+  _bp.c :- just declares bp as a variable
+
+             Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
+
+   This library is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+
+   This library 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 Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+   In other words, you are welcome to use, share and improve this program.
+   You are forbidden to forbid anyone else to use, share and improve
+   what you give them.   Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+
+__data unsigned char bp ;
diff --git a/src/altitude.h b/src/altitude.h
new file mode 100644 (file)
index 0000000..5225df4
--- /dev/null
@@ -0,0 +1,2048 @@
+       15837,  /*  10.56 kPa 0 count */
+       15804,  /*  10.61 kPa 1 count */
+       15772,  /*  10.66 kPa 2 count */
+       15740,  /*  10.72 kPa 3 count */
+       15708,  /*  10.77 kPa 4 count */
+       15676,  /*  10.83 kPa 5 count */
+       15644,  /*  10.88 kPa 6 count */
+       15613,  /*  10.94 kPa 7 count */
+       15581,  /*  10.99 kPa 8 count */
+       15550,  /*  11.04 kPa 9 count */
+       15519,  /*  11.10 kPa 10 count */
+       15488,  /*  11.15 kPa 11 count */
+       15457,  /*  11.21 kPa 12 count */
+       15426,  /*  11.26 kPa 13 count */
+       15396,  /*  11.32 kPa 14 count */
+       15366,  /*  11.37 kPa 15 count */
+       15335,  /*  11.42 kPa 16 count */
+       15305,  /*  11.48 kPa 17 count */
+       15275,  /*  11.53 kPa 18 count */
+       15246,  /*  11.59 kPa 19 count */
+       15216,  /*  11.64 kPa 20 count */
+       15187,  /*  11.70 kPa 21 count */
+       15157,  /*  11.75 kPa 22 count */
+       15128,  /*  11.80 kPa 23 count */
+       15099,  /*  11.86 kPa 24 count */
+       15070,  /*  11.91 kPa 25 count */
+       15041,  /*  11.97 kPa 26 count */
+       15012,  /*  12.02 kPa 27 count */
+       14984,  /*  12.08 kPa 28 count */
+       14955,  /*  12.13 kPa 29 count */
+       14927,  /*  12.18 kPa 30 count */
+       14899,  /*  12.24 kPa 31 count */
+       14871,  /*  12.29 kPa 32 count */
+       14843,  /*  12.35 kPa 33 count */
+       14815,  /*  12.40 kPa 34 count */
+       14787,  /*  12.46 kPa 35 count */
+       14760,  /*  12.51 kPa 36 count */
+       14732,  /*  12.56 kPa 37 count */
+       14705,  /*  12.62 kPa 38 count */
+       14678,  /*  12.67 kPa 39 count */
+       14651,  /*  12.73 kPa 40 count */
+       14624,  /*  12.78 kPa 41 count */
+       14597,  /*  12.84 kPa 42 count */
+       14570,  /*  12.89 kPa 43 count */
+       14543,  /*  12.94 kPa 44 count */
+       14517,  /*  13.00 kPa 45 count */
+       14490,  /*  13.05 kPa 46 count */
+       14464,  /*  13.11 kPa 47 count */
+       14438,  /*  13.16 kPa 48 count */
+       14412,  /*  13.22 kPa 49 count */
+       14386,  /*  13.27 kPa 50 count */
+       14360,  /*  13.32 kPa 51 count */
+       14334,  /*  13.38 kPa 52 count */
+       14308,  /*  13.43 kPa 53 count */
+       14283,  /*  13.49 kPa 54 count */
+       14257,  /*  13.54 kPa 55 count */
+       14232,  /*  13.60 kPa 56 count */
+       14207,  /*  13.65 kPa 57 count */
+       14182,  /*  13.70 kPa 58 count */
+       14156,  /*  13.76 kPa 59 count */
+       14132,  /*  13.81 kPa 60 count */
+       14107,  /*  13.87 kPa 61 count */
+       14082,  /*  13.92 kPa 62 count */
+       14057,  /*  13.98 kPa 63 count */
+       14033,  /*  14.03 kPa 64 count */
+       14008,  /*  14.08 kPa 65 count */
+       13984,  /*  14.14 kPa 66 count */
+       13959,  /*  14.19 kPa 67 count */
+       13935,  /*  14.25 kPa 68 count */
+       13911,  /*  14.30 kPa 69 count */
+       13887,  /*  14.36 kPa 70 count */
+       13863,  /*  14.41 kPa 71 count */
+       13839,  /*  14.46 kPa 72 count */
+       13816,  /*  14.52 kPa 73 count */
+       13792,  /*  14.57 kPa 74 count */
+       13768,  /*  14.63 kPa 75 count */
+       13745,  /*  14.68 kPa 76 count */
+       13721,  /*  14.74 kPa 77 count */
+       13698,  /*  14.79 kPa 78 count */
+       13675,  /*  14.84 kPa 79 count */
+       13652,  /*  14.90 kPa 80 count */
+       13629,  /*  14.95 kPa 81 count */
+       13606,  /*  15.01 kPa 82 count */
+       13583,  /*  15.06 kPa 83 count */
+       13560,  /*  15.12 kPa 84 count */
+       13537,  /*  15.17 kPa 85 count */
+       13515,  /*  15.22 kPa 86 count */
+       13492,  /*  15.28 kPa 87 count */
+       13470,  /*  15.33 kPa 88 count */
+       13447,  /*  15.39 kPa 89 count */
+       13425,  /*  15.44 kPa 90 count */
+       13403,  /*  15.50 kPa 91 count */
+       13380,  /*  15.55 kPa 92 count */
+       13358,  /*  15.60 kPa 93 count */
+       13336,  /*  15.66 kPa 94 count */
+       13314,  /*  15.71 kPa 95 count */
+       13292,  /*  15.77 kPa 96 count */
+       13271,  /*  15.82 kPa 97 count */
+       13249,  /*  15.87 kPa 98 count */
+       13227,  /*  15.93 kPa 99 count */
+       13206,  /*  15.98 kPa 100 count */
+       13184,  /*  16.04 kPa 101 count */
+       13163,  /*  16.09 kPa 102 count */
+       13141,  /*  16.15 kPa 103 count */
+       13120,  /*  16.20 kPa 104 count */
+       13099,  /*  16.25 kPa 105 count */
+       13078,  /*  16.31 kPa 106 count */
+       13057,  /*  16.36 kPa 107 count */
+       13036,  /*  16.42 kPa 108 count */
+       13015,  /*  16.47 kPa 109 count */
+       12994,  /*  16.53 kPa 110 count */
+       12973,  /*  16.58 kPa 111 count */
+       12952,  /*  16.63 kPa 112 count */
+       12932,  /*  16.69 kPa 113 count */
+       12911,  /*  16.74 kPa 114 count */
+       12891,  /*  16.80 kPa 115 count */
+       12870,  /*  16.85 kPa 116 count */
+       12850,  /*  16.91 kPa 117 count */
+       12829,  /*  16.96 kPa 118 count */
+       12809,  /*  17.01 kPa 119 count */
+       12789,  /*  17.07 kPa 120 count */
+       12769,  /*  17.12 kPa 121 count */
+       12749,  /*  17.18 kPa 122 count */
+       12729,  /*  17.23 kPa 123 count */
+       12709,  /*  17.29 kPa 124 count */
+       12689,  /*  17.34 kPa 125 count */
+       12669,  /*  17.39 kPa 126 count */
+       12649,  /*  17.45 kPa 127 count */
+       12630,  /*  17.50 kPa 128 count */
+       12610,  /*  17.56 kPa 129 count */
+       12590,  /*  17.61 kPa 130 count */
+       12571,  /*  17.67 kPa 131 count */
+       12551,  /*  17.72 kPa 132 count */
+       12532,  /*  17.77 kPa 133 count */
+       12513,  /*  17.83 kPa 134 count */
+       12493,  /*  17.88 kPa 135 count */
+       12474,  /*  17.94 kPa 136 count */
+       12455,  /*  17.99 kPa 137 count */
+       12436,  /*  18.05 kPa 138 count */
+       12417,  /*  18.10 kPa 139 count */
+       12398,  /*  18.15 kPa 140 count */
+       12379,  /*  18.21 kPa 141 count */
+       12360,  /*  18.26 kPa 142 count */
+       12341,  /*  18.32 kPa 143 count */
+       12323,  /*  18.37 kPa 144 count */
+       12304,  /*  18.43 kPa 145 count */
+       12285,  /*  18.48 kPa 146 count */
+       12267,  /*  18.53 kPa 147 count */
+       12248,  /*  18.59 kPa 148 count */
+       12230,  /*  18.64 kPa 149 count */
+       12211,  /*  18.70 kPa 150 count */
+       12193,  /*  18.75 kPa 151 count */
+       12174,  /*  18.81 kPa 152 count */
+       12156,  /*  18.86 kPa 153 count */
+       12138,  /*  18.91 kPa 154 count */
+       12120,  /*  18.97 kPa 155 count */
+       12102,  /*  19.02 kPa 156 count */
+       12084,  /*  19.08 kPa 157 count */
+       12065,  /*  19.13 kPa 158 count */
+       12048,  /*  19.19 kPa 159 count */
+       12030,  /*  19.24 kPa 160 count */
+       12012,  /*  19.29 kPa 161 count */
+       11994,  /*  19.35 kPa 162 count */
+       11976,  /*  19.40 kPa 163 count */
+       11958,  /*  19.46 kPa 164 count */
+       11941,  /*  19.51 kPa 165 count */
+       11923,  /*  19.57 kPa 166 count */
+       11906,  /*  19.62 kPa 167 count */
+       11888,  /*  19.67 kPa 168 count */
+       11871,  /*  19.73 kPa 169 count */
+       11853,  /*  19.78 kPa 170 count */
+       11836,  /*  19.84 kPa 171 count */
+       11818,  /*  19.89 kPa 172 count */
+       11801,  /*  19.95 kPa 173 count */
+       11784,  /*  20.00 kPa 174 count */
+       11767,  /*  20.05 kPa 175 count */
+       11750,  /*  20.11 kPa 176 count */
+       11733,  /*  20.16 kPa 177 count */
+       11715,  /*  20.22 kPa 178 count */
+       11698,  /*  20.27 kPa 179 count */
+       11682,  /*  20.33 kPa 180 count */
+       11665,  /*  20.38 kPa 181 count */
+       11648,  /*  20.43 kPa 182 count */
+       11631,  /*  20.49 kPa 183 count */
+       11614,  /*  20.54 kPa 184 count */
+       11597,  /*  20.60 kPa 185 count */
+       11581,  /*  20.65 kPa 186 count */
+       11564,  /*  20.71 kPa 187 count */
+       11547,  /*  20.76 kPa 188 count */
+       11531,  /*  20.81 kPa 189 count */
+       11514,  /*  20.87 kPa 190 count */
+       11498,  /*  20.92 kPa 191 count */
+       11481,  /*  20.98 kPa 192 count */
+       11465,  /*  21.03 kPa 193 count */
+       11449,  /*  21.09 kPa 194 count */
+       11432,  /*  21.14 kPa 195 count */
+       11416,  /*  21.19 kPa 196 count */
+       11400,  /*  21.25 kPa 197 count */
+       11384,  /*  21.30 kPa 198 count */
+       11368,  /*  21.36 kPa 199 count */
+       11352,  /*  21.41 kPa 200 count */
+       11336,  /*  21.47 kPa 201 count */
+       11319,  /*  21.52 kPa 202 count */
+       11304,  /*  21.57 kPa 203 count */
+       11288,  /*  21.63 kPa 204 count */
+       11272,  /*  21.68 kPa 205 count */
+       11256,  /*  21.74 kPa 206 count */
+       11240,  /*  21.79 kPa 207 count */
+       11224,  /*  21.85 kPa 208 count */
+       11208,  /*  21.90 kPa 209 count */
+       11193,  /*  21.95 kPa 210 count */
+       11177,  /*  22.01 kPa 211 count */
+       11162,  /*  22.06 kPa 212 count */
+       11146,  /*  22.12 kPa 213 count */
+       11130,  /*  22.17 kPa 214 count */
+       11115,  /*  22.23 kPa 215 count */
+       11099,  /*  22.28 kPa 216 count */
+       11084,  /*  22.33 kPa 217 count */
+       11069,  /*  22.39 kPa 218 count */
+       11053,  /*  22.44 kPa 219 count */
+       11038,  /*  22.50 kPa 220 count */
+       11023,  /*  22.55 kPa 221 count */
+       11007,  /*  22.61 kPa 222 count */
+       10992,  /*  22.66 kPa 223 count */
+       10977,  /*  22.71 kPa 224 count */
+       10962,  /*  22.77 kPa 225 count */
+       10947,  /*  22.82 kPa 226 count */
+       10932,  /*  22.88 kPa 227 count */
+       10917,  /*  22.93 kPa 228 count */
+       10902,  /*  22.99 kPa 229 count */
+       10887,  /*  23.04 kPa 230 count */
+       10872,  /*  23.09 kPa 231 count */
+       10857,  /*  23.15 kPa 232 count */
+       10842,  /*  23.20 kPa 233 count */
+       10827,  /*  23.26 kPa 234 count */
+       10812,  /*  23.31 kPa 235 count */
+       10797,  /*  23.37 kPa 236 count */
+       10782,  /*  23.42 kPa 237 count */
+       10768,  /*  23.47 kPa 238 count */
+       10753,  /*  23.53 kPa 239 count */
+       10738,  /*  23.58 kPa 240 count */
+       10723,  /*  23.64 kPa 241 count */
+       10709,  /*  23.69 kPa 242 count */
+       10694,  /*  23.75 kPa 243 count */
+       10679,  /*  23.80 kPa 244 count */
+       10665,  /*  23.85 kPa 245 count */
+       10650,  /*  23.91 kPa 246 count */
+       10636,  /*  23.96 kPa 247 count */
+       10621,  /*  24.02 kPa 248 count */
+       10607,  /*  24.07 kPa 249 count */
+       10592,  /*  24.13 kPa 250 count */
+       10578,  /*  24.18 kPa 251 count */
+       10563,  /*  24.23 kPa 252 count */
+       10549,  /*  24.29 kPa 253 count */
+       10535,  /*  24.34 kPa 254 count */
+       10520,  /*  24.40 kPa 255 count */
+       10506,  /*  24.45 kPa 256 count */
+       10492,  /*  24.51 kPa 257 count */
+       10478,  /*  24.56 kPa 258 count */
+       10463,  /*  24.61 kPa 259 count */
+       10449,  /*  24.67 kPa 260 count */
+       10435,  /*  24.72 kPa 261 count */
+       10421,  /*  24.78 kPa 262 count */
+       10407,  /*  24.83 kPa 263 count */
+       10393,  /*  24.89 kPa 264 count */
+       10379,  /*  24.94 kPa 265 count */
+       10364,  /*  24.99 kPa 266 count */
+       10350,  /*  25.05 kPa 267 count */
+       10336,  /*  25.10 kPa 268 count */
+       10322,  /*  25.16 kPa 269 count */
+       10309,  /*  25.21 kPa 270 count */
+       10295,  /*  25.27 kPa 271 count */
+       10281,  /*  25.32 kPa 272 count */
+       10267,  /*  25.37 kPa 273 count */
+       10253,  /*  25.43 kPa 274 count */
+       10239,  /*  25.48 kPa 275 count */
+       10225,  /*  25.54 kPa 276 count */
+       10212,  /*  25.59 kPa 277 count */
+       10198,  /*  25.65 kPa 278 count */
+       10184,  /*  25.70 kPa 279 count */
+       10170,  /*  25.75 kPa 280 count */
+       10157,  /*  25.81 kPa 281 count */
+       10143,  /*  25.86 kPa 282 count */
+       10129,  /*  25.92 kPa 283 count */
+       10116,  /*  25.97 kPa 284 count */
+       10102,  /*  26.03 kPa 285 count */
+       10089,  /*  26.08 kPa 286 count */
+       10075,  /*  26.13 kPa 287 count */
+       10062,  /*  26.19 kPa 288 count */
+       10048,  /*  26.24 kPa 289 count */
+       10035,  /*  26.30 kPa 290 count */
+       10021,  /*  26.35 kPa 291 count */
+       10008,  /*  26.41 kPa 292 count */
+       9994,   /*  26.46 kPa 293 count */
+       9981,   /*  26.51 kPa 294 count */
+       9967,   /*  26.57 kPa 295 count */
+       9954,   /*  26.62 kPa 296 count */
+       9941,   /*  26.68 kPa 297 count */
+       9928,   /*  26.73 kPa 298 count */
+       9914,   /*  26.79 kPa 299 count */
+       9901,   /*  26.84 kPa 300 count */
+       9888,   /*  26.89 kPa 301 count */
+       9875,   /*  26.95 kPa 302 count */
+       9861,   /*  27.00 kPa 303 count */
+       9848,   /*  27.06 kPa 304 count */
+       9835,   /*  27.11 kPa 305 count */
+       9822,   /*  27.17 kPa 306 count */
+       9809,   /*  27.22 kPa 307 count */
+       9796,   /*  27.27 kPa 308 count */
+       9783,   /*  27.33 kPa 309 count */
+       9770,   /*  27.38 kPa 310 count */
+       9757,   /*  27.44 kPa 311 count */
+       9744,   /*  27.49 kPa 312 count */
+       9731,   /*  27.55 kPa 313 count */
+       9718,   /*  27.60 kPa 314 count */
+       9705,   /*  27.65 kPa 315 count */
+       9692,   /*  27.71 kPa 316 count */
+       9679,   /*  27.76 kPa 317 count */
+       9666,   /*  27.82 kPa 318 count */
+       9653,   /*  27.87 kPa 319 count */
+       9640,   /*  27.93 kPa 320 count */
+       9627,   /*  27.98 kPa 321 count */
+       9615,   /*  28.03 kPa 322 count */
+       9602,   /*  28.09 kPa 323 count */
+       9589,   /*  28.14 kPa 324 count */
+       9576,   /*  28.20 kPa 325 count */
+       9564,   /*  28.25 kPa 326 count */
+       9551,   /*  28.31 kPa 327 count */
+       9538,   /*  28.36 kPa 328 count */
+       9526,   /*  28.41 kPa 329 count */
+       9513,   /*  28.47 kPa 330 count */
+       9500,   /*  28.52 kPa 331 count */
+       9488,   /*  28.58 kPa 332 count */
+       9475,   /*  28.63 kPa 333 count */
+       9463,   /*  28.69 kPa 334 count */
+       9450,   /*  28.74 kPa 335 count */
+       9438,   /*  28.79 kPa 336 count */
+       9425,   /*  28.85 kPa 337 count */
+       9413,   /*  28.90 kPa 338 count */
+       9400,   /*  28.96 kPa 339 count */
+       9388,   /*  29.01 kPa 340 count */
+       9375,   /*  29.07 kPa 341 count */
+       9363,   /*  29.12 kPa 342 count */
+       9350,   /*  29.17 kPa 343 count */
+       9338,   /*  29.23 kPa 344 count */
+       9326,   /*  29.28 kPa 345 count */
+       9313,   /*  29.34 kPa 346 count */
+       9301,   /*  29.39 kPa 347 count */
+       9289,   /*  29.44 kPa 348 count */
+       9276,   /*  29.50 kPa 349 count */
+       9264,   /*  29.55 kPa 350 count */
+       9252,   /*  29.61 kPa 351 count */
+       9240,   /*  29.66 kPa 352 count */
+       9227,   /*  29.72 kPa 353 count */
+       9215,   /*  29.77 kPa 354 count */
+       9203,   /*  29.82 kPa 355 count */
+       9191,   /*  29.88 kPa 356 count */
+       9179,   /*  29.93 kPa 357 count */
+       9167,   /*  29.99 kPa 358 count */
+       9155,   /*  30.04 kPa 359 count */
+       9142,   /*  30.10 kPa 360 count */
+       9130,   /*  30.15 kPa 361 count */
+       9118,   /*  30.20 kPa 362 count */
+       9106,   /*  30.26 kPa 363 count */
+       9094,   /*  30.31 kPa 364 count */
+       9082,   /*  30.37 kPa 365 count */
+       9070,   /*  30.42 kPa 366 count */
+       9058,   /*  30.48 kPa 367 count */
+       9046,   /*  30.53 kPa 368 count */
+       9035,   /*  30.58 kPa 369 count */
+       9023,   /*  30.64 kPa 370 count */
+       9011,   /*  30.69 kPa 371 count */
+       8999,   /*  30.75 kPa 372 count */
+       8987,   /*  30.80 kPa 373 count */
+       8975,   /*  30.86 kPa 374 count */
+       8963,   /*  30.91 kPa 375 count */
+       8952,   /*  30.96 kPa 376 count */
+       8940,   /*  31.02 kPa 377 count */
+       8928,   /*  31.07 kPa 378 count */
+       8916,   /*  31.13 kPa 379 count */
+       8904,   /*  31.18 kPa 380 count */
+       8893,   /*  31.24 kPa 381 count */
+       8881,   /*  31.29 kPa 382 count */
+       8869,   /*  31.34 kPa 383 count */
+       8858,   /*  31.40 kPa 384 count */
+       8846,   /*  31.45 kPa 385 count */
+       8834,   /*  31.51 kPa 386 count */
+       8823,   /*  31.56 kPa 387 count */
+       8811,   /*  31.62 kPa 388 count */
+       8800,   /*  31.67 kPa 389 count */
+       8788,   /*  31.72 kPa 390 count */
+       8776,   /*  31.78 kPa 391 count */
+       8765,   /*  31.83 kPa 392 count */
+       8753,   /*  31.89 kPa 393 count */
+       8742,   /*  31.94 kPa 394 count */
+       8730,   /*  32.00 kPa 395 count */
+       8719,   /*  32.05 kPa 396 count */
+       8707,   /*  32.10 kPa 397 count */
+       8696,   /*  32.16 kPa 398 count */
+       8684,   /*  32.21 kPa 399 count */
+       8673,   /*  32.27 kPa 400 count */
+       8662,   /*  32.32 kPa 401 count */
+       8650,   /*  32.38 kPa 402 count */
+       8639,   /*  32.43 kPa 403 count */
+       8628,   /*  32.48 kPa 404 count */
+       8616,   /*  32.54 kPa 405 count */
+       8605,   /*  32.59 kPa 406 count */
+       8594,   /*  32.65 kPa 407 count */
+       8582,   /*  32.70 kPa 408 count */
+       8571,   /*  32.76 kPa 409 count */
+       8560,   /*  32.81 kPa 410 count */
+       8548,   /*  32.86 kPa 411 count */
+       8537,   /*  32.92 kPa 412 count */
+       8526,   /*  32.97 kPa 413 count */
+       8515,   /*  33.03 kPa 414 count */
+       8504,   /*  33.08 kPa 415 count */
+       8492,   /*  33.14 kPa 416 count */
+       8481,   /*  33.19 kPa 417 count */
+       8470,   /*  33.24 kPa 418 count */
+       8459,   /*  33.30 kPa 419 count */
+       8448,   /*  33.35 kPa 420 count */
+       8437,   /*  33.41 kPa 421 count */
+       8426,   /*  33.46 kPa 422 count */
+       8415,   /*  33.52 kPa 423 count */
+       8403,   /*  33.57 kPa 424 count */
+       8392,   /*  33.62 kPa 425 count */
+       8381,   /*  33.68 kPa 426 count */
+       8370,   /*  33.73 kPa 427 count */
+       8359,   /*  33.79 kPa 428 count */
+       8348,   /*  33.84 kPa 429 count */
+       8337,   /*  33.90 kPa 430 count */
+       8326,   /*  33.95 kPa 431 count */
+       8316,   /*  34.00 kPa 432 count */
+       8305,   /*  34.06 kPa 433 count */
+       8294,   /*  34.11 kPa 434 count */
+       8283,   /*  34.17 kPa 435 count */
+       8272,   /*  34.22 kPa 436 count */
+       8261,   /*  34.28 kPa 437 count */
+       8250,   /*  34.33 kPa 438 count */
+       8239,   /*  34.38 kPa 439 count */
+       8228,   /*  34.44 kPa 440 count */
+       8218,   /*  34.49 kPa 441 count */
+       8207,   /*  34.55 kPa 442 count */
+       8196,   /*  34.60 kPa 443 count */
+       8185,   /*  34.66 kPa 444 count */
+       8175,   /*  34.71 kPa 445 count */
+       8164,   /*  34.76 kPa 446 count */
+       8153,   /*  34.82 kPa 447 count */
+       8142,   /*  34.87 kPa 448 count */
+       8132,   /*  34.93 kPa 449 count */
+       8121,   /*  34.98 kPa 450 count */
+       8110,   /*  35.04 kPa 451 count */
+       8100,   /*  35.09 kPa 452 count */
+       8089,   /*  35.14 kPa 453 count */
+       8078,   /*  35.20 kPa 454 count */
+       8068,   /*  35.25 kPa 455 count */
+       8057,   /*  35.31 kPa 456 count */
+       8046,   /*  35.36 kPa 457 count */
+       8036,   /*  35.42 kPa 458 count */
+       8025,   /*  35.47 kPa 459 count */
+       8015,   /*  35.52 kPa 460 count */
+       8004,   /*  35.58 kPa 461 count */
+       7994,   /*  35.63 kPa 462 count */
+       7983,   /*  35.69 kPa 463 count */
+       7973,   /*  35.74 kPa 464 count */
+       7962,   /*  35.80 kPa 465 count */
+       7952,   /*  35.85 kPa 466 count */
+       7941,   /*  35.90 kPa 467 count */
+       7931,   /*  35.96 kPa 468 count */
+       7920,   /*  36.01 kPa 469 count */
+       7910,   /*  36.07 kPa 470 count */
+       7899,   /*  36.12 kPa 471 count */
+       7889,   /*  36.18 kPa 472 count */
+       7879,   /*  36.23 kPa 473 count */
+       7868,   /*  36.28 kPa 474 count */
+       7858,   /*  36.34 kPa 475 count */
+       7847,   /*  36.39 kPa 476 count */
+       7837,   /*  36.45 kPa 477 count */
+       7827,   /*  36.50 kPa 478 count */
+       7816,   /*  36.56 kPa 479 count */
+       7806,   /*  36.61 kPa 480 count */
+       7796,   /*  36.66 kPa 481 count */
+       7785,   /*  36.72 kPa 482 count */
+       7775,   /*  36.77 kPa 483 count */
+       7765,   /*  36.83 kPa 484 count */
+       7755,   /*  36.88 kPa 485 count */
+       7744,   /*  36.94 kPa 486 count */
+       7734,   /*  36.99 kPa 487 count */
+       7724,   /*  37.04 kPa 488 count */
+       7714,   /*  37.10 kPa 489 count */
+       7704,   /*  37.15 kPa 490 count */
+       7693,   /*  37.21 kPa 491 count */
+       7683,   /*  37.26 kPa 492 count */
+       7673,   /*  37.32 kPa 493 count */
+       7663,   /*  37.37 kPa 494 count */
+       7653,   /*  37.42 kPa 495 count */
+       7643,   /*  37.48 kPa 496 count */
+       7633,   /*  37.53 kPa 497 count */
+       7623,   /*  37.59 kPa 498 count */
+       7613,   /*  37.64 kPa 499 count */
+       7602,   /*  37.70 kPa 500 count */
+       7592,   /*  37.75 kPa 501 count */
+       7582,   /*  37.80 kPa 502 count */
+       7572,   /*  37.86 kPa 503 count */
+       7562,   /*  37.91 kPa 504 count */
+       7552,   /*  37.97 kPa 505 count */
+       7542,   /*  38.02 kPa 506 count */
+       7532,   /*  38.08 kPa 507 count */
+       7522,   /*  38.13 kPa 508 count */
+       7512,   /*  38.18 kPa 509 count */
+       7502,   /*  38.24 kPa 510 count */
+       7492,   /*  38.29 kPa 511 count */
+       7483,   /*  38.35 kPa 512 count */
+       7473,   /*  38.40 kPa 513 count */
+       7463,   /*  38.46 kPa 514 count */
+       7453,   /*  38.51 kPa 515 count */
+       7443,   /*  38.56 kPa 516 count */
+       7433,   /*  38.62 kPa 517 count */
+       7423,   /*  38.67 kPa 518 count */
+       7413,   /*  38.73 kPa 519 count */
+       7403,   /*  38.78 kPa 520 count */
+       7394,   /*  38.84 kPa 521 count */
+       7384,   /*  38.89 kPa 522 count */
+       7374,   /*  38.94 kPa 523 count */
+       7364,   /*  39.00 kPa 524 count */
+       7354,   /*  39.05 kPa 525 count */
+       7345,   /*  39.11 kPa 526 count */
+       7335,   /*  39.16 kPa 527 count */
+       7325,   /*  39.22 kPa 528 count */
+       7315,   /*  39.27 kPa 529 count */
+       7306,   /*  39.32 kPa 530 count */
+       7296,   /*  39.38 kPa 531 count */
+       7286,   /*  39.43 kPa 532 count */
+       7277,   /*  39.49 kPa 533 count */
+       7267,   /*  39.54 kPa 534 count */
+       7257,   /*  39.60 kPa 535 count */
+       7248,   /*  39.65 kPa 536 count */
+       7238,   /*  39.70 kPa 537 count */
+       7228,   /*  39.76 kPa 538 count */
+       7219,   /*  39.81 kPa 539 count */
+       7209,   /*  39.87 kPa 540 count */
+       7199,   /*  39.92 kPa 541 count */
+       7190,   /*  39.98 kPa 542 count */
+       7180,   /*  40.03 kPa 543 count */
+       7171,   /*  40.08 kPa 544 count */
+       7161,   /*  40.14 kPa 545 count */
+       7152,   /*  40.19 kPa 546 count */
+       7142,   /*  40.25 kPa 547 count */
+       7132,   /*  40.30 kPa 548 count */
+       7123,   /*  40.36 kPa 549 count */
+       7113,   /*  40.41 kPa 550 count */
+       7104,   /*  40.46 kPa 551 count */
+       7094,   /*  40.52 kPa 552 count */
+       7085,   /*  40.57 kPa 553 count */
+       7075,   /*  40.63 kPa 554 count */
+       7066,   /*  40.68 kPa 555 count */
+       7056,   /*  40.74 kPa 556 count */
+       7047,   /*  40.79 kPa 557 count */
+       7038,   /*  40.84 kPa 558 count */
+       7028,   /*  40.90 kPa 559 count */
+       7019,   /*  40.95 kPa 560 count */
+       7009,   /*  41.01 kPa 561 count */
+       7000,   /*  41.06 kPa 562 count */
+       6991,   /*  41.12 kPa 563 count */
+       6981,   /*  41.17 kPa 564 count */
+       6972,   /*  41.22 kPa 565 count */
+       6962,   /*  41.28 kPa 566 count */
+       6953,   /*  41.33 kPa 567 count */
+       6944,   /*  41.39 kPa 568 count */
+       6934,   /*  41.44 kPa 569 count */
+       6925,   /*  41.50 kPa 570 count */
+       6916,   /*  41.55 kPa 571 count */
+       6907,   /*  41.60 kPa 572 count */
+       6897,   /*  41.66 kPa 573 count */
+       6888,   /*  41.71 kPa 574 count */
+       6879,   /*  41.77 kPa 575 count */
+       6869,   /*  41.82 kPa 576 count */
+       6860,   /*  41.88 kPa 577 count */
+       6851,   /*  41.93 kPa 578 count */
+       6842,   /*  41.98 kPa 579 count */
+       6833,   /*  42.04 kPa 580 count */
+       6823,   /*  42.09 kPa 581 count */
+       6814,   /*  42.15 kPa 582 count */
+       6805,   /*  42.20 kPa 583 count */
+       6796,   /*  42.26 kPa 584 count */
+       6787,   /*  42.31 kPa 585 count */
+       6777,   /*  42.36 kPa 586 count */
+       6768,   /*  42.42 kPa 587 count */
+       6759,   /*  42.47 kPa 588 count */
+       6750,   /*  42.53 kPa 589 count */
+       6741,   /*  42.58 kPa 590 count */
+       6732,   /*  42.64 kPa 591 count */
+       6723,   /*  42.69 kPa 592 count */
+       6714,   /*  42.74 kPa 593 count */
+       6705,   /*  42.80 kPa 594 count */
+       6695,   /*  42.85 kPa 595 count */
+       6686,   /*  42.91 kPa 596 count */
+       6677,   /*  42.96 kPa 597 count */
+       6668,   /*  43.01 kPa 598 count */
+       6659,   /*  43.07 kPa 599 count */
+       6650,   /*  43.12 kPa 600 count */
+       6641,   /*  43.18 kPa 601 count */
+       6632,   /*  43.23 kPa 602 count */
+       6623,   /*  43.29 kPa 603 count */
+       6614,   /*  43.34 kPa 604 count */
+       6605,   /*  43.39 kPa 605 count */
+       6596,   /*  43.45 kPa 606 count */
+       6587,   /*  43.50 kPa 607 count */
+       6578,   /*  43.56 kPa 608 count */
+       6569,   /*  43.61 kPa 609 count */
+       6560,   /*  43.67 kPa 610 count */
+       6552,   /*  43.72 kPa 611 count */
+       6543,   /*  43.77 kPa 612 count */
+       6534,   /*  43.83 kPa 613 count */
+       6525,   /*  43.88 kPa 614 count */
+       6516,   /*  43.94 kPa 615 count */
+       6507,   /*  43.99 kPa 616 count */
+       6498,   /*  44.05 kPa 617 count */
+       6489,   /*  44.10 kPa 618 count */
+       6480,   /*  44.15 kPa 619 count */
+       6472,   /*  44.21 kPa 620 count */
+       6463,   /*  44.26 kPa 621 count */
+       6454,   /*  44.32 kPa 622 count */
+       6445,   /*  44.37 kPa 623 count */
+       6436,   /*  44.43 kPa 624 count */
+       6427,   /*  44.48 kPa 625 count */
+       6419,   /*  44.53 kPa 626 count */
+       6410,   /*  44.59 kPa 627 count */
+       6401,   /*  44.64 kPa 628 count */
+       6392,   /*  44.70 kPa 629 count */
+       6384,   /*  44.75 kPa 630 count */
+       6375,   /*  44.81 kPa 631 count */
+       6366,   /*  44.86 kPa 632 count */
+       6357,   /*  44.91 kPa 633 count */
+       6349,   /*  44.97 kPa 634 count */
+       6340,   /*  45.02 kPa 635 count */
+       6331,   /*  45.08 kPa 636 count */
+       6322,   /*  45.13 kPa 637 count */
+       6314,   /*  45.19 kPa 638 count */
+       6305,   /*  45.24 kPa 639 count */
+       6296,   /*  45.29 kPa 640 count */
+       6288,   /*  45.35 kPa 641 count */
+       6279,   /*  45.40 kPa 642 count */
+       6270,   /*  45.46 kPa 643 count */
+       6262,   /*  45.51 kPa 644 count */
+       6253,   /*  45.57 kPa 645 count */
+       6245,   /*  45.62 kPa 646 count */
+       6236,   /*  45.67 kPa 647 count */
+       6227,   /*  45.73 kPa 648 count */
+       6219,   /*  45.78 kPa 649 count */
+       6210,   /*  45.84 kPa 650 count */
+       6202,   /*  45.89 kPa 651 count */
+       6193,   /*  45.95 kPa 652 count */
+       6184,   /*  46.00 kPa 653 count */
+       6176,   /*  46.05 kPa 654 count */
+       6167,   /*  46.11 kPa 655 count */
+       6159,   /*  46.16 kPa 656 count */
+       6150,   /*  46.22 kPa 657 count */
+       6142,   /*  46.27 kPa 658 count */
+       6133,   /*  46.33 kPa 659 count */
+       6125,   /*  46.38 kPa 660 count */
+       6116,   /*  46.43 kPa 661 count */
+       6108,   /*  46.49 kPa 662 count */
+       6099,   /*  46.54 kPa 663 count */
+       6091,   /*  46.60 kPa 664 count */
+       6082,   /*  46.65 kPa 665 count */
+       6074,   /*  46.71 kPa 666 count */
+       6065,   /*  46.76 kPa 667 count */
+       6057,   /*  46.81 kPa 668 count */
+       6048,   /*  46.87 kPa 669 count */
+       6040,   /*  46.92 kPa 670 count */
+       6032,   /*  46.98 kPa 671 count */
+       6023,   /*  47.03 kPa 672 count */
+       6015,   /*  47.09 kPa 673 count */
+       6006,   /*  47.14 kPa 674 count */
+       5998,   /*  47.19 kPa 675 count */
+       5990,   /*  47.25 kPa 676 count */
+       5981,   /*  47.30 kPa 677 count */
+       5973,   /*  47.36 kPa 678 count */
+       5964,   /*  47.41 kPa 679 count */
+       5956,   /*  47.47 kPa 680 count */
+       5948,   /*  47.52 kPa 681 count */
+       5939,   /*  47.57 kPa 682 count */
+       5931,   /*  47.63 kPa 683 count */
+       5923,   /*  47.68 kPa 684 count */
+       5914,   /*  47.74 kPa 685 count */
+       5906,   /*  47.79 kPa 686 count */
+       5898,   /*  47.85 kPa 687 count */
+       5890,   /*  47.90 kPa 688 count */
+       5881,   /*  47.95 kPa 689 count */
+       5873,   /*  48.01 kPa 690 count */
+       5865,   /*  48.06 kPa 691 count */
+       5856,   /*  48.12 kPa 692 count */
+       5848,   /*  48.17 kPa 693 count */
+       5840,   /*  48.23 kPa 694 count */
+       5832,   /*  48.28 kPa 695 count */
+       5823,   /*  48.33 kPa 696 count */
+       5815,   /*  48.39 kPa 697 count */
+       5807,   /*  48.44 kPa 698 count */
+       5799,   /*  48.50 kPa 699 count */
+       5791,   /*  48.55 kPa 700 count */
+       5782,   /*  48.61 kPa 701 count */
+       5774,   /*  48.66 kPa 702 count */
+       5766,   /*  48.71 kPa 703 count */
+       5758,   /*  48.77 kPa 704 count */
+       5750,   /*  48.82 kPa 705 count */
+       5742,   /*  48.88 kPa 706 count */
+       5733,   /*  48.93 kPa 707 count */
+       5725,   /*  48.99 kPa 708 count */
+       5717,   /*  49.04 kPa 709 count */
+       5709,   /*  49.09 kPa 710 count */
+       5701,   /*  49.15 kPa 711 count */
+       5693,   /*  49.20 kPa 712 count */
+       5685,   /*  49.26 kPa 713 count */
+       5677,   /*  49.31 kPa 714 count */
+       5668,   /*  49.37 kPa 715 count */
+       5660,   /*  49.42 kPa 716 count */
+       5652,   /*  49.47 kPa 717 count */
+       5644,   /*  49.53 kPa 718 count */
+       5636,   /*  49.58 kPa 719 count */
+       5628,   /*  49.64 kPa 720 count */
+       5620,   /*  49.69 kPa 721 count */
+       5612,   /*  49.75 kPa 722 count */
+       5604,   /*  49.80 kPa 723 count */
+       5596,   /*  49.85 kPa 724 count */
+       5588,   /*  49.91 kPa 725 count */
+       5580,   /*  49.96 kPa 726 count */
+       5572,   /*  50.02 kPa 727 count */
+       5564,   /*  50.07 kPa 728 count */
+       5556,   /*  50.13 kPa 729 count */
+       5548,   /*  50.18 kPa 730 count */
+       5540,   /*  50.23 kPa 731 count */
+       5532,   /*  50.29 kPa 732 count */
+       5524,   /*  50.34 kPa 733 count */
+       5516,   /*  50.40 kPa 734 count */
+       5508,   /*  50.45 kPa 735 count */
+       5500,   /*  50.51 kPa 736 count */
+       5492,   /*  50.56 kPa 737 count */
+       5484,   /*  50.61 kPa 738 count */
+       5476,   /*  50.67 kPa 739 count */
+       5468,   /*  50.72 kPa 740 count */
+       5461,   /*  50.78 kPa 741 count */
+       5453,   /*  50.83 kPa 742 count */
+       5445,   /*  50.89 kPa 743 count */
+       5437,   /*  50.94 kPa 744 count */
+       5429,   /*  50.99 kPa 745 count */
+       5421,   /*  51.05 kPa 746 count */
+       5413,   /*  51.10 kPa 747 count */
+       5405,   /*  51.16 kPa 748 count */
+       5398,   /*  51.21 kPa 749 count */
+       5390,   /*  51.27 kPa 750 count */
+       5382,   /*  51.32 kPa 751 count */
+       5374,   /*  51.37 kPa 752 count */
+       5366,   /*  51.43 kPa 753 count */
+       5358,   /*  51.48 kPa 754 count */
+       5351,   /*  51.54 kPa 755 count */
+       5343,   /*  51.59 kPa 756 count */
+       5335,   /*  51.65 kPa 757 count */
+       5327,   /*  51.70 kPa 758 count */
+       5319,   /*  51.75 kPa 759 count */
+       5312,   /*  51.81 kPa 760 count */
+       5304,   /*  51.86 kPa 761 count */
+       5296,   /*  51.92 kPa 762 count */
+       5288,   /*  51.97 kPa 763 count */
+       5281,   /*  52.03 kPa 764 count */
+       5273,   /*  52.08 kPa 765 count */
+       5265,   /*  52.13 kPa 766 count */
+       5257,   /*  52.19 kPa 767 count */
+       5250,   /*  52.24 kPa 768 count */
+       5242,   /*  52.30 kPa 769 count */
+       5234,   /*  52.35 kPa 770 count */
+       5226,   /*  52.41 kPa 771 count */
+       5219,   /*  52.46 kPa 772 count */
+       5211,   /*  52.51 kPa 773 count */
+       5203,   /*  52.57 kPa 774 count */
+       5196,   /*  52.62 kPa 775 count */
+       5188,   /*  52.68 kPa 776 count */
+       5180,   /*  52.73 kPa 777 count */
+       5173,   /*  52.79 kPa 778 count */
+       5165,   /*  52.84 kPa 779 count */
+       5157,   /*  52.89 kPa 780 count */
+       5150,   /*  52.95 kPa 781 count */
+       5142,   /*  53.00 kPa 782 count */
+       5134,   /*  53.06 kPa 783 count */
+       5127,   /*  53.11 kPa 784 count */
+       5119,   /*  53.17 kPa 785 count */
+       5112,   /*  53.22 kPa 786 count */
+       5104,   /*  53.27 kPa 787 count */
+       5096,   /*  53.33 kPa 788 count */
+       5089,   /*  53.38 kPa 789 count */
+       5081,   /*  53.44 kPa 790 count */
+       5074,   /*  53.49 kPa 791 count */
+       5066,   /*  53.55 kPa 792 count */
+       5058,   /*  53.60 kPa 793 count */
+       5051,   /*  53.65 kPa 794 count */
+       5043,   /*  53.71 kPa 795 count */
+       5036,   /*  53.76 kPa 796 count */
+       5028,   /*  53.82 kPa 797 count */
+       5021,   /*  53.87 kPa 798 count */
+       5013,   /*  53.93 kPa 799 count */
+       5006,   /*  53.98 kPa 800 count */
+       4998,   /*  54.03 kPa 801 count */
+       4991,   /*  54.09 kPa 802 count */
+       4983,   /*  54.14 kPa 803 count */
+       4976,   /*  54.20 kPa 804 count */
+       4968,   /*  54.25 kPa 805 count */
+       4961,   /*  54.31 kPa 806 count */
+       4953,   /*  54.36 kPa 807 count */
+       4946,   /*  54.41 kPa 808 count */
+       4938,   /*  54.47 kPa 809 count */
+       4931,   /*  54.52 kPa 810 count */
+       4923,   /*  54.58 kPa 811 count */
+       4916,   /*  54.63 kPa 812 count */
+       4908,   /*  54.69 kPa 813 count */
+       4901,   /*  54.74 kPa 814 count */
+       4893,   /*  54.79 kPa 815 count */
+       4886,   /*  54.85 kPa 816 count */
+       4879,   /*  54.90 kPa 817 count */
+       4871,   /*  54.96 kPa 818 count */
+       4864,   /*  55.01 kPa 819 count */
+       4856,   /*  55.07 kPa 820 count */
+       4849,   /*  55.12 kPa 821 count */
+       4842,   /*  55.17 kPa 822 count */
+       4834,   /*  55.23 kPa 823 count */
+       4827,   /*  55.28 kPa 824 count */
+       4819,   /*  55.34 kPa 825 count */
+       4812,   /*  55.39 kPa 826 count */
+       4805,   /*  55.45 kPa 827 count */
+       4797,   /*  55.50 kPa 828 count */
+       4790,   /*  55.55 kPa 829 count */
+       4783,   /*  55.61 kPa 830 count */
+       4775,   /*  55.66 kPa 831 count */
+       4768,   /*  55.72 kPa 832 count */
+       4761,   /*  55.77 kPa 833 count */
+       4753,   /*  55.83 kPa 834 count */
+       4746,   /*  55.88 kPa 835 count */
+       4739,   /*  55.93 kPa 836 count */
+       4731,   /*  55.99 kPa 837 count */
+       4724,   /*  56.04 kPa 838 count */
+       4717,   /*  56.10 kPa 839 count */
+       4709,   /*  56.15 kPa 840 count */
+       4702,   /*  56.21 kPa 841 count */
+       4695,   /*  56.26 kPa 842 count */
+       4688,   /*  56.31 kPa 843 count */
+       4680,   /*  56.37 kPa 844 count */
+       4673,   /*  56.42 kPa 845 count */
+       4666,   /*  56.48 kPa 846 count */
+       4659,   /*  56.53 kPa 847 count */
+       4651,   /*  56.58 kPa 848 count */
+       4644,   /*  56.64 kPa 849 count */
+       4637,   /*  56.69 kPa 850 count */
+       4630,   /*  56.75 kPa 851 count */
+       4622,   /*  56.80 kPa 852 count */
+       4615,   /*  56.86 kPa 853 count */
+       4608,   /*  56.91 kPa 854 count */
+       4601,   /*  56.96 kPa 855 count */
+       4594,   /*  57.02 kPa 856 count */
+       4586,   /*  57.07 kPa 857 count */
+       4579,   /*  57.13 kPa 858 count */
+       4572,   /*  57.18 kPa 859 count */
+       4565,   /*  57.24 kPa 860 count */
+       4558,   /*  57.29 kPa 861 count */
+       4550,   /*  57.34 kPa 862 count */
+       4543,   /*  57.40 kPa 863 count */
+       4536,   /*  57.45 kPa 864 count */
+       4529,   /*  57.51 kPa 865 count */
+       4522,   /*  57.56 kPa 866 count */
+       4515,   /*  57.62 kPa 867 count */
+       4508,   /*  57.67 kPa 868 count */
+       4500,   /*  57.72 kPa 869 count */
+       4493,   /*  57.78 kPa 870 count */
+       4486,   /*  57.83 kPa 871 count */
+       4479,   /*  57.89 kPa 872 count */
+       4472,   /*  57.94 kPa 873 count */
+       4465,   /*  58.00 kPa 874 count */
+       4458,   /*  58.05 kPa 875 count */
+       4451,   /*  58.10 kPa 876 count */
+       4444,   /*  58.16 kPa 877 count */
+       4437,   /*  58.21 kPa 878 count */
+       4429,   /*  58.27 kPa 879 count */
+       4422,   /*  58.32 kPa 880 count */
+       4415,   /*  58.38 kPa 881 count */
+       4408,   /*  58.43 kPa 882 count */
+       4401,   /*  58.48 kPa 883 count */
+       4394,   /*  58.54 kPa 884 count */
+       4387,   /*  58.59 kPa 885 count */
+       4380,   /*  58.65 kPa 886 count */
+       4373,   /*  58.70 kPa 887 count */
+       4366,   /*  58.76 kPa 888 count */
+       4359,   /*  58.81 kPa 889 count */
+       4352,   /*  58.86 kPa 890 count */
+       4345,   /*  58.92 kPa 891 count */
+       4338,   /*  58.97 kPa 892 count */
+       4331,   /*  59.03 kPa 893 count */
+       4324,   /*  59.08 kPa 894 count */
+       4317,   /*  59.14 kPa 895 count */
+       4310,   /*  59.19 kPa 896 count */
+       4303,   /*  59.24 kPa 897 count */
+       4296,   /*  59.30 kPa 898 count */
+       4289,   /*  59.35 kPa 899 count */
+       4282,   /*  59.41 kPa 900 count */
+       4275,   /*  59.46 kPa 901 count */
+       4268,   /*  59.52 kPa 902 count */
+       4261,   /*  59.57 kPa 903 count */
+       4254,   /*  59.62 kPa 904 count */
+       4247,   /*  59.68 kPa 905 count */
+       4240,   /*  59.73 kPa 906 count */
+       4234,   /*  59.79 kPa 907 count */
+       4227,   /*  59.84 kPa 908 count */
+       4220,   /*  59.90 kPa 909 count */
+       4213,   /*  59.95 kPa 910 count */
+       4206,   /*  60.00 kPa 911 count */
+       4199,   /*  60.06 kPa 912 count */
+       4192,   /*  60.11 kPa 913 count */
+       4185,   /*  60.17 kPa 914 count */
+       4178,   /*  60.22 kPa 915 count */
+       4171,   /*  60.28 kPa 916 count */
+       4164,   /*  60.33 kPa 917 count */
+       4158,   /*  60.38 kPa 918 count */
+       4151,   /*  60.44 kPa 919 count */
+       4144,   /*  60.49 kPa 920 count */
+       4137,   /*  60.55 kPa 921 count */
+       4130,   /*  60.60 kPa 922 count */
+       4123,   /*  60.66 kPa 923 count */
+       4116,   /*  60.71 kPa 924 count */
+       4110,   /*  60.76 kPa 925 count */
+       4103,   /*  60.82 kPa 926 count */
+       4096,   /*  60.87 kPa 927 count */
+       4089,   /*  60.93 kPa 928 count */
+       4082,   /*  60.98 kPa 929 count */
+       4076,   /*  61.04 kPa 930 count */
+       4069,   /*  61.09 kPa 931 count */
+       4062,   /*  61.14 kPa 932 count */
+       4055,   /*  61.20 kPa 933 count */
+       4048,   /*  61.25 kPa 934 count */
+       4042,   /*  61.31 kPa 935 count */
+       4035,   /*  61.36 kPa 936 count */
+       4028,   /*  61.42 kPa 937 count */
+       4021,   /*  61.47 kPa 938 count */
+       4014,   /*  61.52 kPa 939 count */
+       4008,   /*  61.58 kPa 940 count */
+       4001,   /*  61.63 kPa 941 count */
+       3994,   /*  61.69 kPa 942 count */
+       3987,   /*  61.74 kPa 943 count */
+       3981,   /*  61.80 kPa 944 count */
+       3974,   /*  61.85 kPa 945 count */
+       3967,   /*  61.90 kPa 946 count */
+       3960,   /*  61.96 kPa 947 count */
+       3954,   /*  62.01 kPa 948 count */
+       3947,   /*  62.07 kPa 949 count */
+       3940,   /*  62.12 kPa 950 count */
+       3934,   /*  62.18 kPa 951 count */
+       3927,   /*  62.23 kPa 952 count */
+       3920,   /*  62.28 kPa 953 count */
+       3913,   /*  62.34 kPa 954 count */
+       3907,   /*  62.39 kPa 955 count */
+       3900,   /*  62.45 kPa 956 count */
+       3893,   /*  62.50 kPa 957 count */
+       3887,   /*  62.56 kPa 958 count */
+       3880,   /*  62.61 kPa 959 count */
+       3873,   /*  62.66 kPa 960 count */
+       3867,   /*  62.72 kPa 961 count */
+       3860,   /*  62.77 kPa 962 count */
+       3853,   /*  62.83 kPa 963 count */
+       3847,   /*  62.88 kPa 964 count */
+       3840,   /*  62.94 kPa 965 count */
+       3833,   /*  62.99 kPa 966 count */
+       3827,   /*  63.04 kPa 967 count */
+       3820,   /*  63.10 kPa 968 count */
+       3814,   /*  63.15 kPa 969 count */
+       3807,   /*  63.21 kPa 970 count */
+       3800,   /*  63.26 kPa 971 count */
+       3794,   /*  63.32 kPa 972 count */
+       3787,   /*  63.37 kPa 973 count */
+       3780,   /*  63.42 kPa 974 count */
+       3774,   /*  63.48 kPa 975 count */
+       3767,   /*  63.53 kPa 976 count */
+       3761,   /*  63.59 kPa 977 count */
+       3754,   /*  63.64 kPa 978 count */
+       3748,   /*  63.70 kPa 979 count */
+       3741,   /*  63.75 kPa 980 count */
+       3734,   /*  63.80 kPa 981 count */
+       3728,   /*  63.86 kPa 982 count */
+       3721,   /*  63.91 kPa 983 count */
+       3715,   /*  63.97 kPa 984 count */
+       3708,   /*  64.02 kPa 985 count */
+       3702,   /*  64.08 kPa 986 count */
+       3695,   /*  64.13 kPa 987 count */
+       3688,   /*  64.18 kPa 988 count */
+       3682,   /*  64.24 kPa 989 count */
+       3675,   /*  64.29 kPa 990 count */
+       3669,   /*  64.35 kPa 991 count */
+       3662,   /*  64.40 kPa 992 count */
+       3656,   /*  64.46 kPa 993 count */
+       3649,   /*  64.51 kPa 994 count */
+       3643,   /*  64.56 kPa 995 count */
+       3636,   /*  64.62 kPa 996 count */
+       3630,   /*  64.67 kPa 997 count */
+       3623,   /*  64.73 kPa 998 count */
+       3617,   /*  64.78 kPa 999 count */
+       3610,   /*  64.84 kPa 1000 count */
+       3604,   /*  64.89 kPa 1001 count */
+       3597,   /*  64.94 kPa 1002 count */
+       3591,   /*  65.00 kPa 1003 count */
+       3584,   /*  65.05 kPa 1004 count */
+       3578,   /*  65.11 kPa 1005 count */
+       3571,   /*  65.16 kPa 1006 count */
+       3565,   /*  65.22 kPa 1007 count */
+       3559,   /*  65.27 kPa 1008 count */
+       3552,   /*  65.32 kPa 1009 count */
+       3546,   /*  65.38 kPa 1010 count */
+       3539,   /*  65.43 kPa 1011 count */
+       3533,   /*  65.49 kPa 1012 count */
+       3526,   /*  65.54 kPa 1013 count */
+       3520,   /*  65.60 kPa 1014 count */
+       3514,   /*  65.65 kPa 1015 count */
+       3507,   /*  65.70 kPa 1016 count */
+       3501,   /*  65.76 kPa 1017 count */
+       3494,   /*  65.81 kPa 1018 count */
+       3488,   /*  65.87 kPa 1019 count */
+       3481,   /*  65.92 kPa 1020 count */
+       3475,   /*  65.98 kPa 1021 count */
+       3469,   /*  66.03 kPa 1022 count */
+       3462,   /*  66.08 kPa 1023 count */
+       3456,   /*  66.14 kPa 1024 count */
+       3450,   /*  66.19 kPa 1025 count */
+       3443,   /*  66.25 kPa 1026 count */
+       3437,   /*  66.30 kPa 1027 count */
+       3430,   /*  66.36 kPa 1028 count */
+       3424,   /*  66.41 kPa 1029 count */
+       3418,   /*  66.46 kPa 1030 count */
+       3411,   /*  66.52 kPa 1031 count */
+       3405,   /*  66.57 kPa 1032 count */
+       3399,   /*  66.63 kPa 1033 count */
+       3392,   /*  66.68 kPa 1034 count */
+       3386,   /*  66.74 kPa 1035 count */
+       3380,   /*  66.79 kPa 1036 count */
+       3373,   /*  66.84 kPa 1037 count */
+       3367,   /*  66.90 kPa 1038 count */
+       3361,   /*  66.95 kPa 1039 count */
+       3354,   /*  67.01 kPa 1040 count */
+       3348,   /*  67.06 kPa 1041 count */
+       3342,   /*  67.12 kPa 1042 count */
+       3335,   /*  67.17 kPa 1043 count */
+       3329,   /*  67.22 kPa 1044 count */
+       3323,   /*  67.28 kPa 1045 count */
+       3316,   /*  67.33 kPa 1046 count */
+       3310,   /*  67.39 kPa 1047 count */
+       3304,   /*  67.44 kPa 1048 count */
+       3298,   /*  67.50 kPa 1049 count */
+       3291,   /*  67.55 kPa 1050 count */
+       3285,   /*  67.60 kPa 1051 count */
+       3279,   /*  67.66 kPa 1052 count */
+       3273,   /*  67.71 kPa 1053 count */
+       3266,   /*  67.77 kPa 1054 count */
+       3260,   /*  67.82 kPa 1055 count */
+       3254,   /*  67.88 kPa 1056 count */
+       3248,   /*  67.93 kPa 1057 count */
+       3241,   /*  67.98 kPa 1058 count */
+       3235,   /*  68.04 kPa 1059 count */
+       3229,   /*  68.09 kPa 1060 count */
+       3223,   /*  68.15 kPa 1061 count */
+       3216,   /*  68.20 kPa 1062 count */
+       3210,   /*  68.26 kPa 1063 count */
+       3204,   /*  68.31 kPa 1064 count */
+       3198,   /*  68.36 kPa 1065 count */
+       3191,   /*  68.42 kPa 1066 count */
+       3185,   /*  68.47 kPa 1067 count */
+       3179,   /*  68.53 kPa 1068 count */
+       3173,   /*  68.58 kPa 1069 count */
+       3167,   /*  68.64 kPa 1070 count */
+       3160,   /*  68.69 kPa 1071 count */
+       3154,   /*  68.74 kPa 1072 count */
+       3148,   /*  68.80 kPa 1073 count */
+       3142,   /*  68.85 kPa 1074 count */
+       3136,   /*  68.91 kPa 1075 count */
+       3130,   /*  68.96 kPa 1076 count */
+       3123,   /*  69.02 kPa 1077 count */
+       3117,   /*  69.07 kPa 1078 count */
+       3111,   /*  69.12 kPa 1079 count */
+       3105,   /*  69.18 kPa 1080 count */
+       3099,   /*  69.23 kPa 1081 count */
+       3093,   /*  69.29 kPa 1082 count */
+       3087,   /*  69.34 kPa 1083 count */
+       3080,   /*  69.40 kPa 1084 count */
+       3074,   /*  69.45 kPa 1085 count */
+       3068,   /*  69.50 kPa 1086 count */
+       3062,   /*  69.56 kPa 1087 count */
+       3056,   /*  69.61 kPa 1088 count */
+       3050,   /*  69.67 kPa 1089 count */
+       3044,   /*  69.72 kPa 1090 count */
+       3037,   /*  69.78 kPa 1091 count */
+       3031,   /*  69.83 kPa 1092 count */
+       3025,   /*  69.88 kPa 1093 count */
+       3019,   /*  69.94 kPa 1094 count */
+       3013,   /*  69.99 kPa 1095 count */
+       3007,   /*  70.05 kPa 1096 count */
+       3001,   /*  70.10 kPa 1097 count */
+       2995,   /*  70.15 kPa 1098 count */
+       2989,   /*  70.21 kPa 1099 count */
+       2983,   /*  70.26 kPa 1100 count */
+       2977,   /*  70.32 kPa 1101 count */
+       2970,   /*  70.37 kPa 1102 count */
+       2964,   /*  70.43 kPa 1103 count */
+       2958,   /*  70.48 kPa 1104 count */
+       2952,   /*  70.53 kPa 1105 count */
+       2946,   /*  70.59 kPa 1106 count */
+       2940,   /*  70.64 kPa 1107 count */
+       2934,   /*  70.70 kPa 1108 count */
+       2928,   /*  70.75 kPa 1109 count */
+       2922,   /*  70.81 kPa 1110 count */
+       2916,   /*  70.86 kPa 1111 count */
+       2910,   /*  70.91 kPa 1112 count */
+       2904,   /*  70.97 kPa 1113 count */
+       2898,   /*  71.02 kPa 1114 count */
+       2892,   /*  71.08 kPa 1115 count */
+       2886,   /*  71.13 kPa 1116 count */
+       2880,   /*  71.19 kPa 1117 count */
+       2874,   /*  71.24 kPa 1118 count */
+       2868,   /*  71.29 kPa 1119 count */
+       2862,   /*  71.35 kPa 1120 count */
+       2856,   /*  71.40 kPa 1121 count */
+       2850,   /*  71.46 kPa 1122 count */
+       2844,   /*  71.51 kPa 1123 count */
+       2838,   /*  71.57 kPa 1124 count */
+       2832,   /*  71.62 kPa 1125 count */
+       2826,   /*  71.67 kPa 1126 count */
+       2820,   /*  71.73 kPa 1127 count */
+       2814,   /*  71.78 kPa 1128 count */
+       2808,   /*  71.84 kPa 1129 count */
+       2802,   /*  71.89 kPa 1130 count */
+       2796,   /*  71.95 kPa 1131 count */
+       2790,   /*  72.00 kPa 1132 count */
+       2784,   /*  72.05 kPa 1133 count */
+       2778,   /*  72.11 kPa 1134 count */
+       2772,   /*  72.16 kPa 1135 count */
+       2766,   /*  72.22 kPa 1136 count */
+       2760,   /*  72.27 kPa 1137 count */
+       2754,   /*  72.33 kPa 1138 count */
+       2748,   /*  72.38 kPa 1139 count */
+       2743,   /*  72.43 kPa 1140 count */
+       2737,   /*  72.49 kPa 1141 count */
+       2731,   /*  72.54 kPa 1142 count */
+       2725,   /*  72.60 kPa 1143 count */
+       2719,   /*  72.65 kPa 1144 count */
+       2713,   /*  72.71 kPa 1145 count */
+       2707,   /*  72.76 kPa 1146 count */
+       2701,   /*  72.81 kPa 1147 count */
+       2695,   /*  72.87 kPa 1148 count */
+       2689,   /*  72.92 kPa 1149 count */
+       2683,   /*  72.98 kPa 1150 count */
+       2678,   /*  73.03 kPa 1151 count */
+       2672,   /*  73.09 kPa 1152 count */
+       2666,   /*  73.14 kPa 1153 count */
+       2660,   /*  73.19 kPa 1154 count */
+       2654,   /*  73.25 kPa 1155 count */
+       2648,   /*  73.30 kPa 1156 count */
+       2642,   /*  73.36 kPa 1157 count */
+       2636,   /*  73.41 kPa 1158 count */
+       2631,   /*  73.47 kPa 1159 count */
+       2625,   /*  73.52 kPa 1160 count */
+       2619,   /*  73.57 kPa 1161 count */
+       2613,   /*  73.63 kPa 1162 count */
+       2607,   /*  73.68 kPa 1163 count */
+       2601,   /*  73.74 kPa 1164 count */
+       2595,   /*  73.79 kPa 1165 count */
+       2590,   /*  73.85 kPa 1166 count */
+       2584,   /*  73.90 kPa 1167 count */
+       2578,   /*  73.95 kPa 1168 count */
+       2572,   /*  74.01 kPa 1169 count */
+       2566,   /*  74.06 kPa 1170 count */
+       2560,   /*  74.12 kPa 1171 count */
+       2555,   /*  74.17 kPa 1172 count */
+       2549,   /*  74.23 kPa 1173 count */
+       2543,   /*  74.28 kPa 1174 count */
+       2537,   /*  74.33 kPa 1175 count */
+       2531,   /*  74.39 kPa 1176 count */
+       2526,   /*  74.44 kPa 1177 count */
+       2520,   /*  74.50 kPa 1178 count */
+       2514,   /*  74.55 kPa 1179 count */
+       2508,   /*  74.61 kPa 1180 count */
+       2502,   /*  74.66 kPa 1181 count */
+       2497,   /*  74.71 kPa 1182 count */
+       2491,   /*  74.77 kPa 1183 count */
+       2485,   /*  74.82 kPa 1184 count */
+       2479,   /*  74.88 kPa 1185 count */
+       2473,   /*  74.93 kPa 1186 count */
+       2468,   /*  74.99 kPa 1187 count */
+       2462,   /*  75.04 kPa 1188 count */
+       2456,   /*  75.09 kPa 1189 count */
+       2450,   /*  75.15 kPa 1190 count */
+       2445,   /*  75.20 kPa 1191 count */
+       2439,   /*  75.26 kPa 1192 count */
+       2433,   /*  75.31 kPa 1193 count */
+       2427,   /*  75.37 kPa 1194 count */
+       2422,   /*  75.42 kPa 1195 count */
+       2416,   /*  75.47 kPa 1196 count */
+       2410,   /*  75.53 kPa 1197 count */
+       2405,   /*  75.58 kPa 1198 count */
+       2399,   /*  75.64 kPa 1199 count */
+       2393,   /*  75.69 kPa 1200 count */
+       2387,   /*  75.75 kPa 1201 count */
+       2382,   /*  75.80 kPa 1202 count */
+       2376,   /*  75.85 kPa 1203 count */
+       2370,   /*  75.91 kPa 1204 count */
+       2364,   /*  75.96 kPa 1205 count */
+       2359,   /*  76.02 kPa 1206 count */
+       2353,   /*  76.07 kPa 1207 count */
+       2347,   /*  76.13 kPa 1208 count */
+       2342,   /*  76.18 kPa 1209 count */
+       2336,   /*  76.23 kPa 1210 count */
+       2330,   /*  76.29 kPa 1211 count */
+       2325,   /*  76.34 kPa 1212 count */
+       2319,   /*  76.40 kPa 1213 count */
+       2313,   /*  76.45 kPa 1214 count */
+       2308,   /*  76.51 kPa 1215 count */
+       2302,   /*  76.56 kPa 1216 count */
+       2296,   /*  76.61 kPa 1217 count */
+       2291,   /*  76.67 kPa 1218 count */
+       2285,   /*  76.72 kPa 1219 count */
+       2279,   /*  76.78 kPa 1220 count */
+       2274,   /*  76.83 kPa 1221 count */
+       2268,   /*  76.89 kPa 1222 count */
+       2262,   /*  76.94 kPa 1223 count */
+       2257,   /*  76.99 kPa 1224 count */
+       2251,   /*  77.05 kPa 1225 count */
+       2245,   /*  77.10 kPa 1226 count */
+       2240,   /*  77.16 kPa 1227 count */
+       2234,   /*  77.21 kPa 1228 count */
+       2228,   /*  77.27 kPa 1229 count */
+       2223,   /*  77.32 kPa 1230 count */
+       2217,   /*  77.37 kPa 1231 count */
+       2212,   /*  77.43 kPa 1232 count */
+       2206,   /*  77.48 kPa 1233 count */
+       2200,   /*  77.54 kPa 1234 count */
+       2195,   /*  77.59 kPa 1235 count */
+       2189,   /*  77.65 kPa 1236 count */
+       2184,   /*  77.70 kPa 1237 count */
+       2178,   /*  77.75 kPa 1238 count */
+       2172,   /*  77.81 kPa 1239 count */
+       2167,   /*  77.86 kPa 1240 count */
+       2161,   /*  77.92 kPa 1241 count */
+       2156,   /*  77.97 kPa 1242 count */
+       2150,   /*  78.03 kPa 1243 count */
+       2144,   /*  78.08 kPa 1244 count */
+       2139,   /*  78.13 kPa 1245 count */
+       2133,   /*  78.19 kPa 1246 count */
+       2128,   /*  78.24 kPa 1247 count */
+       2122,   /*  78.30 kPa 1248 count */
+       2117,   /*  78.35 kPa 1249 count */
+       2111,   /*  78.41 kPa 1250 count */
+       2105,   /*  78.46 kPa 1251 count */
+       2100,   /*  78.51 kPa 1252 count */
+       2094,   /*  78.57 kPa 1253 count */
+       2089,   /*  78.62 kPa 1254 count */
+       2083,   /*  78.68 kPa 1255 count */
+       2078,   /*  78.73 kPa 1256 count */
+       2072,   /*  78.79 kPa 1257 count */
+       2067,   /*  78.84 kPa 1258 count */
+       2061,   /*  78.89 kPa 1259 count */
+       2056,   /*  78.95 kPa 1260 count */
+       2050,   /*  79.00 kPa 1261 count */
+       2045,   /*  79.06 kPa 1262 count */
+       2039,   /*  79.11 kPa 1263 count */
+       2033,   /*  79.17 kPa 1264 count */
+       2028,   /*  79.22 kPa 1265 count */
+       2022,   /*  79.27 kPa 1266 count */
+       2017,   /*  79.33 kPa 1267 count */
+       2011,   /*  79.38 kPa 1268 count */
+       2006,   /*  79.44 kPa 1269 count */
+       2000,   /*  79.49 kPa 1270 count */
+       1995,   /*  79.55 kPa 1271 count */
+       1989,   /*  79.60 kPa 1272 count */
+       1984,   /*  79.65 kPa 1273 count */
+       1978,   /*  79.71 kPa 1274 count */
+       1973,   /*  79.76 kPa 1275 count */
+       1967,   /*  79.82 kPa 1276 count */
+       1962,   /*  79.87 kPa 1277 count */
+       1957,   /*  79.93 kPa 1278 count */
+       1951,   /*  79.98 kPa 1279 count */
+       1946,   /*  80.03 kPa 1280 count */
+       1940,   /*  80.09 kPa 1281 count */
+       1935,   /*  80.14 kPa 1282 count */
+       1929,   /*  80.20 kPa 1283 count */
+       1924,   /*  80.25 kPa 1284 count */
+       1918,   /*  80.31 kPa 1285 count */
+       1913,   /*  80.36 kPa 1286 count */
+       1907,   /*  80.41 kPa 1287 count */
+       1902,   /*  80.47 kPa 1288 count */
+       1896,   /*  80.52 kPa 1289 count */
+       1891,   /*  80.58 kPa 1290 count */
+       1886,   /*  80.63 kPa 1291 count */
+       1880,   /*  80.69 kPa 1292 count */
+       1875,   /*  80.74 kPa 1293 count */
+       1869,   /*  80.79 kPa 1294 count */
+       1864,   /*  80.85 kPa 1295 count */
+       1858,   /*  80.90 kPa 1296 count */
+       1853,   /*  80.96 kPa 1297 count */
+       1848,   /*  81.01 kPa 1298 count */
+       1842,   /*  81.07 kPa 1299 count */
+       1837,   /*  81.12 kPa 1300 count */
+       1831,   /*  81.17 kPa 1301 count */
+       1826,   /*  81.23 kPa 1302 count */
+       1821,   /*  81.28 kPa 1303 count */
+       1815,   /*  81.34 kPa 1304 count */
+       1810,   /*  81.39 kPa 1305 count */
+       1804,   /*  81.45 kPa 1306 count */
+       1799,   /*  81.50 kPa 1307 count */
+       1794,   /*  81.55 kPa 1308 count */
+       1788,   /*  81.61 kPa 1309 count */
+       1783,   /*  81.66 kPa 1310 count */
+       1777,   /*  81.72 kPa 1311 count */
+       1772,   /*  81.77 kPa 1312 count */
+       1767,   /*  81.83 kPa 1313 count */
+       1761,   /*  81.88 kPa 1314 count */
+       1756,   /*  81.93 kPa 1315 count */
+       1751,   /*  81.99 kPa 1316 count */
+       1745,   /*  82.04 kPa 1317 count */
+       1740,   /*  82.10 kPa 1318 count */
+       1735,   /*  82.15 kPa 1319 count */
+       1729,   /*  82.21 kPa 1320 count */
+       1724,   /*  82.26 kPa 1321 count */
+       1718,   /*  82.31 kPa 1322 count */
+       1713,   /*  82.37 kPa 1323 count */
+       1708,   /*  82.42 kPa 1324 count */
+       1702,   /*  82.48 kPa 1325 count */
+       1697,   /*  82.53 kPa 1326 count */
+       1692,   /*  82.59 kPa 1327 count */
+       1686,   /*  82.64 kPa 1328 count */
+       1681,   /*  82.69 kPa 1329 count */
+       1676,   /*  82.75 kPa 1330 count */
+       1670,   /*  82.80 kPa 1331 count */
+       1665,   /*  82.86 kPa 1332 count */
+       1660,   /*  82.91 kPa 1333 count */
+       1655,   /*  82.97 kPa 1334 count */
+       1649,   /*  83.02 kPa 1335 count */
+       1644,   /*  83.07 kPa 1336 count */
+       1639,   /*  83.13 kPa 1337 count */
+       1633,   /*  83.18 kPa 1338 count */
+       1628,   /*  83.24 kPa 1339 count */
+       1623,   /*  83.29 kPa 1340 count */
+       1617,   /*  83.35 kPa 1341 count */
+       1612,   /*  83.40 kPa 1342 count */
+       1607,   /*  83.45 kPa 1343 count */
+       1602,   /*  83.51 kPa 1344 count */
+       1596,   /*  83.56 kPa 1345 count */
+       1591,   /*  83.62 kPa 1346 count */
+       1586,   /*  83.67 kPa 1347 count */
+       1580,   /*  83.72 kPa 1348 count */
+       1575,   /*  83.78 kPa 1349 count */
+       1570,   /*  83.83 kPa 1350 count */
+       1565,   /*  83.89 kPa 1351 count */
+       1559,   /*  83.94 kPa 1352 count */
+       1554,   /*  84.00 kPa 1353 count */
+       1549,   /*  84.05 kPa 1354 count */
+       1544,   /*  84.10 kPa 1355 count */
+       1538,   /*  84.16 kPa 1356 count */
+       1533,   /*  84.21 kPa 1357 count */
+       1528,   /*  84.27 kPa 1358 count */
+       1523,   /*  84.32 kPa 1359 count */
+       1517,   /*  84.38 kPa 1360 count */
+       1512,   /*  84.43 kPa 1361 count */
+       1507,   /*  84.48 kPa 1362 count */
+       1502,   /*  84.54 kPa 1363 count */
+       1496,   /*  84.59 kPa 1364 count */
+       1491,   /*  84.65 kPa 1365 count */
+       1486,   /*  84.70 kPa 1366 count */
+       1481,   /*  84.76 kPa 1367 count */
+       1475,   /*  84.81 kPa 1368 count */
+       1470,   /*  84.86 kPa 1369 count */
+       1465,   /*  84.92 kPa 1370 count */
+       1460,   /*  84.97 kPa 1371 count */
+       1455,   /*  85.03 kPa 1372 count */
+       1449,   /*  85.08 kPa 1373 count */
+       1444,   /*  85.14 kPa 1374 count */
+       1439,   /*  85.19 kPa 1375 count */
+       1434,   /*  85.24 kPa 1376 count */
+       1429,   /*  85.30 kPa 1377 count */
+       1423,   /*  85.35 kPa 1378 count */
+       1418,   /*  85.41 kPa 1379 count */
+       1413,   /*  85.46 kPa 1380 count */
+       1408,   /*  85.52 kPa 1381 count */
+       1403,   /*  85.57 kPa 1382 count */
+       1398,   /*  85.62 kPa 1383 count */
+       1392,   /*  85.68 kPa 1384 count */
+       1387,   /*  85.73 kPa 1385 count */
+       1382,   /*  85.79 kPa 1386 count */
+       1377,   /*  85.84 kPa 1387 count */
+       1372,   /*  85.90 kPa 1388 count */
+       1366,   /*  85.95 kPa 1389 count */
+       1361,   /*  86.00 kPa 1390 count */
+       1356,   /*  86.06 kPa 1391 count */
+       1351,   /*  86.11 kPa 1392 count */
+       1346,   /*  86.17 kPa 1393 count */
+       1341,   /*  86.22 kPa 1394 count */
+       1336,   /*  86.28 kPa 1395 count */
+       1330,   /*  86.33 kPa 1396 count */
+       1325,   /*  86.38 kPa 1397 count */
+       1320,   /*  86.44 kPa 1398 count */
+       1315,   /*  86.49 kPa 1399 count */
+       1310,   /*  86.55 kPa 1400 count */
+       1305,   /*  86.60 kPa 1401 count */
+       1300,   /*  86.66 kPa 1402 count */
+       1294,   /*  86.71 kPa 1403 count */
+       1289,   /*  86.76 kPa 1404 count */
+       1284,   /*  86.82 kPa 1405 count */
+       1279,   /*  86.87 kPa 1406 count */
+       1274,   /*  86.93 kPa 1407 count */
+       1269,   /*  86.98 kPa 1408 count */
+       1264,   /*  87.04 kPa 1409 count */
+       1259,   /*  87.09 kPa 1410 count */
+       1254,   /*  87.14 kPa 1411 count */
+       1248,   /*  87.20 kPa 1412 count */
+       1243,   /*  87.25 kPa 1413 count */
+       1238,   /*  87.31 kPa 1414 count */
+       1233,   /*  87.36 kPa 1415 count */
+       1228,   /*  87.42 kPa 1416 count */
+       1223,   /*  87.47 kPa 1417 count */
+       1218,   /*  87.52 kPa 1418 count */
+       1213,   /*  87.58 kPa 1419 count */
+       1208,   /*  87.63 kPa 1420 count */
+       1203,   /*  87.69 kPa 1421 count */
+       1198,   /*  87.74 kPa 1422 count */
+       1192,   /*  87.80 kPa 1423 count */
+       1187,   /*  87.85 kPa 1424 count */
+       1182,   /*  87.90 kPa 1425 count */
+       1177,   /*  87.96 kPa 1426 count */
+       1172,   /*  88.01 kPa 1427 count */
+       1167,   /*  88.07 kPa 1428 count */
+       1162,   /*  88.12 kPa 1429 count */
+       1157,   /*  88.18 kPa 1430 count */
+       1152,   /*  88.23 kPa 1431 count */
+       1147,   /*  88.28 kPa 1432 count */
+       1142,   /*  88.34 kPa 1433 count */
+       1137,   /*  88.39 kPa 1434 count */
+       1132,   /*  88.45 kPa 1435 count */
+       1127,   /*  88.50 kPa 1436 count */
+       1122,   /*  88.56 kPa 1437 count */
+       1117,   /*  88.61 kPa 1438 count */
+       1112,   /*  88.66 kPa 1439 count */
+       1107,   /*  88.72 kPa 1440 count */
+       1102,   /*  88.77 kPa 1441 count */
+       1097,   /*  88.83 kPa 1442 count */
+       1091,   /*  88.88 kPa 1443 count */
+       1086,   /*  88.94 kPa 1444 count */
+       1081,   /*  88.99 kPa 1445 count */
+       1076,   /*  89.04 kPa 1446 count */
+       1071,   /*  89.10 kPa 1447 count */
+       1066,   /*  89.15 kPa 1448 count */
+       1061,   /*  89.21 kPa 1449 count */
+       1056,   /*  89.26 kPa 1450 count */
+       1051,   /*  89.32 kPa 1451 count */
+       1046,   /*  89.37 kPa 1452 count */
+       1041,   /*  89.42 kPa 1453 count */
+       1036,   /*  89.48 kPa 1454 count */
+       1031,   /*  89.53 kPa 1455 count */
+       1026,   /*  89.59 kPa 1456 count */
+       1021,   /*  89.64 kPa 1457 count */
+       1016,   /*  89.70 kPa 1458 count */
+       1011,   /*  89.75 kPa 1459 count */
+       1006,   /*  89.80 kPa 1460 count */
+       1001,   /*  89.86 kPa 1461 count */
+       996,    /*  89.91 kPa 1462 count */
+       992,    /*  89.97 kPa 1463 count */
+       987,    /*  90.02 kPa 1464 count */
+       982,    /*  90.08 kPa 1465 count */
+       977,    /*  90.13 kPa 1466 count */
+       972,    /*  90.18 kPa 1467 count */
+       967,    /*  90.24 kPa 1468 count */
+       962,    /*  90.29 kPa 1469 count */
+       957,    /*  90.35 kPa 1470 count */
+       952,    /*  90.40 kPa 1471 count */
+       947,    /*  90.46 kPa 1472 count */
+       942,    /*  90.51 kPa 1473 count */
+       937,    /*  90.56 kPa 1474 count */
+       932,    /*  90.62 kPa 1475 count */
+       927,    /*  90.67 kPa 1476 count */
+       922,    /*  90.73 kPa 1477 count */
+       917,    /*  90.78 kPa 1478 count */
+       912,    /*  90.84 kPa 1479 count */
+       907,    /*  90.89 kPa 1480 count */
+       902,    /*  90.94 kPa 1481 count */
+       897,    /*  91.00 kPa 1482 count */
+       892,    /*  91.05 kPa 1483 count */
+       888,    /*  91.11 kPa 1484 count */
+       883,    /*  91.16 kPa 1485 count */
+       878,    /*  91.22 kPa 1486 count */
+       873,    /*  91.27 kPa 1487 count */
+       868,    /*  91.32 kPa 1488 count */
+       863,    /*  91.38 kPa 1489 count */
+       858,    /*  91.43 kPa 1490 count */
+       853,    /*  91.49 kPa 1491 count */
+       848,    /*  91.54 kPa 1492 count */
+       843,    /*  91.60 kPa 1493 count */
+       838,    /*  91.65 kPa 1494 count */
+       834,    /*  91.70 kPa 1495 count */
+       829,    /*  91.76 kPa 1496 count */
+       824,    /*  91.81 kPa 1497 count */
+       819,    /*  91.87 kPa 1498 count */
+       814,    /*  91.92 kPa 1499 count */
+       809,    /*  91.98 kPa 1500 count */
+       804,    /*  92.03 kPa 1501 count */
+       799,    /*  92.08 kPa 1502 count */
+       794,    /*  92.14 kPa 1503 count */
+       790,    /*  92.19 kPa 1504 count */
+       785,    /*  92.25 kPa 1505 count */
+       780,    /*  92.30 kPa 1506 count */
+       775,    /*  92.36 kPa 1507 count */
+       770,    /*  92.41 kPa 1508 count */
+       765,    /*  92.46 kPa 1509 count */
+       760,    /*  92.52 kPa 1510 count */
+       755,    /*  92.57 kPa 1511 count */
+       751,    /*  92.63 kPa 1512 count */
+       746,    /*  92.68 kPa 1513 count */
+       741,    /*  92.74 kPa 1514 count */
+       736,    /*  92.79 kPa 1515 count */
+       731,    /*  92.84 kPa 1516 count */
+       726,    /*  92.90 kPa 1517 count */
+       721,    /*  92.95 kPa 1518 count */
+       717,    /*  93.01 kPa 1519 count */
+       712,    /*  93.06 kPa 1520 count */
+       707,    /*  93.12 kPa 1521 count */
+       702,    /*  93.17 kPa 1522 count */
+       697,    /*  93.22 kPa 1523 count */
+       692,    /*  93.28 kPa 1524 count */
+       688,    /*  93.33 kPa 1525 count */
+       683,    /*  93.39 kPa 1526 count */
+       678,    /*  93.44 kPa 1527 count */
+       673,    /*  93.50 kPa 1528 count */
+       668,    /*  93.55 kPa 1529 count */
+       664,    /*  93.60 kPa 1530 count */
+       659,    /*  93.66 kPa 1531 count */
+       654,    /*  93.71 kPa 1532 count */
+       649,    /*  93.77 kPa 1533 count */
+       644,    /*  93.82 kPa 1534 count */
+       639,    /*  93.88 kPa 1535 count */
+       635,    /*  93.93 kPa 1536 count */
+       630,    /*  93.98 kPa 1537 count */
+       625,    /*  94.04 kPa 1538 count */
+       620,    /*  94.09 kPa 1539 count */
+       615,    /*  94.15 kPa 1540 count */
+       611,    /*  94.20 kPa 1541 count */
+       606,    /*  94.26 kPa 1542 count */
+       601,    /*  94.31 kPa 1543 count */
+       596,    /*  94.36 kPa 1544 count */
+       591,    /*  94.42 kPa 1545 count */
+       587,    /*  94.47 kPa 1546 count */
+       582,    /*  94.53 kPa 1547 count */
+       577,    /*  94.58 kPa 1548 count */
+       572,    /*  94.64 kPa 1549 count */
+       568,    /*  94.69 kPa 1550 count */
+       563,    /*  94.74 kPa 1551 count */
+       558,    /*  94.80 kPa 1552 count */
+       553,    /*  94.85 kPa 1553 count */
+       549,    /*  94.91 kPa 1554 count */
+       544,    /*  94.96 kPa 1555 count */
+       539,    /*  95.02 kPa 1556 count */
+       534,    /*  95.07 kPa 1557 count */
+       529,    /*  95.12 kPa 1558 count */
+       525,    /*  95.18 kPa 1559 count */
+       520,    /*  95.23 kPa 1560 count */
+       515,    /*  95.29 kPa 1561 count */
+       510,    /*  95.34 kPa 1562 count */
+       506,    /*  95.40 kPa 1563 count */
+       501,    /*  95.45 kPa 1564 count */
+       496,    /*  95.50 kPa 1565 count */
+       492,    /*  95.56 kPa 1566 count */
+       487,    /*  95.61 kPa 1567 count */
+       482,    /*  95.67 kPa 1568 count */
+       477,    /*  95.72 kPa 1569 count */
+       473,    /*  95.78 kPa 1570 count */
+       468,    /*  95.83 kPa 1571 count */
+       463,    /*  95.88 kPa 1572 count */
+       458,    /*  95.94 kPa 1573 count */
+       454,    /*  95.99 kPa 1574 count */
+       449,    /*  96.05 kPa 1575 count */
+       444,    /*  96.10 kPa 1576 count */
+       440,    /*  96.16 kPa 1577 count */
+       435,    /*  96.21 kPa 1578 count */
+       430,    /*  96.26 kPa 1579 count */
+       425,    /*  96.32 kPa 1580 count */
+       421,    /*  96.37 kPa 1581 count */
+       416,    /*  96.43 kPa 1582 count */
+       411,    /*  96.48 kPa 1583 count */
+       407,    /*  96.54 kPa 1584 count */
+       402,    /*  96.59 kPa 1585 count */
+       397,    /*  96.64 kPa 1586 count */
+       392,    /*  96.70 kPa 1587 count */
+       388,    /*  96.75 kPa 1588 count */
+       383,    /*  96.81 kPa 1589 count */
+       378,    /*  96.86 kPa 1590 count */
+       374,    /*  96.91 kPa 1591 count */
+       369,    /*  96.97 kPa 1592 count */
+       364,    /*  97.02 kPa 1593 count */
+       360,    /*  97.08 kPa 1594 count */
+       355,    /*  97.13 kPa 1595 count */
+       350,    /*  97.19 kPa 1596 count */
+       346,    /*  97.24 kPa 1597 count */
+       341,    /*  97.29 kPa 1598 count */
+       336,    /*  97.35 kPa 1599 count */
+       332,    /*  97.40 kPa 1600 count */
+       327,    /*  97.46 kPa 1601 count */
+       322,    /*  97.51 kPa 1602 count */
+       318,    /*  97.57 kPa 1603 count */
+       313,    /*  97.62 kPa 1604 count */
+       308,    /*  97.67 kPa 1605 count */
+       304,    /*  97.73 kPa 1606 count */
+       299,    /*  97.78 kPa 1607 count */
+       294,    /*  97.84 kPa 1608 count */
+       290,    /*  97.89 kPa 1609 count */
+       285,    /*  97.95 kPa 1610 count */
+       280,    /*  98.00 kPa 1611 count */
+       276,    /*  98.05 kPa 1612 count */
+       271,    /*  98.11 kPa 1613 count */
+       267,    /*  98.16 kPa 1614 count */
+       262,    /*  98.22 kPa 1615 count */
+       257,    /*  98.27 kPa 1616 count */
+       253,    /*  98.33 kPa 1617 count */
+       248,    /*  98.38 kPa 1618 count */
+       243,    /*  98.43 kPa 1619 count */
+       239,    /*  98.49 kPa 1620 count */
+       234,    /*  98.54 kPa 1621 count */
+       230,    /*  98.60 kPa 1622 count */
+       225,    /*  98.65 kPa 1623 count */
+       220,    /*  98.71 kPa 1624 count */
+       216,    /*  98.76 kPa 1625 count */
+       211,    /*  98.81 kPa 1626 count */
+       206,    /*  98.87 kPa 1627 count */
+       202,    /*  98.92 kPa 1628 count */
+       197,    /*  98.98 kPa 1629 count */
+       193,    /*  99.03 kPa 1630 count */
+       188,    /*  99.09 kPa 1631 count */
+       183,    /*  99.14 kPa 1632 count */
+       179,    /*  99.19 kPa 1633 count */
+       174,    /*  99.25 kPa 1634 count */
+       170,    /*  99.30 kPa 1635 count */
+       165,    /*  99.36 kPa 1636 count */
+       160,    /*  99.41 kPa 1637 count */
+       156,    /*  99.47 kPa 1638 count */
+       151,    /*  99.52 kPa 1639 count */
+       147,    /*  99.57 kPa 1640 count */
+       142,    /*  99.63 kPa 1641 count */
+       138,    /*  99.68 kPa 1642 count */
+       133,    /*  99.74 kPa 1643 count */
+       128,    /*  99.79 kPa 1644 count */
+       124,    /*  99.85 kPa 1645 count */
+       119,    /*  99.90 kPa 1646 count */
+       115,    /*  99.95 kPa 1647 count */
+       110,    /* 100.01 kPa 1648 count */
+       106,    /* 100.06 kPa 1649 count */
+       101,    /* 100.12 kPa 1650 count */
+       96,     /* 100.17 kPa 1651 count */
+       92,     /* 100.23 kPa 1652 count */
+       87,     /* 100.28 kPa 1653 count */
+       83,     /* 100.33 kPa 1654 count */
+       78,     /* 100.39 kPa 1655 count */
+       74,     /* 100.44 kPa 1656 count */
+       69,     /* 100.50 kPa 1657 count */
+       65,     /* 100.55 kPa 1658 count */
+       60,     /* 100.61 kPa 1659 count */
+       55,     /* 100.66 kPa 1660 count */
+       51,     /* 100.71 kPa 1661 count */
+       46,     /* 100.77 kPa 1662 count */
+       42,     /* 100.82 kPa 1663 count */
+       37,     /* 100.88 kPa 1664 count */
+       33,     /* 100.93 kPa 1665 count */
+       28,     /* 100.99 kPa 1666 count */
+       24,     /* 101.04 kPa 1667 count */
+       19,     /* 101.09 kPa 1668 count */
+       15,     /* 101.15 kPa 1669 count */
+       10,     /* 101.20 kPa 1670 count */
+       6,      /* 101.26 kPa 1671 count */
+       1,      /* 101.31 kPa 1672 count */
+       -3,     /* 101.37 kPa 1673 count */
+       -8,     /* 101.42 kPa 1674 count */
+       -12,    /* 101.47 kPa 1675 count */
+       -17,    /* 101.53 kPa 1676 count */
+       -21,    /* 101.58 kPa 1677 count */
+       -26,    /* 101.64 kPa 1678 count */
+       -30,    /* 101.69 kPa 1679 count */
+       -35,    /* 101.75 kPa 1680 count */
+       -39,    /* 101.80 kPa 1681 count */
+       -44,    /* 101.85 kPa 1682 count */
+       -48,    /* 101.91 kPa 1683 count */
+       -53,    /* 101.96 kPa 1684 count */
+       -57,    /* 102.02 kPa 1685 count */
+       -62,    /* 102.07 kPa 1686 count */
+       -66,    /* 102.13 kPa 1687 count */
+       -71,    /* 102.18 kPa 1688 count */
+       -75,    /* 102.23 kPa 1689 count */
+       -80,    /* 102.29 kPa 1690 count */
+       -84,    /* 102.34 kPa 1691 count */
+       -89,    /* 102.40 kPa 1692 count */
+       -93,    /* 102.45 kPa 1693 count */
+       -98,    /* 102.51 kPa 1694 count */
+       -102,   /* 102.56 kPa 1695 count */
+       -107,   /* 102.61 kPa 1696 count */
+       -111,   /* 102.67 kPa 1697 count */
+       -116,   /* 102.72 kPa 1698 count */
+       -120,   /* 102.78 kPa 1699 count */
+       -125,   /* 102.83 kPa 1700 count */
+       -129,   /* 102.89 kPa 1701 count */
+       -134,   /* 102.94 kPa 1702 count */
+       -138,   /* 102.99 kPa 1703 count */
+       -143,   /* 103.05 kPa 1704 count */
+       -147,   /* 103.10 kPa 1705 count */
+       -151,   /* 103.16 kPa 1706 count */
+       -156,   /* 103.21 kPa 1707 count */
+       -160,   /* 103.27 kPa 1708 count */
+       -165,   /* 103.32 kPa 1709 count */
+       -169,   /* 103.37 kPa 1710 count */
+       -174,   /* 103.43 kPa 1711 count */
+       -178,   /* 103.48 kPa 1712 count */
+       -183,   /* 103.54 kPa 1713 count */
+       -187,   /* 103.59 kPa 1714 count */
+       -191,   /* 103.65 kPa 1715 count */
+       -196,   /* 103.70 kPa 1716 count */
+       -200,   /* 103.75 kPa 1717 count */
+       -205,   /* 103.81 kPa 1718 count */
+       -209,   /* 103.86 kPa 1719 count */
+       -214,   /* 103.92 kPa 1720 count */
+       -218,   /* 103.97 kPa 1721 count */
+       -222,   /* 104.03 kPa 1722 count */
+       -227,   /* 104.08 kPa 1723 count */
+       -231,   /* 104.13 kPa 1724 count */
+       -236,   /* 104.19 kPa 1725 count */
+       -240,   /* 104.24 kPa 1726 count */
+       -245,   /* 104.30 kPa 1727 count */
+       -249,   /* 104.35 kPa 1728 count */
+       -253,   /* 104.41 kPa 1729 count */
+       -258,   /* 104.46 kPa 1730 count */
+       -262,   /* 104.51 kPa 1731 count */
+       -267,   /* 104.57 kPa 1732 count */
+       -271,   /* 104.62 kPa 1733 count */
+       -275,   /* 104.68 kPa 1734 count */
+       -280,   /* 104.73 kPa 1735 count */
+       -284,   /* 104.79 kPa 1736 count */
+       -289,   /* 104.84 kPa 1737 count */
+       -293,   /* 104.89 kPa 1738 count */
+       -297,   /* 104.95 kPa 1739 count */
+       -302,   /* 105.00 kPa 1740 count */
+       -306,   /* 105.06 kPa 1741 count */
+       -311,   /* 105.11 kPa 1742 count */
+       -315,   /* 105.17 kPa 1743 count */
+       -319,   /* 105.22 kPa 1744 count */
+       -324,   /* 105.27 kPa 1745 count */
+       -328,   /* 105.33 kPa 1746 count */
+       -332,   /* 105.38 kPa 1747 count */
+       -337,   /* 105.44 kPa 1748 count */
+       -341,   /* 105.49 kPa 1749 count */
+       -346,   /* 105.55 kPa 1750 count */
+       -350,   /* 105.60 kPa 1751 count */
+       -354,   /* 105.65 kPa 1752 count */
+       -359,   /* 105.71 kPa 1753 count */
+       -363,   /* 105.76 kPa 1754 count */
+       -367,   /* 105.82 kPa 1755 count */
+       -372,   /* 105.87 kPa 1756 count */
+       -376,   /* 105.93 kPa 1757 count */
+       -380,   /* 105.98 kPa 1758 count */
+       -385,   /* 106.03 kPa 1759 count */
+       -389,   /* 106.09 kPa 1760 count */
+       -394,   /* 106.14 kPa 1761 count */
+       -398,   /* 106.20 kPa 1762 count */
+       -402,   /* 106.25 kPa 1763 count */
+       -407,   /* 106.31 kPa 1764 count */
+       -411,   /* 106.36 kPa 1765 count */
+       -415,   /* 106.41 kPa 1766 count */
+       -420,   /* 106.47 kPa 1767 count */
+       -424,   /* 106.52 kPa 1768 count */
+       -428,   /* 106.58 kPa 1769 count */
+       -433,   /* 106.63 kPa 1770 count */
+       -437,   /* 106.69 kPa 1771 count */
+       -441,   /* 106.74 kPa 1772 count */
+       -446,   /* 106.79 kPa 1773 count */
+       -450,   /* 106.85 kPa 1774 count */
+       -454,   /* 106.90 kPa 1775 count */
+       -459,   /* 106.96 kPa 1776 count */
+       -463,   /* 107.01 kPa 1777 count */
+       -467,   /* 107.07 kPa 1778 count */
+       -472,   /* 107.12 kPa 1779 count */
+       -476,   /* 107.17 kPa 1780 count */
+       -480,   /* 107.23 kPa 1781 count */
+       -485,   /* 107.28 kPa 1782 count */
+       -489,   /* 107.34 kPa 1783 count */
+       -493,   /* 107.39 kPa 1784 count */
+       -497,   /* 107.45 kPa 1785 count */
+       -502,   /* 107.50 kPa 1786 count */
+       -506,   /* 107.55 kPa 1787 count */
+       -510,   /* 107.61 kPa 1788 count */
+       -515,   /* 107.66 kPa 1789 count */
+       -519,   /* 107.72 kPa 1790 count */
+       -523,   /* 107.77 kPa 1791 count */
+       -528,   /* 107.83 kPa 1792 count */
+       -532,   /* 107.88 kPa 1793 count */
+       -536,   /* 107.93 kPa 1794 count */
+       -540,   /* 107.99 kPa 1795 count */
+       -545,   /* 108.04 kPa 1796 count */
+       -549,   /* 108.10 kPa 1797 count */
+       -553,   /* 108.15 kPa 1798 count */
+       -558,   /* 108.21 kPa 1799 count */
+       -562,   /* 108.26 kPa 1800 count */
+       -566,   /* 108.31 kPa 1801 count */
+       -570,   /* 108.37 kPa 1802 count */
+       -575,   /* 108.42 kPa 1803 count */
+       -579,   /* 108.48 kPa 1804 count */
+       -583,   /* 108.53 kPa 1805 count */
+       -588,   /* 108.59 kPa 1806 count */
+       -592,   /* 108.64 kPa 1807 count */
+       -596,   /* 108.69 kPa 1808 count */
+       -600,   /* 108.75 kPa 1809 count */
+       -605,   /* 108.80 kPa 1810 count */
+       -609,   /* 108.86 kPa 1811 count */
+       -613,   /* 108.91 kPa 1812 count */
+       -617,   /* 108.97 kPa 1813 count */
+       -622,   /* 109.02 kPa 1814 count */
+       -626,   /* 109.07 kPa 1815 count */
+       -630,   /* 109.13 kPa 1816 count */
+       -634,   /* 109.18 kPa 1817 count */
+       -639,   /* 109.24 kPa 1818 count */
+       -643,   /* 109.29 kPa 1819 count */
+       -647,   /* 109.35 kPa 1820 count */
+       -651,   /* 109.40 kPa 1821 count */
+       -656,   /* 109.45 kPa 1822 count */
+       -660,   /* 109.51 kPa 1823 count */
+       -664,   /* 109.56 kPa 1824 count */
+       -668,   /* 109.62 kPa 1825 count */
+       -673,   /* 109.67 kPa 1826 count */
+       -677,   /* 109.73 kPa 1827 count */
+       -681,   /* 109.78 kPa 1828 count */
+       -685,   /* 109.83 kPa 1829 count */
+       -690,   /* 109.89 kPa 1830 count */
+       -694,   /* 109.94 kPa 1831 count */
+       -698,   /* 110.00 kPa 1832 count */
+       -702,   /* 110.05 kPa 1833 count */
+       -706,   /* 110.11 kPa 1834 count */
+       -711,   /* 110.16 kPa 1835 count */
+       -715,   /* 110.21 kPa 1836 count */
+       -719,   /* 110.27 kPa 1837 count */
+       -723,   /* 110.32 kPa 1838 count */
+       -728,   /* 110.38 kPa 1839 count */
+       -732,   /* 110.43 kPa 1840 count */
+       -736,   /* 110.48 kPa 1841 count */
+       -740,   /* 110.54 kPa 1842 count */
+       -744,   /* 110.59 kPa 1843 count */
+       -749,   /* 110.65 kPa 1844 count */
+       -753,   /* 110.70 kPa 1845 count */
+       -757,   /* 110.76 kPa 1846 count */
+       -761,   /* 110.81 kPa 1847 count */
+       -765,   /* 110.86 kPa 1848 count */
+       -770,   /* 110.92 kPa 1849 count */
+       -774,   /* 110.97 kPa 1850 count */
+       -778,   /* 111.03 kPa 1851 count */
+       -782,   /* 111.08 kPa 1852 count */
+       -786,   /* 111.14 kPa 1853 count */
+       -791,   /* 111.19 kPa 1854 count */
+       -795,   /* 111.24 kPa 1855 count */
+       -799,   /* 111.30 kPa 1856 count */
+       -803,   /* 111.35 kPa 1857 count */
+       -807,   /* 111.41 kPa 1858 count */
+       -812,   /* 111.46 kPa 1859 count */
+       -816,   /* 111.52 kPa 1860 count */
+       -820,   /* 111.57 kPa 1861 count */
+       -824,   /* 111.62 kPa 1862 count */
+       -828,   /* 111.68 kPa 1863 count */
+       -832,   /* 111.73 kPa 1864 count */
+       -837,   /* 111.79 kPa 1865 count */
+       -841,   /* 111.84 kPa 1866 count */
+       -845,   /* 111.90 kPa 1867 count */
+       -849,   /* 111.95 kPa 1868 count */
+       -853,   /* 112.00 kPa 1869 count */
+       -857,   /* 112.06 kPa 1870 count */
+       -862,   /* 112.11 kPa 1871 count */
+       -866,   /* 112.17 kPa 1872 count */
+       -870,   /* 112.22 kPa 1873 count */
+       -874,   /* 112.28 kPa 1874 count */
+       -878,   /* 112.33 kPa 1875 count */
+       -882,   /* 112.38 kPa 1876 count */
+       -887,   /* 112.44 kPa 1877 count */
+       -891,   /* 112.49 kPa 1878 count */
+       -895,   /* 112.55 kPa 1879 count */
+       -899,   /* 112.60 kPa 1880 count */
+       -903,   /* 112.66 kPa 1881 count */
+       -907,   /* 112.71 kPa 1882 count */
+       -911,   /* 112.76 kPa 1883 count */
+       -916,   /* 112.82 kPa 1884 count */
+       -920,   /* 112.87 kPa 1885 count */
+       -924,   /* 112.93 kPa 1886 count */
+       -928,   /* 112.98 kPa 1887 count */
+       -932,   /* 113.04 kPa 1888 count */
+       -936,   /* 113.09 kPa 1889 count */
+       -940,   /* 113.14 kPa 1890 count */
+       -945,   /* 113.20 kPa 1891 count */
+       -949,   /* 113.25 kPa 1892 count */
+       -953,   /* 113.31 kPa 1893 count */
+       -957,   /* 113.36 kPa 1894 count */
+       -961,   /* 113.42 kPa 1895 count */
+       -965,   /* 113.47 kPa 1896 count */
+       -969,   /* 113.52 kPa 1897 count */
+       -973,   /* 113.58 kPa 1898 count */
+       -978,   /* 113.63 kPa 1899 count */
+       -982,   /* 113.69 kPa 1900 count */
+       -986,   /* 113.74 kPa 1901 count */
+       -990,   /* 113.80 kPa 1902 count */
+       -994,   /* 113.85 kPa 1903 count */
+       -998,   /* 113.90 kPa 1904 count */
+       -1002,  /* 113.96 kPa 1905 count */
+       -1006,  /* 114.01 kPa 1906 count */
+       -1010,  /* 114.07 kPa 1907 count */
+       -1015,  /* 114.12 kPa 1908 count */
+       -1019,  /* 114.18 kPa 1909 count */
+       -1023,  /* 114.23 kPa 1910 count */
+       -1027,  /* 114.28 kPa 1911 count */
+       -1031,  /* 114.34 kPa 1912 count */
+       -1035,  /* 114.39 kPa 1913 count */
+       -1039,  /* 114.45 kPa 1914 count */
+       -1043,  /* 114.50 kPa 1915 count */
+       -1047,  /* 114.56 kPa 1916 count */
+       -1051,  /* 114.61 kPa 1917 count */
+       -1056,  /* 114.66 kPa 1918 count */
+       -1060,  /* 114.72 kPa 1919 count */
+       -1064,  /* 114.77 kPa 1920 count */
+       -1068,  /* 114.83 kPa 1921 count */
+       -1072,  /* 114.88 kPa 1922 count */
+       -1076,  /* 114.94 kPa 1923 count */
+       -1080,  /* 114.99 kPa 1924 count */
+       -1084,  /* 115.04 kPa 1925 count */
+       -1088,  /* 115.10 kPa 1926 count */
+       -1092,  /* 115.15 kPa 1927 count */
+       -1096,  /* 115.21 kPa 1928 count */
+       -1100,  /* 115.26 kPa 1929 count */
+       -1104,  /* 115.32 kPa 1930 count */
+       -1109,  /* 115.37 kPa 1931 count */
+       -1113,  /* 115.42 kPa 1932 count */
+       -1117,  /* 115.48 kPa 1933 count */
+       -1121,  /* 115.53 kPa 1934 count */
+       -1125,  /* 115.59 kPa 1935 count */
+       -1129,  /* 115.64 kPa 1936 count */
+       -1133,  /* 115.70 kPa 1937 count */
+       -1137,  /* 115.75 kPa 1938 count */
+       -1141,  /* 115.80 kPa 1939 count */
+       -1145,  /* 115.86 kPa 1940 count */
+       -1149,  /* 115.91 kPa 1941 count */
+       -1153,  /* 115.97 kPa 1942 count */
+       -1157,  /* 116.02 kPa 1943 count */
+       -1161,  /* 116.08 kPa 1944 count */
+       -1165,  /* 116.13 kPa 1945 count */
+       -1169,  /* 116.18 kPa 1946 count */
+       -1173,  /* 116.24 kPa 1947 count */
+       -1177,  /* 116.29 kPa 1948 count */
+       -1182,  /* 116.35 kPa 1949 count */
+       -1186,  /* 116.40 kPa 1950 count */
+       -1190,  /* 116.46 kPa 1951 count */
+       -1194,  /* 116.51 kPa 1952 count */
+       -1198,  /* 116.56 kPa 1953 count */
+       -1202,  /* 116.62 kPa 1954 count */
+       -1206,  /* 116.67 kPa 1955 count */
+       -1210,  /* 116.73 kPa 1956 count */
+       -1214,  /* 116.78 kPa 1957 count */
+       -1218,  /* 116.84 kPa 1958 count */
+       -1222,  /* 116.89 kPa 1959 count */
+       -1226,  /* 116.94 kPa 1960 count */
+       -1230,  /* 117.00 kPa 1961 count */
+       -1234,  /* 117.05 kPa 1962 count */
+       -1238,  /* 117.11 kPa 1963 count */
+       -1242,  /* 117.16 kPa 1964 count */
+       -1246,  /* 117.22 kPa 1965 count */
+       -1250,  /* 117.27 kPa 1966 count */
+       -1254,  /* 117.32 kPa 1967 count */
+       -1258,  /* 117.38 kPa 1968 count */
+       -1262,  /* 117.43 kPa 1969 count */
+       -1266,  /* 117.49 kPa 1970 count */
+       -1270,  /* 117.54 kPa 1971 count */
+       -1274,  /* 117.60 kPa 1972 count */
+       -1278,  /* 117.65 kPa 1973 count */
+       -1282,  /* 117.70 kPa 1974 count */
+       -1286,  /* 117.76 kPa 1975 count */
+       -1290,  /* 117.81 kPa 1976 count */
+       -1294,  /* 117.87 kPa 1977 count */
+       -1298,  /* 117.92 kPa 1978 count */
+       -1302,  /* 117.98 kPa 1979 count */
+       -1306,  /* 118.03 kPa 1980 count */
+       -1310,  /* 118.08 kPa 1981 count */
+       -1314,  /* 118.14 kPa 1982 count */
+       -1318,  /* 118.19 kPa 1983 count */
+       -1322,  /* 118.25 kPa 1984 count */
+       -1326,  /* 118.30 kPa 1985 count */
+       -1330,  /* 118.36 kPa 1986 count */
+       -1334,  /* 118.41 kPa 1987 count */
+       -1338,  /* 118.46 kPa 1988 count */
+       -1342,  /* 118.52 kPa 1989 count */
+       -1346,  /* 118.57 kPa 1990 count */
+       -1350,  /* 118.63 kPa 1991 count */
+       -1354,  /* 118.68 kPa 1992 count */
+       -1358,  /* 118.74 kPa 1993 count */
+       -1362,  /* 118.79 kPa 1994 count */
+       -1366,  /* 118.84 kPa 1995 count */
+       -1370,  /* 118.90 kPa 1996 count */
+       -1374,  /* 118.95 kPa 1997 count */
+       -1378,  /* 119.01 kPa 1998 count */
+       -1382,  /* 119.06 kPa 1999 count */
+       -1386,  /* 119.12 kPa 2000 count */
+       -1390,  /* 119.17 kPa 2001 count */
+       -1394,  /* 119.22 kPa 2002 count */
+       -1397,  /* 119.28 kPa 2003 count */
+       -1401,  /* 119.33 kPa 2004 count */
+       -1405,  /* 119.39 kPa 2005 count */
+       -1409,  /* 119.44 kPa 2006 count */
+       -1413,  /* 119.50 kPa 2007 count */
+       -1417,  /* 119.55 kPa 2008 count */
+       -1421,  /* 119.60 kPa 2009 count */
+       -1425,  /* 119.66 kPa 2010 count */
+       -1429,  /* 119.71 kPa 2011 count */
+       -1433,  /* 119.77 kPa 2012 count */
+       -1437,  /* 119.82 kPa 2013 count */
+       -1441,  /* 119.88 kPa 2014 count */
+       -1445,  /* 119.93 kPa 2015 count */
+       -1449,  /* 119.98 kPa 2016 count */
+       -1453,  /* 120.04 kPa 2017 count */
+       -1457,  /* 120.09 kPa 2018 count */
+       -1461,  /* 120.15 kPa 2019 count */
+       -1465,  /* 120.20 kPa 2020 count */
+       -1469,  /* 120.26 kPa 2021 count */
+       -1472,  /* 120.31 kPa 2022 count */
+       -1476,  /* 120.36 kPa 2023 count */
+       -1480,  /* 120.42 kPa 2024 count */
+       -1484,  /* 120.47 kPa 2025 count */
+       -1488,  /* 120.53 kPa 2026 count */
+       -1492,  /* 120.58 kPa 2027 count */
+       -1496,  /* 120.64 kPa 2028 count */
+       -1500,  /* 120.69 kPa 2029 count */
+       -1504,  /* 120.74 kPa 2030 count */
+       -1508,  /* 120.80 kPa 2031 count */
+       -1512,  /* 120.85 kPa 2032 count */
+       -1516,  /* 120.91 kPa 2033 count */
+       -1520,  /* 120.96 kPa 2034 count */
+       -1523,  /* 121.02 kPa 2035 count */
+       -1527,  /* 121.07 kPa 2036 count */
+       -1531,  /* 121.12 kPa 2037 count */
+       -1535,  /* 121.18 kPa 2038 count */
+       -1539,  /* 121.23 kPa 2039 count */
+       -1543,  /* 121.29 kPa 2040 count */
+       -1547,  /* 121.34 kPa 2041 count */
+       -1551,  /* 121.40 kPa 2042 count */
+       -1555,  /* 121.45 kPa 2043 count */
+       -1559,  /* 121.50 kPa 2044 count */
+       -1562,  /* 121.56 kPa 2045 count */
+       -1566,  /* 121.61 kPa 2046 count */
+       -1570,  /* 121.67 kPa 2047 count */
diff --git a/src/ao-make-product.5c b/src/ao-make-product.5c
new file mode 100644 (file)
index 0000000..933032d
--- /dev/null
@@ -0,0 +1,88 @@
+#!/bin/sh
+
+autoimport ParseArgs;
+
+void
+write_ucs2(string a, string description)
+{
+       int len = String::length(a);
+
+       printf("/* %s */\n", description);
+       printf("#define AO_%s_LEN 0x%02x\n", description, len * 2 + 2);
+       printf("#define AO_%s_STRING \"%s\"\n", description, a);
+       printf("#define AO_%s_UCS2", description);
+       for (int i = 0; i < len; i++) {
+               int     c = a[i];
+               if (i > 0)
+                       printf(",");
+               if (0x20 <= c && c < 128)
+                       printf(" '%c', 0", c);
+               else
+                       printf(" LE_WORD(0x%04x),", c);
+       }
+       printf("\n\n");
+}
+
+void
+write_string(string a, string description)
+{
+       printf ("/* %s */\n", description);
+       printf ("#define AO_%s_STRING \"%s\"\n", description, a);
+}
+
+void
+write_int(int a, string description)
+{
+       printf ("/* %s */\n", description);
+       printf ("#define AO_%s_NUMBER %d\n\n", description, a);
+}
+
+string manufacturer = "altusmetrum.org";
+string product = "TeleMetrum";
+string version = "0.0";
+int serial = 1;
+int user_argind = 0;
+
+argdesc argd = {
+       .args = {
+               {
+                       .var = { .arg_string = &manufacturer },
+                       .abbr = 'm',
+                       .name = "manufacturer",
+                       .expr_name = "manf",
+                       .desc = "Manufacturer name." },
+               {
+                       .var = { .arg_string = &product },
+                       .abbr = 'p',
+                       .name = "product",
+                       .expr_name = "prod",
+                       .desc = "Product name." },
+               {
+                       .var = { .arg_int = &serial },
+                       .abbr = 's',
+                       .name = "serial",
+                       .expr_name = "number",
+                       .desc = "Serial number." },
+               {
+                       .var = { .arg_string = &version },
+                       .abbr = 'v',
+                       .name = "version",
+                       .expr_name = "string",
+                       .desc = "Program version." },
+       },
+       .prog_name = "usb descriptors",
+};
+
+void
+main()
+{
+       string[dim(argv)-1] nargv = {[n] = argv[n+1]};
+       parseargs(&argd, &nargv);
+       write_ucs2(manufacturer, "iManufacturer");
+       write_ucs2(product, "iProduct");
+       write_ucs2(sprintf("%06d", serial), "iSerial");
+       write_int(serial, "iSerial");
+       write_string(version, "iVersion");
+}
+
+main();
diff --git a/src/ao.h b/src/ao.h
new file mode 100644 (file)
index 0000000..c4cb5bf
--- /dev/null
+++ b/src/ao.h
@@ -0,0 +1,926 @@
+/*
+ * Copyright Â© 2009 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_H_
+#define _AO_H_
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include "cc1111.h"
+
+#define TRUE 1
+#define FALSE 0
+
+/* Convert a __data pointer into an __xdata pointer */
+#define DATA_TO_XDATA(a)       ((void __xdata *) ((uint8_t) (a) | 0xff00))
+
+/* Stack runs from above the allocated __data space to 0xfe, which avoids
+ * writing to 0xff as that triggers the stack overflow indicator
+ */
+#define AO_STACK_START 0x80
+#define AO_STACK_END   0xfe
+#define AO_STACK_SIZE  (AO_STACK_END - AO_STACK_START + 1)
+
+/* An AltOS task */
+struct ao_task {
+       __xdata void *wchan;            /* current wait channel (NULL if running) */
+       uint8_t stack_count;            /* amount of saved stack */
+       uint8_t task_id;                /* index in the task array */
+       __code char *name;              /* task name */
+       uint8_t stack[AO_STACK_SIZE];   /* saved stack */
+};
+
+extern __xdata struct ao_task *__data ao_cur_task;
+
+#define AO_NUM_TASKS           16      /* maximum number of tasks */
+#define AO_NO_TASK             0       /* no task id */
+
+/*
+ ao_task.c
+ */
+
+/* Suspend the current task until wchan is awoken */
+void
+ao_sleep(__xdata void *wchan);
+
+/* Wake all tasks sleeping on wchan */
+void
+ao_wakeup(__xdata void *wchan);
+
+/* Yield the processor to another task */
+void
+ao_yield(void) _naked;
+
+/* Add a task to the run queue */
+void
+ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name) __reentrant;
+
+/* Dump task info to console */
+void
+ao_task_info(void);
+
+/* Start the scheduler. This will not return */
+void
+ao_start_scheduler(void);
+
+/*
+ * ao_panic.c
+ */
+
+#define AO_PANIC_NO_TASK       1       /* AO_NUM_TASKS is not large enough */
+#define AO_PANIC_DMA           2       /* Attempt to start DMA while active */
+#define AO_PANIC_MUTEX         3       /* Mis-using mutex API */
+#define AO_PANIC_EE            4       /* Mis-using eeprom API */
+#define AO_PANIC_LOG           5       /* Failing to read/write log data */
+#define AO_PANIC_CMD           6       /* Too many command sets registered */
+
+/* Stop the operating system, beeping and blinking the reason */
+void
+ao_panic(uint8_t reason);
+
+/*
+ * ao_timer.c
+ */
+
+/* Our timer runs at 100Hz */
+#define AO_MS_TO_TICKS(ms)     ((ms) / 10)
+#define AO_SEC_TO_TICKS(s)     ((s) * 100)
+
+/* Returns the current time in ticks */
+uint16_t
+ao_time(void);
+
+/* Suspend the current task until ticks time has passed */
+void
+ao_delay(uint16_t ticks);
+
+/* Set the ADC interval */
+void
+ao_timer_set_adc_interval(uint8_t interval) __critical;
+
+/* Timer interrupt */
+void
+ao_timer_isr(void) interrupt 9;
+
+/* Initialize the timer */
+void
+ao_timer_init(void);
+
+/*
+ * ao_adc.c
+ */
+
+#define AO_ADC_RING    64
+#define ao_adc_ring_next(n)    (((n) + 1) & (AO_ADC_RING - 1))
+#define ao_adc_ring_prev(n)    (((n) - 1) & (AO_ADC_RING - 1))
+
+/*
+ * One set of samples read from the A/D converter
+ */
+struct ao_adc {
+       uint16_t        tick;           /* tick when the sample was read */
+       int16_t         accel;          /* accelerometer */
+       int16_t         pres;           /* pressure sensor */
+       int16_t         temp;           /* temperature sensor */
+       int16_t         v_batt;         /* battery voltage */
+       int16_t         sense_d;        /* drogue continuity sense */
+       int16_t         sense_m;        /* main continuity sense */
+};
+
+/*
+ * A/D data is stored in a ring, with the next sample to be written
+ * at ao_adc_head
+ */
+extern volatile __xdata struct ao_adc  ao_adc_ring[AO_ADC_RING];
+extern volatile __data uint8_t         ao_adc_head;
+
+/* Trigger a conversion sequence (called from the timer interrupt) */
+void
+ao_adc_poll(void);
+
+/* Suspend the current task until another A/D sample is converted */
+void
+ao_adc_sleep(void);
+
+/* Get a copy of the last complete A/D sample set */
+void
+ao_adc_get(__xdata struct ao_adc *packet);
+
+/* The A/D interrupt handler */
+#if !AO_NO_ADC_ISR
+void
+ao_adc_isr(void) interrupt 1;
+#endif
+
+/* Initialize the A/D converter */
+void
+ao_adc_init(void);
+
+/*
+ * ao_beep.c
+ */
+
+/*
+ * Various pre-defined beep frequencies
+ *
+ * frequency = 1/2 (24e6/32) / beep
+ */
+
+#define AO_BEEP_LOW    150     /* 2500Hz */
+#define AO_BEEP_MID    94      /* 3989Hz */
+#define AO_BEEP_HIGH   75      /* 5000Hz */
+#define AO_BEEP_OFF    0       /* off */
+
+#define AO_BEEP_g      240     /* 1562.5Hz */
+#define AO_BEEP_gs     227     /* 1652Hz (1655Hz) */
+#define AO_BEEP_aa     214     /* 1752Hz (1754Hz) */
+#define AO_BEEP_bbf    202     /* 1856Hz (1858Hz) */
+#define AO_BEEP_bb     190     /* 1974Hz (1969Hz) */
+#define AO_BEEP_cc     180     /* 2083Hz (2086Hz) */
+#define AO_BEEP_ccs    170     /* 2205Hz (2210Hz) */
+#define AO_BEEP_dd     160     /* 2344Hz (2341Hz) */
+#define AO_BEEP_eef    151     /* 2483Hz (2480Hz) */
+#define AO_BEEP_ee     143     /* 2622Hz (2628Hz) */
+#define AO_BEEP_ff     135     /* 2778Hz (2784Hz) */
+#define AO_BEEP_ffs    127     /* 2953Hz (2950Hz) */
+#define AO_BEEP_gg     120     /* 3125Hz */
+#define AO_BEEP_ggs    113     /* 3319Hz (3311Hz) */
+#define AO_BEEP_aaa    107     /* 3504Hz (3508Hz) */
+#define AO_BEEP_bbbf   101     /* 3713Hz (3716Hz) */
+#define AO_BEEP_bbb    95      /* 3947Hz (3937Hz) */
+#define AO_BEEP_ccc    90      /* 4167Hz (4171Hz) */
+#define AO_BEEP_cccs   85      /* 4412Hz (4419Hz) */
+#define AO_BEEP_ddd    80      /* 4688Hz (4682Hz) */
+#define AO_BEEP_eeef   76      /* 4934Hz (4961Hz) */
+#define AO_BEEP_eee    71      /* 5282Hz (5256Hz) */
+#define AO_BEEP_fff    67      /* 5597Hz (5568Hz) */
+#define AO_BEEP_fffs   64      /* 5859Hz (5899Hz) */
+#define AO_BEEP_ggg    60      /* 6250Hz */
+
+/* Set the beeper to the specified tone */
+void
+ao_beep(uint8_t beep);
+
+/* Turn on the beeper for the specified time */
+void
+ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant;
+
+/* Initialize the beeper */
+void
+ao_beep_init(void);
+
+/*
+ * ao_led.c
+ */
+
+#define AO_LED_NONE    0
+#define AO_LED_GREEN   1
+#define AO_LED_RED     2
+
+/* Turn on the specified LEDs */
+void
+ao_led_on(uint8_t colors);
+
+/* Turn off the specified LEDs */
+void
+ao_led_off(uint8_t colors);
+
+/* Set all of the LEDs to the specified state */
+void
+ao_led_set(uint8_t colors);
+
+/* Toggle the specified LEDs */
+void
+ao_led_toggle(uint8_t colors);
+
+/* Turn on the specified LEDs for the indicated interval */
+void
+ao_led_for(uint8_t colors, uint16_t ticks) __reentrant;
+
+/* Initialize the LEDs */
+void
+ao_led_init(uint8_t enable);
+
+/*
+ * ao_usb.c
+ */
+
+/* Put one character to the USB output queue */
+void
+ao_usb_putchar(char c);
+
+/* Get one character from the USB input queue */
+char
+ao_usb_getchar(void);
+
+/* Flush the USB output queue */
+void
+ao_usb_flush(void);
+
+/* USB interrupt handler */
+void
+ao_usb_isr(void) interrupt 6;
+
+/* Enable the USB controller */
+void
+ao_usb_enable(void);
+
+/* Disable the USB controller */
+void
+ao_usb_disable(void);
+
+/* Initialize the USB system */
+void
+ao_usb_init(void);
+
+/*
+ * ao_cmd.c
+ */
+
+enum ao_cmd_status {
+       ao_cmd_success = 0,
+       ao_cmd_lex_error = 1,
+       ao_cmd_syntax_error = 2,
+};
+
+extern __xdata uint16_t ao_cmd_lex_i;
+extern __xdata char    ao_cmd_lex_c;
+extern __xdata enum ao_cmd_status ao_cmd_status;
+
+void
+ao_cmd_lex(void);
+
+void
+ao_cmd_put8(uint8_t v);
+
+void
+ao_cmd_put16(uint16_t v);
+
+void
+ao_cmd_white(void);
+
+void
+ao_cmd_hex(void);
+
+void
+ao_cmd_decimal(void);
+
+struct ao_cmds {
+       char            cmd;
+       void            (*func)(void);
+       const char      *help;
+};
+
+void
+ao_cmd_register(__code struct ao_cmds *cmds);
+
+void
+ao_cmd_init(void);
+
+/*
+ * ao_dma.c
+ */
+
+/* Allocate a DMA channel. the 'done' parameter will be set to 1
+ * when the dma is finished and will be used to wakeup any waiters
+ */
+uint8_t
+ao_dma_alloc(__xdata uint8_t * done);
+
+/* Setup a DMA channel */
+void
+ao_dma_set_transfer(uint8_t id,
+                   void __xdata *srcaddr,
+                   void __xdata *dstaddr,
+                   uint16_t count,
+                   uint8_t cfg0,
+                   uint8_t cfg1);
+
+/* Start a DMA channel */
+void
+ao_dma_start(uint8_t id);
+
+/* Manually trigger a DMA channel */
+void
+ao_dma_trigger(uint8_t id);
+
+/* Abort a running DMA transfer */
+void
+ao_dma_abort(uint8_t id);
+
+/* DMA interrupt routine */
+void
+ao_dma_isr(void) interrupt 8;
+
+/*
+ * ao_mutex.c
+ */
+
+void
+ao_mutex_get(__xdata uint8_t *ao_mutex) __reentrant;
+
+void
+ao_mutex_put(__xdata uint8_t *ao_mutex) __reentrant;
+
+/*
+ * ao_ee.c
+ */
+
+/*
+ * We reserve the last block on the device for
+ * configuration space. Writes and reads in this
+ * area return errors.
+ */
+
+#define AO_EE_BLOCK_SIZE       ((uint16_t) (256))
+#define AO_EE_DEVICE_SIZE      ((uint32_t) 128 * (uint32_t) 1024)
+#define AO_EE_DATA_SIZE                (AO_EE_DEVICE_SIZE - (uint32_t) AO_EE_BLOCK_SIZE)
+#define AO_EE_CONFIG_BLOCK     ((uint16_t) (AO_EE_DATA_SIZE / AO_EE_BLOCK_SIZE))
+
+void
+ao_ee_flush(void) __reentrant;
+
+/* Write to the eeprom */
+uint8_t
+ao_ee_write(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant;
+
+/* Read from the eeprom */
+uint8_t
+ao_ee_read(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant;
+
+/* Write the config block (at the end of the eeprom) */
+uint8_t
+ao_ee_write_config(uint8_t *buf, uint16_t len) __reentrant;
+
+/* Read the config block (at the end of the eeprom) */
+uint8_t
+ao_ee_read_config(uint8_t *buf, uint16_t len) __reentrant;
+
+/* Initialize the EEPROM code */
+void
+ao_ee_init(void);
+
+/*
+ * ao_log.c
+ */
+
+/* Structure containing GPS position, either lat or lon */
+
+struct ao_gps_pos {
+       uint8_t degrees;
+       uint8_t minutes;
+       uint16_t minutes_fraction;      /* in units of 1/10000 minutes */
+};
+
+/*
+ * The data log is recorded in the eeprom as a sequence
+ * of data packets.
+ *
+ * Each packet starts with a 4-byte header that has the
+ * packet type, the packet checksum and the tick count. Then
+ * they all contain 2 16 bit values which hold packet-specific
+ * data.
+ *
+ * For each flight, the first packet
+ * is FLIGHT packet, indicating the serial number of the
+ * device and a unique number marking the number of flights
+ * recorded by this device.
+ *
+ * During flight, data from the accelerometer and barometer
+ * are recorded in SENSOR packets, using the raw 16-bit values
+ * read from the A/D converter.
+ *
+ * Also during flight, but at a lower rate, the deployment
+ * sensors are recorded in DEPLOY packets. The goal here is to
+ * detect failure in the deployment circuits.
+ *
+ * STATE packets hold state transitions as the flight computer
+ * transitions through different stages of the flight.
+ */
+#define AO_LOG_FLIGHT          'F'
+#define AO_LOG_SENSOR          'A'
+#define AO_LOG_TEMP_VOLT       'T'
+#define AO_LOG_DEPLOY          'D'
+#define AO_LOG_STATE           'S'
+#define AO_LOG_GPS_TIME                'G'
+#define AO_LOG_GPS_LAT         'N'
+#define AO_LOG_GPS_LON         'W'
+#define AO_LOG_GPS_ALT         'H'
+
+#define AO_LOG_POS_NONE                (~0UL)
+
+struct ao_log_record {
+       char                    type;
+       uint8_t                 csum;
+       uint16_t                tick;
+       union {
+               struct {
+                       int16_t         ground_accel;
+                       uint16_t        flight;
+               } flight;
+               struct {
+                       int16_t         accel;
+                       int16_t         pres;
+               } sensor;
+               struct {
+                       int16_t         temp;
+                       int16_t         v_batt;
+               } temp_volt;
+               struct {
+                       int16_t         drogue;
+                       int16_t         main;
+               } deploy;
+               struct {
+                       uint16_t        state;
+                       uint16_t        reason;
+               } state;
+               struct {
+                       uint8_t         hour;
+                       uint8_t         minute;
+                       uint8_t         second;
+                       uint8_t         flags;
+               } gps_time;
+               struct ao_gps_pos gps_latitude;
+               struct ao_gps_pos gps_longitude;
+               struct {
+                       int16_t         altitude;
+                       uint16_t        unused;
+               } gps_altitude;
+               struct {
+                       uint16_t        d0;
+                       uint16_t        d1;
+               } anon;
+       } u;
+};
+
+/* Write a record to the eeprom log */
+void
+ao_log_data(struct ao_log_record *log);
+
+/* Flush the log */
+void
+ao_log_flush(void);
+
+/* Log dumping API:
+ * ao_log_dump_first() - get first log record
+ * ao_log_dump_next()  - get next log record
+ */
+extern __xdata struct ao_log_record ao_log_dump;
+
+/* Retrieve first log record for the current flight */
+uint8_t
+ao_log_dump_first(void);
+
+/* return next log record for the current flight */
+uint8_t
+ao_log_dump_next(void);
+
+/* Logging thread main routine */
+void
+ao_log(void);
+
+/* Start logging to eeprom */
+void
+ao_log_start(void);
+
+/* Stop logging */
+void
+ao_log_stop(void);
+
+/* Initialize the logging system */
+void
+ao_log_init(void);
+
+/*
+ * ao_flight.c
+ */
+
+enum ao_flight_state {
+       ao_flight_startup = 0,
+       ao_flight_idle = 1,
+       ao_flight_launchpad = 2,
+       ao_flight_boost = 3,
+       ao_flight_coast = 4,
+       ao_flight_apogee = 5,
+       ao_flight_drogue = 6,
+       ao_flight_main = 7,
+       ao_flight_landed = 8,
+       ao_flight_invalid = 9
+};
+
+extern __xdata struct ao_adc           ao_flight_data;
+extern __pdata enum ao_flight_state    ao_flight_state;
+extern __pdata uint16_t                        ao_flight_tick;
+extern __pdata int16_t                 ao_flight_accel;
+extern __pdata int16_t                 ao_flight_pres;
+extern __pdata int32_t                 ao_flight_vel;
+extern __pdata int16_t                 ao_ground_pres;
+extern __pdata int16_t                 ao_ground_accel;
+extern __pdata int16_t                 ao_min_pres;
+extern __pdata uint16_t                        ao_launch_time;
+
+/* Flight thread */
+void
+ao_flight(void);
+
+/* Initialize flight thread */
+void
+ao_flight_init(void);
+
+/*
+ * ao_report.c
+ */
+
+void
+ao_report_init(void);
+
+/*
+ * ao_convert.c
+ *
+ * Given raw data, convert to SI units
+ */
+
+/* pressure from the sensor to altitude in meters */
+int16_t
+ao_pres_to_altitude(int16_t pres) __reentrant;
+
+int16_t
+ao_altitude_to_pres(int16_t alt) __reentrant;
+
+int16_t
+ao_temp_to_dC(int16_t temp) __reentrant;
+
+/*
+ * ao_dbg.c
+ *
+ * debug another telemetrum board
+ */
+
+/* Send a byte to the dbg target */
+void
+ao_dbg_send_byte(uint8_t byte);
+
+/* Receive a byte from the dbg target */
+uint8_t
+ao_dbg_recv_byte(void);
+
+/* Start a bulk transfer to/from dbg target memory */
+void
+ao_dbg_start_transfer(uint16_t addr);
+
+/* End a bulk transfer to/from dbg target memory */
+void
+ao_dbg_end_transfer(void);
+
+/* Write a byte to dbg target memory */
+void
+ao_dbg_write_byte(uint8_t byte);
+
+/* Read a byte from dbg target memory */
+uint8_t
+ao_dbg_read_byte(void);
+
+/* Enable dbg mode, switching use of the pins */
+void
+ao_dbg_debug_mode(void);
+
+/* Reset the dbg target */
+void
+ao_dbg_reset(void);
+
+void
+ao_dbg_init(void);
+
+/*
+ * ao_serial.c
+ */
+
+#if !AO_NO_SERIAL_ISR
+void
+ao_serial_rx1_isr(void) interrupt 3;
+
+void
+ao_serial_tx1_isr(void) interrupt 14;
+#endif
+
+char
+ao_serial_getchar(void) __critical;
+
+void
+ao_serial_putchar(char c) __critical;
+
+void
+ao_serial_init(void);
+
+/*
+ * ao_gps.c
+ */
+
+#define AO_GPS_NUM_SAT_MASK    (0xf << 0)
+#define AO_GPS_NUM_SAT_SHIFT   (0)
+
+#define AO_GPS_VALID           (1 << 4)
+#define AO_GPS_LONGITUDE_MASK  (1 << 5)
+#define AO_GPS_LONGITUDE_EAST  (0 << 5)
+#define AO_GPS_LONGITUDE_WEST  (1 << 5)
+
+#define AO_GPS_LATITUDE_MASK   (1 << 6)
+#define AO_GPS_LATITUDE_NORTH  (0 << 6)
+#define AO_GPS_LATITUDE_SOUTH  (1 << 6)
+
+struct ao_gps_data {
+       uint8_t                 hour;
+       uint8_t                 minute;
+       uint8_t                 second;
+       uint8_t                 flags;
+       struct ao_gps_pos       latitude;
+       struct ao_gps_pos       longitude;
+       int16_t                 altitude;
+};
+
+extern __xdata uint8_t ao_gps_mutex;
+extern __xdata struct ao_gps_data ao_gps_data;
+
+void
+ao_gps(void);
+
+void
+ao_gps_print(__xdata struct ao_gps_data *gps_data);
+
+void
+ao_gps_init(void);
+
+/*
+ * ao_gps_report.c
+ */
+
+void
+ao_gps_report(void);
+
+void
+ao_gps_report_init(void);
+
+/*
+ * ao_telemetry.c
+ */
+
+#define AO_MAX_CALLSIGN                8
+
+struct ao_telemetry {
+       uint8_t                 addr;
+       uint8_t                 flight_state;
+       int16_t                 flight_accel;
+       int16_t                 ground_accel;
+       int32_t                 flight_vel;
+       int16_t                 flight_pres;
+       int16_t                 ground_pres;
+       struct ao_adc           adc;
+       struct ao_gps_data      gps;
+       char                    callsign[AO_MAX_CALLSIGN];
+};
+
+/* Set delay between telemetry reports (0 to disable) */
+
+#define AO_TELEMETRY_INTERVAL_PAD      AO_MS_TO_TICKS(1000)
+#define AO_TELEMETRY_INTERVAL_FLIGHT   AO_MS_TO_TICKS(50)
+#define AO_TELEMETRY_INTERVAL_RECOVER  AO_MS_TO_TICKS(1000)
+
+void
+ao_telemetry_set_interval(uint16_t interval);
+
+void
+ao_telemetry_init(void);
+
+/*
+ * ao_radio.c
+ */
+
+void
+ao_radio_send(__xdata struct ao_telemetry *telemetry) __reentrant;
+
+struct ao_radio_recv {
+       struct ao_telemetry     telemetry;
+       int8_t                  rssi;
+       uint8_t                 status;
+};
+
+void
+ao_radio_recv(__xdata struct ao_radio_recv *recv) __reentrant;
+
+void
+ao_radio_init(void);
+
+/*
+ * ao_monitor.c
+ */
+
+extern const char const * const ao_state_names[];
+
+void
+ao_monitor(void);
+
+void
+ao_set_monitor(uint8_t monitoring);
+
+void
+ao_monitor_init(uint8_t led, uint8_t monitoring) __reentrant;
+
+/*
+ * ao_stdio.c
+ */
+
+void
+flush(void);
+
+/*
+ * ao_ignite.c
+ */
+
+enum ao_igniter {
+       ao_igniter_drogue = 0,
+       ao_igniter_main = 1
+};
+
+void
+ao_ignite(enum ao_igniter igniter);
+
+enum ao_igniter_status {
+       ao_igniter_unknown,     /* unknown status (ambiguous voltage) */
+       ao_igniter_ready,       /* continuity detected */
+       ao_igniter_active,      /* igniter firing */
+       ao_igniter_open,        /* open circuit detected */
+};
+
+enum ao_igniter_status
+ao_igniter_status(enum ao_igniter igniter);
+
+void
+ao_igniter_init(void);
+
+/*
+ * ao_config.c
+ */
+
+#define AO_CONFIG_MAJOR        1
+#define AO_CONFIG_MINOR        0
+
+struct ao_config {
+       uint8_t         major;
+       uint8_t         minor;
+       uint16_t        main_deploy;
+       int16_t         accel_zero_g;
+       uint8_t         radio_channel;
+       char            callsign[AO_MAX_CALLSIGN + 1];
+};
+
+extern __xdata struct ao_config ao_config;
+
+void
+ao_config_get(void);
+
+void
+ao_config_init(void);
+
+/*
+ * ao_rssi.c
+ */
+
+void
+ao_rssi_set(int rssi_value);
+
+void
+ao_rssi_init(uint8_t rssi_led);
+
+/*
+ * ao_product.c
+ *
+ * values which need to be defined for
+ * each instance of a product
+ */
+
+extern const uint8_t ao_usb_descriptors [];
+extern const uint16_t ao_serial_number;
+extern const char ao_version[];
+extern const char ao_manufacturer[];
+extern const char ao_product[];
+
+/*
+ * Fifos
+ */
+
+#define AO_FIFO_SIZE   32
+
+struct ao_fifo {
+       uint8_t insert;
+       uint8_t remove;
+       char    fifo[AO_FIFO_SIZE];
+};
+
+#define ao_fifo_insert(f,c) do { \
+       (f).fifo[(f).insert] = (c); \
+       (f).insert = ((f).insert + 1) & (AO_FIFO_SIZE-1); \
+} while(0)
+
+#define ao_fifo_remove(f,c) do {\
+       c = (f).fifo[(f).remove]; \
+       (f).remove = ((f).remove + 1) & (AO_FIFO_SIZE-1); \
+} while(0)
+
+#define ao_fifo_full(f)                ((((f).insert + 1) & (AO_FIFO_SIZE-1)) == (f).remove)
+#define ao_fifo_empty(f)       ((f).insert == (f).remove)
+
+/*
+ * ao_packet.c
+ *
+ * Packet-based command interface
+ */
+
+#define AO_PACKET_MAX  32
+#define AO_PACKET_WIN  256
+
+#define AO_PACKET_FIN  (1 << 0)
+#define AO_PACKET_SYN  (1 << 1)
+#define AO_PACKET_RST  (1 << 2)
+#define AO_PACKET_ACK  (1 << 3)
+
+struct ao_packet {
+       uint8_t         addr;
+       uint8_t         flags;
+       uint16_t        seq;
+       uint16_t        ack;
+       uint16_t        window;
+       uint8_t         len;
+       uint8_t         d[AO_PACKET_MAX];
+};
+
+uint8_t
+ao_packet_connect(uint8_t dest);
+
+uint8_t
+ao_packet_accept(void);
+
+int
+ao_packet_send(uint8_t *data, int len);
+
+int
+ao_packet_recv(uint8_t *data, int len);
+
+void
+ao_packet_init(void);
+
+#endif /* _AO_H_ */
diff --git a/src/ao_adc.c b/src/ao_adc.c
new file mode 100644 (file)
index 0000000..26209dc
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+volatile __xdata struct ao_adc ao_adc_ring[AO_ADC_RING];
+volatile __data uint8_t                ao_adc_head;
+
+void
+ao_adc_poll(void)
+{
+       ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | 0;
+}
+
+void
+ao_adc_sleep(void)
+{
+       ao_sleep(&ao_adc_ring);
+}
+
+void
+ao_adc_get(__xdata struct ao_adc *packet)
+{
+       uint8_t i = ao_adc_ring_prev(ao_adc_head);
+       memcpy(packet, &ao_adc_ring[i], sizeof (struct ao_adc));
+}
+
+void
+ao_adc_isr(void) interrupt 1
+{
+       uint8_t sequence;
+       uint8_t __xdata *a;
+
+       sequence = (ADCCON2 & ADCCON2_SCH_MASK) >> ADCCON2_SCH_SHIFT;
+       a = (uint8_t __xdata *) (&ao_adc_ring[ao_adc_head].accel + sequence);
+       a[0] = ADCL;
+       a[1] = ADCH;
+       if (sequence < 5) {
+               /* start next channel conversion */
+               ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | (sequence + 1);
+       } else {
+               /* record this conversion series */
+               ao_adc_ring[ao_adc_head].tick = ao_time();
+               ao_adc_head = ao_adc_ring_next(ao_adc_head);
+               ao_wakeup(ao_adc_ring);
+       }
+}
+
+static void
+ao_adc_dump(void)
+{
+       __xdata struct ao_adc   packet;
+       ao_adc_get(&packet);
+       printf("tick: %5u accel: %4d pres: %4d temp: %4d batt: %4d drogue: %4d main: %4d\n",
+              packet.tick, packet.accel >> 4, packet.pres >> 4, packet.temp >> 4,
+              packet.v_batt >> 4, packet.sense_d >> 4, packet.sense_m >> 4);
+}
+
+__code struct ao_cmds ao_adc_cmds[] = {
+       { 'a',  ao_adc_dump,    "a                                  Display current ADC values" },
+       { 0,    ao_adc_dump, NULL },
+};
+
+void
+ao_adc_init(void)
+{
+       ADCCFG = ((1 << 0) |    /* acceleration */
+                 (1 << 1) |    /* pressure */
+                 (1 << 2) |    /* temperature */
+                 (1 << 3) |    /* battery voltage */
+                 (1 << 4) |    /* drogue sense */
+                 (1 << 5));    /* main sense */
+
+       /* enable interrupts */
+       ADCIF = 0;
+       IEN0 |= IEN0_ADCIE;
+       ao_cmd_register(&ao_adc_cmds[0]);
+}
diff --git a/src/ao_adc_fake.c b/src/ao_adc_fake.c
new file mode 100644 (file)
index 0000000..6ca88d4
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+volatile __xdata struct ao_adc ao_adc_ring[AO_ADC_RING];
+volatile __data uint8_t                ao_adc_head;
+
+/* Stub for systems which have no ADC */
+void
+ao_adc_poll(void)
+{
+}
diff --git a/src/ao_beep.c b/src/ao_beep.c
new file mode 100644 (file)
index 0000000..3642f4c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+void
+ao_beep(uint8_t beep)
+{
+       if (beep == 0) {
+               P2_0 = 0;
+               P2SEL = (P2SEL & ~P2SEL_SELP2_0_MASK) | P2SEL_SELP2_0_GPIO;
+               T4CTL = 0;
+       } else {
+               P2SEL = (P2SEL & ~P2SEL_SELP2_0_MASK) | P2SEL_SELP2_0_PERIPHERAL;
+               T4CC0 = beep;
+               T4CTL = TxCTL_DIV_32 | TxCTL_MODE_MODULO | TxCTL_START;
+       }
+}
+
+void
+ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant
+{
+       ao_beep(beep);
+       ao_delay(ticks);
+       ao_beep(0);
+}
+
+void
+ao_beep_init(void)
+{
+       /* Our beeper is on P2_0, which is hooked to timer 4 using
+        * configuration alternative 2
+        */
+       P2_0 = 0;
+       P2SEL = (P2SEL & ~P2SEL_SELP2_0_MASK) | P2SEL_SELP2_0_GPIO;
+       PERCFG = (PERCFG & ~PERCFG_T4CFG_ALT_MASK) | PERCFG_T4CFG_ALT_2;
+       T4CCTL0 = TxCCTLy_CMP_TOGGLE|TxCCTLy_CMP_MODE_ENABLE;
+}
diff --git a/src/ao_cmd.c b/src/ao_cmd.c
new file mode 100644 (file)
index 0000000..33619b2
--- /dev/null
@@ -0,0 +1,318 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+__xdata uint16_t ao_cmd_lex_i;
+__xdata char   ao_cmd_lex_c;
+__xdata enum ao_cmd_status ao_cmd_status;
+static __xdata uint8_t lex_echo;
+
+#define CMD_LEN        32
+
+static __xdata char    cmd_line[CMD_LEN];
+static __xdata uint8_t cmd_len;
+static __xdata uint8_t cmd_i;
+
+static void
+put_string(char *s)
+{
+       __xdata char    c;
+       while (c = *s++)
+               putchar(c);
+}
+
+static void
+readline(void)
+{
+       __xdata char c;
+       if (lex_echo)
+               put_string("> ");
+       cmd_len = 0;
+       for (;;) {
+               flush();
+               c = getchar();
+               /* backspace/delete */
+               if (c == '\010' || c == '\177') {
+                       if (cmd_len != 0) {
+                               if (lex_echo)
+                                       put_string("\010 \010");
+                               --cmd_len;
+                       }
+                       continue;
+               }
+
+               /* ^U */
+               if (c == '\025') {
+                       while (cmd_len != 0) {
+                               if (lex_echo)
+                                       put_string("\010 \010");
+                               --cmd_len;
+                       }
+                       continue;
+               }
+
+               /* map CR to NL */
+               if (c == '\r')
+                       c = '\n';
+
+               if (c == '\n') {
+                       if (lex_echo)
+                               putchar('\n');
+                       break;
+               }
+
+               if (cmd_len >= CMD_LEN - 2) {
+                       if (lex_echo)
+                               putchar('\007');
+                       continue;
+               }
+               cmd_line[cmd_len++] = c;
+               if (lex_echo)
+                       putchar(c);
+       }
+       cmd_line[cmd_len++] = '\n';
+       cmd_line[cmd_len++] = '\0';
+       cmd_i = 0;
+}
+
+void
+ao_cmd_lex(void)
+{
+       ao_cmd_lex_c = '\n';
+       if (cmd_i < cmd_len)
+               ao_cmd_lex_c = cmd_line[cmd_i++];
+}
+
+static void
+putnibble(uint8_t v)
+{
+       if (v < 10)
+               putchar(v + '0');
+       else
+               putchar(v + ('a' - 10));
+}
+
+void
+ao_cmd_put16(uint16_t v)
+{
+       int8_t i;
+       for (i = 3; i >= 0; i--)
+               putnibble((v >> (i << 2)) & 0xf);
+}
+
+void
+ao_cmd_put8(uint8_t v)
+{
+       putnibble((v >> 4) & 0xf);
+       putnibble(v & 0xf);
+}
+
+void
+ao_cmd_white(void)
+{
+       while (ao_cmd_lex_c == ' ' || ao_cmd_lex_c == '\t')
+               ao_cmd_lex();
+}
+
+void
+ao_cmd_hex(void)
+{
+       __xdata uint8_t r = ao_cmd_lex_error;
+
+       ao_cmd_lex_i = 0;
+       ao_cmd_white();
+       for(;;) {
+               if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9')
+                       ao_cmd_lex_i = (ao_cmd_lex_i << 4) | (ao_cmd_lex_c - '0');
+               else if ('a' <= ao_cmd_lex_c && ao_cmd_lex_c <= 'f')
+                       ao_cmd_lex_i = (ao_cmd_lex_i << 4) | (ao_cmd_lex_c - 'a' + 10);
+               else if ('A' <= ao_cmd_lex_c && ao_cmd_lex_c <= 'F')
+                       ao_cmd_lex_i = (ao_cmd_lex_i << 4) | (ao_cmd_lex_c - 'A' + 10);
+               else
+                       break;
+               r = ao_cmd_success;
+               ao_cmd_lex();
+       }
+       if (r != ao_cmd_success)
+               ao_cmd_status = r;
+}
+
+void
+ao_cmd_decimal(void)
+{
+       __xdata uint8_t r = ao_cmd_lex_error;
+
+       ao_cmd_lex_i = 0;
+       ao_cmd_white();
+       for(;;) {
+               if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9')
+                       ao_cmd_lex_i = (ao_cmd_lex_i * 10) + (ao_cmd_lex_c - '0');
+               else
+                       break;
+               r = ao_cmd_success;
+               ao_cmd_lex();
+       }
+       if (r != ao_cmd_success)
+               ao_cmd_status = r;
+}
+
+static void
+eol(void)
+{
+       while (ao_cmd_lex_c != '\n')
+               ao_cmd_lex();
+}
+
+static void
+dump(void)
+{
+       __xdata uint16_t c;
+       __xdata uint8_t * __xdata start, * __xdata end;
+
+       ao_cmd_hex();
+       start = (uint8_t __xdata *) ao_cmd_lex_i;
+       ao_cmd_hex();
+       end = (uint8_t __xdata *) ao_cmd_lex_i;
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       c = 0;
+       while (start <= end) {
+               if ((c & 7) == 0) {
+                       if (c)
+                               putchar('\n');
+                       ao_cmd_put16((uint16_t) start);
+               }
+               putchar(' ');
+               ao_cmd_put8(*start);
+               ++c;
+               start++;
+       }
+       putchar('\n');
+}
+
+static void
+echo(void)
+{
+       ao_cmd_hex();
+       lex_echo = ao_cmd_lex_i != 0;
+}
+
+static void
+version(void)
+{
+       printf("manufacturer     %s\n", ao_manufacturer);
+       printf("product          %s\n", ao_product);
+       printf("serial-number    %u\n", ao_serial_number);
+       printf("software-version %s\n", ao_version);
+}
+
+static const char help_txt[] = "All numbers are in hex";
+
+#define NUM_CMDS       11
+
+static __code struct ao_cmds   *__xdata (ao_cmds[NUM_CMDS]);
+static __xdata uint8_t         ao_ncmds;
+
+static void
+help(void)
+{
+       __xdata uint8_t cmds;
+       __xdata uint8_t cmd;
+       __code struct ao_cmds * __xdata cs;
+       puts(help_txt);
+       for (cmds = 0; cmds < ao_ncmds; cmds++) {
+               cs = ao_cmds[cmds];
+               for (cmd = 0; cs[cmd].cmd != '\0'; cmd++)
+                       puts(cs[cmd].help);
+       }
+}
+
+static void
+report(void)
+{
+       switch(ao_cmd_status) {
+       case ao_cmd_lex_error:
+       case ao_cmd_syntax_error:
+               puts("Syntax error");
+               ao_cmd_status = 0;
+               break;
+       }
+}
+
+void
+ao_cmd_register(__code struct ao_cmds *cmds)
+{
+       if (ao_ncmds >= NUM_CMDS)
+               ao_panic(AO_PANIC_CMD);
+       ao_cmds[ao_ncmds++] = cmds;
+}
+
+void
+ao_cmd(void *parameters)
+{
+       __xdata char    c;
+       __xdata uint8_t cmd, cmds;
+       __code struct ao_cmds * __xdata cs;
+       void (*__xdata func)(void);
+       (void) parameters;
+
+       lex_echo = 1;
+       for (;;) {
+               readline();
+               ao_cmd_lex();
+               ao_cmd_white();
+               c = ao_cmd_lex_c;
+               ao_cmd_lex();
+               if (c == '\r' || c == '\n')
+                       continue;
+               func = (void (*)(void)) NULL;
+               for (cmds = 0; cmds < ao_ncmds; cmds++) {
+                       cs = ao_cmds[cmds];
+                       for (cmd = 0; cs[cmd].cmd != '\0'; cmd++)
+                               if (cs[cmd].cmd == c) {
+                                       func = cs[cmd].func;
+                                       break;
+                               }
+                       if (func)
+                               break;
+               }
+               if (func)
+                       (*func)();
+               else
+                       ao_cmd_status = ao_cmd_syntax_error;
+               report();
+       }
+}
+
+__xdata struct ao_task ao_cmd_task;
+
+__code struct ao_cmds  ao_base_cmds[] = {
+       { '?', help,            "?                                  Print this message" },
+       { 'T', ao_task_info,    "T                                  Show task states" },
+       { 'E', echo,            "E <0 off, 1 on>                    Set command echo mode" },
+       { 'd', dump,            "d <start> <end>                    Dump memory" },
+       { 'v', version,         "v                                  Show version" },
+       { 0,    help,   NULL },
+};
+
+void
+ao_cmd_init(void)
+{
+       ao_cmd_register(&ao_base_cmds[0]);
+       ao_add_task(&ao_cmd_task, ao_cmd, "cmd");
+}
diff --git a/src/ao_config.c b/src/ao_config.c
new file mode 100644 (file)
index 0000000..657c7a8
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+__xdata struct ao_config ao_config;
+__xdata uint8_t ao_config_loaded;
+__xdata uint8_t ao_config_dirty;
+__xdata uint8_t ao_config_mutex;
+
+#define AO_CONFIG_DEFAULT_MAIN_DEPLOY  250
+#define AO_CONFIG_DEFAULT_RADIO_CHANNEL        0
+#define AO_CONFIG_DEFAULT_CALLSIGN     "KD7SQG"
+#define AO_CONFIG_DEFAULT_ACCEL_ZERO_G 16000
+
+static void
+_ao_config_put(void)
+{
+       ao_ee_write_config((uint8_t *) &ao_config, sizeof (ao_config));
+}
+
+static void
+_ao_config_get(void)
+{
+       if (ao_config_loaded)
+               return;
+       ao_ee_read_config((uint8_t *) &ao_config, sizeof (ao_config));
+       if (ao_config.major != AO_CONFIG_MAJOR) {
+               ao_config.major = AO_CONFIG_MAJOR;
+               ao_config.minor = AO_CONFIG_MINOR;
+               ao_config.main_deploy = AO_CONFIG_DEFAULT_MAIN_DEPLOY;
+               ao_config.radio_channel = AO_CONFIG_DEFAULT_RADIO_CHANNEL;
+               ao_config.accel_zero_g = AO_CONFIG_DEFAULT_ACCEL_ZERO_G;
+               memset(&ao_config.callsign, '\0', sizeof (ao_config.callsign));
+               memcpy(&ao_config.callsign, AO_CONFIG_DEFAULT_CALLSIGN,
+                      sizeof(AO_CONFIG_DEFAULT_CALLSIGN) - 1);
+               ao_config_dirty = 1;
+       }
+       /* deal with minor version issues here, at 0 we haven't any */
+       ao_config_loaded = 1;
+}
+
+void
+ao_config_get(void)
+{
+       ao_mutex_get(&ao_config_mutex);
+       _ao_config_get();
+       ao_mutex_put(&ao_config_mutex);
+}
+
+void
+ao_config_callsign_show(void)
+{
+       printf ("Callsign: \"%s\"\n", ao_config.callsign);
+}
+
+void
+ao_config_callsign_set(void) __reentrant
+{
+       uint8_t c;
+       char callsign[AO_MAX_CALLSIGN + 1];
+
+       ao_cmd_white();
+       c = 0;
+       while (ao_cmd_lex_c != '\n') {
+               if (c < AO_MAX_CALLSIGN)
+                       callsign[c++] = ao_cmd_lex_c;
+               else
+                       ao_cmd_status = ao_cmd_lex_error;
+               ao_cmd_lex();
+       }
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_mutex_get(&ao_config_mutex);
+       _ao_config_get();
+       while (c < AO_MAX_CALLSIGN + 1)
+               callsign[c++] = '\0';
+       memcpy(&ao_config.callsign, &callsign,
+              AO_MAX_CALLSIGN + 1);
+       ao_config_dirty = 1;
+       ao_mutex_put(&ao_config_mutex);
+       ao_config_callsign_show();
+}
+
+void
+ao_config_radio_channel_show(void) __reentrant
+{
+       uint32_t        freq = 434550L + ao_config.radio_channel * 100L;
+       uint16_t        mhz = freq / 1000L;
+       uint16_t        khz = freq % 1000L;
+
+       printf("Radio channel: %d (%d.%03dMHz)\n",
+              ao_config.radio_channel, mhz, khz);
+}
+
+void
+ao_config_radio_channel_set(void) __reentrant
+{
+       ao_cmd_decimal();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_mutex_get(&ao_config_mutex);
+       _ao_config_get();
+       ao_config.radio_channel = ao_cmd_lex_i;
+       ao_config_dirty = 1;
+       ao_mutex_put(&ao_config_mutex);
+       ao_config_radio_channel_show();
+}
+
+void
+ao_config_main_deploy_show(void) __reentrant
+{
+       printf("Main deploy set to %d meters (%d feet)\n",
+              ao_config.main_deploy,
+              (int16_t) ((int32_t) ao_config.main_deploy * 328 / 100));
+}
+
+void
+ao_config_main_deploy_set(void) __reentrant
+{
+       ao_cmd_decimal();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_mutex_get(&ao_config_mutex);
+       _ao_config_get();
+       ao_config.main_deploy = ao_cmd_lex_i;
+       ao_config_dirty = 1;
+       ao_mutex_put(&ao_config_mutex);
+       ao_config_main_deploy_show();
+}
+
+void
+ao_config_accel_zero_g_show(void) __reentrant
+{
+       printf("Accel zero g point set to %d\n",
+              ao_config.accel_zero_g);
+}
+
+#define ZERO_G_SAMPLES 1000
+
+static int16_t
+ao_config_accel_zero_g_auto(void) __reentrant
+{
+       uint16_t        i;
+       int32_t         accel_total;
+       uint8_t         cal_adc_ring;
+
+       puts("Calibrating accelerometer..."); flush();
+       i = ZERO_G_SAMPLES;
+       accel_total = 0;
+       cal_adc_ring = ao_adc_head;
+       while (i) {
+               ao_sleep(&ao_adc_ring);
+               while (i && cal_adc_ring != ao_adc_head) {
+                       accel_total += (int32_t) ao_adc_ring[cal_adc_ring].accel;
+                       cal_adc_ring = ao_adc_ring_next(cal_adc_ring);
+                       i--;
+               }
+       }
+       return (int16_t) (accel_total / ZERO_G_SAMPLES);
+}
+void
+ao_config_accel_zero_g_set(void) __reentrant
+{
+       ao_cmd_decimal();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       if (ao_cmd_lex_i == 0)
+               ao_cmd_lex_i = ao_config_accel_zero_g_auto();
+       ao_mutex_get(&ao_config_mutex);
+       _ao_config_get();
+       ao_config.accel_zero_g = ao_cmd_lex_i;
+       ao_config_dirty = 1;
+       ao_mutex_put(&ao_config_mutex);
+       ao_config_accel_zero_g_show();
+}
+
+struct ao_config_var {
+       char            cmd;
+       void            (*set)(void) __reentrant;
+       void            (*show)(void) __reentrant;
+       const char      *help;
+};
+
+void
+ao_config_help(void) __reentrant;
+
+void
+ao_config_show(void) __reentrant;
+
+void
+ao_config_write(void) __reentrant;
+
+__code struct ao_config_var ao_config_vars[] = {
+       { 'm',  ao_config_main_deploy_set,      ao_config_main_deploy_show,
+               "m <meters>  Set height above launch for main deploy (in meters)" },
+       { 'a',  ao_config_accel_zero_g_set,     ao_config_accel_zero_g_show,
+               "a <value>   Set accelerometer zero g point (0 for auto)" },
+       { 'r',  ao_config_radio_channel_set,    ao_config_radio_channel_show,
+               "r <channel> Set radio channel (freq = 434.550 + channel * .1)" },
+       { 'c',  ao_config_callsign_set,         ao_config_callsign_show,
+               "c <call>    Set callsign broadcast in each packet (8 char max)" },
+       { 's',  ao_config_show,                 ao_config_show,
+               "s           Show current config values" },
+       { 'w',  ao_config_write,                ao_config_write,
+               "w           Write current values to eeprom" },
+       { '?',  ao_config_help,                 ao_config_help,
+               "?           Show available config variables" },
+       { 0,    ao_config_main_deploy_set,      ao_config_main_deploy_show,
+               NULL },
+};
+
+void
+ao_config_set(void)
+{
+       char    c;
+       uint8_t cmd;
+       void (*__xdata func)(void) __reentrant;
+
+       ao_cmd_white();
+       c = ao_cmd_lex_c;
+       ao_cmd_lex();
+       func = 0;
+       for (cmd = 0; ao_config_vars[cmd].cmd != '\0'; cmd++)
+               if (ao_config_vars[cmd].cmd == c) {
+                       func = ao_config_vars[cmd].set;
+                       break;
+               }
+       if (func)
+               (*func)();
+       else
+               ao_cmd_status = ao_cmd_syntax_error;
+}
+
+void
+ao_config_help(void) __reentrant
+{
+       uint8_t cmd;
+       for (cmd = 0; ao_config_vars[cmd].cmd != '\0'; cmd++)
+               puts (ao_config_vars[cmd].help);
+}
+
+void
+ao_config_show(void) __reentrant
+{
+       uint8_t cmd;
+       for (cmd = 0; ao_config_vars[cmd].cmd != '\0'; cmd++)
+               if (ao_config_vars[cmd].show != ao_config_vars[cmd].set)
+                       (*ao_config_vars[cmd].show)();
+}
+
+void
+ao_config_write(void) __reentrant
+{
+       ao_mutex_get(&ao_config_mutex);
+       if (ao_config_dirty) {
+               _ao_config_put();
+               ao_config_dirty = 0;
+               printf("Saved\n");
+       }
+       ao_mutex_put(&ao_config_mutex);
+}
+
+__code struct ao_cmds ao_config_cmds[] = {
+       { 'c',  ao_config_set,  "c <var> <value>                    Set config variable (? for help, s to show)" },
+       { '\0', ao_config_set, NULL },
+};
+
+void
+ao_config_init(void)
+{
+       ao_cmd_register(&ao_config_cmds[0]);
+}
diff --git a/src/ao_convert.c b/src/ao_convert.c
new file mode 100644 (file)
index 0000000..57ed737
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+static const int16_t altitude_table[2048] = {
+#include "altitude.h"
+};
+
+int16_t
+ao_pres_to_altitude(int16_t pres) __reentrant
+{
+       pres = pres >> 4;
+       if (pres < 0) pres = 0;
+       if (pres > 2047) pres = 2047;
+       return altitude_table[pres];
+}
+
+int16_t
+ao_altitude_to_pres(int16_t alt) __reentrant
+{
+       int16_t pres;
+
+       for (pres = 0; pres < 2047; pres++)
+               if (altitude_table[pres] <= alt)
+                       break;
+       return pres << 4;
+}
+
+static __xdata uint8_t ao_temp_mutex;
+
+int16_t
+ao_temp_to_dC(int16_t temp) __reentrant
+{
+       int16_t ret;
+
+       ao_mutex_get(&ao_temp_mutex);
+       ret = (int16_t) ((temp >> 4) * 3300L / 2047L) - 500;
+       ao_mutex_put(&ao_temp_mutex);
+       return ret;
+}
diff --git a/src/ao_dbg.c b/src/ao_dbg.c
new file mode 100644 (file)
index 0000000..c8dc6dd
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+#define 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)
+
+static void
+ao_dbg_send_bits(uint8_t msk, uint8_t val)
+{
+       P0 = (P0 & ~msk) | (val & msk);
+       _asm
+               nop
+               nop
+       _endasm;
+}
+
+void
+ao_dbg_send_byte(uint8_t byte)
+{
+       __xdata uint8_t b, d;
+
+       P0 |= DBG_DATA;
+       P0DIR |= DBG_DATA;
+       for (b = 0; b < 8; b++) {
+               d = 0;
+               if (byte & 0x80)
+                       d = DBG_DATA;
+               byte <<= 1;
+               ao_dbg_send_bits(DBG_CLOCK|DBG_DATA, DBG_CLOCK|d);
+               ao_dbg_send_bits(DBG_CLOCK|DBG_DATA,     0    |d);
+       }
+       P0DIR &= ~DBG_DATA;
+}
+
+uint8_t
+ao_dbg_recv_byte(void)
+{
+       __xdata uint8_t byte, b;
+
+       byte = 0;
+       for (b = 0; b < 8; b++) {
+               byte = byte << 1;
+               ao_dbg_send_bits(DBG_CLOCK, DBG_CLOCK);
+               if (DBG_DATA_PIN)
+                       byte |= 1;
+               ao_dbg_send_bits(DBG_CLOCK, 0);
+       }
+       return byte;
+}
+
+/* 8051 instructions
+ */
+#define NOP                    0x00
+#define MOV_direct_data                0x75
+#define LJMP                   0x02
+#define MOV_Rn_data(n)         (0x78 | (n))
+#define DJNZ_Rn_rel(n)         (0xd8 | (n))
+#define MOV_A_direct           0xe5
+#define MOV_direct1_direct2    0x85
+#define MOV_direct_A           0xf5
+#define MOV_DPTR_data16                0x90
+#define MOV_A_data             0x74
+#define MOVX_atDPTR_A          0xf0
+#define MOVX_A_atDPTR          0xe0
+#define INC_DPTR               0xa3
+#define TRAP                   0xa5
+#define SJMP                   0x80
+#define JB                     0x20
+
+#define DEBUG_INSTR(l)         (0x54 | (l))
+
+#define SFR_PSW                        0xD0
+#define SFR_DPL0               0x82
+#define SFR_DPH0               0x83
+#define SFR_DPL1               0x84
+#define SFR_DPH1               0x85
+
+__xdata uint8_t        save_acc;
+__xdata uint8_t save_psw;
+__xdata uint8_t save_dpl0;
+__xdata uint8_t save_dph0;
+__xdata uint8_t save_dpl1;
+__xdata uint8_t save_dph1;
+
+static uint8_t
+ao_dbg_inst1(uint8_t a) __reentrant
+{
+       ao_dbg_send_byte(DEBUG_INSTR(1));
+       ao_dbg_send_byte(a);
+       return ao_dbg_recv_byte();
+}
+
+static uint8_t
+ao_dbg_inst2(uint8_t a, uint8_t b) __reentrant
+{
+       ao_dbg_send_byte(DEBUG_INSTR(2));
+       ao_dbg_send_byte(a);
+       ao_dbg_send_byte(b);
+       return ao_dbg_recv_byte();
+}
+
+static uint8_t
+ao_dbg_inst3(uint8_t a, uint8_t b, uint8_t c) __reentrant
+{
+       ao_dbg_send_byte(DEBUG_INSTR(3));
+       ao_dbg_send_byte(a);
+       ao_dbg_send_byte(b);
+       ao_dbg_send_byte(c);
+       return ao_dbg_recv_byte();
+}
+
+void
+ao_dbg_start_transfer(uint16_t addr)
+{
+       save_acc  = ao_dbg_inst1(NOP);
+       save_psw  = ao_dbg_inst2(MOV_A_direct, SFR_PSW);
+       save_dpl0 = ao_dbg_inst2(MOV_A_direct, SFR_DPL0);
+       save_dph0 = ao_dbg_inst2(MOV_A_direct, SFR_DPH0);
+       save_dpl1 = ao_dbg_inst2(MOV_A_direct, SFR_DPL1);
+       save_dph1 = ao_dbg_inst2(MOV_A_direct, SFR_DPH1);
+       ao_dbg_inst3(MOV_DPTR_data16, addr >> 8, addr);
+}
+
+void
+ao_dbg_end_transfer(void)
+{
+       ao_dbg_inst3(MOV_direct_data, SFR_DPL0, save_dpl0);
+       ao_dbg_inst3(MOV_direct_data, SFR_DPH0, save_dph0);
+       ao_dbg_inst3(MOV_direct_data, SFR_DPL1, save_dpl1);
+       ao_dbg_inst3(MOV_direct_data, SFR_DPH1, save_dph1);
+       ao_dbg_inst3(MOV_direct_data, SFR_PSW, save_psw);
+       ao_dbg_inst2(MOV_A_data, save_acc);
+}
+
+void
+ao_dbg_write_byte(uint8_t byte)
+{
+       ao_dbg_inst2(MOV_A_data, byte);
+       ao_dbg_inst1(MOVX_atDPTR_A);
+       ao_dbg_inst1(INC_DPTR);
+}
+
+uint8_t
+ao_dbg_read_byte(void)
+{
+       ao_dbg_inst1(MOVX_A_atDPTR);
+       return ao_dbg_inst1(INC_DPTR);
+}
+
+static void
+ao_dbg_set_pins(void)
+{
+       /* Disable peripheral use of P0 */
+       ADCCFG = 0;
+       P0SEL = 0;
+
+
+       /* make P0_4 tri-state */
+       P0INP = DBG_DATA;
+       P2INP &= ~(P2INP_PDUP0_PULL_DOWN);
+
+       /* Raise RESET_N and CLOCK */
+       P0 = DBG_RESET_N | DBG_CLOCK;
+
+       /* RESET_N and CLOCK are outputs now */
+       P0DIR = DBG_RESET_N | DBG_CLOCK;
+}
+
+static void
+ao_dbg_long_delay(void)
+{
+       uint8_t n;
+
+       for (n = 0; n < 20; n++)
+               _asm nop _endasm;
+}
+
+void
+ao_dbg_debug_mode(void)
+{
+       ao_dbg_set_pins();
+       ao_dbg_long_delay();
+       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N);
+       ao_dbg_long_delay();
+       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N,     0    |DBG_DATA|    0    );
+       ao_dbg_long_delay();
+       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
+       ao_dbg_long_delay();
+       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N,     0    |DBG_DATA|    0    );
+       ao_dbg_long_delay();
+       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
+       ao_dbg_long_delay();
+       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N,     0    |DBG_DATA|DBG_RESET_N);
+       ao_dbg_long_delay();
+}
+
+void
+ao_dbg_reset(void)
+{
+       ao_dbg_set_pins();
+       ao_dbg_long_delay();
+       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N);
+       ao_dbg_long_delay();
+       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
+       ao_dbg_long_delay();
+       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
+       ao_dbg_long_delay();
+       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
+       ao_dbg_long_delay();
+       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|    0    );
+       ao_dbg_long_delay();
+       ao_dbg_send_bits(DBG_CLOCK|DBG_DATA|DBG_RESET_N, DBG_CLOCK|DBG_DATA|DBG_RESET_N);
+       ao_dbg_long_delay();
+}
+
+static void
+debug_enable(void)
+{
+       ao_dbg_debug_mode();
+}
+
+static void
+debug_reset(void)
+{
+       ao_dbg_reset();
+}
+
+static void
+debug_put(void)
+{
+       for (;;) {
+               ao_cmd_white ();
+               if (ao_cmd_lex_c == '\n')
+                       break;
+               ao_cmd_hex();
+               if (ao_cmd_status != ao_cmd_success)
+                       break;
+               ao_dbg_send_byte(ao_cmd_lex_i);
+       }
+}
+
+static void
+debug_get(void)
+{
+       __xdata uint16_t count;
+       __xdata uint16_t i;
+       __xdata uint8_t byte;
+       ao_cmd_hex();
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       count = ao_cmd_lex_i;
+       if (count > 256) {
+               ao_cmd_status = ao_cmd_syntax_error;
+               return;
+       }
+       for (i = 0; i < count; i++) {
+               if (i && (i & 7) == 0)
+                       putchar('\n');
+               byte = ao_dbg_recv_byte();
+               ao_cmd_put8(byte);
+               putchar(' ');
+       }
+       putchar('\n');
+}
+
+static uint8_t
+getnibble(void)
+{
+       __xdata char    c;
+
+       c = getchar();
+       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);
+       ao_cmd_status = ao_cmd_lex_error;
+       return 0;
+}
+
+static void
+debug_input(void)
+{
+       __xdata uint16_t count;
+       __xdata uint16_t addr;
+       __xdata uint8_t b;
+       __xdata uint8_t i;
+
+       ao_cmd_hex();
+       count = ao_cmd_lex_i;
+       ao_cmd_hex();
+       addr = ao_cmd_lex_i;
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_dbg_start_transfer(addr);
+       i = 0;
+       while (count--) {
+               if (!(i++ & 7))
+                       putchar('\n');
+               b = ao_dbg_read_byte();
+               ao_cmd_put8(b);
+       }
+       ao_dbg_end_transfer();
+       putchar('\n');
+}
+
+static void
+debug_output(void)
+{
+       __xdata uint16_t count;
+       __xdata uint16_t addr;
+       __xdata uint8_t b;
+
+       ao_cmd_hex();
+       count = ao_cmd_lex_i;
+       ao_cmd_hex();
+       addr = ao_cmd_lex_i;
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_dbg_start_transfer(addr);
+       while (count--) {
+               b = getnibble() << 4;
+               b |= getnibble();
+               if (ao_cmd_status != ao_cmd_success)
+                       return;
+               ao_dbg_write_byte(b);
+       }
+       ao_dbg_end_transfer();
+}
+
+__code struct ao_cmds ao_dbg_cmds[7] = {
+       { 'D',  debug_enable,   "D                                  Enable debug mode" },
+       { 'G',  debug_get,      "G <count>                          Get data from debug port" },
+       { 'I',  debug_input,    "I <count> <addr>                   Input <count> bytes to target at <addr>" },
+       { 'O',  debug_output,   "O <count> <addr>                   Output <count> bytes to target at <addr>" },
+       { 'P',  debug_put,      "P <byte> ...                       Put data to debug port" },
+       { 'R',  debug_reset,    "R                                  Reset target" },
+       { 0, debug_reset,       0 },
+};
+
+void
+ao_dbg_init(void)
+{
+       ao_cmd_register(&ao_dbg_cmds[0]);
+}
diff --git a/src/ao_dma.c b/src/ao_dma.c
new file mode 100644 (file)
index 0000000..a4d45f1
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+#define NUM_DMA        5
+
+/*
+ * The config address for DMA0 is programmed
+ * separately from that of DMA1-4, but for simplicity,
+ * we make them all contiguous.
+ */
+
+static __xdata struct cc_dma_channel ao_dma_config[NUM_DMA];
+static __xdata uint8_t * __xdata ao_dma_done[NUM_DMA];
+static __data uint8_t ao_next_dma;
+
+uint8_t
+ao_dma_alloc(__xdata uint8_t *done)
+{
+       uint8_t id;
+
+       if (ao_next_dma == NUM_DMA)
+               ao_panic(AO_PANIC_DMA);
+       id = ao_next_dma++;
+       ao_dma_done[id] = done;
+
+       /* When the first dma object is allocated, set up the DMA
+        * controller
+        */
+       if (id == 0) {
+               DMAIRQ = 0;
+               DMAIF = 0;
+               IEN1 |= IEN1_DMAIE;
+       }
+
+       return id;
+}
+
+void
+ao_dma_set_transfer(uint8_t id,
+                   void __xdata *srcaddr,
+                   void __xdata *dstaddr,
+                   uint16_t count,
+                   uint8_t cfg0,
+                   uint8_t cfg1)
+{
+       if (DMAARM & (1 << id))
+               ao_panic(AO_PANIC_DMA);
+       ao_dma_config[id].src_high = ((uint16_t) srcaddr) >> 8;
+       ao_dma_config[id].src_low = ((uint16_t) srcaddr);
+       ao_dma_config[id].dst_high = ((uint16_t) dstaddr) >> 8;
+       ao_dma_config[id].dst_low = ((uint16_t) dstaddr);
+       ao_dma_config[id].len_high = count >> 8;
+       ao_dma_config[id].len_low = count;
+       ao_dma_config[id].cfg0 = cfg0;
+       ao_dma_config[id].cfg1 = cfg1 | DMA_CFG1_IRQMASK;
+       if (id == 0) {
+               DMA0CFGH = ((uint16_t) (&ao_dma_config[0])) >> 8;
+               DMA0CFGL = ((uint16_t) (&ao_dma_config[0]));
+       } else {
+               DMA1CFGH = ((uint16_t) (&ao_dma_config[1])) >> 8;
+               DMA1CFGL = ((uint16_t) (&ao_dma_config[1]));
+       }
+}
+
+#define nop()  _asm nop _endasm;
+
+void
+ao_dma_start(uint8_t id)
+{
+       uint8_t mask = (1 << id);
+       DMAIRQ &= ~mask;
+       DMAARM = 0x80 | mask;
+       nop(); nop(); nop(); nop();
+       nop(); nop(); nop(); nop();
+       *(ao_dma_done[id]) = 0;
+       DMAARM = mask;
+       nop(); nop(); nop(); nop();
+       nop(); nop(); nop(); nop();
+       nop();
+}
+
+void
+ao_dma_trigger(uint8_t id)
+{
+       DMAREQ |= (1 << id);
+}
+
+void
+ao_dma_abort(uint8_t id)
+{
+       uint8_t mask = (1 << id);
+       DMAARM = 0x80 | mask;
+       DMAIRQ &= ~mask;
+}
+
+void
+ao_dma_isr(void) interrupt 8
+{
+       uint8_t id, mask;
+
+       /* Find the first DMA channel which is done */
+       mask = 1;
+       for (id = 0; id < ao_next_dma; id++) {
+               if (DMAIRQ & mask) {
+                       /* Clear CPU interrupt flag */
+                       DMAIF = 0;
+                       /* Clear the completed ID */
+                       DMAIRQ = ~mask;
+                       *(ao_dma_done[id]) = 1;
+                       ao_wakeup(ao_dma_done[id]);
+                       break;
+               }
+               mask <<= 1;
+       }
+}
diff --git a/src/ao_ee.c b/src/ao_ee.c
new file mode 100644 (file)
index 0000000..f299b92
--- /dev/null
@@ -0,0 +1,459 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+#include "25lc1024.h"
+
+/*
+ * Using SPI on USART 0, with P1_2 as the chip select
+ */
+
+#define EE_CS          P1_2
+#define EE_CS_INDEX    2
+
+__xdata uint8_t ao_ee_dma_in_done;
+__xdata uint8_t ao_ee_dma_out_done;
+__xdata uint8_t ao_ee_mutex;
+
+uint8_t        ao_ee_dma_out_id;
+uint8_t ao_ee_dma_in_id;
+
+static __xdata uint8_t ao_ee_const = 0xff;
+
+#define ao_ee_delay() do { \
+       _asm nop _endasm; \
+       _asm nop _endasm; \
+       _asm nop _endasm; \
+} while(0)
+
+void ao_ee_cs_low(void)
+{
+       ao_ee_delay();
+       EE_CS = 0;
+       ao_ee_delay();
+}
+
+void ao_ee_cs_high(void)
+{
+       ao_ee_delay();
+       EE_CS = 1;
+       ao_ee_delay();
+}
+
+/* Send bytes over SPI.
+ *
+ * This sets up two DMA engines, one writing the data and another reading
+ * bytes coming back.  We use the bytes coming back to tell when the transfer
+ * is complete, as the transmit register is double buffered and hence signals
+ * completion one byte before the transfer is actually complete
+ */
+static void
+ao_ee_send(void __xdata *block, uint16_t len)
+{
+       ao_dma_set_transfer(ao_ee_dma_in_id,
+                           &U0DBUFXADDR,
+                           &ao_ee_const,
+                           len,
+                           DMA_CFG0_WORDSIZE_8 |
+                           DMA_CFG0_TMODE_SINGLE |
+                           DMA_CFG0_TRIGGER_URX0,
+                           DMA_CFG1_SRCINC_0 |
+                           DMA_CFG1_DESTINC_0 |
+                           DMA_CFG1_PRIORITY_NORMAL);
+
+       ao_dma_set_transfer(ao_ee_dma_out_id,
+                           block,
+                           &U0DBUFXADDR,
+                           len,
+                           DMA_CFG0_WORDSIZE_8 |
+                           DMA_CFG0_TMODE_SINGLE |
+                           DMA_CFG0_TRIGGER_UTX0,
+                           DMA_CFG1_SRCINC_1 |
+                           DMA_CFG1_DESTINC_0 |
+                           DMA_CFG1_PRIORITY_NORMAL);
+
+       ao_dma_start(ao_ee_dma_in_id);
+       ao_dma_start(ao_ee_dma_out_id);
+       ao_dma_trigger(ao_ee_dma_out_id);
+       __critical while (!ao_ee_dma_in_done)
+               ao_sleep(&ao_ee_dma_in_done);
+}
+
+/* Receive bytes over SPI.
+ *
+ * This sets up tow DMA engines, one reading the data and another
+ * writing constant values to the SPI transmitter as that is what
+ * clocks the data coming in.
+ */
+static void
+ao_ee_recv(void __xdata *block, uint16_t len)
+{
+       ao_dma_set_transfer(ao_ee_dma_in_id,
+                           &U0DBUFXADDR,
+                           block,
+                           len,
+                           DMA_CFG0_WORDSIZE_8 |
+                           DMA_CFG0_TMODE_SINGLE |
+                           DMA_CFG0_TRIGGER_URX0,
+                           DMA_CFG1_SRCINC_0 |
+                           DMA_CFG1_DESTINC_1 |
+                           DMA_CFG1_PRIORITY_NORMAL);
+
+       ao_dma_set_transfer(ao_ee_dma_out_id,
+                           &ao_ee_const,
+                           &U0DBUFXADDR,
+                           len,
+                           DMA_CFG0_WORDSIZE_8 |
+                           DMA_CFG0_TMODE_SINGLE |
+                           DMA_CFG0_TRIGGER_UTX0,
+                           DMA_CFG1_SRCINC_0 |
+                           DMA_CFG1_DESTINC_0 |
+                           DMA_CFG1_PRIORITY_NORMAL);
+
+       ao_dma_start(ao_ee_dma_in_id);
+       ao_dma_start(ao_ee_dma_out_id);
+       ao_dma_trigger(ao_ee_dma_out_id);
+       __critical while (!ao_ee_dma_in_done)
+               ao_sleep(&ao_ee_dma_in_done);
+}
+
+#define EE_BLOCK       256
+
+struct ao_ee_instruction {
+       uint8_t instruction;
+       uint8_t address[3];
+} __xdata ao_ee_instruction;
+
+static void
+ao_ee_write_enable(void)
+{
+       ao_ee_cs_low();
+       ao_ee_instruction.instruction = EE_WREN;
+       ao_ee_send(&ao_ee_instruction, 1);
+       ao_ee_cs_high();
+}
+
+static uint8_t
+ao_ee_rdsr(void)
+{
+       ao_ee_cs_low();
+       ao_ee_instruction.instruction = EE_RDSR;
+       ao_ee_send(&ao_ee_instruction, 1);
+       ao_ee_recv(&ao_ee_instruction, 1);
+       ao_ee_cs_high();
+       return ao_ee_instruction.instruction;
+}
+
+static void
+ao_ee_wrsr(uint8_t status)
+{
+       ao_ee_cs_low();
+       ao_ee_instruction.instruction = EE_WRSR;
+       ao_ee_instruction.address[0] = status;
+       ao_ee_send(&ao_ee_instruction, 2);
+       ao_ee_cs_high();
+}
+
+#define EE_BLOCK_NONE  0xffff
+
+static __xdata uint8_t ao_ee_data[EE_BLOCK];
+static __pdata uint16_t ao_ee_block = EE_BLOCK_NONE;
+static __pdata uint8_t ao_ee_block_dirty;
+
+/* Write the current block to the EEPROM */
+static void
+ao_ee_write_block(void)
+{
+       uint8_t status;
+
+       status = ao_ee_rdsr();
+       if (status & (EE_STATUS_BP0|EE_STATUS_BP1|EE_STATUS_WPEN)) {
+               status &= ~(EE_STATUS_BP0|EE_STATUS_BP1|EE_STATUS_WPEN);
+               ao_ee_wrsr(status);
+       }
+       ao_ee_write_enable();
+       ao_ee_cs_low();
+       ao_ee_instruction.instruction = EE_WRITE;
+       ao_ee_instruction.address[0] = ao_ee_block >> 8;
+       ao_ee_instruction.address[1] = ao_ee_block;
+       ao_ee_instruction.address[2] = 0;
+       ao_ee_send(&ao_ee_instruction, 4);
+       ao_ee_send(ao_ee_data, EE_BLOCK);
+       ao_ee_cs_high();
+       for (;;) {
+               uint8_t status = ao_ee_rdsr();
+               if ((status & EE_STATUS_WIP) == 0)
+                       break;
+       }
+}
+
+/* Read the current block from the EEPROM */
+static void
+ao_ee_read_block(void)
+{
+       ao_ee_cs_low();
+       ao_ee_instruction.instruction = EE_READ;
+       ao_ee_instruction.address[0] = ao_ee_block >> 8;
+       ao_ee_instruction.address[1] = ao_ee_block;
+       ao_ee_instruction.address[2] = 0;
+       ao_ee_send(&ao_ee_instruction, 4);
+       ao_ee_recv(ao_ee_data, EE_BLOCK);
+       ao_ee_cs_high();
+}
+
+static void
+ao_ee_flush_internal(void)
+{
+       if (ao_ee_block_dirty) {
+               ao_ee_write_block();
+               ao_ee_block_dirty = 0;
+       }
+}
+
+static void
+ao_ee_fill(uint16_t block)
+{
+       if (block != ao_ee_block) {
+               ao_ee_flush_internal();
+               ao_ee_block = block;
+               ao_ee_read_block();
+       }
+}
+
+uint8_t
+ao_ee_write(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant
+{
+       uint16_t block;
+       uint16_t this_len;
+       uint8_t this_off;
+
+       if (pos >= AO_EE_DATA_SIZE || pos + len > AO_EE_DATA_SIZE)
+               return 0;
+       while (len) {
+
+               /* Compute portion of transfer within
+                * a single block
+                */
+               this_off = pos;
+               this_len = 256 - (uint16_t) this_off;
+               block = (uint16_t) (pos >> 8);
+               if (this_len > len)
+                       this_len = len;
+               if (this_len & 0xff00)
+                       ao_panic(AO_PANIC_EE);
+
+               /* Transfer the data */
+               ao_mutex_get(&ao_ee_mutex); {
+                       if (this_len != 256)
+                               ao_ee_fill(block);
+                       else {
+                               ao_ee_flush_internal();
+                               ao_ee_block = block;
+                       }
+                       memcpy(ao_ee_data + this_off, buf, this_len);
+                       ao_ee_block_dirty = 1;
+               } ao_mutex_put(&ao_ee_mutex);
+
+               /* See how much is left */
+               buf += this_len;
+               len -= this_len;
+       }
+       return 1;
+}
+
+uint8_t
+ao_ee_read(uint32_t pos, uint8_t *buf, uint16_t len) __reentrant
+{
+       uint16_t block;
+       uint16_t this_len;
+       uint8_t this_off;
+
+       if (pos >= AO_EE_DATA_SIZE || pos + len > AO_EE_DATA_SIZE)
+               return 0;
+       while (len) {
+
+               /* Compute portion of transfer within
+                * a single block
+                */
+               this_off = pos;
+               this_len = 256 - (uint16_t) this_off;
+               block = (uint16_t) (pos >> 8);
+               if (this_len > len)
+                       this_len = len;
+               if (this_len & 0xff00)
+                       ao_panic(AO_PANIC_EE);
+
+               /* Transfer the data */
+               ao_mutex_get(&ao_ee_mutex); {
+                       ao_ee_fill(block);
+                       memcpy(buf, ao_ee_data + this_off, this_len);
+               } ao_mutex_put(&ao_ee_mutex);
+
+               /* See how much is left */
+               buf += this_len;
+               len -= this_len;
+       }
+       return 1;
+}
+
+void
+ao_ee_flush(void) __reentrant
+{
+       ao_mutex_get(&ao_ee_mutex); {
+               ao_ee_flush_internal();
+       } ao_mutex_put(&ao_ee_mutex);
+}
+
+/*
+ * Read/write the config block, which is in
+ * the last block of the ao_eeprom
+ */
+uint8_t
+ao_ee_write_config(uint8_t *buf, uint16_t len) __reentrant
+{
+       if (len > AO_EE_BLOCK_SIZE)
+               return 0;
+       ao_mutex_get(&ao_ee_mutex); {
+               ao_ee_fill(AO_EE_CONFIG_BLOCK);
+               memcpy(ao_ee_data, buf, len);
+               ao_ee_block_dirty = 1;
+               ao_ee_flush_internal();
+       } ao_mutex_put(&ao_ee_mutex);
+       return 1;
+}
+
+uint8_t
+ao_ee_read_config(uint8_t *buf, uint16_t len) __reentrant
+{
+       if (len > AO_EE_BLOCK_SIZE)
+               return 0;
+       ao_mutex_get(&ao_ee_mutex); {
+               ao_ee_fill(AO_EE_CONFIG_BLOCK);
+               memcpy(buf, ao_ee_data, len);
+       } ao_mutex_put(&ao_ee_mutex);
+       return 1;
+}
+
+static void
+ee_dump(void)
+{
+       __xdata uint8_t b;
+       __xdata uint16_t block;
+       __xdata uint8_t i;
+
+       ao_cmd_hex();
+       block = ao_cmd_lex_i;
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       i = 0;
+       do {
+               if ((i & 7) == 0) {
+                       if (i)
+                               putchar('\n');
+                       ao_cmd_put16((uint16_t) i);
+               }
+               putchar(' ');
+               ao_ee_read(((uint32_t) block << 8) | i, &b, 1);
+               ao_cmd_put8(b);
+               ++i;
+       } while (i != 0);
+       putchar('\n');
+}
+
+static void
+ee_store(void)
+{
+       __xdata uint16_t block;
+       __xdata uint8_t i;
+       __xdata uint16_t len;
+       __xdata uint8_t b;
+       __xdata uint32_t addr;
+
+       ao_cmd_hex();
+       block = ao_cmd_lex_i;
+       ao_cmd_hex();
+       i = ao_cmd_lex_i;
+       addr = ((uint32_t) block << 8) | i;
+       ao_cmd_hex();
+       len = ao_cmd_lex_i;
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       while (len--) {
+               ao_cmd_hex();
+               if (ao_cmd_status != ao_cmd_success)
+                       return;
+               b = ao_cmd_lex_i;
+               ao_ee_write(addr, &b, 1);
+               addr++;
+       }
+       ao_ee_flush();
+}
+
+__code struct ao_cmds ao_ee_cmds[] = {
+       { 'e', ee_dump,         "e <block>                          Dump a block of EEPROM data" },
+       { 'w', ee_store,        "w <block> <start> <len> <data> ... Write data to EEPROM" },
+       { 0,   ee_store, NULL },
+};
+
+/*
+ * To initialize the chip, set up the CS line and
+ * the SPI interface
+ */
+void
+ao_ee_init(void)
+{
+       /* set up CS */
+       EE_CS = 1;
+       P1DIR |= (1 << EE_CS_INDEX);
+       P1SEL &= ~(1 << EE_CS_INDEX);
+
+       /* Set up the USART pin assignment */
+       PERCFG = (PERCFG & ~PERCFG_U0CFG_ALT_MASK) | PERCFG_U0CFG_ALT_2;
+
+       /* Ensure that USART0 takes precidence over USART1 for pins that
+        * they share
+        */
+       P2SEL = (P2SEL & ~P2SEL_PRI3P1_MASK) | P2SEL_PRI3P1_USART0;
+
+       /* Make the SPI pins be controlled by the USART peripheral */
+       P1SEL |= ((1 << 5) | (1 << 4) | (1 << 3));
+
+       /* Set up OUT DMA */
+       ao_ee_dma_out_id = ao_dma_alloc(&ao_ee_dma_out_done);
+
+       /* Set up IN DMA */
+       ao_ee_dma_in_id = ao_dma_alloc(&ao_ee_dma_in_done);
+
+       /* Set up the USART.
+        *
+        * SPI master mode
+        */
+       U0CSR = (UxCSR_MODE_SPI | UxCSR_RE | UxCSR_MASTER);
+
+       /* Set the baud rate and signal parameters
+        *
+        * The cc1111 is limited to a 24/8 MHz SPI clock,
+        * while the 25LC1024 is limited to 20MHz. So,
+        * use the 3MHz clock (BAUD_E 17, BAUD_M 0)
+        */
+       U0BAUD = 0;
+       U0GCR = (UxGCR_CPOL_NEGATIVE |
+                UxGCR_CPHA_FIRST_EDGE |
+                UxGCR_ORDER_MSB |
+                (17 << UxGCR_BAUD_E_SHIFT));
+       ao_cmd_register(&ao_ee_cmds[0]);
+}
diff --git a/src/ao_ee_fake.c b/src/ao_ee_fake.c
new file mode 100644 (file)
index 0000000..b0c1d61
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+/*
+ * For hardware without eeprom, the config code still
+ * wants to call these functions
+ */
+uint8_t
+ao_ee_write_config(uint8_t *buf, uint16_t len) __reentrant
+{
+       (void) buf;
+       (void) len;
+       return 1;
+}
+
+uint8_t
+ao_ee_read_config(uint8_t *buf, uint16_t len) __reentrant
+{
+       memset(buf, '\0', len);
+       return 1;
+}
diff --git a/src/ao_flight.c b/src/ao_flight.c
new file mode 100644 (file)
index 0000000..c0f5683
--- /dev/null
@@ -0,0 +1,484 @@
+/*
+ * Copyright Â© 2009 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_FLIGHT_TEST
+#include "ao.h"
+#endif
+
+/* Main flight thread. */
+
+__pdata enum ao_flight_state   ao_flight_state;        /* current flight state */
+__pdata uint16_t               ao_flight_tick;         /* time of last data */
+__pdata uint16_t               ao_flight_prev_tick;    /* time of previous data */
+__pdata int16_t                        ao_flight_accel;        /* filtered acceleration */
+__pdata int16_t                        ao_flight_pres;         /* filtered pressure */
+__pdata int16_t                        ao_ground_pres;         /* startup pressure */
+__pdata int16_t                        ao_ground_accel;        /* startup acceleration */
+__pdata int16_t                        ao_min_pres;            /* minimum recorded pressure */
+__pdata uint16_t               ao_launch_tick;         /* time of launch detect */
+__pdata int16_t                        ao_main_pres;           /* pressure to eject main */
+
+/*
+ * track min/max data over a long interval to detect
+ * resting
+ */
+__pdata uint16_t               ao_interval_end;
+__pdata int16_t                        ao_interval_cur_min_accel;
+__pdata int16_t                        ao_interval_cur_max_accel;
+__pdata int16_t                        ao_interval_cur_min_pres;
+__pdata int16_t                        ao_interval_cur_max_pres;
+__pdata int16_t                        ao_interval_min_accel;
+__pdata int16_t                        ao_interval_max_accel;
+__pdata int16_t                        ao_interval_min_pres;
+__pdata int16_t                        ao_interval_max_pres;
+
+__data uint8_t ao_flight_adc;
+__pdata int16_t ao_raw_accel, ao_raw_accel_prev, ao_raw_pres;
+
+/* Accelerometer calibration
+ *
+ * We're sampling the accelerometer through a resistor divider which
+ * consists of 5k and 10k resistors. This multiplies the values by 2/3.
+ * That goes into the cc1111 A/D converter, which is running at 11 bits
+ * of precision with the bits in the MSB of the 16 bit value. Only positive
+ * values are used, so values should range from 0-32752 for 0-3.3V. The
+ * specs say we should see 40mV/g (uncalibrated), multiply by 2/3 for what
+ * the A/D converter sees (26.67 mV/g). We should see 32752/3300 counts/mV,
+ * for a final computation of:
+ *
+ * 26.67 mV/g * 32767/3300 counts/mV = 264.8 counts/g
+ *
+ * Zero g was measured at 16000 (we would expect 16384).
+ * Note that this value is only require to tell if the
+ * rocket is standing upright. Once that is determined,
+ * the value of the accelerometer is averaged for 100 samples
+ * to find the resting accelerometer value, which is used
+ * for all further flight computations
+ */
+
+#define GRAVITY 9.80665
+/* convert m/s to velocity count */
+#define VEL_MPS_TO_COUNT(mps) ((int32_t) (((mps) / GRAVITY) * ACCEL_G * 100))
+
+#define ACCEL_G                265
+#define ACCEL_ZERO_G   16000
+#define ACCEL_NOSE_UP  (ACCEL_G * 2 /3)
+#define ACCEL_BOOST    ACCEL_G * 2
+#define ACCEL_INT_LAND (ACCEL_G / 10)
+#define ACCEL_VEL_LAND VEL_MPS_TO_COUNT(10)
+#define ACCEL_VEL_MACH VEL_MPS_TO_COUNT(200)
+#define ACCEL_VEL_APOGEE       VEL_MPS_TO_COUNT(2)
+#define ACCEL_VEL_MAIN VEL_MPS_TO_COUNT(100)
+#define ACCEL_VEL_BOOST        VEL_MPS_TO_COUNT(5)
+
+/*
+ * Barometer calibration
+ *
+ * We directly sample the barometer. The specs say:
+ *
+ * Pressure range: 15-115 kPa
+ * Voltage at 115kPa: 2.82
+ * Output scale: 27mV/kPa
+ *
+ * If we want to detect launch with the barometer, we need
+ * a large enough bump to not be fooled by noise. At typical
+ * launch elevations (0-2000m), a 200Pa pressure change cooresponds
+ * to about a 20m elevation change. This is 5.4mV, or about 3LSB.
+ * As all of our calculations are done in 16 bits, we'll actually see a change
+ * of 16 times this though
+ *
+ * 27 mV/kPa * 32767 / 3300 counts/mV = 268.1 counts/kPa
+ */
+
+#define BARO_kPa       268
+#define BARO_LAUNCH    (BARO_kPa / 5)  /* .2kPa, or about 20m */
+#define BARO_APOGEE    (BARO_kPa / 10) /* .1kPa, or about 10m */
+#define BARO_COAST     (BARO_kPa * 5)  /* 5kpa, or about 500m */
+#define BARO_MAIN      (BARO_kPa)      /* 1kPa, or about 100m */
+#define BARO_INT_LAND  (BARO_kPa / 20) /* .05kPa, or about 5m */
+#define BARO_LAND      (BARO_kPa * 10) /* 10kPa or about 1000m */
+
+/* We also have a clock, which can be used to sanity check things in
+ * case of other failures
+ */
+
+#define BOOST_TICKS_MAX        AO_SEC_TO_TICKS(15)
+
+/* This value is scaled in a weird way. It's a running total of accelerometer
+ * readings minus the ground accelerometer reading. That means it measures
+ * velocity, and quite accurately too. As it gets updated 100 times a second,
+ * it's scaled by 100
+ */
+__pdata int32_t        ao_flight_vel;
+__pdata int32_t ao_min_vel;
+__pdata int32_t        ao_old_vel;
+__pdata int16_t ao_old_vel_tick;
+__xdata int32_t ao_raw_accel_sum, ao_raw_pres_sum;
+
+/* Landing is detected by getting constant readings from both pressure and accelerometer
+ * for a fairly long time (AO_INTERVAL_TICKS)
+ */
+#define AO_INTERVAL_TICKS      AO_SEC_TO_TICKS(20)
+
+#define abs(a) ((a) < 0 ? -(a) : (a))
+
+void
+ao_flight(void)
+{
+       __pdata static uint16_t nsamples = 0;
+
+       ao_flight_adc = ao_adc_head;
+       ao_raw_accel_prev = 0;
+       ao_raw_accel = 0;
+       ao_raw_pres = 0;
+       ao_flight_tick = 0;
+       for (;;) {
+               ao_sleep(&ao_adc_ring);
+               while (ao_flight_adc != ao_adc_head) {
+                       __pdata uint8_t ticks;
+                       __pdata int16_t ao_vel_change;
+                       ao_flight_prev_tick = ao_flight_tick;
+
+                       /* Capture a sample */
+                       ao_raw_accel = ao_adc_ring[ao_flight_adc].accel;
+                       ao_raw_pres = ao_adc_ring[ao_flight_adc].pres;
+                       ao_flight_tick = ao_adc_ring[ao_flight_adc].tick;
+
+                       ao_flight_accel -= ao_flight_accel >> 4;
+                       ao_flight_accel += ao_raw_accel >> 4;
+                       ao_flight_pres -= ao_flight_pres >> 4;
+                       ao_flight_pres += ao_raw_pres >> 4;
+                       /* Update velocity
+                        *
+                        * The accelerometer is mounted so that
+                        * acceleration yields negative values
+                        * while deceleration yields positive values,
+                        * so subtract instead of add.
+                        */
+                       ticks = ao_flight_tick - ao_flight_prev_tick;
+                       ao_vel_change = (((ao_raw_accel >> 1) + (ao_raw_accel_prev >> 1)) - ao_ground_accel);
+                       ao_raw_accel_prev = ao_raw_accel;
+
+                       /* one is a common interval */
+                       if (ticks == 1)
+                               ao_flight_vel -= (int32_t) ao_vel_change;
+                       else
+                               ao_flight_vel -= (int32_t) ao_vel_change * (int32_t) ticks;
+
+                       ao_flight_adc = ao_adc_ring_next(ao_flight_adc);
+               }
+
+               if (ao_flight_pres < ao_min_pres)
+                       ao_min_pres = ao_flight_pres;
+               if (ao_flight_vel >= 0) {
+                       if (ao_flight_vel < ao_min_vel)
+                           ao_min_vel = ao_flight_vel;
+               } else {
+                       if (-ao_flight_vel < ao_min_vel)
+                           ao_min_vel = -ao_flight_vel;
+               }
+
+               switch (ao_flight_state) {
+               case ao_flight_startup:
+
+                       /* startup state:
+                        *
+                        * Collect 1000 samples of acceleration and pressure
+                        * data and average them to find the resting values
+                        */
+                       if (nsamples < 1000) {
+                               ao_raw_accel_sum += ao_raw_accel;
+                               ao_raw_pres_sum += ao_raw_pres;
+                               ++nsamples;
+                               continue;
+                       }
+                       ao_ground_accel = (ao_raw_accel_sum / nsamples);
+                       ao_ground_pres = (ao_raw_pres_sum / nsamples);
+                       ao_min_pres = ao_ground_pres;
+                       ao_config_get();
+                       ao_main_pres = ao_altitude_to_pres(ao_pres_to_altitude(ao_ground_pres) + ao_config.main_deploy);
+                       ao_flight_vel = 0;
+                       ao_min_vel = 0;
+                       ao_old_vel = ao_flight_vel;
+                       ao_old_vel_tick = ao_flight_tick;
+
+                       /* Go to launchpad state if the nose is pointing up */
+                       ao_config_get();
+                       if (ao_flight_accel < ao_config.accel_zero_g - ACCEL_NOSE_UP) {
+
+                               /* Disable the USB controller in flight mode
+                                * to save power
+                                */
+                               ao_usb_disable();
+
+                               /* Turn on telemetry system
+                                */
+                               ao_telemetry_set_interval(AO_TELEMETRY_INTERVAL_PAD);
+
+                               ao_flight_state = ao_flight_launchpad;
+                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
+                       } else {
+                               ao_flight_state = ao_flight_idle;
+
+                               /* Turn on the Green LED in idle mode
+                                */
+                               ao_led_on(AO_LED_GREEN);
+                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
+                       }
+                       /* signal successful initialization by turning off the LED */
+                       ao_led_off(AO_LED_RED);
+                       break;
+               case ao_flight_launchpad:
+
+                       /* Trim velocity
+                        *
+                        * Once a second, remove any velocity from
+                        * a second ago
+                        */
+                       if ((int16_t) (ao_flight_tick - ao_old_vel_tick) >= AO_SEC_TO_TICKS(1)) {
+                               ao_old_vel_tick = ao_flight_tick;
+                               ao_flight_vel -= ao_old_vel;
+                               ao_old_vel = ao_flight_vel;
+                       }
+                       /* pad to boost:
+                        *
+                        * accelerometer: > 2g AND velocity > 5m/s
+                        *             OR
+                        * barometer: > 20m vertical motion
+                        *
+                        * The accelerometer should always detect motion before
+                        * the barometer, but we use both to make sure this
+                        * transition is detected
+                        */
+                       if ((ao_flight_accel < ao_ground_accel - ACCEL_BOOST &&
+                            ao_flight_vel > ACCEL_VEL_BOOST) ||
+                           ao_flight_pres < ao_ground_pres - BARO_LAUNCH)
+                       {
+                               ao_flight_state = ao_flight_boost;
+                               ao_launch_tick = ao_flight_tick;
+
+                               /* start logging data */
+                               ao_log_start();
+
+                               /* Increase telemetry rate */
+                               ao_telemetry_set_interval(AO_TELEMETRY_INTERVAL_FLIGHT);
+
+                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
+                               break;
+                       }
+                       break;
+               case ao_flight_boost:
+
+                       /* boost to coast:
+                        *
+                        * accelerometer: start to fall at > 1/4 G
+                        *              OR
+                        * time: boost for more than 15 seconds
+                        *
+                        * Detects motor burn out by the switch from acceleration to
+                        * deceleration, or by waiting until the maximum burn duration
+                        * (15 seconds) has past.
+                        */
+                       if (ao_flight_accel > ao_ground_accel + (ACCEL_G >> 2) ||
+                           (int16_t) (ao_flight_tick - ao_launch_tick) > BOOST_TICKS_MAX)
+                       {
+                               ao_flight_state = ao_flight_coast;
+                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
+                               break;
+                       }
+                       break;
+               case ao_flight_coast:
+
+                       /* coast to apogee detect:
+                        *
+                        * accelerometer: integrated velocity < 200 m/s
+                        *               OR
+                        * barometer: fall at least 500m from max altitude
+                        *
+                        * This extra state is required to avoid mis-detecting
+                        * apogee due to mach transitions.
+                        *
+                        * XXX this is essentially a single-detector test
+                        * as the 500m altitude change would likely result
+                        * in a loss of the rocket. More data on precisely
+                        * how big a pressure change the mach transition
+                        * generates would be useful here.
+                        */
+                       if (ao_flight_vel < ACCEL_VEL_MACH ||
+                           ao_flight_pres > ao_min_pres + BARO_COAST)
+                       {
+                               /* set min velocity to current velocity for
+                                * apogee detect
+                                */
+                               ao_min_vel = abs(ao_flight_vel);
+                               ao_flight_state = ao_flight_apogee;
+                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
+                       }
+                       break;
+               case ao_flight_apogee:
+
+                       /* apogee detect to drogue deploy:
+                        *
+                        * accelerometer: abs(velocity) > min_velocity + 2m/s
+                        *               OR
+                        * barometer: fall at least 10m
+                        *
+                        * If the barometer saturates because the flight
+                        * goes over its measuring range (about 53k'),
+                        * requiring a 10m fall will avoid prematurely
+                        * detecting apogee; the accelerometer will take
+                        * over in that case and the integrated velocity
+                        * measurement should suffice to find apogee
+                        */
+                       if (/* abs(ao_flight_vel) > ao_min_vel + ACCEL_VEL_APOGEE || */
+                           ao_flight_pres > ao_min_pres + BARO_APOGEE)
+                       {
+                               /* ignite the drogue charge */
+                               ao_ignite(ao_igniter_drogue);
+
+                               /* slow down the telemetry system */
+                               ao_telemetry_set_interval(AO_TELEMETRY_INTERVAL_RECOVER);
+
+                               /* slow down the ADC sample rate */
+                               ao_timer_set_adc_interval(10);
+
+                               /*
+                                * Start recording min/max accel and pres for a while
+                                * to figure out when the rocket has landed
+                                */
+                               /* Set the 'last' limits to max range to prevent
+                                * early resting detection
+                                */
+                               ao_interval_min_accel = 0;
+                               ao_interval_max_accel = 0x7fff;
+                               ao_interval_min_pres = 0;
+                               ao_interval_max_pres = 0x7fff;
+
+                               /* initialize interval values */
+                               ao_interval_end = ao_flight_tick + AO_INTERVAL_TICKS;
+
+                               ao_interval_cur_min_pres = ao_interval_cur_max_pres = ao_flight_pres;
+                               ao_interval_cur_min_accel = ao_interval_cur_max_accel = ao_flight_accel;
+
+                               /* and enter drogue state */
+                               ao_flight_state = ao_flight_drogue;
+                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
+                       }
+
+                       break;
+               case ao_flight_drogue:
+
+                       /* drogue to main deploy:
+                        *
+                        * barometer: reach main deploy altitude
+                        *
+                        * Would like to use the accelerometer for this test, but
+                        * the orientation of the flight computer is unknown after
+                        * drogue deploy, so we ignore it. Could also detect
+                        * high descent rate using the pressure sensor to
+                        * recognize drogue deploy failure and eject the main
+                        * at that point. Perhaps also use the drogue sense lines
+                        * to notice continutity?
+                        */
+                       if (ao_flight_pres >= ao_main_pres)
+                       {
+                               ao_ignite(ao_igniter_main);
+                               ao_flight_state = ao_flight_main;
+                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
+                       }
+
+                       /* fall through... */
+               case ao_flight_main:
+
+                       /* drogue/main to land:
+                        *
+                        * accelerometer: value stable
+                        *                           AND
+                        * barometer: altitude stable and within 1000m of the launch altitude
+                        */
+
+                       if (ao_flight_pres < ao_interval_cur_min_pres)
+                               ao_interval_cur_min_pres = ao_flight_pres;
+                       if (ao_flight_pres > ao_interval_cur_max_pres)
+                               ao_interval_cur_max_pres = ao_flight_pres;
+                       if (ao_flight_accel < ao_interval_cur_min_accel)
+                               ao_interval_cur_min_accel = ao_flight_accel;
+                       if (ao_flight_accel > ao_interval_cur_max_accel)
+                               ao_interval_cur_max_accel = ao_flight_accel;
+
+                       if ((int16_t) (ao_flight_tick - ao_interval_end) >= 0) {
+                               ao_interval_max_pres = ao_interval_cur_max_pres;
+                               ao_interval_min_pres = ao_interval_cur_min_pres;
+                               ao_interval_max_accel = ao_interval_cur_max_accel;
+                               ao_interval_min_accel = ao_interval_cur_min_accel;
+                               ao_interval_end = ao_flight_tick + AO_INTERVAL_TICKS;
+                               ao_interval_cur_min_pres = ao_interval_cur_max_pres = ao_flight_pres;
+                               ao_interval_cur_min_accel = ao_interval_cur_max_accel = ao_flight_accel;
+                       }
+
+                       if ((uint16_t) (ao_interval_max_accel - ao_interval_min_accel) < (uint16_t) ACCEL_INT_LAND &&
+                           ao_flight_pres > ao_ground_pres - BARO_LAND &&
+                           (uint16_t) (ao_interval_max_pres - ao_interval_min_pres) < (uint16_t) BARO_INT_LAND)
+                       {
+                               ao_flight_state = ao_flight_landed;
+
+                               /* turn off the ADC capture */
+                               ao_timer_set_adc_interval(0);
+
+                               ao_wakeup(DATA_TO_XDATA(&ao_flight_state));
+                       }
+                       break;
+               case ao_flight_landed:
+                       break;
+               }
+       }
+}
+
+#define AO_ACCEL_COUNT_TO_MSS(count)   ((count) / 27)
+#define AO_VEL_COUNT_TO_MS(count)      ((int16_t) ((count) / 2700))
+
+static void
+ao_flight_status(void)
+{
+       printf("STATE: %7s accel: %d speed: %d altitude: %d main: %d\n",
+              ao_state_names[ao_flight_state],
+              AO_ACCEL_COUNT_TO_MSS(ACCEL_ZERO_G - ao_flight_accel),
+              AO_VEL_COUNT_TO_MS(ao_flight_vel),
+              ao_pres_to_altitude(ao_flight_pres),
+              ao_pres_to_altitude(ao_main_pres));
+}
+
+static __xdata struct ao_task  flight_task;
+
+__code struct ao_cmds ao_flight_cmds[] = {
+       { 'f', ao_flight_status,        "f                                  Display current flight state" },
+       { 0, ao_flight_status, NULL }
+};
+
+void
+ao_flight_init(void)
+{
+       ao_flight_state = ao_flight_startup;
+       ao_interval_min_accel = 0;
+       ao_interval_max_accel = 0x7fff;
+       ao_interval_min_pres = 0;
+       ao_interval_max_pres = 0x7fff;
+       ao_interval_end = AO_INTERVAL_TICKS;
+
+       ao_add_task(&flight_task, ao_flight, "flight");
+       ao_cmd_register(&ao_flight_cmds[0]);
+}
diff --git a/src/ao_flight_test.c b/src/ao_flight_test.c
new file mode 100644 (file)
index 0000000..f4731aa
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define AO_ADC_RING    64
+#define ao_adc_ring_next(n)    (((n) + 1) & (AO_ADC_RING - 1))
+#define ao_adc_ring_prev(n)    (((n) - 1) & (AO_ADC_RING - 1))
+
+/*
+ * One set of samples read from the A/D converter
+ */
+struct ao_adc {
+       uint16_t        tick;           /* tick when the sample was read */
+       int16_t         accel;          /* accelerometer */
+       int16_t         pres;           /* pressure sensor */
+       int16_t         temp;           /* temperature sensor */
+       int16_t         v_batt;         /* battery voltage */
+       int16_t         sense_d;        /* drogue continuity sense */
+       int16_t         sense_m;        /* main continuity sense */
+};
+
+#define __pdata
+#define __data
+#define __xdata
+#define __code
+#define __reentrant
+
+enum ao_flight_state {
+       ao_flight_startup = 0,
+       ao_flight_idle = 1,
+       ao_flight_launchpad = 2,
+       ao_flight_boost = 3,
+       ao_flight_coast = 4,
+       ao_flight_apogee = 5,
+       ao_flight_drogue = 6,
+       ao_flight_main = 7,
+       ao_flight_landed = 8,
+       ao_flight_invalid = 9
+};
+
+struct ao_adc ao_adc_ring[AO_ADC_RING];
+uint8_t ao_adc_head;
+
+#define ao_led_on(l)
+#define ao_led_off(l)
+#define ao_timer_set_adc_interval(i)
+#define ao_wakeup(wchan) ao_dump_state()
+#define ao_cmd_register(c)
+#define ao_usb_disable()
+#define ao_telemetry_set_interval(x)
+
+enum ao_igniter {
+       ao_igniter_drogue = 0,
+       ao_igniter_main = 1
+};
+
+void
+ao_ignite(enum ao_igniter igniter)
+{
+       printf ("ignite %s\n", igniter == ao_igniter_drogue ? "drogue" : "main");
+}
+
+struct ao_task {
+       int dummy;
+};
+
+#define ao_add_task(t,f,n)
+
+#define ao_log_start()
+#define ao_log_stop()
+
+#define AO_MS_TO_TICKS(ms)     ((ms) / 10)
+#define AO_SEC_TO_TICKS(s)     ((s) * 100)
+
+#define AO_FLIGHT_TEST
+
+struct ao_adc ao_adc_static;
+
+FILE *emulator_in;
+
+void
+ao_dump_state(void);
+
+void
+ao_sleep(void *wchan);
+
+const char const * const ao_state_names[] = {
+       "startup", "idle", "pad", "boost", "coast",
+       "apogee", "drogue", "main", "landed", "invalid"
+};
+
+struct ao_cmds {
+       char            cmd;
+       void            (*func)(void);
+       const char      *help;
+};
+
+
+static int16_t altitude_table[2048] = {
+#include "altitude.h"
+};
+
+int16_t
+ao_pres_to_altitude(int16_t pres) __reentrant
+{
+       pres = pres >> 4;
+       if (pres < 0) pres = 0;
+       if (pres > 2047) pres = 2047;
+       return altitude_table[pres];
+}
+
+int16_t
+ao_altitude_to_pres(int16_t alt) __reentrant
+{
+       int16_t pres;
+
+       for (pres = 0; pres < 2047; pres++)
+               if (altitude_table[pres] <= alt)
+                       break;
+       return pres << 4;
+}
+
+struct ao_config {
+       uint16_t        main_deploy;
+       int16_t         accel_zero_g;
+};
+
+#define ao_config_get()
+
+struct ao_config ao_config = { 250, 16000 };
+
+#include "ao_flight.c"
+
+void
+ao_insert(void)
+{
+       ao_adc_ring[ao_adc_head] = ao_adc_static;
+       ao_adc_head = ao_adc_ring_next(ao_adc_head);
+       if (ao_flight_state != ao_flight_startup) {
+               printf("time %g accel %d pres %d\n",
+                      (double) ao_adc_static.tick / 100,
+                      ao_adc_static.accel,
+                      ao_adc_static.pres);
+       }
+}
+
+static int     ao_records_read = 0;
+static int     ao_eof_read = 0;
+static int     ao_flight_ground_accel;
+static int     ao_flight_started = 0;
+
+void
+ao_sleep(void *wchan)
+{
+       ao_dump_state();
+       if (wchan == &ao_adc_ring) {
+               char            type;
+               uint16_t        tick;
+               uint16_t        a, b;
+               int             ret;
+               char            line[1024];
+               char            *saveptr;
+               char            *l;
+               char            *words[64];
+               int             nword;
+
+               for (;;) {
+                       if (ao_records_read > 2 && ao_flight_state == ao_flight_startup)
+                       {
+                               ao_adc_static.accel = ao_flight_ground_accel;
+                               ao_insert();
+                               return;
+                       }
+
+                       if (!fgets(line, sizeof (line), emulator_in)) {
+                               if (++ao_eof_read >= 1000) {
+                                       printf ("no more data, exiting simulation\n");
+                                       exit(0);
+                               }
+                               ao_adc_static.tick += 10;
+                               ao_insert();
+                               return;
+                       }
+                       l = line;
+                       for (nword = 0; nword < 64; nword++) {
+                               words[nword] = strtok_r(l, " \t\n", &saveptr);
+                               l = NULL;
+                               if (words[nword] == NULL)
+                                       break;
+                       }
+                       if (nword == 4) {
+                               type = words[0][0];
+                               tick = strtoul(words[1], NULL, 16);
+                               a = strtoul(words[2], NULL, 16);
+                               b = strtoul(words[2], NULL, 16);
+                       } else if (nword >= 36 && strcmp(words[0], "CALL") == 0) {
+                               tick = atoi(words[10]);
+                               if (!ao_flight_started) {
+                                       type = 'F';
+                                       a = atoi(words[26]);
+                                       ao_flight_started = 1;
+                               } else {
+                                       type = 'A';
+                                       a = atoi(words[12]);
+                                       b = atoi(words[14]);
+                               }
+                       }
+                       if (type != 'F' && !ao_flight_started)
+                               continue;
+
+                       switch (type) {
+                       case 'F':
+                               ao_flight_ground_accel = a;
+                               ao_flight_started = 1;
+                               break;
+                       case 'S':
+                               break;
+                       case 'A':
+                               ao_adc_static.tick = tick;
+                               ao_adc_static.accel = a;
+                               ao_adc_static.pres = b;
+                               ao_records_read++;
+                               ao_insert();
+                               return;
+                       case 'T':
+                               ao_adc_static.tick = tick;
+                               ao_adc_static.temp = a;
+                               ao_adc_static.v_batt = b;
+                               break;
+                       case 'D':
+                       case 'G':
+                       case 'N':
+                       case 'W':
+                       case 'H':
+                               break;
+                       }
+               }
+
+       }
+}
+#define COUNTS_PER_G 264.8
+
+void
+ao_dump_state(void)
+{
+       if (ao_flight_state == ao_flight_startup)
+               return;
+       printf ("\t\t\t\t\t%s accel %g vel %g alt %d main %d\n",
+               ao_state_names[ao_flight_state],
+               (ao_ground_accel - ao_flight_accel) / COUNTS_PER_G * GRAVITY,
+               (double) ao_flight_vel / 100 / COUNTS_PER_G * GRAVITY,
+               ao_pres_to_altitude(ao_flight_pres) - ao_pres_to_altitude(ao_ground_pres),
+               ao_pres_to_altitude(ao_main_pres) - ao_pres_to_altitude(ao_ground_pres));
+       if (ao_flight_state == ao_flight_landed)
+               exit(0);
+}
+
+int
+main (int argc, char **argv)
+{
+       emulator_in = fopen (argv[1], "r");
+       if (!emulator_in) {
+               perror(argv[1]);
+               exit(1);
+       }
+       ao_flight_init();
+       ao_flight();
+}
diff --git a/src/ao_gps.c b/src/ao_gps.c
new file mode 100644 (file)
index 0000000..cbde8b4
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+#define AO_GPS_LEADER          6
+
+static const char ao_gps_header[] = "GPGGA,";
+__xdata uint8_t ao_gps_mutex;
+static __xdata char ao_gps_char;
+static __xdata uint8_t ao_gps_cksum;
+static __xdata uint8_t ao_gps_error;
+
+__xdata struct ao_gps_data     ao_gps_data;
+static __xdata struct ao_gps_data      ao_gps_next;
+
+const char ao_gps_config[] =
+       "$PSRF103,00,00,01,01*25\r\n"   /* GGA 1 per sec */
+       "$PSRF103,01,00,00,01*25\r\n"   /* GLL disable */
+       "$PSRF103,02,00,00,01*26\r\n"   /* GSA disable */
+       "$PSRF103,03,00,00,01*27\r\n"   /* GSV disable */
+       "$PSRF103,04,00,00,01*20\r\n"   /* RMC disable */
+       "$PSRF103,05,00,00,01*21\r\n";  /* VTG disable */
+
+static void
+ao_gps_lexchar(void)
+{
+       if (ao_gps_error)
+               ao_gps_char = '\n';
+       else
+               ao_gps_char = ao_serial_getchar();
+       ao_gps_cksum ^= ao_gps_char;
+}
+
+void
+ao_gps_skip(void)
+{
+       while (ao_gps_char >= '0')
+               ao_gps_lexchar();
+}
+
+void
+ao_gps_skip_field(void)
+{
+       while (ao_gps_char != ',' && ao_gps_char != '*' && ao_gps_char != '\n')
+               ao_gps_lexchar();
+}
+
+void
+ao_gps_skip_sep(void)
+{
+       while (ao_gps_char == ',' || ao_gps_char == '.' || ao_gps_char == '*')
+               ao_gps_lexchar();
+}
+
+__xdata static uint8_t ao_gps_num_width;
+
+static int16_t
+ao_gps_decimal(uint8_t max_width)
+{
+       int16_t v;
+       __xdata uint8_t neg = 0;
+
+       ao_gps_skip_sep();
+       if (ao_gps_char == '-') {
+               neg = 1;
+               ao_gps_lexchar();
+       }
+       v = 0;
+       ao_gps_num_width = 0;
+       while (ao_gps_num_width < max_width) {
+               if (ao_gps_char < '0' || '9' < ao_gps_char)
+                       break;
+               v = v * (int16_t) 10 + ao_gps_char - '0';
+               ao_gps_num_width++;
+               ao_gps_lexchar();
+       }
+       if (neg)
+               v = -v;
+       return v;
+}
+
+static uint8_t
+ao_gps_hex(uint8_t max_width)
+{
+       uint8_t v, d;
+
+       ao_gps_skip_sep();
+       v = 0;
+       ao_gps_num_width = 0;
+       while (ao_gps_num_width < max_width) {
+               if ('0' <= ao_gps_char && ao_gps_char <= '9')
+                       d = ao_gps_char - '0';
+               else if ('A' <= ao_gps_char && ao_gps_char <= 'F')
+                       d = ao_gps_char - 'A' + 10;
+               else if ('a' <= ao_gps_char && ao_gps_char <= 'f')
+                       d = ao_gps_char - 'a' + 10;
+               else
+                       break;
+               v = (v << 4) | d;
+               ao_gps_num_width++;
+               ao_gps_lexchar();
+       }
+       return v;
+}
+
+static void
+ao_gps_parse_pos(__xdata struct ao_gps_pos * pos, uint8_t deg_width) __reentrant
+{
+       pos->degrees = ao_gps_decimal(deg_width);
+       pos->minutes = ao_gps_decimal(2);
+       if (ao_gps_char == '.') {
+               pos->minutes_fraction = ao_gps_decimal(4);
+               while (ao_gps_num_width < 4) {
+                       pos->minutes_fraction *= 10;
+                       ao_gps_num_width++;
+               }
+       } else {
+               pos->minutes_fraction = 0;
+               if (ao_gps_char != ',')
+                       ao_gps_error = 1;
+       }
+}
+
+static void
+ao_gps_parse_flag(char yes_c, uint8_t yes, char no_c, uint8_t no) __reentrant
+{
+       ao_gps_skip_sep();
+       if (ao_gps_char == yes_c)
+               ao_gps_next.flags |= yes;
+       else if (ao_gps_char == no_c)
+               ao_gps_next.flags |= no;
+       else
+               ao_gps_error = 1;
+       ao_gps_lexchar();
+}
+
+
+void
+ao_gps(void) __reentrant
+{
+       char    c;
+       uint8_t i;
+
+       for (i = 0; (c = ao_gps_config[i]); i++)
+               ao_serial_putchar(c);
+       for (;;) {
+               /* Locate the begining of the next record */
+               for (;;) {
+                       c = ao_serial_getchar();
+                       if (c == '$')
+                               break;
+               }
+
+               ao_gps_cksum = 0;
+               ao_gps_error = 0;
+
+               /* Skip anything other than GGA */
+               for (i = 0; i < AO_GPS_LEADER; i++) {
+                       ao_gps_lexchar();
+                       if (ao_gps_char != ao_gps_header[i])
+                               break;
+               }
+               if (i != AO_GPS_LEADER)
+                       continue;
+
+               /* Now read the data into the gps data record
+                *
+                * $GPGGA,025149.000,4528.1723,N,12244.2480,W,1,05,2.0,103.5,M,-19.5,M,,0000*66
+                *
+                * Essential fix data
+                *
+                *         025149.000   time (02:51:49.000 GMT)
+                *         4528.1723,N  Latitude 45°28.1723' N
+                *         12244.2480,W Longitude 122°44.2480' W
+                *         1            Fix quality:
+                *                                 0 = invalid
+                *                                 1 = GPS fix (SPS)
+                *                                 2 = DGPS fix
+                *                                 3 = PPS fix
+                *                                 4 = Real Time Kinematic
+                *                                 5 = Float RTK
+                *                                 6 = estimated (dead reckoning)
+                *                                 7 = Manual input mode
+                *                                 8 = Simulation mode
+                *         05           Number of satellites (5)
+                *         2.0          Horizontal dilution
+                *         103.5,M              Altitude, 103.5M above msl
+                *         -19.5,M              Height of geoid above WGS84 ellipsoid
+                *         ?            time in seconds since last DGPS update
+                *         0000         DGPS station ID
+                *         *66          checksum
+                */
+
+               ao_gps_next.flags = 0;
+               ao_gps_next.hour = ao_gps_decimal(2);
+               ao_gps_next.minute = ao_gps_decimal(2);
+               ao_gps_next.second = ao_gps_decimal(2);
+               ao_gps_skip_field();    /* skip seconds fraction */
+
+               ao_gps_parse_pos(&ao_gps_next.latitude, 2);
+               ao_gps_parse_flag('N', AO_GPS_LATITUDE_NORTH, 'S', AO_GPS_LATITUDE_SOUTH);
+               ao_gps_parse_pos(&ao_gps_next.longitude, 3);
+               ao_gps_parse_flag('W', AO_GPS_LONGITUDE_WEST, 'E', AO_GPS_LONGITUDE_EAST);
+
+               i = ao_gps_decimal(0xff);
+               if (i == 1)
+                       ao_gps_next.flags |= AO_GPS_VALID;
+
+               i = ao_gps_decimal(0xff) << AO_GPS_NUM_SAT_SHIFT;
+               if (i > AO_GPS_NUM_SAT_MASK)
+                       i = AO_GPS_NUM_SAT_MASK;
+               ao_gps_next.flags |= i;
+
+               ao_gps_lexchar();
+               ao_gps_skip_field();    /* Horizontal dilution */
+
+               ao_gps_next.altitude = ao_gps_decimal(0xff);
+               ao_gps_skip_field();    /* skip any fractional portion */
+
+               /* Skip remaining fields */
+               while (ao_gps_char != '*' && ao_gps_char != '\n' && ao_gps_char != '\r') {
+                       ao_gps_lexchar();
+                       ao_gps_skip_field();
+               }
+               if (ao_gps_char == '*') {
+                       uint8_t cksum = ao_gps_cksum ^ '*';
+                       if (cksum != ao_gps_hex(2))
+                               ao_gps_error = 1;
+               } else
+                       ao_gps_error = 1;
+               if (!ao_gps_error) {
+                       ao_mutex_get(&ao_gps_mutex);
+                       memcpy(&ao_gps_data, &ao_gps_next, sizeof (struct ao_gps_data));
+                       ao_mutex_put(&ao_gps_mutex);
+                       ao_wakeup(&ao_gps_data);
+               }
+       }
+}
+
+__xdata struct ao_task ao_gps_task;
+
+static void
+gps_dump(void) __reentrant
+{
+       ao_mutex_get(&ao_gps_mutex);
+       ao_gps_print(&ao_gps_data);
+       ao_mutex_put(&ao_gps_mutex);
+}
+
+__code struct ao_cmds ao_gps_cmds[] = {
+       { 'g', gps_dump,        "g                                  Display current GPS values" },
+       { 0, gps_dump, NULL },
+};
+
+void
+ao_gps_init(void)
+{
+       ao_add_task(&ao_gps_task, ao_gps, "gps");
+       ao_cmd_register(&ao_gps_cmds[0]);
+}
diff --git a/src/ao_gps_print.c b/src/ao_gps_print.c
new file mode 100644 (file)
index 0000000..7e157db
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+void
+ao_gps_print(__xdata struct ao_gps_data *gps_data) __reentrant
+{
+       printf("GPS %2d sat",
+              (gps_data->flags & AO_GPS_NUM_SAT_MASK) >> AO_GPS_NUM_SAT_SHIFT);;
+       if (gps_data->flags & AO_GPS_VALID) {
+               printf(" %2d:%02d:%02d %2d°%2d.%04d'%c %2d°%2d.%04d'%c %5dm\n",
+                      gps_data->hour,
+                      gps_data->minute,
+                      gps_data->second,
+                      gps_data->latitude.degrees,
+                      gps_data->latitude.minutes,
+                      gps_data->latitude.minutes_fraction,
+                      (gps_data->flags & AO_GPS_LATITUDE_MASK) == AO_GPS_LATITUDE_NORTH ?
+                      'N' : 'S',
+                      gps_data->longitude.degrees,
+                      gps_data->longitude.minutes,
+                      gps_data->longitude.minutes_fraction,
+                      (gps_data->flags & AO_GPS_LONGITUDE_MASK) == AO_GPS_LONGITUDE_WEST ?
+                      'W' : 'E',
+                      gps_data->altitude,
+                      (gps_data->flags & AO_GPS_NUM_SAT_MASK) >> AO_GPS_NUM_SAT_SHIFT);
+       } else {
+               printf(" unlocked\n");
+       }
+}
diff --git a/src/ao_gps_report.c b/src/ao_gps_report.c
new file mode 100644 (file)
index 0000000..1b5402a
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+void
+ao_gps_report(void)
+{
+       static __xdata struct ao_log_record     gps_log;
+       static __xdata struct ao_gps_data       gps_data;
+
+       for (;;) {
+               ao_sleep(&ao_gps_data);
+               ao_mutex_get(&ao_gps_mutex);
+               memcpy(&gps_data, &ao_gps_data, sizeof (struct ao_gps_data));
+               ao_mutex_put(&ao_gps_mutex);
+
+               if (!(gps_data.flags & AO_GPS_VALID))
+                       continue;
+
+               gps_log.tick = ao_time();
+               gps_log.type = AO_LOG_GPS_TIME;
+               gps_log.u.gps_time.hour = gps_data.hour;
+               gps_log.u.gps_time.minute = gps_data.minute;
+               gps_log.u.gps_time.second = gps_data.second;
+               gps_log.u.gps_time.flags = gps_data.flags;
+               ao_log_data(&gps_log);
+               gps_log.type = AO_LOG_GPS_LAT;
+               gps_log.u.gps_latitude.degrees = gps_data.latitude.degrees;
+               gps_log.u.gps_latitude.minutes = gps_data.latitude.minutes;
+               gps_log.u.gps_latitude.minutes_fraction = gps_data.latitude.minutes_fraction;
+               ao_log_data(&gps_log);
+               gps_log.type = AO_LOG_GPS_LON;
+               gps_log.u.gps_longitude.degrees = gps_data.longitude.degrees;
+               gps_log.u.gps_longitude.minutes = gps_data.longitude.minutes;
+               gps_log.u.gps_longitude.minutes_fraction = gps_data.longitude.minutes_fraction;
+               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;
+               ao_log_data(&gps_log);
+       }
+}
+
+__xdata struct ao_task ao_gps_report_task;
+
+void
+ao_gps_report_init(void)
+{
+       ao_add_task(&ao_gps_report_task, ao_gps_report, "gps_report");
+}
diff --git a/src/ao_ignite.c b/src/ao_ignite.c
new file mode 100644 (file)
index 0000000..be29152
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+#define AO_IGNITER_DROGUE      P2_3
+#define AO_IGNITER_MAIN                P2_4
+#define AO_IGNITER_DIR         P2DIR
+#define AO_IGNITER_DROGUE_BIT  (1 << 3)
+#define AO_IGNITER_MAIN_BIT    (1 << 4)
+
+/* test these values with real igniters */
+#define AO_IGNITER_OPEN                1000
+#define AO_IGNITER_CLOSED      7000
+#define AO_IGNITER_FIRE_TIME   AO_MS_TO_TICKS(500)
+#define AO_IGNITER_CHARGE_TIME AO_MS_TO_TICKS(2000)
+
+struct ao_ignition {
+       uint8_t request;
+       uint8_t fired;
+       uint8_t firing;
+};
+
+__xdata struct ao_ignition ao_ignition[2];
+
+void
+ao_ignite(enum ao_igniter igniter) __critical
+{
+       ao_ignition[igniter].request = 1;
+       ao_wakeup(&ao_ignition[0]);
+}
+
+enum ao_igniter_status
+ao_igniter_status(enum ao_igniter igniter)
+{
+       __xdata struct ao_adc adc;
+       __xdata int16_t value;
+       __xdata uint8_t request, firing, fired;
+
+       __critical {
+               ao_adc_sleep();
+               ao_adc_get(&adc);
+               request = ao_ignition[igniter].request;
+               fired = ao_ignition[igniter].fired;
+               firing = ao_ignition[igniter].firing;
+       }
+       if (firing || (request && !fired))
+               return ao_igniter_active;
+
+       value = (AO_IGNITER_CLOSED>>1);
+       switch (igniter) {
+       case ao_igniter_drogue:
+               value = adc.sense_d;
+               break;
+       case ao_igniter_main:
+               value = adc.sense_m;
+               break;
+       }
+       if (value < AO_IGNITER_OPEN)
+               return ao_igniter_open;
+       else if (value > AO_IGNITER_CLOSED)
+               return ao_igniter_ready;
+       else
+               return ao_igniter_unknown;
+}
+
+void
+ao_igniter_fire(enum ao_igniter igniter) __critical
+{
+       ao_ignition[igniter].firing = 1;
+       switch (igniter) {
+       case ao_igniter_drogue:
+               AO_IGNITER_DROGUE = 1;
+               ao_delay(AO_IGNITER_FIRE_TIME);
+               AO_IGNITER_DROGUE = 0;
+               break;
+       case ao_igniter_main:
+               AO_IGNITER_MAIN = 1;
+               ao_delay(AO_IGNITER_FIRE_TIME);
+               AO_IGNITER_MAIN = 0;
+               break;
+       }
+       ao_ignition[igniter].firing = 0;
+}
+
+void
+ao_igniter(void)
+{
+       __xdata enum ao_ignter igniter;
+       __xdata enum ao_igniter_status status;
+
+       for (;;) {
+               ao_sleep(&ao_ignition);
+               for (igniter = ao_igniter_drogue; igniter <= ao_igniter_main; igniter++) {
+                       if (ao_ignition[igniter].request && !ao_ignition[igniter].fired) {
+                               ao_igniter_fire(igniter);
+                               ao_delay(AO_IGNITER_CHARGE_TIME);
+                               status = ao_igniter_status(igniter);
+                               if (status == ao_igniter_open)
+                                       ao_ignition[igniter].fired = 1;
+                       }
+               }
+       }
+}
+
+static uint8_t
+ao_match_word(__code char *word)
+{
+       while (*word) {
+               if (ao_cmd_lex_c != *word) {
+                       ao_cmd_status = ao_cmd_syntax_error;
+                       return 0;
+               }
+               word++;
+               ao_cmd_lex();
+       }
+       return 1;
+}
+
+void
+ao_ignite_manual(void)
+{
+       ao_cmd_white();
+       if (!ao_match_word("DoIt"))
+               return;
+       ao_cmd_white();
+       if (ao_cmd_lex_c == 'm') {
+               if(ao_match_word("main"))
+                       ao_igniter_fire(ao_igniter_main);
+       } else {
+               if(ao_match_word("drogue"))
+                       ao_igniter_fire(ao_igniter_drogue);
+       }
+}
+
+static __code char *igniter_status_names[] = {
+       "unknown", "ready", "active", "open"
+};
+
+void
+ao_ignite_print_status(enum ao_igniter igniter, __code char *name) __reentrant
+{
+       enum ao_igniter_status status = ao_igniter_status(igniter);
+       printf("Igniter: %6s Status: %s\n",
+              name,
+              igniter_status_names[status]);
+}
+
+void
+ao_ignite_test(void)
+{
+       ao_ignite_print_status(ao_igniter_drogue, "drogue");
+       ao_ignite_print_status(ao_igniter_main, "main");
+}
+
+__code struct ao_cmds ao_ignite_cmds[] = {
+       { 'i',  ao_ignite_manual,       "i <key> {main|drogue}              Fire igniter. <key> is doit with D&I" },
+       { 't',  ao_ignite_test,         "t                                  Test igniter continuity" },
+       { 0,    ao_ignite_manual,       NULL },
+};
+
+__xdata struct ao_task ao_igniter_task;
+
+void
+ao_igniter_init(void)
+{
+       AO_IGNITER_DROGUE = 0;
+       AO_IGNITER_MAIN = 0;
+       AO_IGNITER_DIR |= AO_IGNITER_DROGUE_BIT | AO_IGNITER_MAIN_BIT;
+       ao_cmd_register(&ao_ignite_cmds[0]);
+       ao_add_task(&ao_igniter_task, ao_igniter, "igniter");
+}
diff --git a/src/ao_led.c b/src/ao_led.c
new file mode 100644 (file)
index 0000000..6c698b4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+#define AO_LED_ALL     (AO_LED_GREEN|AO_LED_RED)
+
+__pdata uint8_t ao_led_enable;
+
+void
+ao_led_on(uint8_t colors)
+{
+       P1 |= (colors & ao_led_enable);
+}
+
+void
+ao_led_off(uint8_t colors)
+{
+       P1 &= ~(colors & ao_led_enable);
+}
+
+void
+ao_led_set(uint8_t colors)
+{
+       P1 = (P1 & ~(ao_led_enable)) | (colors & ao_led_enable);
+}
+
+void
+ao_led_toggle(uint8_t colors)
+{
+       P1 ^= (colors & ao_led_enable);
+}
+
+void
+ao_led_for(uint8_t colors, uint16_t ticks) __reentrant
+{
+       ao_led_on(colors);
+       ao_delay(ticks);
+       ao_led_off(colors);
+}
+
+void
+ao_led_init(uint8_t enable)
+{
+       ao_led_enable = enable;
+       P1SEL &= ~enable;
+       P1 &= ~enable;
+       P1DIR |= enable;
+}
diff --git a/src/ao_log.c b/src/ao_log.c
new file mode 100644 (file)
index 0000000..19bfdfb
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+static __pdata uint32_t        ao_log_current_pos;
+static __pdata uint32_t        ao_log_start_pos;
+static __xdata uint8_t ao_log_running;
+static __xdata uint8_t ao_log_mutex;
+
+static uint8_t
+ao_log_csum(uint8_t *b)
+{
+       uint8_t sum = 0x5a;
+       uint8_t i;
+
+       for (i = 0; i < sizeof (struct ao_log_record); i++)
+               sum += *b++;
+       return -sum;
+}
+
+void
+ao_log_data(struct ao_log_record *log)
+{
+       /* set checksum */
+       log->csum = 0;
+       log->csum = ao_log_csum((uint8_t *) log);
+       ao_mutex_get(&ao_log_mutex); {
+               if (ao_log_running) {
+                       ao_ee_write(ao_log_current_pos,
+                                   (uint8_t *) log,
+                                   sizeof (struct ao_log_record));
+                       ao_log_current_pos += sizeof (struct ao_log_record);
+                       if (ao_log_current_pos >= AO_EE_DATA_SIZE)
+                               ao_log_current_pos = 0;
+                       if (ao_log_current_pos == ao_log_start_pos)
+                               ao_log_running = 0;
+               }
+       } ao_mutex_put(&ao_log_mutex);
+}
+
+void
+ao_log_flush(void)
+{
+       ao_ee_flush();
+}
+
+__xdata struct ao_log_record ao_log_dump;
+static __xdata uint16_t ao_log_dump_flight;
+static __xdata uint32_t ao_log_dump_pos;
+
+static uint8_t
+ao_log_dump_check_data(void)
+{
+       if (ao_log_csum((uint8_t *) &ao_log_dump) != 0)
+               return 0;
+       return 1;
+}
+
+static uint8_t
+ao_log_dump_scan(void)
+{
+       if (!ao_ee_read(0, (uint8_t *) &ao_log_dump, sizeof (struct ao_log_record)))
+               ao_panic(AO_PANIC_LOG);
+       if (ao_log_dump_check_data() && ao_log_dump.type == AO_LOG_FLIGHT) {
+               ao_log_dump_flight = ao_log_dump.u.flight.flight;
+               return 1;
+       } else {
+               ao_log_dump_flight = 0;
+               return 0;
+       }
+}
+
+uint8_t
+ao_log_dump_first(void)
+{
+       ao_log_dump_pos = 0;
+       if (!ao_log_dump_scan())
+               return 0;
+       return 1;
+}
+
+uint8_t
+ao_log_dump_next(void)
+{
+       ao_log_dump_pos += sizeof (struct ao_log_record);
+       if (ao_log_dump_pos >= AO_EE_DEVICE_SIZE)
+               return 0;
+       if (!ao_ee_read(ao_log_dump_pos, (uint8_t *) &ao_log_dump,
+                       sizeof (struct ao_log_record)))
+               return 0;
+       return ao_log_dump_check_data();
+}
+
+__xdata uint8_t        ao_log_adc_pos;
+__xdata enum flight_state ao_log_state;
+
+void
+ao_log(void)
+{
+       static __xdata struct ao_log_record     log;
+
+       ao_log_dump_scan();
+
+       while (!ao_log_running)
+               ao_sleep(&ao_log_running);
+
+       log.type = AO_LOG_FLIGHT;
+       log.tick = ao_flight_tick;
+       log.u.flight.ground_accel = ao_ground_accel;
+       log.u.flight.flight = ao_log_dump_flight + 1;
+       ao_log_data(&log);
+
+       /* Write the whole contents of the ring to the log
+        * when starting up.
+        */
+       ao_log_adc_pos = ao_adc_ring_next(ao_adc_head);
+       for (;;) {
+               /* Write samples to EEPROM */
+               while (ao_log_adc_pos != ao_adc_head) {
+                       log.type = AO_LOG_SENSOR;
+                       log.tick = ao_adc_ring[ao_log_adc_pos].tick;
+                       log.u.sensor.accel = ao_adc_ring[ao_log_adc_pos].accel;
+                       log.u.sensor.pres = ao_adc_ring[ao_log_adc_pos].pres;
+                       ao_log_data(&log);
+                       if ((ao_log_adc_pos & 0x1f) == 0) {
+                               log.type = AO_LOG_TEMP_VOLT;
+                               log.tick = ao_adc_ring[ao_log_adc_pos].tick;
+                               log.u.temp_volt.temp = ao_adc_ring[ao_log_adc_pos].temp;
+                               log.u.temp_volt.v_batt = ao_adc_ring[ao_log_adc_pos].v_batt;
+                               ao_log_data(&log);
+                               log.type = AO_LOG_DEPLOY;
+                               log.tick = ao_adc_ring[ao_log_adc_pos].tick;
+                               log.u.deploy.drogue = ao_adc_ring[ao_log_adc_pos].sense_d;
+                               log.u.deploy.main = ao_adc_ring[ao_log_adc_pos].sense_m;
+                               ao_log_data(&log);
+                       }
+                       ao_log_adc_pos = ao_adc_ring_next(ao_log_adc_pos);
+               }
+               /* Write state change to EEPROM */
+               if (ao_flight_state != ao_log_state) {
+                       ao_log_state = ao_flight_state;
+                       log.type = AO_LOG_STATE;
+                       log.tick = ao_flight_tick;
+                       log.u.state.state = ao_log_state;
+                       log.u.state.reason = 0;
+                       ao_log_data(&log);
+
+                       if (ao_log_state == ao_flight_landed)
+                               ao_log_stop();
+               }
+
+               /* Wait for a while */
+               ao_delay(AO_MS_TO_TICKS(100));
+
+               /* Stop logging when told to */
+               while (!ao_log_running)
+                       ao_sleep(&ao_log_running);
+       }
+}
+
+void
+ao_log_start(void)
+{
+       /* start logging */
+       ao_log_running = 1;
+       ao_wakeup(&ao_log_running);
+}
+
+void
+ao_log_stop(void)
+{
+       ao_log_running = 0;
+       ao_log_flush();
+}
+
+static void
+dump_log(void)
+{
+       uint8_t more;
+
+       for (more = ao_log_dump_first(); more; more = ao_log_dump_next()) {
+               printf("%c %4x %4x %4x\n",
+                      ao_log_dump.type,
+                      ao_log_dump.tick,
+                      ao_log_dump.u.anon.d0,
+                      ao_log_dump.u.anon.d1);
+               if (ao_log_dump.type == AO_LOG_STATE &&
+                   ao_log_dump.u.state.state == ao_flight_landed)
+                       break;
+       }
+       printf("end\n");
+}
+
+__code struct ao_cmds ao_log_cmds[] = {
+       { 'l',  dump_log,               "l                                  Dump last flight log" },
+       { 0, dump_log, NULL },
+};
+
+static __xdata struct ao_task ao_log_task;
+
+void
+ao_log_init(void)
+{
+       ao_log_running = 0;
+
+       /* For now, just log the flight starting at the begining of eeprom */
+       ao_log_start_pos = 0;
+       ao_log_current_pos = ao_log_start_pos;
+       ao_log_state = ao_flight_invalid;
+
+       /* Create a task to log events to eeprom */
+       ao_add_task(&ao_log_task, ao_log, "log");
+       ao_cmd_register(&ao_log_cmds[0]);
+}
diff --git a/src/ao_main.c b/src/ao_main.c
new file mode 100644 (file)
index 0000000..1f7a829
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+void
+main(void)
+{
+       CLKCON = 0;
+       while (!(SLEEP & SLEEP_XOSC_STB))
+               ;
+
+       /* Turn on the red LED until the system is stable */
+       ao_led_init();
+       ao_led_on(AO_LED_RED);
+
+       ao_timer_init();
+       ao_adc_init();
+       ao_beep_init();
+       ao_cmd_init();
+       ao_ee_init();
+       ao_flight_init();
+       ao_log_init();
+       ao_report_init();
+       ao_usb_init();
+       ao_serial_init();
+       ao_gps_init();
+       ao_telemetry_init();
+       ao_radio_init();
+       ao_start_scheduler();
+}
diff --git a/src/ao_monitor.c b/src/ao_monitor.c
new file mode 100644 (file)
index 0000000..5997d42
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+__xdata uint8_t ao_monitoring;
+__pdata uint8_t ao_monitor_led;
+
+void
+ao_monitor(void)
+{
+       __xdata struct ao_radio_recv recv;
+       __xdata char callsign[AO_MAX_CALLSIGN+1];
+       uint8_t state;
+
+       for (;;) {
+               __critical while (!ao_monitoring)
+                       ao_sleep(&ao_monitoring);
+               ao_radio_recv(&recv);
+               state = recv.telemetry.flight_state;
+               memcpy(callsign, recv.telemetry.callsign, AO_MAX_CALLSIGN);
+               if (state > ao_flight_invalid)
+                       state = ao_flight_invalid;
+               if (recv.status & PKT_APPEND_STATUS_1_CRC_OK) {
+                       printf ("CALL %s SERIAL %3d RSSI %4d STATUS %02x STATE %7s ",
+                               callsign,
+                               recv.telemetry.addr,
+                               (int) recv.rssi - 74, recv.status,
+                               ao_state_names[state]);
+                       printf("%5u a: %5d p: %5d t: %5d v: %5d d: %5d m: %5d fa: %5d ga: %d fv: %7ld fp: %5d gp: %5d ",
+                              recv.telemetry.adc.tick,
+                              recv.telemetry.adc.accel,
+                              recv.telemetry.adc.pres,
+                              recv.telemetry.adc.temp,
+                              recv.telemetry.adc.v_batt,
+                              recv.telemetry.adc.sense_d,
+                              recv.telemetry.adc.sense_m,
+                              recv.telemetry.flight_accel,
+                              recv.telemetry.ground_accel,
+                              recv.telemetry.flight_vel,
+                              recv.telemetry.flight_pres,
+                              recv.telemetry.ground_pres);
+                       ao_gps_print(&recv.telemetry.gps);
+                       ao_rssi_set((int) recv.rssi - 74);
+               } else {
+                       printf("CRC INVALID RSSI %3d\n", (int) recv.rssi - 74);
+               }
+               ao_usb_flush();
+               ao_led_toggle(ao_monitor_led);
+       }
+}
+
+__xdata struct ao_task ao_monitor_task;
+
+void
+ao_set_monitor(uint8_t monitoring)
+{
+       ao_monitoring = monitoring;
+       ao_wakeup(&ao_monitoring);
+}
+
+static void
+set_monitor(void)
+{
+       ao_cmd_hex();
+       ao_set_monitor(ao_cmd_lex_i != 0);
+}
+
+__code struct ao_cmds ao_monitor_cmds[] = {
+       { 'm',  set_monitor,    "m <0 off, 1 on>                    Enable/disable radio monitoring" },
+       { 0,    set_monitor,    NULL },
+};
+
+void
+ao_monitor_init(uint8_t monitor_led, uint8_t monitoring) __reentrant
+{
+       ao_monitor_led = monitor_led;
+       ao_monitoring = monitoring;
+       ao_cmd_register(&ao_monitor_cmds[0]);
+       ao_add_task(&ao_monitor_task, ao_monitor, "monitor");
+}
diff --git a/src/ao_mutex.c b/src/ao_mutex.c
new file mode 100644 (file)
index 0000000..c82a7d5
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+void
+ao_mutex_get(__xdata uint8_t *mutex) __reentrant
+{
+       if (*mutex == ao_cur_task->task_id)
+               ao_panic(AO_PANIC_MUTEX);
+       __critical {
+               while (*mutex)
+                       ao_sleep(mutex);
+               *mutex = ao_cur_task->task_id;
+       }
+}
+
+void
+ao_mutex_put(__xdata uint8_t *mutex) __reentrant
+{
+       if (*mutex != ao_cur_task->task_id)
+               ao_panic(AO_PANIC_MUTEX);
+       __critical {
+               *mutex = 0;
+               ao_wakeup(mutex);
+       }
+}
diff --git a/src/ao_panic.c b/src/ao_panic.c
new file mode 100644 (file)
index 0000000..e996371
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+static void
+ao_panic_delay(uint8_t n)
+{
+       uint8_t i = 0, j = 0;
+
+       while (n--)
+               while (--j)
+                       while (--i)
+                               _asm nop _endasm;
+}
+
+void
+ao_panic(uint8_t reason)
+{
+       uint8_t n;
+
+       __critical for (;;) {
+               ao_panic_delay(20);
+               for (n = 0; n < 5; n++) {
+                       ao_led_on(AO_LED_RED);
+                       ao_beep(AO_BEEP_HIGH);
+                       ao_panic_delay(1);
+                       ao_led_off(AO_LED_RED);
+                       ao_beep(AO_BEEP_LOW);
+                       ao_panic_delay(1);
+               }
+               ao_beep(AO_BEEP_OFF);
+               ao_panic_delay(2);
+#pragma disable_warning 126
+               for (n = 0; n < reason; n++) {
+                       ao_led_on(AO_LED_RED);
+                       ao_beep(AO_BEEP_MID);
+                       ao_panic_delay(10);
+                       ao_led_off(AO_LED_RED);
+                       ao_beep(AO_BEEP_OFF);
+                       ao_panic_delay(10);
+               }
+       }
+}
diff --git a/src/ao_product.c b/src/ao_product.c
new file mode 100644 (file)
index 0000000..b42e62c
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+#include "ao_usb.h"
+#include PRODUCT_DEFS
+
+/* Defines which mark this particular AltOS product */
+
+const uint16_t ao_serial_number = AO_iSerial_NUMBER;
+const char ao_version[] = AO_iVersion_STRING;
+const char ao_manufacturer[] = AO_iManufacturer_STRING;
+const char ao_product[] = AO_iProduct_STRING;
+
+#define LE_WORD(x)    ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8))
+
+/* USB descriptors in one giant block of bytes */
+const uint8_t ao_usb_descriptors [] =
+{
+       /* Device descriptor */
+       0x12,
+       AO_USB_DESC_DEVICE,
+       LE_WORD(0x0110),        /*  bcdUSB */
+       0x02,                   /*  bDeviceClass */
+       0x00,                   /*  bDeviceSubClass */
+       0x00,                   /*  bDeviceProtocol */
+       AO_USB_CONTROL_SIZE,    /*  bMaxPacketSize */
+       LE_WORD(0xFFFE),        /*  idVendor */
+       LE_WORD(0x000A),        /*  idProduct */
+       LE_WORD(0x0100),        /*  bcdDevice */
+       0x01,                   /*  iManufacturer */
+       0x02,                   /*  iProduct */
+       0x03,                   /*  iSerialNumber */
+       0x01,                   /*  bNumConfigurations */
+
+       /* Configuration descriptor */
+       0x09,
+       AO_USB_DESC_CONFIGURATION,
+       LE_WORD(67),            /*  wTotalLength */
+       0x02,                   /*  bNumInterfaces */
+       0x01,                   /*  bConfigurationValue */
+       0x00,                   /*  iConfiguration */
+       0xC0,                   /*  bmAttributes */
+       0x32,                   /*  bMaxPower */
+
+       /* Control class interface */
+       0x09,
+       AO_USB_DESC_INTERFACE,
+       0x00,                   /*  bInterfaceNumber */
+       0x00,                   /*  bAlternateSetting */
+       0x01,                   /*  bNumEndPoints */
+       0x02,                   /*  bInterfaceClass */
+       0x02,                   /*  bInterfaceSubClass */
+       0x01,                   /*  bInterfaceProtocol, linux requires value of 1 for the cdc_acm module */
+       0x00,                   /*  iInterface */
+
+       /* Header functional descriptor */
+       0x05,
+       CS_INTERFACE,
+       0x00,                   /*  bDescriptor SubType Header */
+       LE_WORD(0x0110),        /*  CDC version 1.1 */
+
+       /* Call management functional descriptor */
+       0x05,
+       CS_INTERFACE,
+       0x01,                   /* bDescriptor SubType Call Management */
+       0x01,                   /* bmCapabilities = device handles call management */
+       0x01,                   /* bDataInterface call management interface number */
+
+       /* ACM functional descriptor */
+       0x04,
+       CS_INTERFACE,
+       0x02,                   /* bDescriptor SubType Abstract Control Management */
+       0x02,                   /* bmCapabilities = D1 (Set_line_Coding, Set_Control_Line_State, Get_Line_Coding and Serial_State) */
+
+       /* Union functional descriptor */
+       0x05,
+       CS_INTERFACE,
+       0x06,                   /* bDescriptor SubType Union Functional descriptor */
+       0x00,                   /* bMasterInterface */
+       0x01,                   /* bSlaveInterface0 */
+
+       /* Notification EP */
+       0x07,
+       AO_USB_DESC_ENDPOINT,
+       AO_USB_INT_EP|0x80,     /* bEndpointAddress */
+       0x03,                   /* bmAttributes = intr */
+       LE_WORD(8),             /* wMaxPacketSize */
+       0x0A,                   /* bInterval */
+
+       /* Data class interface descriptor */
+       0x09,
+       AO_USB_DESC_INTERFACE,
+       0x01,                   /* bInterfaceNumber */
+       0x00,                   /* bAlternateSetting */
+       0x02,                   /* bNumEndPoints */
+       0x0A,                   /* bInterfaceClass = data */
+       0x00,                   /* bInterfaceSubClass */
+       0x00,                   /* bInterfaceProtocol */
+       0x00,                   /* iInterface */
+
+       /* Data EP OUT */
+       0x07,
+       AO_USB_DESC_ENDPOINT,
+       AO_USB_OUT_EP,          /* bEndpointAddress */
+       0x02,                   /* bmAttributes = bulk */
+       LE_WORD(AO_USB_OUT_SIZE),/* wMaxPacketSize */
+       0x00,                   /* bInterval */
+
+       /* Data EP in */
+       0x07,
+       AO_USB_DESC_ENDPOINT,
+       AO_USB_IN_EP|0x80,      /* bEndpointAddress */
+       0x02,                   /* bmAttributes = bulk */
+       LE_WORD(AO_USB_IN_SIZE),/* wMaxPacketSize */
+       0x00,                   /* bInterval */
+
+       /* String descriptors */
+       0x04,
+       AO_USB_DESC_STRING,
+       LE_WORD(0x0409),
+
+       /* iManufacturer */
+       AO_iManufacturer_LEN,
+       AO_USB_DESC_STRING,
+       AO_iManufacturer_UCS2,
+
+       /* iProduct */
+       AO_iProduct_LEN,
+       AO_USB_DESC_STRING,
+       AO_iProduct_UCS2,
+
+       /* iSerial */
+       AO_iSerial_LEN,
+       AO_USB_DESC_STRING,
+       AO_iSerial_UCS2,
+
+       /* Terminating zero */
+       0
+};
diff --git a/src/ao_radio.c b/src/ao_radio.c
new file mode 100644 (file)
index 0000000..ca1ec7e
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+/* Values from SmartRF® Studio for:
+ *
+ * Deviation:  20.507812 kHz
+ * Datarate:   38.360596 kBaud
+ * Modulation: GFSK
+ * RF Freq:    434.549927 MHz
+ * Channel:    99.975586 kHz
+ * Channel:    0
+ * RX filter:  93.75 kHz
+ */
+
+/*
+ * For 434.550MHz, the frequency value is:
+ *
+ * 434.550e6 / (24e6 / 2**16) = 1186611.2
+ */
+
+#define FREQ_CONTROL   1186611
+
+/*
+ * For IF freq of 140.62kHz, the IF value is:
+ *
+ * 140.62e3 / (24e6 / 2**10) = 6
+ */
+
+#define IF_FREQ_CONTROL        6
+
+/*
+ * For channel bandwidth of 93.75 kHz, the CHANBW_E and CHANBW_M values are
+ *
+ * BW = 24e6 / (8 * (4 + M) * 2 ** E)
+ *
+ * So, M = 0 and E = 3
+ */
+
+#define CHANBW_M       0
+#define CHANBW_E       3
+
+/*
+ * For a symbol rate of 38360kBaud, the DRATE_E and DRATE_M values are:
+ *
+ * R = (256 + M) * 2** E * 24e6 / 2**28
+ *
+ * So M is 163 and E is 10
+ */
+
+#define DRATE_E                10
+#define DRATE_M                163
+
+/*
+ * For a channel deviation of 20.5kHz, the DEVIATION_E and DEVIATION_M values are:
+ *
+ * F = 24e6/2**17 * (8 + DEVIATION_M) * 2**DEVIATION_E
+ *
+ * So M is 6 and E is 3
+ */
+
+#define DEVIATION_M    6
+#define DEVIATION_E    3
+
+/* This are from the table for 433MHz */
+
+#define RF_POWER_M30_DBM       0x12
+#define RF_POWER_M20_DBM       0x0e
+#define RF_POWER_M15_DBM       0x1d
+#define RF_POWER_M10_DBM       0x34
+#define RF_POWER_M5_DBM                0x2c
+#define RF_POWER_0_DBM         0x60
+#define RF_POWER_5_DBM         0x84
+#define RF_POWER_7_DBM         0xc8
+#define RF_POWER_10_DBM                0xc0
+
+#define RF_POWER               RF_POWER_10_DBM
+
+static __code uint8_t radio_setup[] = {
+       RF_PA_TABLE7_OFF,       RF_POWER,
+       RF_PA_TABLE6_OFF,       RF_POWER,
+       RF_PA_TABLE5_OFF,       RF_POWER,
+       RF_PA_TABLE4_OFF,       RF_POWER,
+       RF_PA_TABLE3_OFF,       RF_POWER,
+       RF_PA_TABLE2_OFF,       RF_POWER,
+       RF_PA_TABLE1_OFF,       RF_POWER,
+       RF_PA_TABLE0_OFF,       RF_POWER,
+
+       RF_FREQ2_OFF,           (FREQ_CONTROL >> 16) & 0xff,
+       RF_FREQ1_OFF,           (FREQ_CONTROL >> 8) & 0xff,
+       RF_FREQ0_OFF,           (FREQ_CONTROL >> 0) & 0xff,
+
+       RF_FSCTRL1_OFF,         (IF_FREQ_CONTROL << RF_FSCTRL1_FREQ_IF_SHIFT),
+       RF_FSCTRL0_OFF,         (0 << RF_FSCTRL0_FREQOFF_SHIFT),
+
+       RF_MDMCFG4_OFF,         ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
+                                (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) |
+                                (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)),
+       RF_MDMCFG3_OFF,         (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
+       RF_MDMCFG2_OFF,         (RF_MDMCFG2_DEM_DCFILT_OFF |
+                                RF_MDMCFG2_MOD_FORMAT_GFSK |
+                                RF_MDMCFG2_SYNC_MODE_15_16_THRES),
+       RF_MDMCFG1_OFF,         (RF_MDMCFG1_FEC_EN |
+                                RF_MDMCFG1_NUM_PREAMBLE_4 |
+                                (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)),
+       RF_MDMCFG0_OFF,         (17 << RF_MDMCFG0_CHANSPC_M_SHIFT),
+
+       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
+        */
+       RF_FREND0_OFF,          ((1 << RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT) |
+                                (0 << RF_FREND0_PA_POWER_SHIFT)),
+
+       RF_FREND1_OFF,          ((1 << RF_FREND1_LNA_CURRENT_SHIFT) |
+                                (1 << RF_FREND1_LNA2MIX_CURRENT_SHIFT) |
+                                (1 << RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT) |
+                                (2 << RF_FREND1_MIX_CURRENT_SHIFT)),
+
+       RF_FSCAL3_OFF,          0xE9,
+       RF_FSCAL2_OFF,          0x0A,
+       RF_FSCAL1_OFF,          0x00,
+       RF_FSCAL0_OFF,          0x1F,
+
+       RF_TEST2_OFF,           0x88,
+       RF_TEST1_OFF,           0x31,
+       RF_TEST0_OFF,           0x09,
+
+       /* default sync values */
+       RF_SYNC1_OFF,           0xD3,
+       RF_SYNC0_OFF,           0x91,
+
+       /* max packet length */
+       RF_PKTLEN_OFF,          sizeof (struct ao_telemetry),
+
+       RF_PKTCTRL1_OFF,        ((1 << PKTCTRL1_PQT_SHIFT)|
+                                PKTCTRL1_APPEND_STATUS|
+                                PKTCTRL1_ADR_CHK_NONE),
+       RF_PKTCTRL0_OFF,        (RF_PKTCTRL0_WHITE_DATA|
+                                RF_PKTCTRL0_PKT_FORMAT_NORMAL|
+                                RF_PKTCTRL0_CRC_EN|
+                                RF_PKTCTRL0_LENGTH_CONFIG_FIXED),
+       RF_ADDR_OFF,            0x00,
+       RF_MCSM2_OFF,           (RF_MCSM2_RX_TIME_END_OF_PACKET),
+       RF_MCSM1_OFF,           (RF_MCSM1_CCA_MODE_RSSI_BELOW_UNLESS_RECEIVING|
+                                RF_MCSM1_RXOFF_MODE_IDLE|
+                                RF_MCSM1_TXOFF_MODE_IDLE),
+       RF_MCSM0_OFF,           (RF_MCSM0_FS_AUTOCAL_FROM_IDLE|
+                                RF_MCSM0_MAGIC_3|
+                                RF_MCSM0_CLOSE_IN_RX_0DB),
+       RF_FOCCFG_OFF,          (RF_FOCCFG_FOC_PRE_K_3K,
+                                RF_FOCCFG_FOC_POST_K_PRE_K,
+                                RF_FOCCFG_FOC_LIMIT_BW_OVER_4),
+       RF_BSCFG_OFF,           (RF_BSCFG_BS_PRE_K_2K|
+                                RF_BSCFG_BS_PRE_KP_3KP|
+                                RF_BSCFG_BS_POST_KI_PRE_KI|
+                                RF_BSCFG_BS_POST_KP_PRE_KP|
+                                RF_BSCFG_BS_LIMIT_0),
+       RF_AGCCTRL2_OFF,        0x43,
+       RF_AGCCTRL1_OFF,        0x40,
+       RF_AGCCTRL0_OFF,        0x91,
+
+       RF_IOCFG2_OFF,          0x00,
+       RF_IOCFG1_OFF,          0x00,
+       RF_IOCFG0_OFF,          0x00,
+};
+
+
+static __code uint8_t telemetry_setup[] = {
+       RF_MDMCFG4_OFF,         ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
+                                (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) |
+                                (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)),
+       RF_MDMCFG3_OFF,         (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
+       RF_MDMCFG2_OFF,         (RF_MDMCFG2_DEM_DCFILT_OFF |
+                                RF_MDMCFG2_MOD_FORMAT_GFSK |
+                                RF_MDMCFG2_SYNC_MODE_15_16_THRES),
+       RF_MDMCFG1_OFF,         (RF_MDMCFG1_FEC_EN |
+                                RF_MDMCFG1_NUM_PREAMBLE_4 |
+                                (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)),
+
+       RF_DEVIATN_OFF,         ((DEVIATION_E << RF_DEVIATN_DEVIATION_E_SHIFT) |
+                                (DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)),
+
+       /* max packet length */
+       RF_PKTLEN_OFF,          sizeof (struct ao_telemetry),
+       RF_PKTCTRL1_OFF,        ((1 << PKTCTRL1_PQT_SHIFT)|
+                                PKTCTRL1_APPEND_STATUS|
+                                PKTCTRL1_ADR_CHK_NONE),
+       RF_PKTCTRL0_OFF,        (RF_PKTCTRL0_WHITE_DATA|
+                                RF_PKTCTRL0_PKT_FORMAT_NORMAL|
+                                RF_PKTCTRL0_CRC_EN|
+                                RF_PKTCTRL0_LENGTH_CONFIG_FIXED),
+};
+
+__xdata uint8_t        ao_radio_dma;
+__xdata uint8_t ao_radio_dma_done;
+__xdata uint8_t ao_radio_mutex;
+
+static void
+ao_radio_idle(void)
+{
+       if (RF_MARCSTATE != RF_MARCSTATE_IDLE)
+       {
+               RFST = RFST_SIDLE;
+               do {
+                       ao_yield();
+               } while (RF_MARCSTATE != RF_MARCSTATE_IDLE);
+       }
+}
+
+void
+ao_radio_send(__xdata struct ao_telemetry *telemetry) __reentrant
+{
+       ao_config_get();
+       ao_mutex_get(&ao_radio_mutex);
+       ao_radio_idle();
+       RF_CHANNR = ao_config.radio_channel;
+       ao_dma_set_transfer(ao_radio_dma,
+                           telemetry,
+                           &RFDXADDR,
+                           sizeof (struct ao_telemetry),
+                           DMA_CFG0_WORDSIZE_8 |
+                           DMA_CFG0_TMODE_SINGLE |
+                           DMA_CFG0_TRIGGER_RADIO,
+                           DMA_CFG1_SRCINC_1 |
+                           DMA_CFG1_DESTINC_0 |
+                           DMA_CFG1_PRIORITY_HIGH);
+       ao_dma_start(ao_radio_dma);
+       RFST = RFST_STX;
+       __critical while (!ao_radio_dma_done)
+               ao_sleep(&ao_radio_dma_done);
+       ao_mutex_put(&ao_radio_mutex);
+}
+
+void
+ao_radio_recv(__xdata struct ao_radio_recv *radio) __reentrant
+{
+       ao_config_get();
+       ao_mutex_get(&ao_radio_mutex);
+       ao_radio_idle();
+       RF_CHANNR = ao_config.radio_channel;
+       ao_dma_set_transfer(ao_radio_dma,
+                           &RFDXADDR,
+                           radio,
+                           sizeof (struct ao_radio_recv),
+                           DMA_CFG0_WORDSIZE_8 |
+                           DMA_CFG0_TMODE_SINGLE |
+                           DMA_CFG0_TRIGGER_RADIO,
+                           DMA_CFG1_SRCINC_0 |
+                           DMA_CFG1_DESTINC_1 |
+                           DMA_CFG1_PRIORITY_HIGH);
+       ao_dma_start(ao_radio_dma);
+       RFST = RFST_SRX;
+       __critical while (!ao_radio_dma_done)
+               ao_sleep(&ao_radio_dma_done);
+       ao_mutex_put(&ao_radio_mutex);
+}
+
+void
+ao_radio_init(void)
+{
+       uint8_t i;
+       for (i = 0; i < sizeof (radio_setup); i += 2)
+               RF[radio_setup[i]] = radio_setup[i+1];
+       ao_radio_dma_done = 1;
+       ao_radio_dma = ao_dma_alloc(&ao_radio_dma_done);
+}
diff --git a/src/ao_report.c b/src/ao_report.c
new file mode 100644 (file)
index 0000000..e52b292
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+static const char * __xdata flight_reports[] = {
+       "...",          /* startup, 'S' */
+       "..",           /* idle 'I' */
+       ".--.",         /* launchpad 'P' */
+       "-...",         /* boost 'B' */
+       "-.-.",         /* coast 'C' */
+       ".-",           /* apogee 'A' */
+       "-..",          /* drogue 'D' */
+       "--",           /* main 'M' */
+       ".-..",         /* landed 'L' */
+       ".-.-.-",       /* invalid */
+};
+
+#if 1
+#define signal(time)   ao_beep_for(AO_BEEP_MID, time)
+#else
+#define signal(time)   ao_led_for(AO_LED_RED, time)
+#endif
+#define pause(time)    ao_delay(time)
+
+static __xdata enum ao_flight_state ao_report_state;
+
+static void
+ao_report_beep(void) __reentrant
+{
+       char *r = flight_reports[ao_flight_state];
+       char c;
+
+       if (!r)
+               return;
+       while (c = *r++) {
+               if (c == '.')
+                       signal(AO_MS_TO_TICKS(200));
+               else
+                       signal(AO_MS_TO_TICKS(600));
+               pause(AO_MS_TO_TICKS(200));
+       }
+       pause(AO_MS_TO_TICKS(400));
+}
+
+static void
+ao_report_digit(uint8_t digit) __reentrant
+{
+       if (!digit) {
+               signal(AO_MS_TO_TICKS(500));
+               pause(AO_MS_TO_TICKS(200));
+       } else {
+               while (digit--) {
+                       signal(AO_MS_TO_TICKS(200));
+                       pause(AO_MS_TO_TICKS(200));
+               }
+       }
+       pause(AO_MS_TO_TICKS(300));
+}
+
+static void
+ao_report_altitude(void)
+{
+       __xdata int16_t agl = ao_pres_to_altitude(ao_min_pres) - ao_pres_to_altitude(ao_ground_pres);
+       __xdata uint8_t digits[10];
+       __xdata uint8_t ndigits, i;
+
+       if (agl < 0)
+               agl = 0;
+       ndigits = 0;
+       do {
+               digits[ndigits++] = agl % 10;
+               agl /= 10;
+       } while (agl);
+
+       for (;;) {
+               ao_report_beep();
+               i = ndigits;
+               do
+                       ao_report_digit(digits[--i]);
+               while (i != 0);
+               pause(AO_SEC_TO_TICKS(5));
+       }
+}
+
+void
+ao_report(void)
+{
+       ao_report_state = ao_flight_state;
+       for(;;) {
+               if (ao_flight_state == ao_flight_landed)
+                       ao_report_altitude();
+               ao_report_beep();
+               __critical {
+                       while (ao_report_state == ao_flight_state)
+                               ao_sleep(DATA_TO_XDATA(&ao_flight_state));
+                       ao_report_state = ao_flight_state;
+               }
+       }
+}
+
+static __xdata struct ao_task ao_report_task;
+
+void
+ao_report_init(void)
+{
+       ao_add_task(&ao_report_task, ao_report, "report");
+}
diff --git a/src/ao_rssi.c b/src/ao_rssi.c
new file mode 100644 (file)
index 0000000..6912b9a
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+static __xdata volatile uint16_t       ao_rssi_time;
+static __xdata volatile uint16_t       ao_rssi_delay;
+static __xdata uint8_t                 ao_rssi_led;
+
+void
+ao_rssi(void)
+{
+       for (;;) {
+               while ((int16_t) (ao_time() - ao_rssi_time) > AO_SEC_TO_TICKS(3))
+                       ao_sleep(&ao_rssi_time);
+               ao_led_for(ao_rssi_led, AO_MS_TO_TICKS(100));
+               ao_delay(ao_rssi_delay);
+       }
+}
+
+void
+ao_rssi_set(int rssi_value)
+{
+       if (rssi_value > 0)
+               rssi_value = 0;
+       ao_rssi_delay = AO_MS_TO_TICKS((-rssi_value) * 5);
+       ao_rssi_time = ao_time();
+       ao_wakeup(&ao_rssi_time);
+}
+
+__xdata struct ao_task ao_rssi_task;
+
+void
+ao_rssi_init(uint8_t rssi_led)
+{
+       ao_rssi_led = rssi_led;
+       ao_rssi_delay = 0;
+       ao_add_task(&ao_rssi_task, ao_rssi, "rssi");
+}
diff --git a/src/ao_serial.c b/src/ao_serial.c
new file mode 100644 (file)
index 0000000..ce11694
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+volatile __xdata struct ao_fifo        ao_usart1_rx_fifo;
+volatile __xdata struct ao_fifo        ao_usart1_tx_fifo;
+
+void
+ao_serial_rx1_isr(void) interrupt 3
+{
+       if (!ao_fifo_full(ao_usart1_rx_fifo))
+               ao_fifo_insert(ao_usart1_rx_fifo, U1DBUF);
+       ao_wakeup(&ao_usart1_rx_fifo);
+}
+
+static __xdata uint8_t ao_serial_tx1_started;
+
+static void
+ao_serial_tx1_start(void)
+{
+       if (!ao_fifo_empty(ao_usart1_tx_fifo) &&
+           !ao_serial_tx1_started)
+       {
+               ao_serial_tx1_started = 1;
+               ao_fifo_remove(ao_usart1_tx_fifo, U1DBUF);
+       }
+}
+
+void
+ao_serial_tx1_isr(void) interrupt 14
+{
+       UTX1IF = 0;
+       ao_serial_tx1_started = 0;
+       ao_serial_tx1_start();
+       ao_wakeup(&ao_usart1_tx_fifo);
+}
+
+char
+ao_serial_getchar(void) __critical
+{
+       char    c;
+       while (ao_fifo_empty(ao_usart1_rx_fifo))
+               ao_sleep(&ao_usart1_rx_fifo);
+       ao_fifo_remove(ao_usart1_rx_fifo, c);
+       return c;
+}
+
+void
+ao_serial_putchar(char c) __critical
+{
+       while (ao_fifo_full(ao_usart1_tx_fifo))
+               ao_sleep(&ao_usart1_tx_fifo);
+       ao_fifo_insert(ao_usart1_tx_fifo, c);
+       ao_serial_tx1_start();
+}
+
+static void
+send_serial(void)
+{
+       ao_cmd_white();
+       while (ao_cmd_lex_c != '\n') {
+               ao_serial_putchar(ao_cmd_lex_c);
+               ao_cmd_lex();
+       }
+}
+
+__code struct ao_cmds ao_serial_cmds[] = {
+       { 'S', send_serial,             "S <data>                           Send data to serial line" },
+       { 0, send_serial, NULL },
+};
+
+void
+ao_serial_init(void)
+{
+       /* Set up the USART pin assignment */
+       PERCFG = (PERCFG & ~PERCFG_U1CFG_ALT_MASK) | PERCFG_U1CFG_ALT_2;
+
+       /* ee has already set the P2SEL bits */
+
+       /* Make the USART pins be controlled by the USART */
+       P1SEL |= (1 << 6) | (1 << 7);
+
+       /* UART mode with receiver enabled */
+       U1CSR = (UxCSR_MODE_UART | UxCSR_RE);
+
+       /* Pick a 4800 baud rate */
+       U1BAUD = 163;                           /* 4800 */
+       U1GCR = 7 << UxGCR_BAUD_E_SHIFT;        /* 4800 */
+
+       /* Reasonable serial parameters */
+       U1UCR = (UxUCR_FLUSH |
+                UxUCR_FLOW_DISABLE |
+                UxUCR_D9_ODD_PARITY |
+                UxUCR_BIT9_8_BITS |
+                UxUCR_PARITY_DISABLE |
+                UxUCR_SPB_1_STOP_BIT |
+                UxUCR_STOP_HIGH |
+                UxUCR_START_LOW);
+
+       IEN0 |= IEN0_URX1IE;
+       IEN2 |= IEN2_UTX1IE;
+
+       ao_cmd_register(&ao_serial_cmds[0]);
+}
diff --git a/src/ao_state.c b/src/ao_state.c
new file mode 100644 (file)
index 0000000..96b4c1a
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+const char const * const ao_state_names[] = {
+       "startup", "idle", "pad", "boost", "coast",
+       "apogee", "drogue", "main", "landed", "invalid"
+};
diff --git a/src/ao_stdio.c b/src/ao_stdio.c
new file mode 100644 (file)
index 0000000..fb8ce09
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+/*
+ * Basic I/O functions to support SDCC stdio package
+ */
+
+void
+putchar(char c)
+{
+       if (c == '\n')
+               ao_usb_putchar('\r');
+       ao_usb_putchar(c);
+}
+
+void
+flush(void)
+{
+       ao_usb_flush();
+}
+
+char
+getchar(void)
+{
+       return ao_usb_getchar();
+}
diff --git a/src/ao_task.c b/src/ao_task.c
new file mode 100644 (file)
index 0000000..12b7394
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+#define AO_NO_TASK_INDEX       0xff
+
+__xdata struct ao_task * __xdata ao_tasks[AO_NUM_TASKS];
+__data uint8_t ao_num_tasks;
+__data uint8_t ao_cur_task_index;
+__xdata struct ao_task *__data ao_cur_task;
+
+void
+ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name) __reentrant
+{
+       uint8_t __xdata *stack;
+       if (ao_num_tasks == AO_NUM_TASKS)
+               ao_panic(AO_PANIC_NO_TASK);
+       ao_tasks[ao_num_tasks++] = task;
+       task->task_id = ao_num_tasks;
+       task->name = name;
+       /*
+        * Construct a stack frame so that it will 'return'
+        * to the start of the task
+        */
+       stack = task->stack;
+
+       *stack++ = ((uint16_t) start);
+       *stack++ = ((uint16_t) start) >> 8;
+
+       /* and the stuff saved by ao_switch */
+       *stack++ = 0;           /* acc */
+       *stack++ = 0x80;        /* IE */
+       *stack++ = 0;           /* DPL */
+       *stack++ = 0;           /* DPH */
+       *stack++ = 0;           /* B */
+       *stack++ = 0;           /* R2 */
+       *stack++ = 0;           /* R3 */
+       *stack++ = 0;           /* R4 */
+       *stack++ = 0;           /* R5 */
+       *stack++ = 0;           /* R6 */
+       *stack++ = 0;           /* R7 */
+       *stack++ = 0;           /* R0 */
+       *stack++ = 0;           /* R1 */
+       *stack++ = 0;           /* PSW */
+       *stack++ = 0;           /* BP */
+       task->stack_count = stack - task->stack;
+       task->wchan = NULL;
+}
+
+/* Task switching function. This must not use any stack variables */
+void
+ao_yield(void) _naked
+{
+
+       /* Save current context */
+       _asm
+               /* Push ACC first, as when restoring the context it must be restored
+                * last (it is used to set the IE register). */
+               push    ACC
+               /* Store the IE register then enable interrupts. */
+               push    _IEN0
+               setb    _EA
+               push    DPL
+               push    DPH
+               push    b
+               push    ar2
+               push    ar3
+               push    ar4
+               push    ar5
+               push    ar6
+               push    ar7
+               push    ar0
+               push    ar1
+               push    PSW
+       _endasm;
+       PSW = 0;
+       _asm
+               push    _bp
+       _endasm;
+
+       if (ao_cur_task_index != AO_NO_TASK_INDEX)
+       {
+               uint8_t stack_len;
+               __data uint8_t *stack_ptr;
+               __xdata uint8_t *save_ptr;
+               /* Save the current stack */
+               stack_len = SP - (AO_STACK_START - 1);
+               ao_cur_task->stack_count = stack_len;
+               stack_ptr = (uint8_t __data *) AO_STACK_START;
+               save_ptr = (uint8_t __xdata *) ao_cur_task->stack;
+               do
+                       *save_ptr++ = *stack_ptr++;
+               while (--stack_len);
+       }
+
+       /* Empty the stack; might as well let interrupts have the whole thing */
+       SP = AO_STACK_START - 1;
+
+       /* Find a task to run. If there isn't any runnable task,
+        * this loop will run forever, which is just fine
+        */
+       {
+               __pdata uint8_t ao_next_task_index = ao_cur_task_index;
+               for (;;) {
+                       ++ao_next_task_index;
+                       if (ao_next_task_index == ao_num_tasks)
+                               ao_next_task_index = 0;
+
+                       ao_cur_task = ao_tasks[ao_next_task_index];
+                       if (ao_cur_task->wchan == NULL) {
+                               ao_cur_task_index = ao_next_task_index;
+                               break;
+                       }
+
+                       /* Enter lower power mode when there isn't anything to do */
+                       if (ao_next_task_index == ao_cur_task_index)
+                               PCON = PCON_IDLE;
+               }
+       }
+
+       {
+               uint8_t stack_len;
+               __data uint8_t *stack_ptr;
+               __xdata uint8_t *save_ptr;
+
+               /* Restore the old stack */
+               stack_len = ao_cur_task->stack_count;
+               SP = AO_STACK_START - 1 + stack_len;
+
+               stack_ptr = (uint8_t __data *) AO_STACK_START;
+               save_ptr = (uint8_t __xdata *) ao_cur_task->stack;
+               do
+                       *stack_ptr++ = *save_ptr++;
+               while (--stack_len);
+       }
+
+       _asm
+               pop             _bp
+               pop             PSW
+               pop             ar1
+               pop             ar0
+               pop             ar7
+               pop             ar6
+               pop             ar5
+               pop             ar4
+               pop             ar3
+               pop             ar2
+               pop             b
+               pop             DPH
+               pop             DPL
+               /* The next byte of the stack is the IE register.  Only the global
+               enable bit forms part of the task context.  Pop off the IE then set
+               the global enable bit to match that of the stored IE register. */
+               pop             ACC
+               JB              ACC.7,0098$
+               CLR             _EA
+               LJMP    0099$
+       0098$:
+               SETB            _EA
+       0099$:
+               /* Finally pop off the ACC, which was the first register saved. */
+               pop             ACC
+               ret
+       _endasm;
+}
+
+void
+ao_sleep(__xdata void *wchan)
+{
+       __critical {
+               ao_cur_task->wchan = wchan;
+       }
+       ao_yield();
+}
+
+void
+ao_wakeup(__xdata void *wchan)
+{
+       uint8_t i;
+
+       for (i = 0; i < ao_num_tasks; i++)
+               if (ao_tasks[i]->wchan == wchan)
+                       ao_tasks[i]->wchan = NULL;
+}
+
+void
+ao_task_info(void)
+{
+       uint8_t i;
+       uint8_t pc_loc;
+       __xdata struct ao_task *task;
+
+       for (i = 0; i < ao_num_tasks; i++) {
+               task = ao_tasks[i];
+               pc_loc = task->stack_count - 17;
+               printf("%12s: wchan %04x pc %04x\n",
+                      task->name,
+                      (int16_t) task->wchan,
+                      (task->stack[pc_loc]) | (task->stack[pc_loc+1] << 8));
+       }
+}
+
+void
+ao_start_scheduler(void)
+{
+       ao_cur_task_index = AO_NO_TASK_INDEX;
+       ao_cur_task = NULL;
+       ao_yield();
+}
diff --git a/src/ao_teledongle.c b/src/ao_teledongle.c
new file mode 100644 (file)
index 0000000..567751c
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#define AO_NO_SERIAL_ISR 1
+#define AO_NO_ADC_ISR 1
+#include "ao.h"
+
+void
+main(void)
+{
+       CLKCON = 0;
+       while (!(SLEEP & SLEEP_XOSC_STB))
+               ;
+
+       /* Turn on the LED until the system is stable */
+       ao_led_init(AO_LED_RED|AO_LED_GREEN);
+       ao_led_on(AO_LED_RED);
+       ao_timer_init();
+       ao_cmd_init();
+       ao_usb_init();
+       ao_monitor_init(AO_LED_GREEN, TRUE);
+       ao_rssi_init(AO_LED_RED);
+       ao_radio_init();
+       ao_dbg_init();
+       ao_config_init();
+       ao_start_scheduler();
+}
diff --git a/src/ao_telemetrum.c b/src/ao_telemetrum.c
new file mode 100644 (file)
index 0000000..a680ce1
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+void
+main(void)
+{
+       CLKCON = 0;
+       while (!(SLEEP & SLEEP_XOSC_STB))
+               ;
+
+       /* Turn on the red LED until the system is stable */
+       ao_led_init(AO_LED_RED|AO_LED_GREEN);
+       ao_led_on(AO_LED_RED);
+
+       ao_timer_init();
+       ao_adc_init();
+       ao_beep_init();
+       ao_cmd_init();
+       ao_ee_init();
+       ao_flight_init();
+       ao_log_init();
+       ao_report_init();
+       ao_usb_init();
+       ao_serial_init();
+       ao_gps_init();
+       ao_gps_report_init();
+       ao_telemetry_init();
+       ao_radio_init();
+       ao_igniter_init();
+       ao_dbg_init();
+       ao_config_init();
+       ao_start_scheduler();
+}
diff --git a/src/ao_telemetry.c b/src/ao_telemetry.c
new file mode 100644 (file)
index 0000000..463bcd9
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+__xdata uint16_t ao_telemetry_interval = 0;
+
+void
+ao_telemetry(void)
+{
+       static __xdata struct ao_telemetry telemetry;
+
+       ao_config_get();
+       memcpy(telemetry.callsign, ao_config.callsign, AO_MAX_CALLSIGN);
+       telemetry.addr = ao_serial_number;
+       for (;;) {
+               while (ao_telemetry_interval == 0)
+                       ao_sleep(&ao_telemetry_interval);
+               telemetry.flight_state = ao_flight_state;
+               telemetry.flight_accel = ao_flight_accel;
+               telemetry.ground_accel = ao_ground_accel;
+               telemetry.flight_vel = ao_flight_vel;
+               telemetry.flight_pres = ao_flight_pres;
+               telemetry.ground_pres = ao_ground_pres;
+               ao_adc_get(&telemetry.adc);
+               ao_mutex_get(&ao_gps_mutex);
+               memcpy(&telemetry.gps, &ao_gps_data, sizeof (struct ao_gps_data));
+               ao_mutex_put(&ao_gps_mutex);
+               ao_radio_send(&telemetry);
+               ao_delay(ao_telemetry_interval);
+       }
+}
+
+void
+ao_telemetry_set_interval(uint16_t interval)
+{
+       ao_telemetry_interval = interval;
+       ao_wakeup(&ao_telemetry_interval);
+}
+
+__xdata struct ao_task ao_telemetry_task;
+
+void
+ao_telemetry_init()
+{
+       ao_add_task(&ao_telemetry_task, ao_telemetry, "telemetry");
+}
diff --git a/src/ao_teleterra.c b/src/ao_teleterra.c
new file mode 100644 (file)
index 0000000..ad3e2d9
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#define AO_NO_ADC_ISR 1
+#include "ao.h"
+
+void
+main(void)
+{
+       CLKCON = 0;
+       while (!(SLEEP & SLEEP_XOSC_STB))
+               ;
+
+       /* Turn on the red LED until the system is stable */
+       ao_led_init(AO_LED_RED|AO_LED_GREEN);
+       ao_led_on(AO_LED_RED);
+       ao_timer_init();
+       ao_beep_init();
+       ao_cmd_init();
+       ao_usb_init();
+       ao_serial_init();
+       ao_gps_init();
+       ao_monitor_init(AO_LED_GREEN, TRUE);
+       ao_radio_init();
+       ao_dbg_init();
+       ao_config_init();
+       ao_start_scheduler();
+}
diff --git a/src/ao_test.c b/src/ao_test.c
new file mode 100644 (file)
index 0000000..c9bb02a
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+struct ao_task __xdata blink_0_task;
+struct ao_task __xdata blink_1_task;
+struct ao_task __xdata wakeup_task;
+struct ao_task __xdata beep_task;
+struct ao_task __xdata echo_task;
+
+void delay(int n) __reentrant
+{
+       uint8_t j = 0;
+       while (--n)
+               while (--j)
+                       ao_yield();
+}
+
+static __xdata uint8_t blink_chan;
+
+void
+blink_0(void)
+{
+       uint8_t b = 0;
+       for (;;) {
+               b = 1 - b;
+               if (b)
+                       ao_led_on(AO_LED_GREEN);
+               else
+                       ao_led_off(AO_LED_GREEN);
+               ao_sleep(&blink_chan);
+       }
+}
+
+void
+blink_1(void)
+{
+       static __xdata struct ao_adc adc;
+
+       for (;;) {
+               ao_sleep(&ao_adc_ring);
+               ao_adc_get(&adc);
+               if (adc.accel < 15900)
+                       ao_led_on(AO_LED_RED);
+               else
+                       ao_led_off(AO_LED_RED);
+       }
+}
+
+void
+wakeup(void)
+{
+       for (;;) {
+               ao_delay(AO_MS_TO_TICKS(100));
+               ao_wakeup(&blink_chan);
+       }
+}
+
+void
+beep(void)
+{
+       static __xdata struct ao_adc adc;
+
+       for (;;) {
+               ao_delay(AO_SEC_TO_TICKS(1));
+               ao_adc_get(&adc);
+               if (adc.temp > 7400)
+                       ao_beep_for(AO_BEEP_LOW, AO_MS_TO_TICKS(50));
+       }
+}
+
+void
+echo(void)
+{
+       char    c;
+       for (;;) {
+               ao_usb_flush();
+               c = ao_usb_getchar();
+               ao_usb_putchar(c);
+               if (c == '\r')
+                       ao_usb_putchar('\n');
+       }
+}
+
+void
+main(void)
+{
+       CLKCON = 0;
+       while (!(SLEEP & SLEEP_XOSC_STB))
+               ;
+
+//     ao_add_task(&blink_0_task, blink_0);
+//     ao_add_task(&blink_1_task, blink_1);
+//     ao_add_task(&wakeup_task, wakeup);
+//     ao_add_task(&beep_task, beep);
+       ao_add_task(&echo_task, echo);
+       ao_timer_init();
+       ao_adc_init();
+       ao_beep_init();
+       ao_led_init();
+       ao_usb_init();
+
+       ao_start_scheduler();
+}
diff --git a/src/ao_tidongle.c b/src/ao_tidongle.c
new file mode 100644 (file)
index 0000000..6dfa9ae
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#define AO_NO_SERIAL_ISR 1
+#define AO_NO_ADC_ISR 1
+#include "ao.h"
+
+void
+main(void)
+{
+       CLKCON = 0;
+       while (!(SLEEP & SLEEP_XOSC_STB))
+               ;
+
+       /* Turn on the LED until the system is stable */
+       ao_led_init(AO_LED_RED);
+       ao_led_on(AO_LED_RED);
+       ao_timer_init();
+       ao_cmd_init();
+       ao_usb_init();
+       ao_monitor_init(AO_LED_RED, TRUE);
+       ao_rssi_init(AO_LED_RED);
+       ao_radio_init();
+       ao_dbg_init();
+       ao_config_init();
+       /* Bring up the USB link */
+       P1DIR |= 1;
+       P1 |= 1;
+       ao_start_scheduler();
+}
diff --git a/src/ao_timer.c b/src/ao_timer.c
new file mode 100644 (file)
index 0000000..81c3b37
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+
+static volatile __data uint16_t ao_tick_count;
+
+uint16_t ao_time(void) __critical
+{
+       return ao_tick_count;
+}
+
+void
+ao_delay(uint16_t ticks)
+{
+       uint16_t until = ao_time() + ticks;
+
+       while ((int16_t) (until - ao_time()) > 0)
+               ao_sleep(DATA_TO_XDATA(&ao_tick_count));
+}
+
+#define T1_CLOCK_DIVISOR       8       /* 24e6/8 = 3e6 */
+#define T1_SAMPLE_TIME         30000   /* 3e6/30000 = 100 */
+
+volatile __data uint8_t        ao_adc_interval = 1;
+volatile __data uint8_t        ao_adc_count;
+
+void ao_timer_isr(void) interrupt 9
+{
+       ++ao_tick_count;
+       if (++ao_adc_count == ao_adc_interval) {
+               ao_adc_count = 0;
+               ao_adc_poll();
+       }
+       ao_wakeup(DATA_TO_XDATA(&ao_tick_count));
+}
+
+void
+ao_timer_set_adc_interval(uint8_t interval) __critical
+{
+       ao_adc_interval = interval;
+       ao_adc_count = 0;
+}
+
+void
+ao_timer_init(void)
+{
+       /* NOTE:  This uses a timer only present on cc1111 architecture. */
+
+       /* disable timer 1 */
+       T1CTL = 0;
+
+       /* set the sample rate */
+       T1CC0H = T1_SAMPLE_TIME >> 8;
+       T1CC0L = (uint8_t) T1_SAMPLE_TIME;
+
+       T1CCTL0 = T1CCTL_MODE_COMPARE;
+       T1CCTL1 = 0;
+       T1CCTL2 = 0;
+
+       /* clear timer value */
+       T1CNTL = 0;
+
+       /* enable overflow interrupt */
+       OVFIM = 1;
+       /* enable timer 1 interrupt */
+       T1IE = 1;
+
+       /* enable timer 1 in module mode, dividing by 8 */
+       T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_8;
+}
diff --git a/src/ao_usb.c b/src/ao_usb.c
new file mode 100644 (file)
index 0000000..99f0715
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * Copyright Â© 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao.h"
+#include "ao_usb.h"
+
+struct ao_task __xdata ao_usb_task;
+
+static __xdata uint16_t        ao_usb_in_bytes;
+static __xdata uint16_t        ao_usb_out_bytes;
+static __xdata uint8_t ao_usb_iif;
+static __xdata uint8_t ao_usb_running;
+
+static void
+ao_usb_set_interrupts(void)
+{
+       /* IN interrupts on the control an IN endpoints */
+       USBIIE = (1 << AO_USB_CONTROL_EP) | (1 << AO_USB_IN_EP);
+
+       /* OUT interrupts on the OUT endpoint */
+       USBOIE = (1 << AO_USB_OUT_EP);
+
+       /* Only care about reset */
+       USBCIE = USBCIE_RSTIE;
+}
+
+/* This interrupt is shared with port 2,
+ * so when we hook that up, fix this
+ */
+void
+ao_usb_isr(void) interrupt 6
+{
+       USBIF = 0;
+       ao_usb_iif |= USBIIF;
+       if (ao_usb_iif & 1)
+               ao_wakeup(&ao_usb_task);
+       if (ao_usb_iif & (1 << AO_USB_IN_EP))
+               ao_wakeup(&ao_usb_in_bytes);
+
+       if (USBOIF & (1 << AO_USB_OUT_EP))
+               ao_wakeup(&ao_usb_out_bytes);
+
+       if (USBCIF & USBCIF_RSTIF)
+               ao_usb_set_interrupts();
+}
+
+struct ao_usb_setup {
+       uint8_t         dir_type_recip;
+       uint8_t         request;
+       uint16_t        value;
+       uint16_t        index;
+       uint16_t        length;
+} __xdata ao_usb_setup;
+
+__xdata uint8_t ao_usb_ep0_state;
+uint8_t * __xdata ao_usb_ep0_in_data;
+__xdata uint8_t ao_usb_ep0_in_len;
+__xdata uint8_t        ao_usb_ep0_in_buf[2];
+__xdata uint8_t ao_usb_ep0_out_len;
+__xdata uint8_t *__data ao_usb_ep0_out_data;
+__xdata uint8_t ao_usb_configuration;
+
+/* Send an IN data packet */
+static void
+ao_usb_ep0_flush(void)
+{
+       __xdata uint8_t this_len;
+       __xdata uint8_t cs0;
+
+       USBINDEX = 0;
+       cs0 = USBCS0;
+       if (cs0 & USBCS0_INPKT_RDY)
+               ao_panic(0);
+
+       this_len = ao_usb_ep0_in_len;
+       if (this_len > AO_USB_CONTROL_SIZE)
+               this_len = AO_USB_CONTROL_SIZE;
+       cs0 = USBCS0_INPKT_RDY;
+       if (this_len != AO_USB_CONTROL_SIZE) {
+               cs0 = USBCS0_INPKT_RDY | USBCS0_DATA_END;
+               ao_usb_ep0_state = AO_USB_EP0_IDLE;
+       }
+       ao_usb_ep0_in_len -= this_len;
+       while (this_len--)
+               USBFIFO[0] = *ao_usb_ep0_in_data++;
+       USBINDEX = 0;
+       USBCS0 = cs0;
+}
+
+__xdata static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
+
+/* Walk through the list of descriptors and find a match
+ */
+static void
+ao_usb_get_descriptor(uint16_t value)
+{
+       const uint8_t           *__xdata descriptor;
+       __xdata uint8_t         type = value >> 8;
+       __xdata uint8_t         index = value;
+
+       descriptor = ao_usb_descriptors;
+       while (descriptor[0] != 0) {
+               if (descriptor[1] == type && index-- == 0) {
+                       if (type == AO_USB_DESC_CONFIGURATION)
+                               ao_usb_ep0_in_len = descriptor[2];
+                       else
+                               ao_usb_ep0_in_len = descriptor[0];
+                       ao_usb_ep0_in_data = descriptor;
+                       break;
+               }
+               descriptor += descriptor[0];
+       }
+}
+
+/* Read data from the ep0 OUT fifo
+ */
+static void
+ao_usb_ep0_fill(void)
+{
+       __xdata uint8_t len;
+
+       USBINDEX = 0;
+       len = USBCNT0;
+       if (len > ao_usb_ep0_out_len)
+               len = ao_usb_ep0_out_len;
+       ao_usb_ep0_out_len -= len;
+       while (len--)
+               *ao_usb_ep0_out_data++ = USBFIFO[0];
+}
+
+void
+ao_usb_ep0_queue_byte(uint8_t a)
+{
+       ao_usb_ep0_in_buf[ao_usb_ep0_in_len++] = a;
+}
+
+void
+ao_usb_set_address(uint8_t address)
+{
+       ao_usb_running = 1;
+       USBADDR = address | 0x80;
+       while (USBADDR & 0x80)
+               ;
+}
+
+static void
+ao_usb_set_configuration(void)
+{
+       /* Set the IN max packet size, double buffered */
+       USBINDEX = AO_USB_IN_EP;
+       USBMAXI = AO_USB_IN_SIZE >> 3;
+       USBCSIH |= USBCSIH_IN_DBL_BUF;
+
+       /* Set the OUT max packet size, double buffered */
+       USBINDEX = AO_USB_OUT_EP;
+       USBMAXO = AO_USB_OUT_SIZE >> 3;
+       USBCSOH = USBCSOH_OUT_DBL_BUF;
+}
+
+static void
+ao_usb_ep0_setup(void)
+{
+       /* Pull the setup packet out of the fifo */
+       ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_setup;
+       ao_usb_ep0_out_len = 8;
+       ao_usb_ep0_fill();
+       if (ao_usb_ep0_out_len != 0)
+               return;
+
+       /* Figure out how to ACK the setup packet */
+       if (ao_usb_setup.dir_type_recip & AO_USB_DIR_IN) {
+               if (ao_usb_setup.length)
+                       ao_usb_ep0_state = AO_USB_EP0_DATA_IN;
+               else
+                       ao_usb_ep0_state = AO_USB_EP0_IDLE;
+       } else {
+               if (ao_usb_setup.length)
+                       ao_usb_ep0_state = AO_USB_EP0_DATA_OUT;
+               else
+                       ao_usb_ep0_state = AO_USB_EP0_IDLE;
+       }
+       USBINDEX = 0;
+       if (ao_usb_ep0_state == AO_USB_EP0_IDLE)
+               USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END;
+       else
+               USBCS0 = USBCS0_CLR_OUTPKT_RDY;
+
+       ao_usb_ep0_in_data = ao_usb_ep0_in_buf;
+       ao_usb_ep0_in_len = 0;
+       switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_TYPE_MASK) {
+       case AO_USB_TYPE_STANDARD:
+               switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_RECIP_MASK) {
+               case AO_USB_RECIP_DEVICE:
+                       switch(ao_usb_setup.request) {
+                       case AO_USB_REQ_GET_STATUS:
+                               ao_usb_ep0_queue_byte(0);
+                               ao_usb_ep0_queue_byte(0);
+                               break;
+                       case AO_USB_REQ_SET_ADDRESS:
+                               ao_usb_set_address(ao_usb_setup.value);
+                               break;
+                       case AO_USB_REQ_GET_DESCRIPTOR:
+                               ao_usb_get_descriptor(ao_usb_setup.value);
+                               break;
+                       case AO_USB_REQ_GET_CONFIGURATION:
+                               ao_usb_ep0_queue_byte(ao_usb_configuration);
+                               break;
+                       case AO_USB_REQ_SET_CONFIGURATION:
+                               ao_usb_configuration = ao_usb_setup.value;
+                               ao_usb_set_configuration();
+                               break;
+                       }
+                       break;
+               case AO_USB_RECIP_INTERFACE:
+                       #pragma disable_warning 110
+                       switch(ao_usb_setup.request) {
+                       case AO_USB_REQ_GET_STATUS:
+                               ao_usb_ep0_queue_byte(0);
+                               ao_usb_ep0_queue_byte(0);
+                               break;
+                       case AO_USB_REQ_GET_INTERFACE:
+                               ao_usb_ep0_queue_byte(0);
+                               break;
+                       case AO_USB_REQ_SET_INTERFACE:
+                               break;
+                       }
+                       break;
+               case AO_USB_RECIP_ENDPOINT:
+                       switch(ao_usb_setup.request) {
+                       case AO_USB_REQ_GET_STATUS:
+                               ao_usb_ep0_queue_byte(0);
+                               ao_usb_ep0_queue_byte(0);
+                               break;
+                       }
+                       break;
+               }
+               break;
+       case AO_USB_TYPE_CLASS:
+               switch (ao_usb_setup.request) {
+               case SET_LINE_CODING:
+                       ao_usb_ep0_out_len = 7;
+                       ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_line_coding;
+                       break;
+               case GET_LINE_CODING:
+                       ao_usb_ep0_in_len = 7;
+                       ao_usb_ep0_in_data = (uint8_t *) &ao_usb_line_coding;
+                       break;
+               case SET_CONTROL_LINE_STATE:
+                       break;
+               }
+               break;
+       }
+       if (ao_usb_ep0_state != AO_USB_EP0_DATA_OUT) {
+               if (ao_usb_setup.length < ao_usb_ep0_in_len)
+                       ao_usb_ep0_in_len = ao_usb_setup.length;
+               ao_usb_ep0_flush();
+       }
+}
+
+/* End point 0 receives all of the control messages. */
+static void
+ao_usb_ep0(void)
+{
+       __xdata uint8_t cs0;
+
+       ao_usb_ep0_state = AO_USB_EP0_IDLE;
+       for (;;) {
+               __critical for (;;) {
+                       if (ao_usb_iif & 1) {
+                               ao_usb_iif &= ~1;
+                               break;
+                       }
+                       ao_sleep(&ao_usb_task);
+               }
+               USBINDEX = 0;
+               cs0 = USBCS0;
+               if (cs0 & USBCS0_SETUP_END) {
+                       ao_usb_ep0_state = AO_USB_EP0_IDLE;
+                       USBCS0 = USBCS0_CLR_SETUP_END;
+               }
+               if (cs0 & USBCS0_SENT_STALL) {
+                       ao_usb_ep0_state = AO_USB_EP0_IDLE;
+                       USBCS0 &= ~USBCS0_SENT_STALL;
+               }
+               if (ao_usb_ep0_state == AO_USB_EP0_DATA_IN &&
+                   (cs0 & USBCS0_INPKT_RDY) == 0)
+               {
+                       ao_usb_ep0_flush();
+               }
+               if (cs0 & USBCS0_OUTPKT_RDY) {
+                       switch (ao_usb_ep0_state) {
+                       case AO_USB_EP0_IDLE:
+                               ao_usb_ep0_setup();
+                               break;
+                       case AO_USB_EP0_DATA_OUT:
+                               ao_usb_ep0_fill();
+                               if (ao_usb_ep0_out_len == 0)
+                                       ao_usb_ep0_state = AO_USB_EP0_IDLE;
+                               USBINDEX = 0;
+                               if (ao_usb_ep0_state == AO_USB_EP0_IDLE)
+                                       USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END;
+                               else
+                                       USBCS0 = USBCS0_CLR_OUTPKT_RDY;
+                               break;
+                       }
+               }
+       }
+}
+
+void
+ao_usb_flush(void) __critical
+{
+       if (ao_usb_in_bytes) {
+               USBINDEX = AO_USB_IN_EP;
+               USBCSIL |= USBCSIL_INPKT_RDY;
+               ao_usb_in_bytes = 0;
+       }
+}
+
+void
+ao_usb_putchar(char c) __critical
+{
+       if (!ao_usb_running)
+               return;
+       for (;;) {
+               USBINDEX = AO_USB_IN_EP;
+               if ((USBCSIL & USBCSIL_INPKT_RDY) == 0)
+                       break;
+               ao_sleep(&ao_usb_in_bytes);
+       }
+       USBFIFO[AO_USB_IN_EP << 1] = c;
+       if (++ao_usb_in_bytes == AO_USB_IN_SIZE) {
+               USBINDEX = AO_USB_IN_EP;
+               USBCSIL |= USBCSIL_INPKT_RDY;
+               ao_usb_in_bytes = 0;
+       }
+}
+
+char
+ao_usb_getchar(void) __critical
+{
+       __xdata char    c;
+       while (ao_usb_out_bytes == 0) {
+               for (;;) {
+                       USBINDEX = AO_USB_OUT_EP;
+                       if ((USBCSOL & USBCSOL_OUTPKT_RDY) != 0)
+                               break;
+                       ao_sleep(&ao_usb_out_bytes);
+               }
+               ao_usb_out_bytes = (USBCNTH << 8) | USBCNTL;
+       }
+       --ao_usb_out_bytes;
+       c = USBFIFO[AO_USB_OUT_EP << 1];
+       if (ao_usb_out_bytes == 0) {
+               USBINDEX = AO_USB_OUT_EP;
+               USBCSOL &= ~USBCSOL_OUTPKT_RDY;
+       }
+       return c;
+}
+
+void
+ao_usb_enable(void)
+{
+       /* Turn on the USB controller */
+       SLEEP |= SLEEP_USB_EN;
+
+       ao_usb_set_configuration();
+
+       ao_usb_set_interrupts();
+
+       /* enable USB interrupts */
+       IEN2 |= IEN2_USBIE;
+
+       /* Clear any pending interrupts */
+       USBCIF = 0;
+       USBOIF = 0;
+       USBIIF = 0;
+}
+
+void
+ao_usb_disable(void)
+{
+       /* Disable USB interrupts */
+       USBIIE = 0;
+       USBOIE = 0;
+       USBCIE = 0;
+       IEN2 &= ~IEN2_USBIE;
+
+       /* Clear any pending interrupts */
+       USBCIF = 0;
+       USBOIF = 0;
+       USBIIF = 0;
+
+       /* Turn off the USB controller */
+       SLEEP &= ~SLEEP_USB_EN;
+}
+
+void
+ao_usb_init(void)
+{
+       ao_usb_enable();
+
+       ao_add_task(&ao_usb_task, ao_usb_ep0, "usb");
+}
diff --git a/src/ao_usb.h b/src/ao_usb.h
new file mode 100644 (file)
index 0000000..6633daf
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright Â© 2009 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_USB_H_
+#define _AO_USB_H_
+
+#define AO_USB_SETUP_DIR_MASK  (0x01 << 7)
+#define AO_USB_SETUP_TYPE_MASK (0x03 << 5)
+#define AO_USB_SETUP_RECIP_MASK        (0x1f)
+
+#define AO_USB_DIR_OUT                 0
+#define AO_USB_DIR_IN                  (1 << 7)
+
+#define AO_USB_TYPE_STANDARD           0
+#define AO_USB_TYPE_CLASS              (1 << 5)
+#define AO_USB_TYPE_VENDOR             (2 << 5)
+#define AO_USB_TYPE_RESERVED           (3 << 5)
+
+#define AO_USB_RECIP_DEVICE            0
+#define AO_USB_RECIP_INTERFACE         1
+#define AO_USB_RECIP_ENDPOINT          2
+#define AO_USB_RECIP_OTHER             3
+
+/* standard requests */
+#define        AO_USB_REQ_GET_STATUS           0x00
+#define AO_USB_REQ_CLEAR_FEATURE       0x01
+#define AO_USB_REQ_SET_FEATURE         0x03
+#define AO_USB_REQ_SET_ADDRESS         0x05
+#define AO_USB_REQ_GET_DESCRIPTOR      0x06
+#define AO_USB_REQ_SET_DESCRIPTOR      0x07
+#define AO_USB_REQ_GET_CONFIGURATION   0x08
+#define AO_USB_REQ_SET_CONFIGURATION   0x09
+#define AO_USB_REQ_GET_INTERFACE       0x0A
+#define AO_USB_REQ_SET_INTERFACE       0x0B
+#define AO_USB_REQ_SYNCH_FRAME         0x0C
+
+#define AO_USB_DESC_DEVICE             1
+#define AO_USB_DESC_CONFIGURATION      2
+#define AO_USB_DESC_STRING             3
+#define AO_USB_DESC_INTERFACE          4
+#define AO_USB_DESC_ENDPOINT           5
+#define AO_USB_DESC_DEVICE_QUALIFIER   6
+#define AO_USB_DESC_OTHER_SPEED                7
+#define AO_USB_DESC_INTERFACE_POWER    8
+
+#define AO_USB_GET_DESC_TYPE(x)                (((x)>>8)&0xFF)
+#define AO_USB_GET_DESC_INDEX(x)       ((x)&0xFF)
+
+#define AO_USB_CONTROL_EP      0
+#define AO_USB_INT_EP          1
+#define AO_USB_OUT_EP          4
+#define AO_USB_IN_EP           5
+#define AO_USB_CONTROL_SIZE    32
+/*
+ * Double buffer IN and OUT EPs, so each
+ * gets half of the available space
+ *
+ * Ah, but USB bulk packets can only come in 8, 16, 32 and 64
+ * byte sizes, so we'll use 64 for everything
+ */
+#define AO_USB_IN_SIZE         64
+#define AO_USB_OUT_SIZE                64
+
+#define AO_USB_EP0_IDLE                0
+#define AO_USB_EP0_DATA_IN     1
+#define AO_USB_EP0_DATA_OUT    2
+
+#define LE_WORD(x)    ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8))
+
+/* CDC definitions */
+#define CS_INTERFACE      0x24
+#define CS_ENDPOINT       0x25
+
+#define SET_LINE_CODING         0x20
+#define GET_LINE_CODING         0x21
+#define SET_CONTROL_LINE_STATE  0x22
+
+/* Data structure for GET_LINE_CODING / SET_LINE_CODING class requests */
+struct ao_usb_line_coding {
+       uint32_t        rate;
+       uint8_t         char_format;
+       uint8_t         parity;
+       uint8_t         data_bits;
+} ;
+
+#endif /* _AO_USB_H_ */
diff --git a/src/cc1111.h b/src/cc1111.h
new file mode 100644 (file)
index 0000000..f55e802
--- /dev/null
@@ -0,0 +1,1214 @@
+/*-------------------------------------------------------------------------
+   Register Declarations for the ChipCon CC1111 Processor Range
+
+   Copyright Â© 2008 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.
+
+   Adapted from the Cygnal C8051F12x config file which is:
+
+   Copyright (C) 2003 - Maarten Brock, sourceforge.brock@dse.nl
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+-------------------------------------------------------------------------*/
+
+#ifndef _CC1111_H_
+#define _CC1111_H_
+#include <cc1110.h>
+#include <stdint.h>
+
+sfr at 0xA8 IEN0;              /* Interrupt Enable 0 Register */
+
+sbit at 0xA8 RFTXRXIE;         /* RF TX/RX done interrupt enable */
+sbit at 0xA9 ADCIE;            /* ADC interrupt enable */
+sbit at 0xAA URX0IE;           /* USART0 RX interrupt enable */
+sbit at 0xAB URX1IE;           /* USART1 RX interrupt enable (shared with I2S RX) */
+sbit at 0xAB I2SRXIE;          /* I2S RX interrupt enable (shared with USART1 RX) */
+sbit at 0xAC ENCIE;            /* AES encryption/decryption interrupt enable */
+sbit at 0xAD STIE;             /* Sleep Timer interrupt enable */
+sbit at 0xAF EA;               /* Enable All */
+
+#define IEN0_EA                        (1 << 7)
+#define IEN0_STIE              (1 << 5)
+#define IEN0_ENCIE             (1 << 4)
+#define IEN0_URX1IE            (1 << 3)
+#define IEN0_I2SRXIE           (1 << 3)
+#define IEN0_URX0IE            (1 << 2)
+#define IEN0_ADCIE             (1 << 1)
+#define IEN0_RFTXRXIE          (1 << 0)
+
+sfr at 0xB8 IEN1;              /* Interrupt Enable 1 Register */
+
+#define IEN1_P0IE              (1 << 5)        /* Port 0 interrupt enable */
+#define IEN1_T4IE              (1 << 4)        /* Timer 4 interrupt enable */
+#define IEN1_T3IE              (1 << 3)        /* Timer 3 interrupt enable */
+#define IEN1_T2IE              (1 << 2)        /* Timer 2 interrupt enable */
+#define IEN1_T1IE              (1 << 1)        /* Timer 1 interrupt enable */
+#define IEN1_DMAIE             (1 << 0)        /* DMA transfer interrupt enable */
+
+/* IEN2 */
+sfr at 0x9A IEN2;              /* Interrupt Enable 2 Register */
+
+#define IEN2_WDTIE             (1 << 5)        /* Watchdog timer interrupt enable */
+#define IEN2_P1IE              (1 << 4)        /* Port 1 interrupt enable */
+#define IEN2_UTX1IE            (1 << 3)        /* USART1 TX interrupt enable */
+#define IEN2_I2STXIE           (1 << 3)        /* I2S TX interrupt enable */
+#define IEN2_UTX0IE            (1 << 2)        /* USART0 TX interrupt enable */
+#define IEN2_P2IE              (1 << 1)        /* Port 2 interrupt enable */
+#define IEN2_USBIE             (1 << 1)        /* USB interrupt enable */
+#define IEN2_RFIE              (1 << 0)        /* RF general interrupt enable */
+
+/* SLEEP 0xBE */
+#define SLEEP_USB_EN           (1 << 7)
+#define SLEEP_XOSC_STB         (1 << 6)
+#define SLEEP_HFRC_STB         (1 << 5)
+#define SLEEP_RST_POWER                (0 << 3)
+#define SLEEP_RST_EXTERNAL     (1 << 3)
+#define SLEEP_RST_WATCHDOG     (2 << 3)
+#define SLEEP_RST_MASK         (3 << 3)
+#define SLEEP_OSC_PD           (1 << 2)
+#define SLEEP_MODE_PM0         (0 << 0)
+#define SLEEP_MODE_PM1         (1 << 0)
+#define SLEEP_MODE_PM2         (2 << 0)
+#define SLEEP_MODE_PM3         (3 << 0)
+#define SLEEP_MODE_MASK                (3 << 0)
+
+/* PCON 0x87 */
+sfr at 0x87 PCON;              /* Power Mode Control Register */
+
+#define PCON_IDLE              (1 << 0)
+
+/*
+ * TCON
+ */
+sfr at 0x88 TCON;      /* CPU Interrupt Flag 1 */
+
+sbit at 0x8F URX1IF;   /* USART1 RX interrupt flag. Automatically cleared */
+sbit at 0x8F I2SRXIF;  /* I2S RX interrupt flag. Automatically cleared */
+sbit at 0x8D ADCIF;    /* ADC interrupt flag. Automatically cleared */
+sbit at 0x8B URX0IF;   /* USART0 RX interrupt flag. Automatically cleared */
+sbit at 0x89 RFTXRXIF; /* RF TX/RX complete interrupt flag. Automatically cleared */
+
+#define TCON_URX1IF    (1 << 7)
+#define TCON_I2SRXIF   (1 << 7)
+#define TCON_ADCIF     (1 << 5)
+#define TCON_URX0IF    (1 << 3)
+#define TCON_RFTXRXIF  (1 << 1)
+
+/*
+ * S0CON
+ */
+sfr at 0x98 S0CON;     /* CPU Interrupt Flag 2 */
+
+sbit at 0x98 ENCIF_0;  /* AES interrupt 0. */
+sbit at 0x99 ENCIF_1;  /* AES interrupt 1. */
+
+#define S0CON_ENCIF_1  (1 << 1)
+#define S0CON_ENCIF_0  (1 << 0)
+
+/*
+ * S1CON
+ */
+sfr at 0x9B S1CON;     /* CPU Interrupt Flag 3 */
+
+#define S1CON_RFIF_1   (1 << 1)
+#define S1CON_RFIF_0   (1 << 0)
+
+/*
+ * IRCON
+ */
+sfr at 0xC0 IRCON;     /* CPU Interrupt Flag 4 */
+
+sbit at 0xC0 DMAIF;    /* DMA complete interrupt flag */
+sbit at 0xC1 T1IF;     /* Timer 1 interrupt flag. Automatically cleared */
+sbit at 0xC2 T2IF;     /* Timer 2 interrupt flag. Automatically cleared */
+sbit at 0xC3 T3IF;     /* Timer 3 interrupt flag. Automatically cleared */
+sbit at 0xC4 T4IF;     /* Timer 4 interrupt flag. Automatically cleared */
+sbit at 0xC5 P0IF;     /* Port0 interrupt flag */
+sbit at 0xC7 STIF;     /* Sleep Timer interrupt flag */
+
+#define IRCON_DMAIF    (1 << 0)        /* DMA complete interrupt flag */
+#define IRCON_T1IF     (1 << 1)        /* Timer 1 interrupt flag. Automatically cleared */
+#define IRCON_T2IF     (1 << 2)        /* Timer 2 interrupt flag. Automatically cleared */
+#define IRCON_T3IF     (1 << 3)        /* Timer 3 interrupt flag. Automatically cleared */
+#define IRCON_T4IF     (1 << 4)        /* Timer 4 interrupt flag. Automatically cleared */
+#define IRCON_P0IF     (1 << 5)        /* Port0 interrupt flag */
+#define IRCON_STIF     (1 << 7)        /* Sleep Timer interrupt flag */
+
+/*
+ * IRCON2
+ */
+sfr at 0xE8 IRCON2;    /* CPU Interrupt Flag 5 */
+
+sbit at 0xE8 USBIF;    /* USB interrupt flag (shared with Port2) */
+sbit at 0xE8 P2IF;     /* Port2 interrupt flag (shared with USB) */
+sbit at 0xE9 UTX0IF;   /* USART0 TX interrupt flag */
+sbit at 0xEA UTX1IF;   /* USART1 TX interrupt flag (shared with I2S TX) */
+sbit at 0xEA I2STXIF;  /* I2S TX interrupt flag (shared with USART1 TX) */
+sbit at 0xEB P1IF;     /* Port1 interrupt flag */
+sbit at 0xEC WDTIF;    /* Watchdog timer interrupt flag */
+
+#define IRCON2_USBIF   (1 << 0)        /* USB interrupt flag (shared with Port2) */
+#define IRCON2_P2IF    (1 << 0)        /* Port2 interrupt flag (shared with USB) */
+#define IRCON2_UTX0IF  (1 << 1)        /* USART0 TX interrupt flag */
+#define IRCON2_UTX1IF  (1 << 2)        /* USART1 TX interrupt flag (shared with I2S TX) */
+#define IRCON2_I2STXIF (1 << 2)        /* I2S TX interrupt flag (shared with USART1 TX) */
+#define IRCON2_P1IF    (1 << 3)        /* Port1 interrupt flag */
+#define IRCON2_WDTIF   (1 << 4)        /* Watchdog timer interrupt flag */
+
+/*
+ * IP1 - Interrupt Priority 1
+ */
+
+/*
+ * Interrupt priority groups:
+ *
+ * IPG0                RFTXRX          RF              DMA
+ * IPG1                ADC             T1              P2INT/USB
+ * IPG2                URX0            T2              UTX0
+ * IPG3                URX1/I2SRX      T3              UTX1 / I2STX
+ * IPG4                ENC             T4              P1INT
+ * IPG5                ST              P0INT           WDT
+ *
+ * Priority = (IP1 << 1) | IP0. Higher priority interrupts served first
+ */
+
+sfr at 0xB9 IP1;       /* Interrupt Priority 1 */
+sfr at 0xA9 IP0;       /* Interrupt Priority 0 */
+
+#define IP1_IPG5       (1 << 5)
+#define IP1_IPG4       (1 << 4)
+#define IP1_IPG3       (1 << 3)
+#define IP1_IPG2       (1 << 2)
+#define IP1_IPG1       (1 << 1)
+#define IP1_IPG0       (1 << 0)
+
+#define IP0_IPG5       (1 << 5)
+#define IP0_IPG4       (1 << 4)
+#define IP0_IPG3       (1 << 3)
+#define IP0_IPG2       (1 << 2)
+#define IP0_IPG1       (1 << 1)
+#define IP0_IPG0       (1 << 0)
+
+/*
+ * Timer 1
+ */
+#define T1CTL_MODE_SUSPENDED   (0 << 0)
+#define T1CTL_MODE_FREE                (1 << 0)
+#define T1CTL_MODE_MODULO      (2 << 0)
+#define T1CTL_MODE_UP_DOWN     (3 << 0)
+#define T1CTL_MODE_MASK                (3 << 0)
+#define T1CTL_DIV_1            (0 << 2)
+#define T1CTL_DIV_8            (1 << 2)
+#define T1CTL_DIV_32           (2 << 2)
+#define T1CTL_DIV_128          (3 << 2)
+#define T1CTL_DIV_MASK         (3 << 2)
+#define T1CTL_OVFIF            (1 << 4)
+#define T1CTL_CH0IF            (1 << 5)
+#define T1CTL_CH1IF            (1 << 6)
+#define T1CTL_CH2IF            (1 << 7)
+
+#define T1CCTL_NO_CAPTURE      (0 << 0)
+#define T1CCTL_CAPTURE_RISING  (1 << 0)
+#define T1CCTL_CAPTURE_FALLING (2 << 0)
+#define T1CCTL_CAPTURE_BOTH    (3 << 0)
+#define T1CCTL_CAPTURE_MASK    (3 << 0)
+
+#define T1CCTL_MODE_CAPTURE    (0 << 2)
+#define T1CCTL_MODE_COMPARE    (1 << 2)
+
+#define T1CTL_CMP_SET          (0 << 3)
+#define T1CTL_CMP_CLEAR                (1 << 3)
+#define T1CTL_CMP_TOGGLE       (2 << 3)
+#define T1CTL_CMP_SET_CLEAR    (3 << 3)
+#define T1CTL_CMP_CLEAR_SET    (4 << 3)
+
+#define T1CTL_IM_DISABLED      (0 << 6)
+#define T1CTL_IM_ENABLED       (1 << 6)
+
+#define T1CTL_CPSEL_NORMAL     (0 << 7)
+#define T1CTL_CPSEL_RF         (1 << 7)
+
+/*
+ * Timer 3 and Timer 4
+ */
+
+/* Timer count */
+sfr at 0xCA T3CNT;
+sfr at 0xEA T4CNT;
+
+/* Timer control */
+
+sfr at 0xCB T3CTL;
+sfr at 0xEB T4CTL;
+
+#define TxCTL_DIV_1            (0 << 5)
+#define TxCTL_DIV_2            (1 << 5)
+#define TxCTL_DIV_4            (2 << 5)
+#define TxCTL_DIV_8            (3 << 5)
+#define TxCTL_DIV_16           (4 << 5)
+#define TxCTL_DIV_32           (5 << 5)
+#define TxCTL_DIV_64           (6 << 5)
+#define TxCTL_DIV_128          (7 << 5)
+#define TxCTL_START            (1 << 4)
+#define TxCTL_OVFIM            (1 << 3)
+#define TxCTL_CLR              (1 << 2)
+#define TxCTL_MODE_FREE                (0 << 0)
+#define TxCTL_MODE_DOWN                (1 << 0)
+#define TxCTL_MODE_MODULO      (2 << 0)
+#define TxCTL_MODE_UP_DOWN     (3 << 0)
+
+/* Timer 4 channel 0 compare control */
+
+sfr at 0xCC T3CCTL0;
+sfr at 0xCE T3CCTL1;
+sfr at 0xEC T4CCTL0;
+sfr at 0xEE T4CCTL1;
+
+#define TxCCTLy_IM                     (1 << 6)
+#define TxCCTLy_CMP_SET                        (0 << 3)
+#define TxCCTLy_CMP_CLEAR              (1 << 3)
+#define TxCCTLy_CMP_TOGGLE             (2 << 3)
+#define TxCCTLy_CMP_SET_UP_CLEAR_DOWN  (3 << 3)
+#define TxCCTLy_CMP_CLEAR_UP_SET_DOWN  (4 << 3)
+#define TxCCTLy_CMP_SET_CLEAR_FF       (5 << 3)
+#define TxCCTLy_CMP_CLEAR_SET_00       (6 << 3)
+#define TxCCTLy_CMP_MODE_ENABLE                (1 << 2)
+
+/* Timer compare value */
+sfr at 0xCD T3CC0;
+sfr at 0xCF T3CC1;
+sfr at 0xED T4CC0;
+sfr at 0xEF T4CC1;
+
+/*
+ * Peripheral control
+ */
+
+sfr at 0xf1 PERCFG;
+#define PERCFG_T1CFG_ALT_1      (0 << 6)
+#define PERCFG_T1CFG_ALT_2      (1 << 6)
+#define PERCFG_T1CFG_ALT_MASK   (1 << 6)
+
+#define PERCFG_T3CFG_ALT_1      (0 << 5)
+#define PERCFG_T3CFG_ALT_2      (1 << 5)
+#define PERCFG_T3CFG_ALT_MASK   (1 << 5)
+
+#define PERCFG_T4CFG_ALT_1      (0 << 4)
+#define PERCFG_T4CFG_ALT_2      (1 << 4)
+#define PERCFG_T4CFG_ALT_MASK   (1 << 4)
+
+#define PERCFG_U1CFG_ALT_1      (0 << 1)
+#define PERCFG_U1CFG_ALT_2      (1 << 1)
+#define PERCFG_U1CFG_ALT_MASK   (1 << 1)
+
+#define PERCFG_U0CFG_ALT_1      (0 << 0)
+#define PERCFG_U0CFG_ALT_2      (1 << 0)
+#define PERCFG_U0CFG_ALT_MASK   (1 << 0)
+
+/* directly addressed USB registers */
+__xdata __at (0xde00) volatile uint8_t USBADDR;
+__xdata __at (0xde01) volatile uint8_t USBPOW;
+__xdata __at (0xde02) volatile uint8_t USBIIF;
+
+__xdata __at (0xde04) volatile uint8_t USBOIF;
+
+__xdata __at (0xde06) volatile uint8_t USBCIF;
+
+# define USBCIF_SOFIF          (1 << 3)
+# define USBCIF_RSTIF          (1 << 2)
+# define USBCIF_RESUMEIF       (1 << 1)
+# define USBCIF_SUSPENDIF      (1 << 0)
+
+__xdata __at (0xde07) volatile uint8_t USBIIE;
+
+__xdata __at (0xde09) volatile uint8_t USBOIE;
+
+__xdata __at (0xde0b) volatile uint8_t USBCIE;
+
+# define USBCIE_SOFIE          (1 << 3)
+# define USBCIE_RSTIE          (1 << 2)
+# define USBCIE_RESUMEIE       (1 << 1)
+# define USBCIE_SUSPENDIE      (1 << 0)
+
+__xdata __at (0xde0c) volatile uint8_t USBFRML;
+__xdata __at (0xde0d) volatile uint8_t USBFRMH;
+__xdata __at (0xde0e) volatile uint8_t USBINDEX;
+
+/* indexed USB registers, must set USBINDEX to 0-5 */
+__xdata __at (0xde10) volatile uint8_t USBMAXI;
+__xdata __at (0xde11) volatile uint8_t USBCS0;
+
+# define USBCS0_CLR_SETUP_END          (1 << 7)
+# define USBCS0_CLR_OUTPKT_RDY         (1 << 6)
+# define USBCS0_SEND_STALL             (1 << 5)
+# define USBCS0_SETUP_END              (1 << 4)
+# define USBCS0_DATA_END               (1 << 3)
+# define USBCS0_SENT_STALL             (1 << 2)
+# define USBCS0_INPKT_RDY              (1 << 1)
+# define USBCS0_OUTPKT_RDY             (1 << 0)
+
+__xdata __at (0xde11) volatile uint8_t USBCSIL;
+
+# define USBCSIL_CLR_DATA_TOG          (1 << 6)
+# define USBCSIL_SENT_STALL            (1 << 5)
+# define USBCSIL_SEND_STALL            (1 << 4)
+# define USBCSIL_FLUSH_PACKET          (1 << 3)
+# define USBCSIL_UNDERRUN              (1 << 2)
+# define USBCSIL_PKT_PRESENT           (1 << 1)
+# define USBCSIL_INPKT_RDY             (1 << 0)
+
+__xdata __at (0xde12) volatile uint8_t USBCSIH;
+
+# define USBCSIH_AUTOSET               (1 << 7)
+# define USBCSIH_ISO                   (1 << 6)
+# define USBCSIH_FORCE_DATA_TOG                (1 << 3)
+# define USBCSIH_IN_DBL_BUF            (1 << 0)
+
+__xdata __at (0xde13) volatile uint8_t USBMAXO;
+__xdata __at (0xde14) volatile uint8_t USBCSOL;
+
+# define USBCSOL_CLR_DATA_TOG          (1 << 7)
+# define USBCSOL_SENT_STALL            (1 << 6)
+# define USBCSOL_SEND_STALL            (1 << 5)
+# define USBCSOL_FLUSH_PACKET          (1 << 4)
+# define USBCSOL_DATA_ERROR            (1 << 3)
+# define USBCSOL_OVERRUN               (1 << 2)
+# define USBCSOL_FIFO_FULL             (1 << 1)
+# define USBCSOL_OUTPKT_RDY            (1 << 0)
+
+__xdata __at (0xde15) volatile uint8_t USBCSOH;
+
+# define USBCSOH_AUTOCLEAR             (1 << 7)
+# define USBCSOH_ISO                   (1 << 6)
+# define USBCSOH_OUT_DBL_BUF           (1 << 0)
+
+__xdata __at (0xde16) volatile uint8_t USBCNT0;
+__xdata __at (0xde16) volatile uint8_t USBCNTL;
+__xdata __at (0xde17) volatile uint8_t USBCNTH;
+
+__xdata __at (0xde20) volatile uint8_t USBFIFO[12];
+
+/* ADC Data register, low and high */
+sfr at 0xBA ADCL;
+sfr at 0xBB ADCH;
+__xdata __at (0xDFBA) volatile uint16_t ADCXDATA;
+
+/* ADC Control Register 1 */
+sfr at 0xB4 ADCCON1;
+
+# define ADCCON1_EOC           (1 << 7)        /* conversion complete */
+# define ADCCON1_ST            (1 << 6)        /* start conversion */
+
+# define ADCCON1_STSEL_MASK    (3 << 4)        /* start select */
+# define ADCCON1_STSEL_EXTERNAL        (0 << 4)        /* P2_0 pin triggers */
+# define ADCCON1_STSEL_FULLSPEED (1 << 4)      /* full speed, no waiting */
+# define ADCCON1_STSEL_TIMER1  (2 << 4)        /* timer 1 channel 0 */
+# define ADCCON1_STSEL_START   (3 << 4)        /* set start bit */
+
+# define ADCCON1_RCTRL_MASK    (3 << 2)        /* random number control */
+# define ADCCON1_RCTRL_COMPLETE        (0 << 2)        /* operation completed */
+# define ADCCON1_RCTRL_CLOCK_LFSR (1 << 2)     /* Clock the LFSR once */
+
+/* ADC Control Register 2 */
+sfr at 0xB5 ADCCON2;
+
+# define ADCCON2_SREF_MASK     (3 << 6)        /* reference voltage */
+# define ADCCON2_SREF_1_25V    (0 << 6)        /* internal 1.25V */
+# define ADCCON2_SREF_EXTERNAL (1 << 6)        /* external on AIN7 cc1110 */
+# define ADCCON2_SREF_VDD      (2 << 6)        /* VDD on the AVDD pin */
+# define ADCCON2_SREF_EXTERNAL_DIFF (3 << 6)   /* external on AIN6-7 cc1110 */
+
+# define ADCCON2_SDIV_MASK     (3 << 4)        /* decimation rate */
+# define ADCCON2_SDIV_64       (0 << 4)        /* 7 bits */
+# define ADCCON2_SDIV_128      (1 << 4)        /* 9 bits */
+# define ADCCON2_SDIV_256      (2 << 4)        /* 10 bits */
+# define ADCCON2_SDIV_512      (3 << 4)        /* 12 bits */
+
+# define ADCCON2_SCH_MASK      (0xf << 0)      /* Sequence channel select */
+# define ADCCON2_SCH_SHIFT     0
+# define ADCCON2_SCH_AIN0      (0 << 0)
+# define ADCCON2_SCH_AIN1      (1 << 0)
+# define ADCCON2_SCH_AIN2      (2 << 0)
+# define ADCCON2_SCH_AIN3      (3 << 0)
+# define ADCCON2_SCH_AIN4      (4 << 0)
+# define ADCCON2_SCH_AIN5      (5 << 0)
+# define ADCCON2_SCH_AIN6      (6 << 0)
+# define ADCCON2_SCH_AIN7      (7 << 0)
+# define ADCCON2_SCH_AIN0_AIN1 (8 << 0)
+# define ADCCON2_SCH_AIN2_AIN3 (9 << 0)
+# define ADCCON2_SCH_AIN4_AIN5 (0xa << 0)
+# define ADCCON2_SCH_AIN6_AIN7 (0xb << 0)
+# define ADCCON2_SCH_GND       (0xc << 0)
+# define ADCCON2_SCH_VREF      (0xd << 0)
+# define ADCCON2_SCH_TEMP      (0xe << 0)
+# define ADCCON2_SCH_VDD_3     (0xf << 0)
+
+
+/* ADC Control Register 3 */
+sfr at 0xB6 ADCCON3;
+
+# define ADCCON3_EREF_MASK     (3 << 6)        /* extra conversion reference */
+# define ADCCON3_EREF_1_25     (0 << 6)        /* internal 1.25V */
+# define ADCCON3_EREF_EXTERNAL (1 << 6)        /* external AIN7 cc1110 */
+# define ADCCON3_EREF_VDD      (2 << 6)        /* VDD on the AVDD pin */
+# define ADCCON3_EREF_EXTERNAL_DIFF (3 << 6)   /* external AIN6-7 cc1110 */
+# define ADCCON3_EDIV_MASK     (3 << 4)        /* extral decimation */
+# define ADCCON3_EDIV_64       (0 << 4)        /* 7 bits */
+# define ADCCON3_EDIV_128      (1 << 4)        /* 9 bits */
+# define ADCCON3_EDIV_256      (2 << 4)        /* 10 bits */
+# define ADCCON3_EDIV_512      (3 << 4)        /* 12 bits */
+# define ADCCON3_ECH_MASK      (0xf << 0)      /* Sequence channel select */
+# define ADCCON3_ECH_SHIFT     0
+# define ADCCON3_ECH_AIN0      (0 << 0)
+# define ADCCON3_ECH_AIN1      (1 << 0)
+# define ADCCON3_ECH_AIN2      (2 << 0)
+# define ADCCON3_ECH_AIN3      (3 << 0)
+# define ADCCON3_ECH_AIN4      (4 << 0)
+# define ADCCON3_ECH_AIN5      (5 << 0)
+# define ADCCON3_ECH_AIN6      (6 << 0)
+# define ADCCON3_ECH_AIN7      (7 << 0)
+# define ADCCON3_ECH_AIN0_AIN1 (8 << 0)
+# define ADCCON3_ECH_AIN2_AIN3 (9 << 0)
+# define ADCCON3_ECH_AIN4_AIN5 (0xa << 0)
+# define ADCCON3_ECH_AIN6_AIN7 (0xb << 0)
+# define ADCCON3_ECH_GND       (0xc << 0)
+# define ADCCON3_ECH_VREF      (0xd << 0)
+# define ADCCON3_ECH_TEMP      (0xe << 0)
+# define ADCCON3_ECH_VDD_3     (0xf << 0)
+
+/*
+ * ADC configuration register, this selects which
+ * GPIO pins are to be used as ADC inputs
+ */
+sfr at 0xF2 ADCCFG;
+
+/*
+ * Pin selectors, these set which pins are
+ * using their peripheral function
+ */
+sfr at 0xF3 P0SEL;
+sfr at 0xF4 P1SEL;
+sfr at 0xF5 P2SEL;
+
+#define P2SEL_PRI3P1_USART0            (0 << 6)
+#define P2SEL_PRI3P1_USART1            (1 << 6)
+#define P2SEL_PRI3P1_MASK              (1 << 6)
+#define P2SEL_PRI2P1_USART1            (0 << 5)
+#define P2SEL_PRI2P1_TIMER3            (1 << 5)
+#define P2SEL_PRI1P1_TIMER1            (0 << 4)
+#define P2SEL_PRI1P1_TIMER4            (1 << 4)
+#define P2SEL_PRI0P1_USART0            (0 << 3)
+#define P2SEL_PRI0P1_TIMER1            (1 << 3)
+#define P2SEL_SELP2_4_GPIO             (0 << 2)
+#define P2SEL_SELP2_4_PERIPHERAL       (1 << 2)
+#define P2SEL_SELP2_3_GPIO             (0 << 1)
+#define P2SEL_SELP2_3_PERIPHERAL       (1 << 1)
+#define P2SEL_SELP2_0_GPIO             (0 << 0)
+#define P2SEL_SELP2_0_PERIPHERAL       (1 << 0)
+#define P2SEL_SELP2_0_MASK             (1 << 0)
+
+/*
+ * For pins used as GPIOs, these set which are used as outputs
+ */
+sfr at 0xFD P0DIR;
+sfr at 0xFE P1DIR;
+sfr at 0xFF P2DIR;
+
+sfr at 0x8F P0INP;
+
+/* Select between tri-state and pull up/down
+ * for pins P0_0 - P0_7.
+ */
+#define P0INP_MDP0_7_PULL      (0 << 7)
+#define P0INP_MDP0_7_TRISTATE  (1 << 7)
+#define P0INP_MDP0_6_PULL      (0 << 6)
+#define P0INP_MDP0_6_TRISTATE  (1 << 6)
+#define P0INP_MDP0_5_PULL      (0 << 5)
+#define P0INP_MDP0_5_TRISTATE  (1 << 5)
+#define P0INP_MDP0_4_PULL      (0 << 4)
+#define P0INP_MDP0_4_TRISTATE  (1 << 4)
+#define P0INP_MDP0_3_PULL      (0 << 3)
+#define P0INP_MDP0_3_TRISTATE  (1 << 3)
+#define P0INP_MDP0_2_PULL      (0 << 2)
+#define P0INP_MDP0_2_TRISTATE  (1 << 2)
+#define P0INP_MDP0_1_PULL      (0 << 1)
+#define P0INP_MDP0_1_TRISTATE  (1 << 1)
+#define P0INP_MDP0_0_PULL      (0 << 0)
+#define P0INP_MDP0_0_TRISTATE  (1 << 0)
+
+sfr at 0xF6 P1INP;
+
+/* Select between tri-state and pull up/down
+ * for pins P1_2 - P1_7. Pins P1_0 and P1_1 are
+ * always tri-stated
+ */
+#define P1INP_MDP1_7_PULL      (0 << 7)
+#define P1INP_MDP1_7_TRISTATE  (1 << 7)
+#define P1INP_MDP1_6_PULL      (0 << 6)
+#define P1INP_MDP1_6_TRISTATE  (1 << 6)
+#define P1INP_MDP1_5_PULL      (0 << 5)
+#define P1INP_MDP1_5_TRISTATE  (1 << 5)
+#define P1INP_MDP1_4_PULL      (0 << 4)
+#define P1INP_MDP1_4_TRISTATE  (1 << 4)
+#define P1INP_MDP1_3_PULL      (0 << 3)
+#define P1INP_MDP1_3_TRISTATE  (1 << 3)
+#define P1INP_MDP1_2_PULL      (0 << 2)
+#define P1INP_MDP1_2_TRISTATE  (1 << 2)
+
+sfr at 0xF7 P2INP;
+/* P2INP has three extra bits which are used to choose
+ * between pull-up and pull-down when they are not tri-stated
+ */
+#define P2INP_PDUP2_PULL_UP    (0 << 7)
+#define P2INP_PDUP2_PULL_DOWN  (1 << 7)
+#define P2INP_PDUP1_PULL_UP    (0 << 6)
+#define P2INP_PDUP1_PULL_DOWN  (1 << 6)
+#define P2INP_PDUP0_PULL_UP    (0 << 5)
+#define P2INP_PDUP0_PULL_DOWN  (1 << 5)
+
+/* For the P2 pins, choose between tri-state and pull up/down
+ * mode
+ */
+#define P2INP_MDP2_4_PULL      (0 << 4)
+#define P2INP_MDP2_4_TRISTATE  (1 << 4)
+#define P2INP_MDP2_3_PULL      (0 << 3)
+#define P2INP_MDP2_3_TRISTATE  (1 << 3)
+#define P2INP_MDP2_2_PULL      (0 << 2)
+#define P2INP_MDP2_2_TRISTATE  (1 << 2)
+#define P2INP_MDP2_1_PULL      (0 << 1)
+#define P2INP_MDP2_1_TRISTATE  (1 << 1)
+#define P2INP_MDP2_0_PULL      (0 << 0)
+#define P2INP_MDP2_0_TRISTATE  (1 << 0)
+
+/* GPIO interrupt status flags */
+sfr at 0x89 P0IFG;
+sfr at 0x8A P1IFG;
+sfr at 0x8B P2IFG;
+
+#define P0IFG_USB_RESUME       (1 << 7)
+
+/* GPIO pins */
+sfr at 0x80 P0;
+
+sbit at 0x80 P0_0;
+sbit at 0x81 P0_1;
+sbit at 0x82 P0_2;
+sbit at 0x83 P0_3;
+sbit at 0x84 P0_4;
+sbit at 0x85 P0_5;
+sbit at 0x86 P0_6;
+sbit at 0x87 P0_7;
+
+sfr at 0x90 P1;
+
+sbit at 0x90 P1_0;
+sbit at 0x91 P1_1;
+sbit at 0x92 P1_2;
+sbit at 0x93 P1_3;
+sbit at 0x94 P1_4;
+sbit at 0x95 P1_5;
+sbit at 0x96 P1_6;
+sbit at 0x97 P1_7;
+
+sfr at 0xa0 P2;
+
+sbit at 0xa0 P2_0;
+sbit at 0xa1 P2_1;
+sbit at 0xa2 P2_2;
+sbit at 0xa3 P2_3;
+sbit at 0xa4 P2_4;
+sbit at 0xa5 P2_5;
+sbit at 0xa6 P2_6;
+sbit at 0xa7 P2_7;
+
+/* DMA controller */
+struct cc_dma_channel {
+       uint8_t src_high;
+       uint8_t src_low;
+       uint8_t dst_high;
+       uint8_t dst_low;
+       uint8_t len_high;
+       uint8_t len_low;
+       uint8_t cfg0;
+       uint8_t cfg1;
+};
+
+# define DMA_LEN_HIGH_VLEN_MASK                (7 << 5)
+# define DMA_LEN_HIGH_VLEN_LEN         (0 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_1      (1 << 5)
+# define DMA_LEN_HIGH_VLEN             (2 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_2      (3 << 5)
+# define DMA_LEN_HIGH_VLEN_PLUS_3      (4 << 5)
+# define DMA_LEN_HIGH_MASK             (0x1f)
+
+# define DMA_CFG0_WORDSIZE_8           (0 << 7)
+# define DMA_CFG0_WORDSIZE_16          (1 << 7)
+# define DMA_CFG0_TMODE_MASK           (3 << 5)
+# define DMA_CFG0_TMODE_SINGLE         (0 << 5)
+# define DMA_CFG0_TMODE_BLOCK          (1 << 5)
+# define DMA_CFG0_TMODE_REPEATED_SINGLE        (2 << 5)
+# define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5)
+
+/*
+ * DMA triggers
+ */
+# define DMA_CFG0_TRIGGER_NONE         0
+# define DMA_CFG0_TRIGGER_PREV         1
+# define DMA_CFG0_TRIGGER_T1_CH0       2
+# define DMA_CFG0_TRIGGER_T1_CH1       3
+# define DMA_CFG0_TRIGGER_T1_CH2       4
+# define DMA_CFG0_TRIGGER_T2_OVFL      6
+# define DMA_CFG0_TRIGGER_T3_CH0       7
+# define DMA_CFG0_TRIGGER_T3_CH1       8
+# define DMA_CFG0_TRIGGER_T4_CH0       9
+# define DMA_CFG0_TRIGGER_T4_CH1       10
+# define DMA_CFG0_TRIGGER_IOC_0                12
+# define DMA_CFG0_TRIGGER_IOC_1                13
+# define DMA_CFG0_TRIGGER_URX0         14
+# define DMA_CFG0_TRIGGER_UTX0         15
+# define DMA_CFG0_TRIGGER_URX1         16
+# define DMA_CFG0_TRIGGER_UTX1         17
+# define DMA_CFG0_TRIGGER_FLASH                18
+# define DMA_CFG0_TRIGGER_RADIO                19
+# define DMA_CFG0_TRIGGER_ADC_CHALL    20
+# define DMA_CFG0_TRIGGER_ADC_CH0      21
+# define DMA_CFG0_TRIGGER_ADC_CH1      22
+# define DMA_CFG0_TRIGGER_ADC_CH2      23
+# define DMA_CFG0_TRIGGER_ADC_CH3      24
+# define DMA_CFG0_TRIGGER_ADC_CH4      25
+# define DMA_CFG0_TRIGGER_ADC_CH5      26
+# define DMA_CFG0_TRIGGER_ADC_CH6      27
+# define DMA_CFG0_TRIGGER_I2SRX                27
+# define DMA_CFG0_TRIGGER_ADC_CH7      28
+# define DMA_CFG0_TRIGGER_I2STX                28
+# define DMA_CFG0_TRIGGER_ENC_DW       29
+# define DMA_CFG0_TRIGGER_DNC_UP       30
+
+# define DMA_CFG1_SRCINC_MASK          (3 << 6)
+# define DMA_CFG1_SRCINC_0             (0 << 6)
+# define DMA_CFG1_SRCINC_1             (1 << 6)
+# define DMA_CFG1_SRCINC_2             (2 << 6)
+# define DMA_CFG1_SRCINC_MINUS_1       (3 << 6)
+
+# define DMA_CFG1_DESTINC_MASK         (3 << 4)
+# define DMA_CFG1_DESTINC_0            (0 << 4)
+# define DMA_CFG1_DESTINC_1            (1 << 4)
+# define DMA_CFG1_DESTINC_2            (2 << 4)
+# define DMA_CFG1_DESTINC_MINUS_1      (3 << 4)
+
+# define DMA_CFG1_IRQMASK              (1 << 3)
+# define DMA_CFG1_M8                   (1 << 2)
+
+# define DMA_CFG1_PRIORITY_MASK                (3 << 0)
+# define DMA_CFG1_PRIORITY_LOW         (0 << 0)
+# define DMA_CFG1_PRIORITY_NORMAL      (1 << 0)
+# define DMA_CFG1_PRIORITY_HIGH                (2 << 0)
+
+/*
+ * DMAARM - DMA Channel Arm
+ */
+
+sfr at 0xD6 DMAARM;
+
+# define DMAARM_ABORT                  (1 << 7)
+# define DMAARM_DMAARM4                        (1 << 4)
+# define DMAARM_DMAARM3                        (1 << 3)
+# define DMAARM_DMAARM2                        (1 << 2)
+# define DMAARM_DMAARM1                        (1 << 1)
+# define DMAARM_DMAARM0                        (1 << 0)
+
+/*
+ * DMAREQ - DMA Channel Start Request and Status
+ */
+
+sfr at 0xD7 DMAREQ;
+
+# define DMAREQ_DMAREQ4                        (1 << 4)
+# define DMAREQ_DMAREQ3                        (1 << 3)
+# define DMAREQ_DMAREQ2                        (1 << 2)
+# define DMAREQ_DMAREQ1                        (1 << 1)
+# define DMAREQ_DMAREQ0                        (1 << 0)
+
+/*
+ * DMA configuration 0 address
+ */
+
+sfr at 0xD5 DMA0CFGH;
+sfr at 0xD4 DMA0CFGL;
+
+/*
+ * DMA configuration 1-4 address
+ */
+
+sfr at 0xD3 DMA1CFGH;
+sfr at 0xD2 DMA1CFGL;
+
+/*
+ * DMAIRQ - DMA Interrupt Flag
+ */
+
+sfr at 0xD1 DMAIRQ;
+
+# define DMAIRQ_DMAIF4                 (1 << 4)
+# define DMAIRQ_DMAIF3                 (1 << 3)
+# define DMAIRQ_DMAIF2                 (1 << 2)
+# define DMAIRQ_DMAIF1                 (1 << 1)
+# define DMAIRQ_DMAIF0                 (1 << 0)
+
+/*
+ * UART registers
+ */
+
+/* USART config/status registers */
+sfr at 0x86 U0CSR;
+sfr at 0xF8 U1CSR;
+
+# define UxCSR_MODE_UART               (1 << 7)
+# define UxCSR_MODE_SPI                        (0 << 7)
+# define UxCSR_RE                      (1 << 6)
+# define UxCSR_SLAVE                   (1 << 5)
+# define UxCSR_MASTER                  (0 << 5)
+# define UxCSR_FE                      (1 << 4)
+# define UxCSR_ERR                     (1 << 3)
+# define UxCSR_RX_BYTE                 (1 << 2)
+# define UxCSR_TX_BYTE                 (1 << 1)
+# define UxCSR_ACTIVE                  (1 << 0)
+
+/* UART configuration registers */
+sfr at 0xc4 U0UCR;
+sfr at 0xfb U1UCR;
+
+# define UxUCR_FLUSH                    (1 << 7)
+# define UxUCR_FLOW_DISABLE             (0 << 6)
+# define UxUCR_FLOW_ENABLE              (1 << 6)
+# define UxUCR_D9_EVEN_PARITY           (0 << 5)
+# define UxUCR_D9_ODD_PARITY            (1 << 5)
+# define UxUCR_BIT9_8_BITS              (0 << 4)
+# define UxUCR_BIT9_9_BITS              (1 << 4)
+# define UxUCR_PARITY_DISABLE           (0 << 3)
+# define UxUCR_PARITY_ENABLE            (1 << 3)
+# define UxUCR_SPB_1_STOP_BIT           (0 << 2)
+# define UxUCR_SPB_2_STOP_BITS          (1 << 2)
+# define UxUCR_STOP_LOW                 (0 << 1)
+# define UxUCR_STOP_HIGH                (1 << 1)
+# define UxUCR_START_LOW                (0 << 0)
+# define UxUCR_START_HIGH               (1 << 0)
+
+/* USART General configuration registers (mostly SPI) */
+sfr at 0xc5 U0GCR;
+sfr at 0xfc U1GCR;
+
+# define UxGCR_CPOL_NEGATIVE           (0 << 7)
+# define UxGCR_CPOL_POSITIVE           (1 << 7)
+# define UxGCR_CPHA_FIRST_EDGE         (0 << 6)
+# define UxGCR_CPHA_SECOND_EDGE                (1 << 6)
+# define UxGCR_ORDER_LSB               (0 << 5)
+# define UxGCR_ORDER_MSB               (1 << 5)
+# define UxGCR_BAUD_E_MASK             (0x1f)
+# define UxGCR_BAUD_E_SHIFT            0
+
+/* USART data registers */
+sfr at 0xc1 U0DBUF;
+__xdata __at (0xDFC1) volatile uint8_t U0DBUFXADDR;
+sfr at 0xf9 U1DBUF;
+__xdata __at (0xDFF9) volatile uint8_t U1DBUFXADDR;
+
+/* USART baud rate registers, M value */
+sfr at 0xc2 U0BAUD;
+sfr at 0xfa U1BAUD;
+
+/* Radio */
+
+sfr at 0xD9 RFD;
+__xdata at (0xDFD9) volatile uint8_t RFDXADDR;
+
+sfr at 0xE9 RFIF;
+#define RFIF_IM_TXUNF  (1 << 7)
+#define RFIF_IM_RXOVF  (1 << 6)
+#define RFIF_IM_TIMEOUT        (1 << 5)
+#define RFIF_IM_DONE   (1 << 4)
+#define RFIF_IM_CS     (1 << 3)
+#define RFIF_IM_PQT    (1 << 2)
+#define RFIF_IM_CCA    (1 << 1)
+#define RFIF_IM_SFD    (1 << 0)
+
+sfr at 0xE1 RFST;
+
+#define RFST_SFSTXON   0x00
+#define RFST_SCAL      0x01
+#define RFST_SRX       0x02
+#define RFST_STX       0x03
+#define RFST_SIDLE     0x04
+
+__xdata __at (0xdf00) uint8_t RF[0x3c];
+
+__xdata __at (0xdf2f) uint8_t RF_IOCFG2;
+#define RF_IOCFG2_OFF  0x2f
+
+__xdata __at (0xdf30) uint8_t RF_IOCFG1;
+#define RF_IOCFG1_OFF  0x30
+
+__xdata __at (0xdf31) uint8_t RF_IOCFG0;
+#define RF_IOCFG0_OFF  0x31
+
+__xdata __at (0xdf00) uint8_t RF_SYNC1;
+#define RF_SYNC1_OFF   0x00
+
+__xdata __at (0xdf01) uint8_t RF_SYNC0;
+#define RF_SYNC0_OFF   0x01
+
+__xdata __at (0xdf02) uint8_t RF_PKTLEN;
+#define RF_PKTLEN_OFF  0x02
+
+__xdata __at (0xdf03) uint8_t RF_PKTCTRL1;
+#define RF_PKTCTRL1_OFF        0x03
+#define PKTCTRL1_PQT_MASK                      (0x7 << 5)
+#define PKTCTRL1_PQT_SHIFT                     5
+#define PKTCTRL1_APPEND_STATUS                 (1 << 2)
+#define PKTCTRL1_ADR_CHK_NONE                  (0 << 0)
+#define PKTCTRL1_ADR_CHK_NO_BROADCAST          (1 << 0)
+#define PKTCTRL1_ADR_CHK_00_BROADCAST          (2 << 0)
+#define PKTCTRL1_ADR_CHK_00_FF_BROADCAST       (3 << 0)
+
+/* If APPEND_STATUS is used, two bytes will be added to the packet data */
+#define PKT_APPEND_STATUS_0_RSSI_MASK          (0xff)
+#define PKT_APPEND_STATUS_0_RSSI_SHIFT         0
+#define PKT_APPEND_STATUS_1_CRC_OK             (1 << 7)
+#define PKT_APPEND_STATUS_1_LQI_MASK           (0x7f)
+#define PKT_APPEND_STATUS_1_LQI_SHIFT          0
+
+__xdata __at (0xdf04) uint8_t RF_PKTCTRL0;
+#define RF_PKTCTRL0_OFF        0x04
+#define RF_PKTCTRL0_WHITE_DATA                 (1 << 6)
+#define RF_PKTCTRL0_PKT_FORMAT_NORMAL          (0 << 4)
+#define RF_PKTCTRL0_PKT_FORMAT_RANDOM          (2 << 4)
+#define RF_PKTCTRL0_CRC_EN                     (1 << 2)
+#define RF_PKTCTRL0_LENGTH_CONFIG_FIXED                (0 << 0)
+#define RF_PKTCTRL0_LENGTH_CONFIG_VARIABLE     (1 << 0)
+
+__xdata __at (0xdf05) uint8_t RF_ADDR;
+#define RF_ADDR_OFF    0x05
+
+__xdata __at (0xdf06) uint8_t RF_CHANNR;
+#define RF_CHANNR_OFF  0x06
+
+__xdata __at (0xdf07) uint8_t RF_FSCTRL1;
+#define RF_FSCTRL1_OFF 0x07
+
+#define RF_FSCTRL1_FREQ_IF_SHIFT       (0)
+
+__xdata __at (0xdf08) uint8_t RF_FSCTRL0;
+#define RF_FSCTRL0_OFF 0x08
+
+#define RF_FSCTRL0_FREQOFF_SHIFT       (0)
+
+__xdata __at (0xdf09) uint8_t RF_FREQ2;
+#define RF_FREQ2_OFF   0x09
+
+__xdata __at (0xdf0a) uint8_t RF_FREQ1;
+#define RF_FREQ1_OFF   0x0a
+
+__xdata __at (0xdf0b) uint8_t RF_FREQ0;
+#define RF_FREQ0_OFF   0x0b
+
+__xdata __at (0xdf0c) uint8_t RF_MDMCFG4;
+#define RF_MDMCFG4_OFF 0x0c
+
+#define RF_MDMCFG4_CHANBW_E_SHIFT      6
+#define RF_MDMCFG4_CHANBW_M_SHIFT      4
+#define RF_MDMCFG4_DRATE_E_SHIFT       0
+
+__xdata __at (0xdf0d) uint8_t RF_MDMCFG3;
+#define RF_MDMCFG3_OFF 0x0d
+
+#define RF_MDMCFG3_DRATE_M_SHIFT       0
+
+__xdata __at (0xdf0e) uint8_t RF_MDMCFG2;
+#define RF_MDMCFG2_OFF 0x0e
+
+#define RF_MDMCFG2_DEM_DCFILT_OFF      (1 << 7)
+#define RF_MDMCFG2_DEM_DCFILT_ON       (0 << 7)
+
+#define RF_MDMCFG2_MOD_FORMAT_MASK     (7 << 4)
+#define RF_MDMCFG2_MOD_FORMAT_2_FSK    (0 << 4)
+#define RF_MDMCFG2_MOD_FORMAT_GFSK     (1 << 4)
+#define RF_MDMCFG2_MOD_FORMAT_ASK_OOK  (3 << 4)
+#define RF_MDMCFG2_MOD_FORMAT_MSK      (7 << 4)
+
+#define RF_MDMCFG2_MANCHESTER_EN       (1 << 3)
+
+#define RF_MDMCFG2_SYNC_MODE_MASK              (0x7 << 0)
+#define RF_MDMCFG2_SYNC_MODE_NONE              (0x0 << 0)
+#define RF_MDMCFG2_SYNC_MODE_15_16             (0x1 << 0)
+#define RF_MDMCFG2_SYNC_MODE_16_16             (0x2 << 0)
+#define RF_MDMCFG2_SYNC_MODE_30_32             (0x3 << 0)
+#define RF_MDMCFG2_SYNC_MODE_NONE_THRES                (0x4 << 0)
+#define RF_MDMCFG2_SYNC_MODE_15_16_THRES       (0x5 << 0)
+#define RF_MDMCFG2_SYNC_MODE_16_16_THRES       (0x6 << 0)
+#define RF_MDMCFG2_SYNC_MODE_30_32_THRES       (0x7 << 0)
+
+__xdata __at (0xdf0f) uint8_t RF_MDMCFG1;
+#define RF_MDMCFG1_OFF 0x0f
+
+#define RF_MDMCFG1_FEC_EN                      (1 << 7)
+#define RF_MDMCFG1_FEC_DIS                     (0 << 7)
+
+#define RF_MDMCFG1_NUM_PREAMBLE_MASK           (7 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_2              (0 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_3              (1 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_4              (2 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_6              (3 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_8              (4 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_12             (5 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_16             (6 << 4)
+#define RF_MDMCFG1_NUM_PREAMBLE_24             (7 << 4)
+
+#define RF_MDMCFG1_CHANSPC_E_MASK              (3 << 0)
+#define RF_MDMCFG1_CHANSPC_E_SHIFT             (0)
+
+__xdata __at (0xdf10) uint8_t RF_MDMCFG0;
+#define RF_MDMCFG0_OFF 0x10
+
+#define RF_MDMCFG0_CHANSPC_M_SHIFT             (0)
+
+__xdata __at (0xdf11) uint8_t RF_DEVIATN;
+#define RF_DEVIATN_OFF 0x11
+
+#define RF_DEVIATN_DEVIATION_E_SHIFT           4
+#define RF_DEVIATN_DEVIATION_M_SHIFT           0
+
+__xdata __at (0xdf12) uint8_t RF_MCSM2;
+#define RF_MCSM2_OFF   0x12
+#define RF_MCSM2_RX_TIME_RSSI                  (1 << 4)
+#define RF_MCSM2_RX_TIME_QUAL                  (1 << 3)
+#define RF_MCSM2_RX_TIME_MASK                  (0x7)
+#define RF_MCSM2_RX_TIME_SHIFT                 0
+#define RF_MCSM2_RX_TIME_END_OF_PACKET         (7)
+
+__xdata __at (0xdf13) uint8_t RF_MCSM1;
+#define RF_MCSM1_OFF   0x13
+#define RF_MCSM1_CCA_MODE_ALWAYS                       (0 << 4)
+#define RF_MCSM1_CCA_MODE_RSSI_BELOW                   (1 << 4)
+#define RF_MCSM1_CCA_MODE_UNLESS_RECEIVING             (2 << 4)
+#define RF_MCSM1_CCA_MODE_RSSI_BELOW_UNLESS_RECEIVING  (3 << 4)
+#define RF_MCSM1_RXOFF_MODE_IDLE                       (0 << 2)
+#define RF_MCSM1_RXOFF_MODE_FSTXON                     (1 << 2)
+#define RF_MCSM1_RXOFF_MODE_TX                         (2 << 2)
+#define RF_MCSM1_RXOFF_MODE_RX                         (3 << 2)
+#define RF_MCSM1_TXOFF_MODE_IDLE                       (0 << 0)
+#define RF_MCSM1_TXOFF_MODE_FSTXON                     (1 << 0)
+#define RF_MCSM1_TXOFF_MODE_TX                         (2 << 0)
+#define RF_MCSM1_TXOFF_MODE_RX                         (3 << 0)
+
+__xdata __at (0xdf14) uint8_t RF_MCSM0;
+#define RF_MCSM0_OFF   0x14
+#define RF_MCSM0_FS_AUTOCAL_NEVER              (0 << 4)
+#define RF_MCSM0_FS_AUTOCAL_FROM_IDLE          (1 << 4)
+#define RF_MCSM0_FS_AUTOCAL_TO_IDLE            (2 << 4)
+#define RF_MCSM0_FS_AUTOCAL_TO_IDLE_EVERY_4    (3 << 4)
+#define RF_MCSM0_MAGIC_3                       (1 << 3)
+#define RF_MCSM0_MAGIC_2                       (1 << 2)
+#define RF_MCSM0_CLOSE_IN_RX_0DB               (0 << 0)
+#define RF_MCSM0_CLOSE_IN_RX_6DB               (1 << 0)
+#define RF_MCSM0_CLOSE_IN_RX_12DB              (2 << 0)
+#define RF_MCSM0_CLOSE_IN_RX_18DB              (3 << 0)
+
+__xdata __at (0xdf15) uint8_t RF_FOCCFG;
+#define RF_FOCCFG_OFF  0x15
+#define RF_FOCCFG_FOC_BS_CS_GATE               (1 << 5)
+#define RF_FOCCFG_FOC_PRE_K_1K                 (0 << 3)
+#define RF_FOCCFG_FOC_PRE_K_2K                 (1 << 3)
+#define RF_FOCCFG_FOC_PRE_K_3K                 (2 << 3)
+#define RF_FOCCFG_FOC_PRE_K_4K                 (3 << 3)
+#define RF_FOCCFG_FOC_POST_K_PRE_K             (0 << 2)
+#define RF_FOCCFG_FOC_POST_K_PRE_K_OVER_2      (1 << 2)
+#define RF_FOCCFG_FOC_LIMIT_0                  (0 << 0)
+#define RF_FOCCFG_FOC_LIMIT_BW_OVER_8          (1 << 0)
+#define RF_FOCCFG_FOC_LIMIT_BW_OVER_4          (2 << 0)
+#define RF_FOCCFG_FOC_LIMIT_BW_OVER_2          (3 << 0)
+
+__xdata __at (0xdf16) uint8_t RF_BSCFG;
+#define RF_BSCFG_OFF   0x16
+#define RF_BSCFG_BS_PRE_K_1K                   (0 << 6)
+#define RF_BSCFG_BS_PRE_K_2K                   (1 << 6)
+#define RF_BSCFG_BS_PRE_K_3K                   (2 << 6)
+#define RF_BSCFG_BS_PRE_K_4K                   (3 << 6)
+#define RF_BSCFG_BS_PRE_KP_1KP                 (0 << 4)
+#define RF_BSCFG_BS_PRE_KP_2KP                 (1 << 4)
+#define RF_BSCFG_BS_PRE_KP_3KP                 (2 << 4)
+#define RF_BSCFG_BS_PRE_KP_4KP                 (3 << 4)
+#define RF_BSCFG_BS_POST_KI_PRE_KI             (0 << 3)
+#define RF_BSCFG_BS_POST_KI_PRE_KI_OVER_2      (1 << 3)
+#define RF_BSCFG_BS_POST_KP_PRE_KP             (0 << 2)
+#define RF_BSCFG_BS_POST_KP_PRE_KP_OVER_2      (1 << 2)
+#define RF_BSCFG_BS_LIMIT_0                    (0 << 0)
+#define RF_BSCFG_BS_LIMIT_3_125                        (1 << 0)
+#define RF_BSCFG_BS_LIMIT_6_25                 (2 << 0)
+#define RF_BSCFG_BS_LIMIT_12_5                 (3 << 0)
+
+__xdata __at (0xdf17) uint8_t RF_AGCCTRL2;
+#define RF_AGCCTRL2_OFF        0x17
+
+__xdata __at (0xdf18) uint8_t RF_AGCCTRL1;
+#define RF_AGCCTRL1_OFF        0x18
+
+__xdata __at (0xdf19) uint8_t RF_AGCCTRL0;
+#define RF_AGCCTRL0_OFF        0x19
+
+__xdata __at (0xdf1a) uint8_t RF_FREND1;
+#define RF_FREND1_OFF  0x1a
+
+#define RF_FREND1_LNA_CURRENT_SHIFT            6
+#define RF_FREND1_LNA2MIX_CURRENT_SHIFT                4
+#define RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT   2
+#define RF_FREND1_MIX_CURRENT_SHIFT            0
+
+__xdata __at (0xdf1b) uint8_t RF_FREND0;
+#define RF_FREND0_OFF  0x1b
+
+#define RF_FREND0_LODIV_BUF_CURRENT_TX_MASK    (0x3 << 4)
+#define RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT   4
+#define RF_FREND0_PA_POWER_MASK                        (0x7)
+#define RF_FREND0_PA_POWER_SHIFT               0
+
+__xdata __at (0xdf1c) uint8_t RF_FSCAL3;
+#define RF_FSCAL3_OFF  0x1c
+
+__xdata __at (0xdf1d) uint8_t RF_FSCAL2;
+#define RF_FSCAL2_OFF  0x1d
+
+__xdata __at (0xdf1e) uint8_t RF_FSCAL1;
+#define RF_FSCAL1_OFF  0x1e
+
+__xdata __at (0xdf1f) uint8_t RF_FSCAL0;
+#define RF_FSCAL0_OFF  0x1f
+
+__xdata __at (0xdf23) uint8_t RF_TEST2;
+#define RF_TEST2_OFF   0x23
+
+#define RF_TEST2_NORMAL_MAGIC          0x88
+#define RF_TEST2_RX_LOW_DATA_RATE_MAGIC        0x81
+
+__xdata __at (0xdf24) uint8_t RF_TEST1;
+#define RF_TEST1_OFF   0x24
+
+#define RF_TEST1_TX_MAGIC              0x31
+#define RF_TEST1_RX_LOW_DATA_RATE_MAGIC        0x35
+
+__xdata __at (0xdf25) uint8_t RF_TEST0;
+#define RF_TEST0_OFF   0x25
+
+#define RF_TEST0_7_2_MASK              (0xfc)
+#define RF_TEST0_VCO_SEL_CAL_EN                (1 << 1)
+#define RF_TEST0_0_MASK                        (1)
+
+/* These are undocumented, and must be computed
+ * using the provided tool.
+ */
+__xdata __at (0xdf27) uint8_t RF_PA_TABLE7;
+#define RF_PA_TABLE7_OFF       0x27
+
+__xdata __at (0xdf28) uint8_t RF_PA_TABLE6;
+#define RF_PA_TABLE6_OFF       0x28
+
+__xdata __at (0xdf29) uint8_t RF_PA_TABLE5;
+#define RF_PA_TABLE5_OFF       0x29
+
+__xdata __at (0xdf2a) uint8_t RF_PA_TABLE4;
+#define RF_PA_TABLE4_OFF       0x2a
+
+__xdata __at (0xdf2b) uint8_t RF_PA_TABLE3;
+#define RF_PA_TABLE3_OFF       0x2b
+
+__xdata __at (0xdf2c) uint8_t RF_PA_TABLE2;
+#define RF_PA_TABLE2_OFF       0x2c
+
+__xdata __at (0xdf2d) uint8_t RF_PA_TABLE1;
+#define RF_PA_TABLE1_OFF       0x2d
+
+__xdata __at (0xdf2e) uint8_t RF_PA_TABLE0;
+#define RF_PA_TABLE0_OFF       0x2e
+
+__xdata __at (0xdf36) uint8_t RF_PARTNUM;
+#define RF_PARTNUM_OFF 0x36
+
+__xdata __at (0xdf37) uint8_t RF_VERSION;
+#define RF_VERSION_OFF 0x37
+
+__xdata __at (0xdf38) uint8_t RF_FREQEST;
+#define RF_FREQEST_OFF 0x38
+
+__xdata __at (0xdf39) uint8_t RF_LQI;
+#define RF_LQI_OFF     0x39
+
+#define RF_LQI_CRC_OK                  (1 << 7)
+#define RF_LQI_LQI_EST_MASK            (0x7f)
+
+__xdata __at (0xdf3a) uint8_t RF_RSSI;
+#define RF_RSSI_OFF    0x3a
+
+__xdata __at (0xdf3b) uint8_t RF_MARCSTATE;
+#define RF_MARCSTATE_OFF       0x3b
+
+#define RF_MARCSTATE_MASK              0x1f
+#define RF_MARCSTATE_SLEEP             0x00
+#define RF_MARCSTATE_IDLE              0x01
+#define RF_MARCSTATE_VCOON_MC          0x03
+#define RF_MARCSTATE_REGON_MC          0x04
+#define RF_MARCSTATE_MANCAL            0x05
+#define RF_MARCSTATE_VCOON             0x06
+#define RF_MARCSTATE_REGON             0x07
+#define RF_MARCSTATE_STARTCAL          0x08
+#define RF_MARCSTATE_BWBOOST           0x09
+#define RF_MARCSTATE_FS_LOCK           0x0a
+#define RF_MARCSTATE_IFADCON           0x0b
+#define RF_MARCSTATE_ENDCAL            0x0c
+#define RF_MARCSTATE_RX                        0x0d
+#define RF_MARCSTATE_RX_END            0x0e
+#define RF_MARCSTATE_RX_RST            0x0f
+#define RF_MARCSTATE_TXRX_SWITCH       0x10
+#define RF_MARCSTATE_RX_OVERFLOW       0x11
+#define RF_MARCSTATE_FSTXON            0x12
+#define RF_MARCSTATE_TX                        0x13
+#define RF_MARCSTATE_TX_END            0x14
+#define RF_MARCSTATE_RXTX_SWITCH       0x15
+#define RF_MARCSTATE_TX_UNDERFLOW      0x16
+
+
+__xdata __at (0xdf3c) uint8_t RF_PKTSTATUS;
+#define RF_PKTSTATUS_OFF       0x3c
+
+#define RF_PKTSTATUS_CRC_OK            (1 << 7)
+#define RF_PKTSTATUS_CS                        (1 << 6)
+#define RF_PKTSTATUS_PQT_REACHED       (1 << 5)
+#define RF_PKTSTATUS_CCA               (1 << 4)
+#define RF_PKTSTATUS_SFD               (1 << 3)
+
+__xdata __at (0xdf3d) uint8_t RF_VCO_VC_DAC;
+#define RF_VCO_VC_DAC_OFF      0x3d
+
+#endif
diff --git a/src/check-stack b/src/check-stack
new file mode 100755 (executable)
index 0000000..82680b8
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+HEADER=$1
+MEM=$2
+
+HEADER_STACK=`awk '/#define AO_STACK_START/ {print $3}' $HEADER | nickle`
+MEM_STACK=`awk '/Stack starts at/ {print $4}' $MEM | nickle`
+
+if [ "$HEADER_STACK" -lt "$MEM_STACK" ]; then
+       MIN=0x`nickle -e "$MEM_STACK # 16"`
+       echo "Set AO_STACK_START to at least $MIN"
+       exit 1
+else
+       exit 0
+fi
diff --git a/src/gps-cksum b/src/gps-cksum
new file mode 100755 (executable)
index 0000000..a08153b
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/env nickle
+
+int checksum(string a)
+{
+       int     c = 0;
+       for (int i = 0; i < String::length(a); i++)
+               c ^= a[i];
+       return c;
+}
+
+void main()
+{
+       for (int i = 1; i < dim(argv); i++)
+               printf ("$%s*%02x\n", argv[i], checksum(argv[i]));
+}
+
+main();
diff --git a/src/make-altitude b/src/make-altitude
new file mode 100644 (file)
index 0000000..ac04e84
--- /dev/null
@@ -0,0 +1,192 @@
+#!/usr/bin/nickle -f
+/*
+ * Pressure Sensor Model, version 1.1
+ *
+ * written by Holly Grimes
+ *
+ * Uses the International Standard Atmosphere as described in
+ *   "A Quick Derivation relating altitude to air pressure" (version 1.03)
+ *    from the Portland State Aerospace Society, except that the atmosphere
+ *    is divided into layers with each layer having a different lapse rate.
+ *
+ * Lapse rate data for each layer was obtained from Wikipedia on Sept. 1, 2007
+ *    at site <http://en.wikipedia.org/wiki/International_Standard_Atmosphere
+ *
+ * Height measurements use the local tangent plane.  The postive z-direction is up.
+ *
+ * All measurements are given in SI units (Kelvin, Pascal, meter, meters/second^2).
+ *   The lapse rate is given in Kelvin/meter, the gas constant for air is given
+ *   in Joules/(kilogram-Kelvin).
+ */
+
+const real GRAVITATIONAL_ACCELERATION = -9.80665;
+const real AIR_GAS_CONSTANT = 287.053;
+const int NUMBER_OF_LAYERS = 7;
+const real MAXIMUM_ALTITUDE = 84852;
+const real MINIMUM_PRESSURE = 0.3734;
+const real LAYER0_BASE_TEMPERATURE = 288.15;
+const real LAYER0_BASE_PRESSURE = 101325;
+
+/* lapse rate and base altitude for each layer in the atmosphere */
+const real[NUMBER_OF_LAYERS] lapse_rate = {
+       -0.0065, 0.0, 0.001, 0.0028, 0.0, -0.0028, -0.002
+};
+const int[NUMBER_OF_LAYERS] base_altitude = {
+       0, 11000, 20000, 32000, 47000, 51000, 71000
+};
+
+
+/* outputs atmospheric pressure associated with the given altitude. altitudes
+   are measured with respect to the mean sea level */
+real altitude_to_pressure(real altitude) {
+
+   real base_temperature = LAYER0_BASE_TEMPERATURE;
+   real base_pressure = LAYER0_BASE_PRESSURE;
+
+   real pressure;
+   real base; /* base for function to determine pressure */
+   real exponent; /* exponent for function to determine pressure */
+   int layer_number; /* identifies layer in the atmosphere */
+   int delta_z; /* difference between two altitudes */
+
+   if (altitude > MAXIMUM_ALTITUDE) /* FIX ME: use sensor data to improve model */
+      return 0;
+
+   /* calculate the base temperature and pressure for the atmospheric layer
+      associated with the inputted altitude */
+   for(layer_number = 0; layer_number < NUMBER_OF_LAYERS - 1 && altitude > base_altitude[layer_number + 1]; layer_number++) {
+      delta_z = base_altitude[layer_number + 1] - base_altitude[layer_number];
+      if (lapse_rate[layer_number] == 0.0) {
+         exponent = GRAVITATIONAL_ACCELERATION * delta_z
+              / AIR_GAS_CONSTANT / base_temperature;
+         base_pressure *= exp(exponent);
+      }
+      else {
+         base = (lapse_rate[layer_number] * delta_z / base_temperature) + 1.0;
+         exponent = GRAVITATIONAL_ACCELERATION /
+              (AIR_GAS_CONSTANT * lapse_rate[layer_number]);
+         base_pressure *= pow(base, exponent);
+      }
+      base_temperature += delta_z * lapse_rate[layer_number];
+   }
+
+   /* calculate the pressure at the inputted altitude */
+   delta_z = altitude - base_altitude[layer_number];
+   if (lapse_rate[layer_number] == 0.0) {
+      exponent = GRAVITATIONAL_ACCELERATION * delta_z
+           / AIR_GAS_CONSTANT / base_temperature;
+      pressure = base_pressure * exp(exponent);
+   }
+   else {
+      base = (lapse_rate[layer_number] * delta_z / base_temperature) + 1.0;
+      exponent = GRAVITATIONAL_ACCELERATION /
+           (AIR_GAS_CONSTANT * lapse_rate[layer_number]);
+      pressure = base_pressure * pow(base, exponent);
+   }
+
+   return pressure;
+}
+
+
+/* outputs the altitude associated with the given pressure. the altitude
+   returned is measured with respect to the mean sea level */
+real pressure_to_altitude(real pressure) {
+
+   real next_base_temperature = LAYER0_BASE_TEMPERATURE;
+   real next_base_pressure = LAYER0_BASE_PRESSURE;
+
+   real altitude;
+   real base_pressure;
+   real base_temperature;
+   real base; /* base for function to determine base pressure of next layer */
+   real exponent; /* exponent for function to determine base pressure
+                             of next layer */
+   real coefficient;
+   int layer_number; /* identifies layer in the atmosphere */
+   int delta_z; /* difference between two altitudes */
+
+   if (pressure < 0)  /* illegal pressure */
+      return -1;
+   if (pressure < MINIMUM_PRESSURE) /* FIX ME: use sensor data to improve model */
+      return MAXIMUM_ALTITUDE;
+
+   /* calculate the base temperature and pressure for the atmospheric layer
+      associated with the inputted pressure. */
+   layer_number = -1;
+   do {
+      layer_number++;
+      base_pressure = next_base_pressure;
+      base_temperature = next_base_temperature;
+      delta_z = base_altitude[layer_number + 1] - base_altitude[layer_number];
+      if (lapse_rate[layer_number] == 0.0) {
+         exponent = GRAVITATIONAL_ACCELERATION * delta_z
+              / AIR_GAS_CONSTANT / base_temperature;
+         next_base_pressure *= exp(exponent);
+      }
+      else {
+         base = (lapse_rate[layer_number] * delta_z / base_temperature) + 1.0;
+         exponent = GRAVITATIONAL_ACCELERATION /
+              (AIR_GAS_CONSTANT * lapse_rate[layer_number]);
+         next_base_pressure *= pow(base, exponent);
+      }
+      next_base_temperature += delta_z * lapse_rate[layer_number];
+   }
+   while(layer_number < NUMBER_OF_LAYERS - 1 && pressure < next_base_pressure);
+
+   /* calculate the altitude associated with the inputted pressure */
+   if (lapse_rate[layer_number] == 0.0) {
+      coefficient = (AIR_GAS_CONSTANT / GRAVITATIONAL_ACCELERATION)
+                                                    * base_temperature;
+      altitude = base_altitude[layer_number]
+                    + coefficient * log(pressure / base_pressure);
+   }
+   else {
+      base = pressure / base_pressure;
+      exponent = AIR_GAS_CONSTANT * lapse_rate[layer_number]
+                                       / GRAVITATIONAL_ACCELERATION;
+      coefficient = base_temperature / lapse_rate[layer_number];
+      altitude = base_altitude[layer_number]
+                      + coefficient * (pow(base, exponent) - 1);
+   }
+
+   return altitude;
+}
+
+real feet_to_meters(real feet)
+{
+    return feet * (12 * 2.54 / 100);
+}
+
+real meters_to_feet(real meters)
+{
+    return meters / (12 * 2.54 / 100);
+}
+
+/*
+ * Values for our MP3H6115A pressure sensor
+ *
+ * From the data sheet:
+ *
+ * Pressure range: 15-115 kPa
+ * Voltage at 115kPa: 2.82
+ * Output scale: 27mV/kPa
+ *
+ *
+ * 27 mV/kPa * 2047 / 3300 counts/mV = 16.75 counts/kPa
+ * 2.82V * 2047 / 3.3 counts/V = 1749 counts/115 kPa
+ */
+
+real counts_per_kPa = 27 * 2047 / 3300;
+real counts_at_101_3kPa = 1674;
+
+real count_to_kPa(real count)
+{
+       return (count / 2047 + 0.095) / 0.009;
+}
+
+for (real count = 0; count <= 2047; count++) {
+       real    kPa = count_to_kPa(count);
+       real    meters = pressure_to_altitude(kPa * 1000);
+       printf ("       %d,     /* %6.2g kPa %d count */\n",
+               floor (meters + 0.5), kPa, count);
+}