update docs
authorBdale Garbee <bdale@gag.com>
Mon, 29 Nov 2010 02:31:44 +0000 (19:31 -0700)
committerBdale Garbee <bdale@gag.com>
Mon, 29 Nov 2010 02:31:44 +0000 (19:31 -0700)
AltOS/doc/altos.html [new file with mode: 0644]
AltOS/doc/altos.pdf [new file with mode: 0644]
AltOS/doc/altusmetrum.html
AltOS/doc/altusmetrum.pdf

diff --git a/AltOS/doc/altos.html b/AltOS/doc/altos.html
new file mode 100644 (file)
index 0000000..dea05ee
--- /dev/null
@@ -0,0 +1,817 @@
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>AltOS</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="AltOS"><div class="titlepage"><div><div><h1 class="title"><a name="id2287738"></a>AltOS</h1></div><div><h2 class="subtitle">Altos Metrum Operating System</h2></div><div><div class="author"><h3 class="author"><span class="firstname">Keith</span> <span class="surname">Packard</span></h3></div></div><div><p class="copyright">Copyright © 2010 Keith Packard</p></div><div><div class="legalnotice" title="Legal Notice"><a name="id2569423"></a><p>
+        This document is released under the terms of the
+        <a class="ulink" href="http://creativecommons.org/licenses/by-sa/3.0/" target="_top">
+          Creative Commons ShareAlike 3.0
+        </a>
+        license.
+      </p></div></div><div><div class="revhistory"><table border="1" width="100%" summary="Revision history"><tr><th align="left" valign="top" colspan="2"><b>Revision History</b></th></tr><tr><td align="left">Revision 0.1</td><td align="left">22 November 2010</td></tr><tr><td align="left" colspan="2">Initial content</td></tr></table></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#id2555194">1. Overview</a></span></dt><dt><span class="chapter"><a href="#id2579104">2. Programming the 8051 with SDCC</a></span></dt><dd><dl><dt><span class="section"><a href="#id2572549">8051 memory spaces</a></span></dt><dd><dl><dt><span class="section"><a href="#id2587147">__data</a></span></dt><dt><span class="section"><a href="#id2574082">__idata</a></span></dt><dt><span class="section"><a href="#id2585502">__xdata</a></span></dt><dt><span class="section"><a href="#id2568787">__pdata</a></span></dt><dt><span class="section"><a href="#id2564890">__code</a></span></dt><dt><span class="section"><a href="#id2570929">__bit</a></span></dt><dt><span class="section"><a href="#id2558641">__sfr, __sfr16, __sfr32, __sbit</a></span></dt></dl></dd><dt><span class="section"><a href="#id2565185">Function calls on the 8051</a></span></dt><dd><dl><dt><span class="section"><a href="#id2557511">__reentrant functions</a></span></dt><dt><span class="section"><a href="#id2558653">Non __reentrant functions</a></span></dt><dt><span class="section"><a href="#id2587007">__interrupt functions</a></span></dt><dt><span class="section"><a href="#id2570923">__critical functions and statements</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#id2578729">3. Task functions</a></span></dt><dd><dl><dt><span class="section"><a href="#id2566460">ao_add_task</a></span></dt><dt><span class="section"><a href="#id2549662">ao_exit</a></span></dt><dt><span class="section"><a href="#id2588863">ao_sleep</a></span></dt><dt><span class="section"><a href="#id2555754">ao_wakeup</a></span></dt><dt><span class="section"><a href="#id2578893">ao_alarm</a></span></dt><dt><span class="section"><a href="#id2565595">ao_wake_task</a></span></dt><dt><span class="section"><a href="#id2561847">ao_start_scheduler</a></span></dt><dt><span class="section"><a href="#id2571836">ao_clock_init</a></span></dt></dl></dd><dt><span class="chapter"><a href="#id2574991">4. Timer Functions</a></span></dt><dd><dl><dt><span class="section"><a href="#id2568218">ao_time</a></span></dt><dt><span class="section"><a href="#id2581923">ao_delay</a></span></dt><dt><span class="section"><a href="#id2581648">ao_timer_set_adc_interval</a></span></dt><dt><span class="section"><a href="#id2586062">ao_timer_init</a></span></dt></dl></dd><dt><span class="chapter"><a href="#id2589986">5. AltOS Mutexes</a></span></dt><dd><dl><dt><span class="section"><a href="#id2570322">ao_mutex_get</a></span></dt><dt><span class="section"><a href="#id2555486">ao_mutex_put</a></span></dt></dl></dd><dt><span class="chapter"><a href="#id2582719">6. CC1111 DMA engine</a></span></dt><dd><dl><dt><span class="section"><a href="#id2579029">ao_dma_alloc</a></span></dt><dt><span class="section"><a href="#id2568950">ao_dma_set_transfer</a></span></dt><dt><span class="section"><a href="#id2576818">ao_dma_start</a></span></dt><dt><span class="section"><a href="#id2586065">ao_dma_trigger</a></span></dt><dt><span class="section"><a href="#id2570488">ao_dma_abort</a></span></dt></dl></dd><dt><span class="chapter"><a href="#id2571669">7. SDCC Stdio interface</a></span></dt><dd><dl><dt><span class="section"><a href="#id2583460">putchar</a></span></dt><dt><span class="section"><a href="#id2569848">getchar</a></span></dt><dt><span class="section"><a href="#id2584689">flush</a></span></dt><dt><span class="section"><a href="#id2578522">ao_add_stdio</a></span></dt></dl></dd><dt><span class="chapter"><a href="#id2577396">8. Command line interface</a></span></dt><dd><dl><dt><span class="section"><a href="#id2573332">ao_cmd_register</a></span></dt><dt><span class="section"><a href="#id2573326">ao_cmd_lex</a></span></dt><dt><span class="section"><a href="#id2569393">ao_cmd_put16</a></span></dt><dt><span class="section"><a href="#id2565433">ao_cmd_put8</a></span></dt><dt><span class="section"><a href="#id2587125">ao_cmd_white</a></span></dt><dt><span class="section"><a href="#id2583867">ao_cmd_hex</a></span></dt><dt><span class="section"><a href="#id2589264">ao_cmd_decimal</a></span></dt><dt><span class="section"><a href="#id2578518">ao_match_word</a></span></dt><dt><span class="section"><a href="#id2589111">ao_cmd_init</a></span></dt></dl></dd><dt><span class="chapter"><a href="#id2573826">9. CC1111 USB target device</a></span></dt><dd><dl><dt><span class="section"><a href="#id2567131">ao_usb_flush</a></span></dt><dt><span class="section"><a href="#id2582959">ao_usb_putchar</a></span></dt><dt><span class="section"><a href="#id2589206">ao_usb_pollchar</a></span></dt><dt><span class="section"><a href="#id2550786">ao_usb_getchar</a></span></dt><dt><span class="section"><a href="#id2569256">ao_usb_disable</a></span></dt><dt><span class="section"><a href="#id2566705">ao_usb_enable</a></span></dt><dt><span class="section"><a href="#id2566594">ao_usb_init</a></span></dt></dl></dd><dt><span class="chapter"><a href="#id2575764">10. CC1111 Serial peripheral</a></span></dt><dd><dl><dt><span class="section"><a href="#id2576363">ao_serial_getchar</a></span></dt><dt><span class="section"><a href="#id2552673">ao_serial_putchar</a></span></dt><dt><span class="section"><a href="#id2553935">ao_serial_drain</a></span></dt><dt><span class="section"><a href="#id2564334">ao_serial_set_speed</a></span></dt><dt><span class="section"><a href="#id2574349">ao_serial_init</a></span></dt></dl></dd><dt><span class="chapter"><a href="#id2580359">11. CC1111 Radio peripheral</a></span></dt><dd><dl><dt><span class="section"><a href="#id2552360">ao_radio_set_telemetry</a></span></dt><dt><span class="section"><a href="#id2581777">ao_radio_set_packet</a></span></dt><dt><span class="section"><a href="#id2585369">ao_radio_set_rdf</a></span></dt><dt><span class="section"><a href="#id2573544">ao_radio_idle</a></span></dt><dt><span class="section"><a href="#id2551519">ao_radio_get</a></span></dt><dt><span class="section"><a href="#id2586346">ao_radio_put</a></span></dt><dt><span class="section"><a href="#id2590004">ao_radio_abort</a></span></dt><dt><span class="section"><a href="#id2565052">ao_radio_send</a></span></dt><dt><span class="section"><a href="#id2569083">ao_radio_recv</a></span></dt><dt><span class="section"><a href="#id2583861">ao_radio_rdf</a></span></dt><dt><span class="section"><a href="#id2590408">ao_packet_putchar</a></span></dt><dt><span class="section"><a href="#id2587711">ao_packet_pollchar</a></span></dt><dt><span class="section"><a href="#id2590396">ao_packet_slave_start</a></span></dt><dt><span class="section"><a href="#id2563331">ao_packet_slave_stop</a></span></dt><dt><span class="section"><a href="#id2562720">ao_packet_slave_init</a></span></dt><dt><span class="section"><a href="#id2574661">ao_packet_master_init</a></span></dt></dl></dd></dl></div><div class="chapter" title="Chapter 1. Overview"><div class="titlepage"><div><div><h2 class="title"><a name="id2555194"></a>Chapter 1. Overview</h2></div></div></div><p>
+      AltOS is a operating system built for the 8051-compatible
+      processor found in the TI cc1111 microcontroller. It's designed
+      to be small and easy to program with. The main features are:
+      </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Multi-tasking. While the 8051 doesn't provide separate
+         address spaces, it's often easier to write code that operates
+         in separate threads instead of tying everything into one giant
+         event loop.
+         </p></li><li class="listitem"><p>Non-preemptive. This increases latency for thread
+         switching but reduces the number of places where context
+         switching can occur. It also simplifies the operating system
+         design somewhat. Nothing in the target system (rocket flight
+         control) has tight timing requirements, and so this seems like
+         a reasonable compromise.
+         </p></li><li class="listitem"><p>Sleep/wakeup scheduling. Taken directly from ancient
+         Unix designs, these two provide the fundemental scheduling
+         primitive within AltOS.
+         </p></li><li class="listitem"><p>Mutexes. As a locking primitive, mutexes are easier to
+         use than semaphores, at least in my experience.
+         </p></li><li class="listitem"><p>Timers. Tasks can set an alarm which will abort any
+         pending sleep, allowing operations to time-out instead of
+         blocking forever.
+         </p></li></ul></div><p>
+    </p><p>
+      The device drivers and other subsystems in AltOS are
+      conventionally enabled by invoking their _init() function from
+      the 'main' function before that calls
+      ao_start_scheduler(). These functions initialize the pin
+      assignments, add various commands to the command processor and
+      may add tasks to the scheduler to handle the device. A typical
+      main program, thus, looks like:
+      </p><pre class="programlisting">
+       void
+       main(void)
+       {
+               ao_clock_init();
+
+               /* Turn on the LED until the system is stable */
+               ao_led_init(LEDS_AVAILABLE);
+               ao_led_on(AO_LED_RED);
+               ao_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_packet_slave_init();
+               ao_packet_master_init();
+               #if HAS_DBG
+               ao_dbg_init();
+               #endif
+               ao_config_init();
+               ao_start_scheduler();
+       }
+      </pre><p>
+      As you can see, a long sequence of subsystems are initialized
+      and then the scheduler is started.
+    </p></div><div class="chapter" title="Chapter 2. Programming the 8051 with SDCC"><div class="titlepage"><div><div><h2 class="title"><a name="id2579104"></a>Chapter 2. Programming the 8051 with SDCC</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2572549">8051 memory spaces</a></span></dt><dd><dl><dt><span class="section"><a href="#id2587147">__data</a></span></dt><dt><span class="section"><a href="#id2574082">__idata</a></span></dt><dt><span class="section"><a href="#id2585502">__xdata</a></span></dt><dt><span class="section"><a href="#id2568787">__pdata</a></span></dt><dt><span class="section"><a href="#id2564890">__code</a></span></dt><dt><span class="section"><a href="#id2570929">__bit</a></span></dt><dt><span class="section"><a href="#id2558641">__sfr, __sfr16, __sfr32, __sbit</a></span></dt></dl></dd><dt><span class="section"><a href="#id2565185">Function calls on the 8051</a></span></dt><dd><dl><dt><span class="section"><a href="#id2557511">__reentrant functions</a></span></dt><dt><span class="section"><a href="#id2558653">Non __reentrant functions</a></span></dt><dt><span class="section"><a href="#id2587007">__interrupt functions</a></span></dt><dt><span class="section"><a href="#id2570923">__critical functions and statements</a></span></dt></dl></dd></dl></div><p>
+      The 8051 is a primitive 8-bit processor, designed in the mists
+      of time in as few transistors as possible. The architecture is
+      highly irregular and includes several separate memory
+      spaces. Furthermore, accessing stack variables is slow, and the
+      stack itself is of limited size. While SDCC papers over the
+      instruction set, it is not completely able to hide the memory
+      architecture from the application designer.
+    </p><div class="section" title="8051 memory spaces"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2572549"></a>8051 memory spaces</h2></div></div></div><p>
+       The __data/__xdata/__code memory spaces below were completely
+       separate in the original 8051 design. In the cc1111, this
+       isn't true&#8212;they all live in a single unified 64kB address
+       space, and so it's possible to convert any address into a
+       unique 16-bit address. SDCC doesn't know this, and so a
+       'global' address to SDCC consumes 3 bytes of memory, 1 byte as
+       a tag indicating the memory space and 2 bytes of offset within
+       that space. AltOS avoids these 3-byte addresses as much as
+       possible; using them involves a function call per byte
+       access. The result is that nearly every variable declaration
+       is decorated with a memory space identifier which clutters the
+       code but makes the resulting code far smaller and more
+       efficient.
+      </p><div class="section" title="__data"><div class="titlepage"><div><div><h3 class="title"><a name="id2587147"></a>__data</h3></div></div></div><p>
+         The 8051 can directly address these 128 bytes of
+         memory. This makes them precious so they should be
+         reserved for frequently addressed values. Oh, just to
+         confuse things further, the 8 general registers in the
+         CPU are actually stored in this memory space. There are
+         magic instructions to 'bank switch' among 4 banks of
+         these registers located at 0x00 - 0x1F. AltOS uses only
+         the first bank at 0x00 - 0x07, leaving the other 24
+         bytes available for other data.
+       </p></div><div class="section" title="__idata"><div class="titlepage"><div><div><h3 class="title"><a name="id2574082"></a>__idata</h3></div></div></div><p>
+         There are an additional 128 bytes of internal memory
+         that share the same address space as __data but which
+         cannot be directly addressed. The stack normally
+         occupies this space and so AltOS doesn't place any
+         static storage here.
+       </p></div><div class="section" title="__xdata"><div class="titlepage"><div><div><h3 class="title"><a name="id2585502"></a>__xdata</h3></div></div></div><p>
+         This is additional general memory accessed through a
+         single 16-bit address register. The CC1111F32 has 32kB
+         of memory available here. Most program data should live
+         in this memory space.
+       </p></div><div class="section" title="__pdata"><div class="titlepage"><div><div><h3 class="title"><a name="id2568787"></a>__pdata</h3></div></div></div><p>
+         This is an alias for the first 256 bytes of __xdata
+         memory, but uses a shorter addressing mode with
+         single global 8-bit value for the high 8 bits of the
+         address and any of several 8-bit registers for the low 8
+         bits. AltOS uses a few bits of this memory, it should
+         probably use more.
+       </p></div><div class="section" title="__code"><div class="titlepage"><div><div><h3 class="title"><a name="id2564890"></a>__code</h3></div></div></div><p>
+         All executable code must live in this address space, but
+         you can stick read-only data here too. It is addressed
+         using the 16-bit address register and special 'code'
+         access opcodes. Anything read-only should live in this space.
+       </p></div><div class="section" title="__bit"><div class="titlepage"><div><div><h3 class="title"><a name="id2570929"></a>__bit</h3></div></div></div><p>
+         The 8051 has 128 bits of bit-addressible memory that
+         lives in the __data segment from 0x20 through
+         0x2f. Special instructions access these bits
+         in a single atomic operation. This isn't so much a
+         separate address space as a special addressing mode for
+         a few bytes in the __data segment.
+       </p></div><div class="section" title="__sfr, __sfr16, __sfr32, __sbit"><div class="titlepage"><div><div><h3 class="title"><a name="id2558641"></a>__sfr, __sfr16, __sfr32, __sbit</h3></div></div></div><p>
+         Access to physical registers in the device use this mode
+         which declares the variable name, it's type and the
+         address it lives at. No memory is allocated for these
+         variables.
+       </p></div></div><div class="section" title="Function calls on the 8051"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2565185"></a>Function calls on the 8051</h2></div></div></div><p>
+       Because stack addressing is expensive, and stack space
+       limited, the default function call declaration in SDCC
+       allocates all parameters and local variables in static global
+       memory. Just like fortran. This makes these functions
+       non-reentrant, and also consume space for parameters and
+       locals even when they are not running. The benefit is smaller
+       code and faster execution.
+      </p><div class="section" title="__reentrant functions"><div class="titlepage"><div><div><h3 class="title"><a name="id2557511"></a>__reentrant functions</h3></div></div></div><p>
+         All functions which are re-entrant, either due to recursion
+         or due to a potential context switch while executing, should
+         be marked as __reentrant so that their parameters and local
+         variables get allocated on the stack. This ensures that
+         these values are not overwritten by another invocation of
+         the function.
+       </p><p>
+         Functions which use significant amounts of space for
+         arguments and/or local variables and which are not often
+         invoked can also be marked as __reentrant. The resulting
+         code will be larger, but the savings in memory are
+         frequently worthwhile.
+       </p></div><div class="section" title="Non __reentrant functions"><div class="titlepage"><div><div><h3 class="title"><a name="id2558653"></a>Non __reentrant functions</h3></div></div></div><p>
+         All parameters and locals in non-reentrant functions can
+         have data space decoration so that they are allocated in
+         __xdata, __pdata or __data space as desired. This can avoid
+         consuming __data space for infrequently used variables in
+         frequently used functions.
+       </p><p>
+         All library functions called by SDCC, including functions
+         for multiplying and dividing large data types, are
+         non-reentrant. Because of this, interrupt handlers must not
+         invoke any library functions, including the multiply and
+         divide code.
+       </p></div><div class="section" title="__interrupt functions"><div class="titlepage"><div><div><h3 class="title"><a name="id2587007"></a>__interrupt functions</h3></div></div></div><p>
+         Interrupt functions are declared with with an __interrupt
+         decoration that includes the interrupt number. SDCC saves
+         and restores all of the registers in these functions and
+         uses the 'reti' instruction at the end so that they operate
+         as stand-alone interrupt handlers. Interrupt functions may
+         call the ao_wakeup function to wake AltOS tasks.
+       </p></div><div class="section" title="__critical functions and statements"><div class="titlepage"><div><div><h3 class="title"><a name="id2570923"></a>__critical functions and statements</h3></div></div></div><p>
+         SDCC has built-in support for suspending interrupts during
+         critical code. Functions marked as __critical will have
+         interrupts suspended for the whole period of
+         execution. Individual statements may also be marked as
+         __critical which blocks interrupts during the execution of
+         that statement. Keeping critical sections as short as
+         possible is key to ensuring that interrupts are handled as
+         quickly as possible.
+       </p></div></div></div><div class="chapter" title="Chapter 3. Task functions"><div class="titlepage"><div><div><h2 class="title"><a name="id2578729"></a>Chapter 3. Task functions</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2566460">ao_add_task</a></span></dt><dt><span class="section"><a href="#id2549662">ao_exit</a></span></dt><dt><span class="section"><a href="#id2588863">ao_sleep</a></span></dt><dt><span class="section"><a href="#id2555754">ao_wakeup</a></span></dt><dt><span class="section"><a href="#id2578893">ao_alarm</a></span></dt><dt><span class="section"><a href="#id2565595">ao_wake_task</a></span></dt><dt><span class="section"><a href="#id2561847">ao_start_scheduler</a></span></dt><dt><span class="section"><a href="#id2571836">ao_clock_init</a></span></dt></dl></div><p>
+      This chapter documents how to create, destroy and schedule AltOS tasks.
+    </p><div class="section" title="ao_add_task"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2566460"></a>ao_add_task</h2></div></div></div><pre class="programlisting">
+       void
+       ao_add_task(__xdata struct ao_task * task,
+                   void (*start)(void),
+                   __code char *name);
+      </pre><p>
+       This initializes the statically allocated task structure,
+       assigns a name to it (not used for anything but the task
+       display), and the start address. It does not switch to the
+       new task. 'start' must not ever return; there is no place
+       to return to.
+      </p></div><div class="section" title="ao_exit"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2549662"></a>ao_exit</h2></div></div></div><pre class="programlisting">
+       void
+       ao_exit(void)
+      </pre><p>
+       This terminates the current task.
+      </p></div><div class="section" title="ao_sleep"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2588863"></a>ao_sleep</h2></div></div></div><pre class="programlisting">
+       void
+       ao_sleep(__xdata void *wchan)
+      </pre><p>
+       This suspends the current task until 'wchan' is signaled
+       by ao_wakeup, or until the timeout, set by ao_alarm,
+       fires. If 'wchan' is signaled, ao_sleep returns 0, otherwise
+       it returns 1. This is the only way to switch to another task.
+      </p><p>
+       Because ao_wakeup wakes every task waiting on a particular
+       location, ao_sleep should be used in a loop that first
+       checks the desired condition, blocks in ao_sleep and then
+       rechecks until the condition is satisfied. If the
+       location may be signaled from an interrupt handler, the
+       code will need to block interrupts by using the __critical
+       label around the block of code. Here's a complete example:
+       </p><pre class="programlisting">
+         __critical while (!ao_radio_done)
+                 ao_sleep(&amp;ao_radio_done);
+       </pre><p>
+      </p></div><div class="section" title="ao_wakeup"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2555754"></a>ao_wakeup</h2></div></div></div><pre class="programlisting">
+       void
+       ao_wakeup(__xdata void *wchan)
+      </pre><p>
+       Wake all tasks blocked on 'wchan'. This makes them
+       available to be run again, but does not actually switch
+       to another task. Here's an example of using this:
+       </p><pre class="programlisting">
+         if (RFIF &amp; RFIF_IM_DONE) {
+                 ao_radio_done = 1;
+                 ao_wakeup(&amp;ao_radio_done);
+                 RFIF &amp;= ~RFIF_IM_DONE;
+         }
+       </pre><p>
+       Note that this need not be enclosed in __critical as the
+       ao_sleep block can only be run from normal mode, and so
+       this sequence can never be interrupted with execution of
+       the other sequence.
+      </p></div><div class="section" title="ao_alarm"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2578893"></a>ao_alarm</h2></div></div></div><pre class="programlisting">
+       void
+       ao_alarm(uint16_t delay)
+      </pre><p>
+       Schedules an alarm to fire in at least 'delay' ticks. If
+       the task is asleep when the alarm fires, it will wakeup
+       and ao_sleep will return 1.
+       </p><pre class="programlisting">
+         ao_alarm(ao_packet_master_delay);
+         __critical while (!ao_radio_dma_done)
+                 if (ao_sleep(&amp;ao_radio_dma_done) != 0)
+                         ao_radio_abort();
+       </pre><p>
+       In this example, a timeout is set before waiting for
+       incoming radio data. If no data is received before the
+       timeout fires, ao_sleep will return 1 and then this code
+       will abort the radio receive operation.
+      </p></div><div class="section" title="ao_wake_task"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2565595"></a>ao_wake_task</h2></div></div></div><pre class="programlisting">
+       void
+       ao_wake_task(__xdata struct ao_task *task)
+      </pre><p>
+       Force a specific task to wake up, independent of which
+       'wchan' it is waiting for.
+      </p></div><div class="section" title="ao_start_scheduler"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2561847"></a>ao_start_scheduler</h2></div></div></div><pre class="programlisting">
+       void
+       ao_start_scheduler(void)
+      </pre><p>
+       This is called from 'main' when the system is all
+       initialized and ready to run. It will not return.
+      </p></div><div class="section" title="ao_clock_init"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2571836"></a>ao_clock_init</h2></div></div></div><pre class="programlisting">
+       void
+       ao_clock_init(void)
+      </pre><p>
+       This turns on the external 48MHz clock then switches the
+       hardware to using it. This is required by many of the
+       internal devices like USB. It should be called by the
+       'main' function first, before initializing any of the
+       other devices in the system.
+      </p></div></div><div class="chapter" title="Chapter 4. Timer Functions"><div class="titlepage"><div><div><h2 class="title"><a name="id2574991"></a>Chapter 4. Timer Functions</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2568218">ao_time</a></span></dt><dt><span class="section"><a href="#id2581923">ao_delay</a></span></dt><dt><span class="section"><a href="#id2581648">ao_timer_set_adc_interval</a></span></dt><dt><span class="section"><a href="#id2586062">ao_timer_init</a></span></dt></dl></div><p>
+      AltOS sets up one of the cc1111 timers to run at 100Hz and
+      exposes this tick as the fundemental unit of time. At each
+      interrupt, AltOS increments the counter, and schedules any tasks
+      waiting for that time to pass, then fires off the ADC system to
+      collect current data readings. Doing this from the ISR ensures
+      that the ADC values are sampled at a regular rate, independent
+      of any scheduling jitter.
+    </p><div class="section" title="ao_time"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2568218"></a>ao_time</h2></div></div></div><pre class="programlisting">
+       uint16_t
+       ao_time(void)
+      </pre><p>
+       Returns the current system tick count. Note that this is
+       only a 16 bit value, and so it wraps every 655.36 seconds.
+      </p></div><div class="section" title="ao_delay"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2581923"></a>ao_delay</h2></div></div></div><pre class="programlisting">
+       void
+       ao_delay(uint16_t ticks);
+      </pre><p>
+       Suspend the current task for at least 'ticks' clock units.
+      </p></div><div class="section" title="ao_timer_set_adc_interval"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2581648"></a>ao_timer_set_adc_interval</h2></div></div></div><pre class="programlisting">
+       void
+       ao_timer_set_adc_interval(uint8_t interval);
+      </pre><p>
+       This sets the number of ticks between ADC samples. If set
+       to 0, no ADC samples are generated. AltOS uses this to
+       slow down the ADC sampling rate to save power.
+      </p></div><div class="section" title="ao_timer_init"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2586062"></a>ao_timer_init</h2></div></div></div><pre class="programlisting">
+       void
+       ao_timer_init(void)
+      </pre><p>
+       This turns on the 100Hz tick using the CC1111 timer 1. It
+       is required for any of the time-based functions to
+       work. It should be called by 'main' before ao_start_scheduler.
+      </p></div></div><div class="chapter" title="Chapter 5. AltOS Mutexes"><div class="titlepage"><div><div><h2 class="title"><a name="id2589986"></a>Chapter 5. AltOS Mutexes</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2570322">ao_mutex_get</a></span></dt><dt><span class="section"><a href="#id2555486">ao_mutex_put</a></span></dt></dl></div><p>
+      AltOS provides mutexes as a basic synchronization primitive. Each
+      mutexes is simply a byte of memory which holds 0 when the mutex
+      is free or the task id of the owning task when the mutex is
+      owned. Mutex calls are checked&#8212;attempting to acquire a mutex
+      already held by the current task or releasing a mutex not held
+      by the current task will both cause a panic.
+    </p><div class="section" title="ao_mutex_get"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2570322"></a>ao_mutex_get</h2></div></div></div><pre class="programlisting">
+       void
+       ao_mutex_get(__xdata uint8_t *mutex);
+      </pre><p>
+       Acquires the specified mutex, blocking if the mutex is
+       owned by another task.
+      </p></div><div class="section" title="ao_mutex_put"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2555486"></a>ao_mutex_put</h2></div></div></div><pre class="programlisting">
+       void
+       ao_mutex_put(__xdata uint8_t *mutex);
+      </pre><p>
+       Releases the specified mutex, waking up all tasks waiting
+       for it.
+      </p></div></div><div class="chapter" title="Chapter 6. CC1111 DMA engine"><div class="titlepage"><div><div><h2 class="title"><a name="id2582719"></a>Chapter 6. CC1111 DMA engine</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2579029">ao_dma_alloc</a></span></dt><dt><span class="section"><a href="#id2568950">ao_dma_set_transfer</a></span></dt><dt><span class="section"><a href="#id2576818">ao_dma_start</a></span></dt><dt><span class="section"><a href="#id2586065">ao_dma_trigger</a></span></dt><dt><span class="section"><a href="#id2570488">ao_dma_abort</a></span></dt></dl></div><p>
+      The CC1111 contains a useful bit of extra hardware in the form
+      of five programmable DMA engines. They can be configured to copy
+      data in memory, or between memory and devices (or even between
+      two devices). AltOS exposes a general interface to this hardware
+      and uses it to handle radio and SPI data.
+    </p><p>
+      Code using a DMA engine should allocate one at startup
+      time. There is no provision to free them, and if you run out,
+      AltOS will simply panic.
+    </p><p>
+      During operation, the DMA engine is initialized with the
+      transfer parameters. Then it is started, at which point it
+      awaits a suitable event to start copying data. When copying data
+      from hardware to memory, that trigger event is supplied by the
+      hardware device. When copying data from memory to hardware, the
+      transfer is usually initiated by software.
+    </p><div class="section" title="ao_dma_alloc"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2579029"></a>ao_dma_alloc</h2></div></div></div><pre class="programlisting">
+       uint8_t
+       ao_dma_alloc(__xdata uint8_t *done)
+      </pre><p>
+       Allocates a DMA engine, returning the identifier. Whenever
+       this DMA engine completes a transfer. 'done' is cleared
+       when the DMA is started, and then receives the
+       AO_DMA_DONE bit on a successful transfer or the
+       AO_DMA_ABORTED bit if ao_dma_abort was called. Note that
+       it is possible to get both bits if the transfer was
+       aborted after it had finished.
+      </p></div><div class="section" title="ao_dma_set_transfer"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2568950"></a>ao_dma_set_transfer</h2></div></div></div><pre class="programlisting">
+       void
+       ao_dma_set_transfer(uint8_t id,
+                           void __xdata *srcaddr,
+                           void __xdata *dstaddr,
+                           uint16_t count,
+                           uint8_t cfg0,
+                           uint8_t cfg1)
+      </pre><p>
+       Initializes the specified dma engine to copy data
+       from 'srcaddr' to 'dstaddr' for 'count' units. cfg0 and
+       cfg1 are values directly out of the CC1111 documentation
+       and tell the DMA engine what the transfer unit size,
+       direction and step are.
+      </p></div><div class="section" title="ao_dma_start"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2576818"></a>ao_dma_start</h2></div></div></div><pre class="programlisting">
+       void
+       ao_dma_start(uint8_t id);
+      </pre><p>
+       Arm the specified DMA engine and await a signal from
+       either hardware or software to start transferring data.
+      </p></div><div class="section" title="ao_dma_trigger"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2586065"></a>ao_dma_trigger</h2></div></div></div><pre class="programlisting">
+       void
+       ao_dma_trigger(uint8_t id)
+      </pre><p>
+       Trigger the specified DMA engine to start copying data.
+      </p></div><div class="section" title="ao_dma_abort"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2570488"></a>ao_dma_abort</h2></div></div></div><pre class="programlisting">
+       void
+       ao_dma_abort(uint8_t id)
+      </pre><p>
+       Terminate any in-progress DMA transation, marking its
+       'done' variable with the AO_DMA_ABORTED bit.
+      </p></div></div><div class="chapter" title="Chapter 7. SDCC Stdio interface"><div class="titlepage"><div><div><h2 class="title"><a name="id2571669"></a>Chapter 7. SDCC Stdio interface</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2583460">putchar</a></span></dt><dt><span class="section"><a href="#id2569848">getchar</a></span></dt><dt><span class="section"><a href="#id2584689">flush</a></span></dt><dt><span class="section"><a href="#id2578522">ao_add_stdio</a></span></dt></dl></div><p>
+      AltOS offers a stdio interface over both USB and the RF packet
+      link. This provides for control of the device localy or
+      remotely. This is hooked up to the stdio functions in SDCC by
+      providing the standard putchar/getchar/flush functions. These
+      automatically multiplex the two available communication
+      channels; output is always delivered to the channel which
+      provided the most recent input.
+    </p><div class="section" title="putchar"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2583460"></a>putchar</h2></div></div></div><pre class="programlisting">
+       void
+       putchar(char c)
+      </pre><p>
+       Delivers a single character to the current console
+       device.
+      </p></div><div class="section" title="getchar"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2569848"></a>getchar</h2></div></div></div><pre class="programlisting">
+       char
+       getchar(void)
+      </pre><p>
+       Reads a single character from any of the available
+       console devices. The current console device is set to
+       that which delivered this character. This blocks until
+       a character is available.
+      </p></div><div class="section" title="flush"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2584689"></a>flush</h2></div></div></div><pre class="programlisting">
+       void
+       flush(void)
+      </pre><p>
+       Flushes the current console device output buffer. Any
+       pending characters will be delivered to the target device.
+      xo         </p></div><div class="section" title="ao_add_stdio"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2578522"></a>ao_add_stdio</h2></div></div></div><pre class="programlisting">
+       void
+       ao_add_stdio(char (*pollchar)(void),
+                          void (*putchar)(char),
+                          void (*flush)(void))
+      </pre><p>
+       This adds another console device to the available
+       list.
+      </p><p>
+       'pollchar' returns either an available character or
+       AO_READ_AGAIN if none is available. Significantly, it does
+       not block. The device driver must set 'ao_stdin_ready' to
+       1 and call ao_wakeup(&amp;ao_stdin_ready) when it receives
+       input to tell getchar that more data is available, at
+       which point 'pollchar' will be called again.
+      </p><p>
+       'putchar' queues a character for output, flushing if the output buffer is
+       full. It may block in this case.
+      </p><p>
+       'flush' forces the output buffer to be flushed. It may
+       block until the buffer is delivered, but it is not
+       required to do so.
+      </p></div></div><div class="chapter" title="Chapter 8. Command line interface"><div class="titlepage"><div><div><h2 class="title"><a name="id2577396"></a>Chapter 8. Command line interface</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2573332">ao_cmd_register</a></span></dt><dt><span class="section"><a href="#id2573326">ao_cmd_lex</a></span></dt><dt><span class="section"><a href="#id2569393">ao_cmd_put16</a></span></dt><dt><span class="section"><a href="#id2565433">ao_cmd_put8</a></span></dt><dt><span class="section"><a href="#id2587125">ao_cmd_white</a></span></dt><dt><span class="section"><a href="#id2583867">ao_cmd_hex</a></span></dt><dt><span class="section"><a href="#id2589264">ao_cmd_decimal</a></span></dt><dt><span class="section"><a href="#id2578518">ao_match_word</a></span></dt><dt><span class="section"><a href="#id2589111">ao_cmd_init</a></span></dt></dl></div><p>
+      AltOS includes a simple command line parser which is hooked up
+      to the stdio interfaces permitting remote control of the device
+      over USB or the RF link as desired. Each command uses a single
+      character to invoke it, the remaining characters on the line are
+      available as parameters to the command.
+    </p><div class="section" title="ao_cmd_register"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2573332"></a>ao_cmd_register</h2></div></div></div><pre class="programlisting">
+       void
+       ao_cmd_register(__code struct ao_cmds *cmds)
+      </pre><p>
+       This registers a set of commands with the command
+       parser. There is a fixed limit on the number of command
+       sets, the system will panic if too many are registered.
+       Each command is defined by a struct ao_cmds entry:
+       </p><pre class="programlisting">
+         struct ao_cmds {
+                 char          cmd;
+                 void          (*func)(void);
+                 const char    *help;
+         };
+       </pre><p>
+       'cmd' is the character naming the command. 'func' is the
+       function to invoke and 'help' is a string displayed by the
+       '?' command. Syntax errors found while executing 'func'
+       should be indicated by modifying the global ao_cmd_status
+       variable with one of the following values:
+       </p><div class="variablelist"><dl><dt></dt><dd><p>
+               The command was parsed successfully. There is no
+               need to assign this value, it is the default.
+             </p></dd><dt></dt><dd><p>
+               A token in the line was invalid, such as a number
+               containing invalid characters. The low-level
+               lexing functions already assign this value as needed.
+             </p></dd><dt></dt><dd><p>
+               The command line is invalid for some reason other
+               than invalid tokens.
+             </p></dd></dl></div><p>
+      </p></div><div class="section" title="ao_cmd_lex"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2573326"></a>ao_cmd_lex</h2></div></div></div><pre class="programlisting">
+       void
+       ao_cmd_lex(void);
+      </pre><p>
+       This gets the next character out of the command line
+       buffer and sticks it into ao_cmd_lex_c. At the end of the
+       line, ao_cmd_lex_c will get a newline ('\n') character.
+      </p></div><div class="section" title="ao_cmd_put16"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2569393"></a>ao_cmd_put16</h2></div></div></div><pre class="programlisting">
+       void
+       ao_cmd_put16(uint16_t v);
+      </pre><p>
+       Writes 'v' as four hexadecimal characters.
+      </p></div><div class="section" title="ao_cmd_put8"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2565433"></a>ao_cmd_put8</h2></div></div></div><pre class="programlisting">
+       void
+       ao_cmd_put8(uint8_t v);
+      </pre><p>
+       Writes 'v' as two hexadecimal characters.
+      </p></div><div class="section" title="ao_cmd_white"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2587125"></a>ao_cmd_white</h2></div></div></div><pre class="programlisting">
+       void
+       ao_cmd_white(void)
+      </pre><p>
+       This skips whitespace by calling ao_cmd_lex while
+       ao_cmd_lex_c is either a space or tab. It does not skip
+       any characters if ao_cmd_lex_c already non-white.
+      </p></div><div class="section" title="ao_cmd_hex"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2583867"></a>ao_cmd_hex</h2></div></div></div><pre class="programlisting">
+       void
+       ao_cmd_hex(void)
+      </pre><p>
+       This reads a 16-bit hexadecimal value from the command
+       line with optional leading whitespace. The resulting value
+       is stored in ao_cmd_lex_i;
+      </p></div><div class="section" title="ao_cmd_decimal"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2589264"></a>ao_cmd_decimal</h2></div></div></div><pre class="programlisting">
+       void
+       ao_cmd_decimal(void)
+      </pre><p>
+       This reads a 32-bit decimal value from the command
+       line with optional leading whitespace. The resulting value
+       is stored in ao_cmd_lex_u32 and the low 16 bits are stored
+       in ao_cmd_lex_i;
+      </p></div><div class="section" title="ao_match_word"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2578518"></a>ao_match_word</h2></div></div></div><pre class="programlisting">
+       uint8_t
+       ao_match_word(__code char *word)
+      </pre><p>
+       This checks to make sure that 'word' occurs on the command
+       line. It does not skip leading white space. If 'word' is
+       found, then 1 is returned. Otherwise, ao_cmd_status is set to
+       ao_cmd_syntax_error and 0 is returned.
+      </p></div><div class="section" title="ao_cmd_init"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2589111"></a>ao_cmd_init</h2></div></div></div><pre class="programlisting">
+       void
+       ao_cmd_init(void
+      </pre><p>
+       Initializes the command system, setting up the built-in
+       commands and adding a task to run the command processing
+       loop. It should be called by 'main' before ao_start_scheduler.
+      </p></div></div><div class="chapter" title="Chapter 9. CC1111 USB target device"><div class="titlepage"><div><div><h2 class="title"><a name="id2573826"></a>Chapter 9. CC1111 USB target device</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2567131">ao_usb_flush</a></span></dt><dt><span class="section"><a href="#id2582959">ao_usb_putchar</a></span></dt><dt><span class="section"><a href="#id2589206">ao_usb_pollchar</a></span></dt><dt><span class="section"><a href="#id2550786">ao_usb_getchar</a></span></dt><dt><span class="section"><a href="#id2569256">ao_usb_disable</a></span></dt><dt><span class="section"><a href="#id2566705">ao_usb_enable</a></span></dt><dt><span class="section"><a href="#id2566594">ao_usb_init</a></span></dt></dl></div><p>
+      The CC1111 contains a full-speed USB target device. It can be
+      programmed to offer any kind of USB target, but to simplify
+      interactions with a variety of operating systems, AltOS provides
+      only a single target device profile, that of a USB modem which
+      has native drivers for Linux, Windows and Mac OS X. It would be
+      easy to change the code to provide an alternate target device if
+      necessary.
+    </p><p>
+      To the rest of the system, the USB device looks like a simple
+      two-way byte stream. It can be hooked into the command line
+      interface if desired, offering control of the device over the
+      USB link. Alternatively, the functions can be accessed directly
+      to provide for USB-specific I/O.
+    </p><div class="section" title="ao_usb_flush"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2567131"></a>ao_usb_flush</h2></div></div></div><pre class="programlisting">
+       void
+       ao_usb_flush(void);
+      </pre><p>
+       Flushes any pending USB output. This queues an 'IN' packet
+       to be delivered to the USB host if there is pending data,
+       or if the last IN packet was full to indicate to the host
+       that there isn't any more pending data available.
+      </p></div><div class="section" title="ao_usb_putchar"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2582959"></a>ao_usb_putchar</h2></div></div></div><pre class="programlisting">
+       void
+       ao_usb_putchar(char c);
+      </pre><p>
+       If there is a pending 'IN' packet awaiting delivery to the
+       host, this blocks until that has been fetched. Then, this
+       adds a byte to the pending IN packet for delivery to the
+       USB host. If the USB packet is full, this queues the 'IN'
+       packet for delivery.
+      </p></div><div class="section" title="ao_usb_pollchar"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2589206"></a>ao_usb_pollchar</h2></div></div></div><pre class="programlisting">
+       char
+       ao_usb_pollchar(void);
+      </pre><p>
+       If there are no characters remaining in the last 'OUT'
+       packet received, this returns AO_READ_AGAIN. Otherwise, it
+       returns the next character, reporting to the host that it
+       is ready for more data when the last character is gone.
+      </p></div><div class="section" title="ao_usb_getchar"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2550786"></a>ao_usb_getchar</h2></div></div></div><pre class="programlisting">
+       char
+       ao_usb_getchar(void);
+      </pre><p>
+       This uses ao_pollchar to receive the next character,
+       blocking while ao_pollchar returns AO_READ_AGAIN.
+      </p></div><div class="section" title="ao_usb_disable"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2569256"></a>ao_usb_disable</h2></div></div></div><pre class="programlisting">
+       void
+       ao_usb_disable(void);
+      </pre><p>
+       This turns off the USB controller. It will no longer
+       respond to host requests, nor return characters. Calling
+       any of the i/o routines while the USB device is disabled
+       is undefined, and likely to break things. Disabling the
+       USB device when not needed saves power.
+      </p><p>
+       Note that neither TeleDongle nor TeleMetrum are able to
+       signal to the USB host that they have disconnected, so
+       after disabling the USB device, it's likely that the cable
+       will need to be disconnected and reconnected before it
+       will work again.
+      </p></div><div class="section" title="ao_usb_enable"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2566705"></a>ao_usb_enable</h2></div></div></div><pre class="programlisting">
+       void
+       ao_usb_enable(void);
+      </pre><p>
+       This turns the USB controller on again after it has been
+       disabled. See the note above about needing to physically
+       remove and re-insert the cable to get the host to
+       re-initialize the USB link.
+      </p></div><div class="section" title="ao_usb_init"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2566594"></a>ao_usb_init</h2></div></div></div><pre class="programlisting">
+       void
+       ao_usb_init(void);
+      </pre><p>
+       This turns the USB controller on, adds a task to handle
+       the control end point and adds the usb I/O functions to
+       the stdio system. Call this from main before
+       ao_start_scheduler.
+      </p></div></div><div class="chapter" title="Chapter 10. CC1111 Serial peripheral"><div class="titlepage"><div><div><h2 class="title"><a name="id2575764"></a>Chapter 10. CC1111 Serial peripheral</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2576363">ao_serial_getchar</a></span></dt><dt><span class="section"><a href="#id2552673">ao_serial_putchar</a></span></dt><dt><span class="section"><a href="#id2553935">ao_serial_drain</a></span></dt><dt><span class="section"><a href="#id2564334">ao_serial_set_speed</a></span></dt><dt><span class="section"><a href="#id2574349">ao_serial_init</a></span></dt></dl></div><p>
+      The CC1111 provides two USART peripherals. AltOS uses one for
+      asynch serial data, generally to communicate with a GPS device,
+      and the other for a SPI bus. The UART is configured to operate
+      in 8-bits, no parity, 1 stop bit framing. The default
+      configuration has clock settings for 4800, 9600 and 57600 baud
+      operation. Additional speeds can be added by computing
+      appropriate clock values.
+    </p><p>
+      To prevent loss of data, AltOS provides receive and transmit
+      fifos of 32 characters each.
+    </p><div class="section" title="ao_serial_getchar"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2576363"></a>ao_serial_getchar</h2></div></div></div><pre class="programlisting">
+       char
+       ao_serial_getchar(void);
+      </pre><p>
+       Returns the next character from the receive fifo, blocking
+       until a character is received if the fifo is empty.
+      </p></div><div class="section" title="ao_serial_putchar"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2552673"></a>ao_serial_putchar</h2></div></div></div><pre class="programlisting">
+       void
+       ao_serial_putchar(char c);
+      </pre><p>
+       Adds a character to the transmit fifo, blocking if the
+       fifo is full. Starts transmitting characters.
+      </p></div><div class="section" title="ao_serial_drain"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2553935"></a>ao_serial_drain</h2></div></div></div><pre class="programlisting">
+       void
+       ao_serial_drain(void);
+      </pre><p>
+       Blocks until the transmit fifo is empty. Used internally
+       when changing serial speeds.
+      </p></div><div class="section" title="ao_serial_set_speed"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2564334"></a>ao_serial_set_speed</h2></div></div></div><pre class="programlisting">
+       void
+       ao_serial_set_speed(uint8_t speed);
+      </pre><p>
+       Changes the serial baud rate to one of
+       AO_SERIAL_SPEED_4800, AO_SERIAL_SPEED_9600 or
+       AO_SERIAL_SPEED_57600. This first flushes the transmit
+       fifo using ao_serial_drain.
+      </p></div><div class="section" title="ao_serial_init"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2574349"></a>ao_serial_init</h2></div></div></div><pre class="programlisting">
+       void
+       ao_serial_init(void)
+      </pre><p>
+       Initializes the serial peripheral. Call this from 'main'
+       before jumping to ao_start_scheduler. The default speed
+       setting is AO_SERIAL_SPEED_4800.
+      </p></div></div><div class="chapter" title="Chapter 11. CC1111 Radio peripheral"><div class="titlepage"><div><div><h2 class="title"><a name="id2580359"></a>Chapter 11. CC1111 Radio peripheral</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2552360">ao_radio_set_telemetry</a></span></dt><dt><span class="section"><a href="#id2581777">ao_radio_set_packet</a></span></dt><dt><span class="section"><a href="#id2585369">ao_radio_set_rdf</a></span></dt><dt><span class="section"><a href="#id2573544">ao_radio_idle</a></span></dt><dt><span class="section"><a href="#id2551519">ao_radio_get</a></span></dt><dt><span class="section"><a href="#id2586346">ao_radio_put</a></span></dt><dt><span class="section"><a href="#id2590004">ao_radio_abort</a></span></dt><dt><span class="section"><a href="#id2565052">ao_radio_send</a></span></dt><dt><span class="section"><a href="#id2569083">ao_radio_recv</a></span></dt><dt><span class="section"><a href="#id2583861">ao_radio_rdf</a></span></dt><dt><span class="section"><a href="#id2590408">ao_packet_putchar</a></span></dt><dt><span class="section"><a href="#id2587711">ao_packet_pollchar</a></span></dt><dt><span class="section"><a href="#id2590396">ao_packet_slave_start</a></span></dt><dt><span class="section"><a href="#id2563331">ao_packet_slave_stop</a></span></dt><dt><span class="section"><a href="#id2562720">ao_packet_slave_init</a></span></dt><dt><span class="section"><a href="#id2574661">ao_packet_master_init</a></span></dt></dl></div><p>
+      The CC1111 radio transceiver sends and receives digital packets
+      with forward error correction and detection. The AltOS driver is
+      fairly specific to the needs of the TeleMetrum and TeleDongle
+      devices, using it for other tasks may require customization of
+      the driver itself. There are three basic modes of operation:
+      </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+           Telemetry mode. In this mode, TeleMetrum transmits telemetry
+           frames at a fixed rate. The frames are of fixed size. This
+           is strictly a one-way communication from TeleMetrum to
+           TeleDongle.
+         </p></li><li class="listitem"><p>
+           Packet mode. In this mode, the radio is used to create a
+           reliable duplex byte stream between TeleDongle and
+           TeleMetrum. This is an asymmetrical protocol with
+           TeleMetrum only transmitting in response to a packet sent
+           from TeleDongle. Thus getting data from TeleMetrum to
+           TeleDongle requires polling. The polling rate is adaptive,
+           when no data has been received for a while, the rate slows
+           down. The packets are checked at both ends and invalid
+           data are ignored.
+         </p><p>
+           On the TeleMetrum side, the packet link is hooked into the
+           stdio mechanism, providing an alternate data path for the
+           command processor. It is enabled when the unit boots up in
+           'idle' mode.
+         </p><p>
+           On the TeleDongle side, the packet link is enabled with a
+           command; data from the stdio package is forwarded over the
+           packet link providing a connection from the USB command
+           stream to the remote TeleMetrum device.
+         </p></li><li class="listitem"><p>
+           Radio Direction Finding mode. In this mode, TeleMetrum
+           constructs a special packet that sounds like an audio tone
+           when received by a conventional narrow-band FM
+           receiver. This is designed to provide a beacon to track
+           the device when other location mechanisms fail.
+         </p></li></ol></div><p>
+    </p><div class="section" title="ao_radio_set_telemetry"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2552360"></a>ao_radio_set_telemetry</h2></div></div></div><pre class="programlisting">
+         void
+         ao_radio_set_telemetry(void);
+       </pre><p>
+         Configures the radio to send or receive telemetry
+         packets. This includes packet length, modulation scheme and
+         other RF parameters. It does not include the base frequency
+         or channel though. Those are set at the time of transmission
+         or reception, in case the values are changed by the user.
+       </p></div><div class="section" title="ao_radio_set_packet"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2581777"></a>ao_radio_set_packet</h2></div></div></div><pre class="programlisting">
+         void
+         ao_radio_set_packet(void);
+       </pre><p>
+         Configures the radio to send or receive packet data.  This
+         includes packet length, modulation scheme and other RF
+         parameters. It does not include the base frequency or
+         channel though. Those are set at the time of transmission or
+         reception, in case the values are changed by the user.
+       </p></div><div class="section" title="ao_radio_set_rdf"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2585369"></a>ao_radio_set_rdf</h2></div></div></div><pre class="programlisting">
+         void
+         ao_radio_set_rdf(void);
+       </pre><p>
+         Configures the radio to send RDF 'packets'. An RDF 'packet'
+         is a sequence of hex 0x55 bytes sent at a base bit rate of
+         2kbps using a 5kHz deviation. All of the error correction
+         and data whitening logic is turned off so that the resulting
+         modulation is received as a 1kHz tone by a conventional 70cm
+         FM audio receiver.
+       </p></div><div class="section" title="ao_radio_idle"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2573544"></a>ao_radio_idle</h2></div></div></div><pre class="programlisting">
+         void
+         ao_radio_idle(void);
+       </pre><p>
+         Sets the radio device to idle mode, waiting until it reaches
+         that state. This will terminate any in-progress transmit or
+         receive operation.
+       </p></div><div class="section" title="ao_radio_get"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2551519"></a>ao_radio_get</h2></div></div></div><pre class="programlisting">
+         void
+         ao_radio_get(void);
+       </pre><p>
+         Acquires the radio mutex and then configures the radio
+         frequency using the global radio calibration and channel
+         values.
+       </p></div><div class="section" title="ao_radio_put"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2586346"></a>ao_radio_put</h2></div></div></div><pre class="programlisting">
+         void
+         ao_radio_put(void);
+       </pre><p>
+         Releases the radio mutex.
+       </p></div><div class="section" title="ao_radio_abort"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2590004"></a>ao_radio_abort</h2></div></div></div><pre class="programlisting">
+         void
+         ao_radio_abort(void);
+       </pre><p>
+         Aborts any transmission or reception process by aborting the
+         associated DMA object and calling ao_radio_idle to terminate
+         the radio operation.
+       </p></div><p>
+      In telemetry mode, you can send or receive a telemetry
+      packet. The data from receiving a packet also includes the RSSI
+      and status values supplied by the receiver. These are added
+      after the telemetry data.
+    </p><div class="section" title="ao_radio_send"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2565052"></a>ao_radio_send</h2></div></div></div><pre class="programlisting">
+         void
+         ao_radio_send(__xdata struct ao_telemetry *telemetry);
+       </pre><p>
+         This sends the specific telemetry packet, waiting for the
+         transmission to complete. The radio must have been set to
+         telemetry mode. This function calls ao_radio_get() before
+         sending, and ao_radio_put() afterwards, to correctly
+         serialize access to the radio device.
+       </p></div><div class="section" title="ao_radio_recv"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2569083"></a>ao_radio_recv</h2></div></div></div><pre class="programlisting">
+         void
+         ao_radio_recv(__xdata struct ao_radio_recv *radio);
+       </pre><p>
+         This blocks waiting for a telemetry packet to be received.
+         The radio must have been set to telemetry mode. This
+         function calls ao_radio_get() before receiving, and
+         ao_radio_put() afterwards, to correctly serialize access
+         to the radio device. This returns non-zero if a packet was
+         received, or zero if the operation was aborted (from some
+         other task calling ao_radio_abort()).
+       </p></div><p>
+      In radio direction finding mode, there's just one function to
+      use
+    </p><div class="section" title="ao_radio_rdf"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2583861"></a>ao_radio_rdf</h2></div></div></div><pre class="programlisting">
+         void
+         ao_radio_rdf(int ms);
+       </pre><p>
+         This sends an RDF packet lasting for the specified amount
+         of time. The maximum length is 1020 ms.
+       </p></div><p>
+      Packet mode is asymmetrical and is configured at compile time
+      for either master or slave mode (but not both). The basic I/O
+      functions look the same at both ends, but the internals are
+      different, along with the initialization steps.
+    </p><div class="section" title="ao_packet_putchar"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2590408"></a>ao_packet_putchar</h2></div></div></div><pre class="programlisting">
+         void
+         ao_packet_putchar(char c);
+       </pre><p>
+         If the output queue is full, this first blocks waiting for
+         that data to be delivered. Then, queues a character for
+         packet transmission. On the master side, this will
+         transmit a packet if the output buffer is full. On the
+         slave side, any pending data will be sent the next time
+         the master polls for data.
+       </p></div><div class="section" title="ao_packet_pollchar"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2587711"></a>ao_packet_pollchar</h2></div></div></div><pre class="programlisting">
+         char
+         ao_packet_pollchar(void);
+       </pre><p>
+         This returns a pending input character if available,
+         otherwise returns AO_READ_AGAIN. On the master side, if
+         this empties the buffer, it triggers a poll for more data.
+       </p></div><div class="section" title="ao_packet_slave_start"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2590396"></a>ao_packet_slave_start</h2></div></div></div><pre class="programlisting">
+         void
+         ao_packet_slave_start(void);
+       </pre><p>
+         This is available only on the slave side and starts a task
+         to listen for packet data.
+       </p></div><div class="section" title="ao_packet_slave_stop"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2563331"></a>ao_packet_slave_stop</h2></div></div></div><pre class="programlisting">
+         void
+         ao_packet_slave_stop(void);
+       </pre><p>
+         Disables the packet slave task, stopping the radio receiver.
+       </p></div><div class="section" title="ao_packet_slave_init"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2562720"></a>ao_packet_slave_init</h2></div></div></div><pre class="programlisting">
+         void
+         ao_packet_slave_init(void);
+       </pre><p>
+         Adds the packet stdio functions to the stdio package so
+         that when packet slave mode is enabled, characters will
+         get send and received through the stdio functions.
+       </p></div><div class="section" title="ao_packet_master_init"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2574661"></a>ao_packet_master_init</h2></div></div></div><pre class="programlisting">
+         void
+         ao_packet_master_init(void);
+       </pre><p>
+         Adds the 'p' packet forward command to start packet mode.
+       </p></div></div></div></body></html>
diff --git a/AltOS/doc/altos.pdf b/AltOS/doc/altos.pdf
new file mode 100644 (file)
index 0000000..1236a65
Binary files /dev/null and b/AltOS/doc/altos.pdf differ
index 4edd96652586ebeab03e65dec7717191a68243af..772a245982de8dae27e19069a66aafd880cf4ba5 100644 (file)
@@ -1,14 +1,37 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>TeleMetrum</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="TeleMetrum"><div class="titlepage"><div><div><h1 class="title"><a name="id2276207"></a>TeleMetrum</h1></div><div><h2 class="subtitle">Owner's Manual for the TeleMetrum System</h2></div><div><div class="author"><h3 class="author"><span class="firstname">Bdale</span> <span class="surname">Garbee</span></h3></div></div><div><div class="author"><h3 class="author"><span class="firstname">Keith</span> <span class="surname">Packard</span></h3></div></div><div><p class="copyright">Copyright © 2010 Bdale Garbee and Keith Packard</p></div><div><div class="legalnotice" title="Legal Notice"><a name="id2559812"></a><p>
-        This document is released under the terms of the 
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>The Altus Metrum System</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="The Altus Metrum System"><div class="titlepage"><div><div><h1 class="title"><a name="id2291362"></a>The Altus Metrum System</h1></div><div><h2 class="subtitle">An Owner's Manual for TeleMetrum and TeleDongle Devices</h2></div><div><div class="author"><h3 class="author"><span class="firstname">Bdale</span> <span class="surname">Garbee</span></h3></div></div><div><div class="author"><h3 class="author"><span class="firstname">Keith</span> <span class="surname">Packard</span></h3></div></div><div><div class="author"><h3 class="author"><span class="firstname">Bob</span> <span class="surname">Finch</span></h3></div></div><div><div class="author"><h3 class="author"><span class="firstname">Anthony</span> <span class="surname">Towns</span></h3></div></div><div><p class="copyright">Copyright © 2010 Bdale Garbee and Keith Packard</p></div><div><div class="legalnotice" title="Legal Notice"><a name="id2566861"></a><p>
+        This document is released under the terms of the
         <a class="ulink" href="http://creativecommons.org/licenses/by-sa/3.0/" target="_top">
           Creative Commons ShareAlike 3.0
         </a>
         license.
-      </p></div></div><div><div class="revhistory"><table border="1" width="100%" summary="Revision history"><tr><th align="left" valign="top" colspan="2"><b>Revision History</b></th></tr><tr><td align="left">Revision 0.3</td><td align="left">12 November 2010</td></tr><tr><td align="left" colspan="2">
-          Add instructions for re-flashing devices using AltosUI
-        </td></tr><tr><td align="left">Revision 0.2</td><td align="left">18 July 2010</td></tr><tr><td align="left" colspan="2">Significant update</td></tr><tr><td align="left">Revision 0.1</td><td align="left">30 March 2010</td></tr><tr><td align="left" colspan="2">Initial content</td></tr></table></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#id2555013">1. Introduction and Overview</a></span></dt><dt><span class="chapter"><a href="#id2540100">2. Getting Started</a></span></dt><dd><dl><dt><span class="section"><a href="#id2559795">FAQ</a></span></dt></dl></dd><dt><span class="chapter"><a href="#id2546901">3. Specifications</a></span></dt><dt><span class="chapter"><a href="#id2574755">4. Handling Precautions</a></span></dt><dt><span class="chapter"><a href="#id2547133">5. Hardware Overview</a></span></dt><dt><span class="chapter"><a href="#id2552998">6. Operation</a></span></dt><dd><dl><dt><span class="section"><a href="#id2556146">Firmware Modes </a></span></dt><dt><span class="section"><a href="#id2557858">GPS </a></span></dt><dt><span class="section"><a href="#id2572262">Ground Testing </a></span></dt><dt><span class="section"><a href="#id2572259">Radio Link </a></span></dt><dt><span class="section"><a href="#id2542980">Configurable Parameters</a></span></dt><dd><dl><dt><span class="section"><a href="#id2563251">Radio Channel</a></span></dt><dt><span class="section"><a href="#id2554165">Apogee Delay</a></span></dt><dt><span class="section"><a href="#id2571971">Main Deployment Altitude</a></span></dt></dl></dd><dt><span class="section"><a href="#id2550600">Calibration</a></span></dt><dd><dl><dt><span class="section"><a href="#id2574322">Radio Frequency</a></span></dt><dt><span class="section"><a href="#id2564433">Accelerometer</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#id2554553">7. Updating Device Firmware</a></span></dt><dd><dl><dt><span class="section"><a href="#id2569887">Updating TeleMetrum Firmware</a></span></dt><dt><span class="section"><a href="#id2552683">Updating TeleDongle Firmware</a></span></dt></dl></dd><dt><span class="chapter"><a href="#id2539483">8. Using Altus Metrum Products</a></span></dt><dd><dl><dt><span class="section"><a href="#id2558109">Being Legal</a></span></dt><dd><dl><dt><span class="section"><a href="#id2554650">In the Rocket</a></span></dt><dt><span class="section"><a href="#id2572268">On the Ground</a></span></dt><dt><span class="section"><a href="#id2569008">Data Analysis</a></span></dt><dt><span class="section"><a href="#id2563568">Future Plans</a></span></dt></dl></dd><dt><span class="section"><a href="#id2567979">
-        How GPS Works
-      </a></span></dt></dl></dd></dl></div><div class="chapter" title="Chapter 1. Introduction and Overview"><div class="titlepage"><div><div><h2 class="title"><a name="id2555013"></a>Chapter 1. Introduction and Overview</h2></div></div></div><p>
+      </p></div></div><div><div class="revhistory"><table border="1" width="100%" summary="Revision history"><tr><th align="left" valign="top" colspan="2"><b>Revision History</b></th></tr><tr><td align="left">Revision 0.8</td><td align="left">24 November 2010</td></tr><tr><td align="left" colspan="2">Updated for software version 0.8 </td></tr></table></div></div></div><hr></div><div class="acknowledgements" title="Acknowledgements"><div class="titlepage"><div><div><h2 class="title"><a name="id2558408"></a>Acknowledgements</h2></div></div></div>
+    <p>
+      Thanks to Bob Finch, W9YA, NAR 12965, TRA 12350 for writing "The
+      Mere-Mortals Quick Start/Usage Guide to the Altus Metrum Starter
+      Kit" which has turned into the Getting Started chapter in this
+      book. Bob was one of our first customers for a production
+      TeleMetrum, and the enthusiasm that led to his contribution of
+      this section is immensely gratifying and highy appreciated!
+    </p>
+    <p>
+      And thanks to Anthony (AJ) Towns for contributing the
+      AltosUI graphing and site map code and documentation. Free
+      software means that our customers and friends can become our
+      collaborators, and we certainly appreciate this level of
+      contribution.
+    </p>
+    <p>
+      Have fun using these products, and we hope to meet all of you
+      out on the rocket flight line somewhere.
+      </p><div class="literallayout"><p><br>
+Bdale Garbee, KB0G<br>
+NAR #87103, TRA #12201<br>
+<br>
+Keith Packard, KD7SQG<br>
+NAR #88757, TRA #12200<br>
+      </p></div><p>
+    </p>
+  </div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#id2562143">1. Introduction and Overview</a></span></dt><dt><span class="chapter"><a href="#id2535919">2. Getting Started</a></span></dt><dd><dl><dt><span class="section"><a href="#id2574950">FAQ</a></span></dt></dl></dd><dt><span class="chapter"><a href="#id2562056">3. Specifications</a></span></dt><dt><span class="chapter"><a href="#id2589910">4. Handling Precautions</a></span></dt><dt><span class="chapter"><a href="#id2562288">5. Hardware Overview</a></span></dt><dt><span class="chapter"><a href="#id2568154">6. System Operation</a></span></dt><dd><dl><dt><span class="section"><a href="#id2571301">Firmware Modes </a></span></dt><dt><span class="section"><a href="#id2573013">GPS </a></span></dt><dt><span class="section"><a href="#id2587417">Ground Testing </a></span></dt><dt><span class="section"><a href="#id2587414">Radio Link </a></span></dt><dt><span class="section"><a href="#id2558135">Configurable Parameters</a></span></dt><dd><dl><dt><span class="section"><a href="#id2578406">Radio Channel</a></span></dt><dt><span class="section"><a href="#id2569320">Apogee Delay</a></span></dt><dt><span class="section"><a href="#id2587127">Main Deployment Altitude</a></span></dt></dl></dd><dt><span class="section"><a href="#id2565755">Calibration</a></span></dt><dd><dl><dt><span class="section"><a href="#id2589478">Radio Frequency</a></span></dt><dt><span class="section"><a href="#id2579588">Accelerometer</a></span></dt></dl></dd><dt><span class="section"><a href="#id2587826">Updating Device Firmware</a></span></dt><dd><dl><dt><span class="section"><a href="#id2560725">Updating TeleMetrum Firmware</a></span></dt><dt><span class="section"><a href="#id2579530">Updating TeleDongle Firmware</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#id2576399">7. AltosUI</a></span></dt><dd><dl><dt><span class="section"><a href="#id2576677">Packet Command Mode</a></span></dt><dt><span class="section"><a href="#id2581723">Monitor Flight</a></span></dt><dd><dl><dt><span class="section"><a href="#id2576742">Launch Pad</a></span></dt><dt><span class="section"><a href="#id2571392">Ascent</a></span></dt><dt><span class="section"><a href="#id2578242">Descent</a></span></dt><dt><span class="section"><a href="#id2586734">Landed</a></span></dt><dt><span class="section"><a href="#id2568067">Site Map</a></span></dt></dl></dd><dt><span class="section"><a href="#id2572352">Save Flight Data</a></span></dt><dt><span class="section"><a href="#id2592536">Replay Flight</a></span></dt><dt><span class="section"><a href="#id2579359">Graph Data</a></span></dt><dt><span class="section"><a href="#id2574359">Export Data</a></span></dt><dd><dl><dt><span class="section"><a href="#id2581561">Comma Separated Value Format</a></span></dt><dt><span class="section"><a href="#id2585122">Keyhole Markup Language (for Google Earth)</a></span></dt></dl></dd><dt><span class="section"><a href="#id2576382">Configure TeleMetrum</a></span></dt><dd><dl><dt><span class="section"><a href="#id2565240">Main Deploy Altitude</a></span></dt><dt><span class="section"><a href="#id2558922">Apogee Delay</a></span></dt><dt><span class="section"><a href="#id2588372">Radio Channel</a></span></dt><dt><span class="section"><a href="#id2569947">Radio Calibration</a></span></dt><dt><span class="section"><a href="#id2567826">Callsign</a></span></dt></dl></dd><dt><span class="section"><a href="#id2567986">Configure AltosUI</a></span></dt><dd><dl><dt><span class="section"><a href="#id2554292">Voice Settings</a></span></dt><dt><span class="section"><a href="#id2592599">Log Directory</a></span></dt><dt><span class="section"><a href="#id2559399">Callsign</a></span></dt></dl></dd><dt><span class="section"><a href="#id2579274">Flash Image</a></span></dt><dt><span class="section"><a href="#id2577046">Fire Igniter</a></span></dt></dl></dd><dt><span class="chapter"><a href="#id2587842">8. Using Altus Metrum Products</a></span></dt><dd><dl><dt><span class="section"><a href="#id2574948">Being Legal</a></span></dt><dd><dl><dt><span class="section"><a href="#id2561015">In the Rocket</a></span></dt><dt><span class="section"><a href="#id2575161">On the Ground</a></span></dt><dt><span class="section"><a href="#id2581564">Data Analysis</a></span></dt><dt><span class="section"><a href="#id2562286">Future Plans</a></span></dt></dl></dd></dl></dd></dl></div><div class="chapter" title="Chapter 1. Introduction and Overview"><div class="titlepage"><div><div><h2 class="title"><a name="id2562143"></a>Chapter 1. Introduction and Overview</h2></div></div></div><p>
       Welcome to the Altus Metrum community!  Our circuits and software reflect
       our passion for both hobby rocketry and Free Software.  We hope their
       capabilities and performance will delight you in every way, but by
       we also hope to empower you to take as active a role in our collective
       future as you wish!
     </p><p>
-      The focal point of our community is TeleMetrum, a dual deploy altimeter 
+      The focal point of our community is TeleMetrum, a dual deploy altimeter
       with fully integrated GPS and radio telemetry as standard features, and
-      a "companion interface" that will support optional capabilities in the 
+      a "companion interface" that will support optional capabilities in the
       future.
-    </p><p>    
-      Complementing TeleMetrum is TeleDongle, a USB to RF interface for 
-      communicating with TeleMetrum.  Combined with your choice of antenna and 
+    </p><p>
+      Complementing TeleMetrum is TeleDongle, a USB to RF interface for
+      communicating with TeleMetrum.  Combined with your choice of antenna and
       notebook computer, TeleDongle and our associated user interface software
       form a complete ground station capable of logging and displaying in-flight
       telemetry, aiding rocket recovery, then processing and archiving flight
       More products will be added to the Altus Metrum family over time, and
       we currently envision that this will be a single, comprehensive manual
       for the entire product family.
-    </p></div><div class="chapter" title="Chapter 2. Getting Started"><div class="titlepage"><div><div><h2 class="title"><a name="id2540100"></a>Chapter 2. Getting Started</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2559795">FAQ</a></span></dt></dl></div><p>
-      This chapter began as "The Mere-Mortals Quick Start/Usage Guide to 
-      the Altus Metrum Starter Kit" by Bob Finch, W9YA, NAR 12965, TRA 12350, 
-      w9ya@amsat.org.  Bob was one of our first customers for a production
-      TeleMetrum, and the enthusiasm that led to his contribution of this
-      section is immensely gratifying and highy appreciated!
-    </p><p>
-      The first thing to do after you check the inventory of parts in your 
-      "starter kit" is to charge the battery by plugging it into the 
-      corresponding socket of the TeleMetrum and then using the USB A to B 
-      cable to plug the Telemetrum into your computer's USB socket. The 
-      TeleMetrum circuitry will charge the battery whenever it is plugged 
-      into the usb socket. The TeleMetrum's on-off switch does NOT control 
-      the charging circuitry.  When the GPS chip is initially searching for
-      satellites, the unit will pull more current than it can pull from the
-      usb port, so the battery must be plugged in order to get a good 
-      satellite lock.  Once GPS is locked the current consumption goes back 
-      down enough to enable charging while 
-      running. So it's a good idea to fully charge the battery as your 
-      first item of business so there is no issue getting and maintaining 
-      satellite lock.  The yellow charge indicator led will go out when the 
-      battery is nearly full and the charger goes to trickle charge.
+    </p></div><div class="chapter" title="Chapter 2. Getting Started"><div class="titlepage"><div><div><h2 class="title"><a name="id2535919"></a>Chapter 2. Getting Started</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2574950">FAQ</a></span></dt></dl></div><p>
+      The first thing to do after you check the inventory of parts in your
+      "starter kit" is to charge the battery by plugging it into the
+      corresponding socket of the TeleMetrum and then using the USB A to
+      mini B
+      cable to plug the Telemetrum into your computer's USB socket. The
+      TeleMetrum circuitry will charge the battery whenever it is plugged
+      in, because the TeleMetrum's on-off switch does NOT control the
+      charging circuitry.  When the GPS chip is initially searching for
+      satellites, TeleMetrum will consume more current than it can pull
+      from the usb port, so the battery must be attached in order to get
+      satellite lock.  Once GPS is locked, the current consumption goes back
+      down enough to enable charging while
+      running. So it's a good idea to fully charge the battery as your
+      first item of business so there is no issue getting and maintaining
+      satellite lock.  The yellow charge indicator led will go out when the
+      battery is nearly full and the charger goes to trickle charge. It
+      can take several hours to fully recharge a deeply discharged battery.
     </p><p>
-      The other active device in the starter kit is the half-duplex TeleDongle 
-      rf link.  If you plug it in to your computer it should "just work",
-      showing up as a serial port device.  If you are using Linux and are
+      The other active device in the starter kit is the TeleDongle USB to
+      RF interface.  If you plug it in to your Mac or Linux computer it should
+      "just work", showing up as a serial port device.  Windows systems need
+      driver information that is part of the AltOS download to know that the
+      existing USB modem driver will work.  If you are using Linux and are
       having problems, try moving to a fresher kernel (2.6.33 or newer), as
-      there were some ugly USB serial driver bugs in earlier versions.
-    </p><p>
-      Next you should obtain and install the AltOS utilities.  The first
-      generation sofware was written for Linux only.  New software is coming
-      soon that will also run on Windows and Mac.  For now, we'll concentrate
-      on Linux.  If you are using Debian, an 'altos' package already exists, 
-      see http://altusmetrum.org/AltOS for details on how to install it.
-      User-contributed directions for building packages on ArchLinux may be 
-      found in the contrib/arch-linux directory as PKGBUILD files.
-      Between the debian/rules file and the PKGBUILD files in 
-      contrib, you should find enough information to learn how to build the 
-      software for any other version of Linux.
+      the USB serial driver had ugly bugs in some earlier versions.
     </p><p>
-      When you have successfully installed the software suite (either from 
-      compiled source code or as the pre-built Debian package) you will 
-      have 10 or so executable programs all of which have names beginning 
-      with 'ao-'.
-      ('ao-view' is the lone GUI-based program, the rest are command-line 
-      oriented.) You will also have man pages, that give you basic info 
-      on each program.
-      You will also get this documentation in two file types in the doc/ 
-      directory, telemetrum-doc.pdf and telemetrum-doc.html.
-      Finally you will have a couple control files that allow the ao-view 
-      GUI-based program to appear in your menu of programs (under 
-      the 'Internet' category). 
+      Next you should obtain and install the AltOS utilities.  These include
+      the AltosUI ground station program, current firmware images for
+      TeleMetrum and TeleDongle, and a number of standalone utilities that
+      are rarely needed.  Pre-built binary packages are available for Debian
+      Linux, Microsoft Windows, and recent MacOSX versions.  Full sourcecode
+      and build instructions for some other Linux variants are also available.
+      The latest version may always be downloaded from
+      <a class="ulink" href="http://altusmetrum.org/AltOS" target="_top">http://altusmetrum.org/AltOS</a>.
     </p><p>
-      Both Telemetrum and TeleDongle can be directly communicated 
-      with using USB ports. The first thing you should try after getting 
-      both units plugged into to your computer's usb port(s) is to run 
-      'ao-list' from a terminal-window to see what port-device-name each 
-      device has been assigned by the operating system. 
-      You will need this information to access the devices via their 
+      Both Telemetrum and TeleDongle can be directly communicated
+      with using USB ports. The first thing you should try after getting
+      both units plugged into to your computer's usb port(s) is to run
+      'ao-list' from a terminal-window to see what port-device-name each
+      device has been assigned by the operating system.
+      You will need this information to access the devices via their
       respective on-board firmware and data using other command line
       programs in the AltOS software suite.
     </p><p>
       To access the device's firmware for configuration you need a terminal
-      program such as you would use to talk to a modem.  The software 
+      program such as you would use to talk to a modem.  The software
       authors prefer using the program 'cu' which comes from the UUCP package
       on most Unix-like systems such as Linux.  An example command line for
-      cu might be 'cu -l /dev/ttyACM0', substituting the correct number 
+      cu might be 'cu -l /dev/ttyACM0', substituting the correct number
       indicated from running the
       ao-list program.  Another reasonable terminal program for Linux is
-      'cutecom'.  The default 'escape' 
+      'cutecom'.  The default 'escape'
       character used by CU (i.e. the character you use to
-      issue commands to cu itself instead of sending the command as input 
-      to the connected device) is a '~'. You will need this for use in 
-      only two different ways during normal operations. First is to exit 
-      the program by sending a '~.' which is called a 'escape-disconnect' 
+      issue commands to cu itself instead of sending the command as input
+      to the connected device) is a '~'. You will need this for use in
+      only two different ways during normal operations. First is to exit
+      the program by sending a '~.' which is called a 'escape-disconnect'
       and allows you to close-out from 'cu'. The
       second use will be outlined later.
     </p><p>
-      Both TeleMetrum and TeleDongle share the concept of a two level 
-      command set in their firmware.  
-      The first layer has several single letter commands. Once 
-      you are using 'cu' (or 'cutecom') sending (typing) a '?' 
+      Both TeleMetrum and TeleDongle share the concept of a two level
+      command set in their firmware.
+      The first layer has several single letter commands. Once
+      you are using 'cu' (or 'cutecom') sending (typing) a '?'
       returns a full list of these
-      commands. The second level are configuration sub-commands accessed 
-      using the 'c' command, for 
-      instance typing 'c?' will give you this second level of commands 
+      commands. The second level are configuration sub-commands accessed
+      using the 'c' command, for
+      instance typing 'c?' will give you this second level of commands
       (all of which require the
       letter 'c' to access).  Please note that most configuration options
       are stored only in DataFlash memory, and only TeleMetrum has this
-      memory to save the various values entered like the channel number 
+      memory to save the various values entered like the channel number
       and your callsign when powered off.  TeleDongle requires that you
       set these each time you plug it in, which ao-view can help with.
     </p><p>
       Try setting these config ('c' or second level menu) values.  A good
       place to start is by setting your call sign.  By default, the boards
       use 'N0CALL' which is cute, but not exactly legal!
-      Spend a few minutes getting comfortable with the units, their 
+      Spend a few minutes getting comfortable with the units, their
       firmware, and 'cu' (or possibly 'cutecom').
-      For instance, try to send 
-      (type) a 'c r 2' and verify the channel change by sending a 'c s'. 
+      For instance, try to send
+      (type) a 'c r 2' and verify the channel change by sending a 'c s'.
       Verify you can connect and disconnect from the units while in your
       terminal program by sending the escape-disconnect mentioned above.
     </p><p>
-      Note that the 'reboot' command, which is very useful on TeleMetrum, 
+      Note that the 'reboot' command, which is very useful on TeleMetrum,
       will likely just cause problems with the dongle.  The *correct* way
       to reset the dongle is just to unplug and re-plug it.
     </p><p>
-      A fun thing to do at the launch site and something you can do while 
-      learning how to use these units is to play with the rf-link access 
+      A fun thing to do at the launch site and something you can do while
+      learning how to use these units is to play with the rf-link access
       of the TeleMetrum from the TeleDongle.  Be aware that you *must* create
-      some physical separation between the devices, otherwise the link will 
+      some physical separation between the devices, otherwise the link will
       not function due to signal overload in the receivers in each device.
     </p><p>
       Now might be a good time to take a break and read the rest of this
-      manual, particularly about the two "modes" that the TeleMetrum 
-      can be placed in and how the position of the TeleMetrum when booting 
+      manual, particularly about the two "modes" that the TeleMetrum
+      can be placed in and how the position of the TeleMetrum when booting
       up will determine whether the unit is in "pad" or "idle" mode.
     </p><p>
-      You can access a TeleMetrum in idle mode from the Teledongle's USB 
+      You can access a TeleMetrum in idle mode from the Teledongle's USB
       connection using the rf link
       by issuing a 'p' command to the TeleDongle. Practice connecting and
-      disconnecting ('~~' while using 'cu') from the TeleMetrum.  If 
-      you cannot escape out of the "p" command, (by using a '~~' when in 
+      disconnecting ('~~' while using 'cu') from the TeleMetrum.  If
+      you cannot escape out of the "p" command, (by using a '~~' when in
       CU) then it is likely that your kernel has issues.  Try a newer version.
     </p><p>
-      Using this rf link allows you to configure the TeleMetrum, test 
-      fire e-matches and igniters from the flight line, check pyro-match 
-      continuity and so forth. You can leave the unit turned on while it 
+      Using this rf link allows you to configure the TeleMetrum, test
+      fire e-matches and igniters from the flight line, check pyro-match
+      continuity and so forth. You can leave the unit turned on while it
       is in 'idle mode' and then place the
-      rocket vertically on the launch pad, walk away and then issue a 
-      reboot command.  The TeleMetrum will reboot and start sending data 
-      having changed to the "pad" mode. If the TeleDongle is not receiving 
-      this data, you can disconnect 'cu' from the Teledongle using the 
-      procedures mentioned above and THEN connect to the TeleDongle from 
+      rocket vertically on the launch pad, walk away and then issue a
+      reboot command.  The TeleMetrum will reboot and start sending data
+      having changed to the "pad" mode. If the TeleDongle is not receiving
+      this data, you can disconnect 'cu' from the Teledongle using the
+      procedures mentioned above and THEN connect to the TeleDongle from
       inside 'ao-view'. If this doesn't work, disconnect from the
       TeleDongle, unplug it, and try again after plugging it back in.
     </p><p>
-      Eventually the GPS will find enough satellites, lock in on them, 
-      and 'ao-view' will both auditorially announce and visually indicate 
+      Eventually the GPS will find enough satellites, lock in on them,
+      and 'ao-view' will both auditorially announce and visually indicate
       that GPS is ready.
-      Now you can launch knowing that you have a good data path and 
-      good satellite lock for flight data and recovery.  Remember 
-      you MUST tell ao-view to connect to the TeleDongle explicitly in 
+      Now you can launch knowing that you have a good data path and
+      good satellite lock for flight data and recovery.  Remember
+      you MUST tell ao-view to connect to the TeleDongle explicitly in
       order for ao-view to be able to receive data.
     </p><p>
-      Both RDF (radio direction finding) tones from the TeleMetrum and 
-      GPS trekking data are available and together are very useful in 
-      locating the rocket once it has landed. (The last good GPS data 
+      Both RDF (radio direction finding) tones from the TeleMetrum and
+      GPS trekking data are available and together are very useful in
+      locating the rocket once it has landed. (The last good GPS data
       received before touch-down will be on the data screen of 'ao-view'.)
     </p><p>
-      Once you have recovered the rocket you can download the eeprom 
+      Once you have recovered the rocket you can download the eeprom
       contents using either 'ao-dumplog' (or possibly 'ao-eeprom'), over
       either a USB cable or over the radio link using TeleDongle.
-      And by following the man page for 'ao-postflight' you can create 
-      various data output reports, graphs, and even kml data to see the 
-      flight trajectory in google-earth. (Moving the viewing angle making 
+      And by following the man page for 'ao-postflight' you can create
+      various data output reports, graphs, and even kml data to see the
+      flight trajectory in google-earth. (Moving the viewing angle making
       sure to connect the yellow lines while in google-earth is the proper
       technique.)
     </p><p>
-      As for ao-view.... some things are in the menu but don't do anything 
+      As for ao-view.... some things are in the menu but don't do anything
       very useful.  The developers have stopped working on ao-view to focus
-      on a new, cross-platform ground station program.  So ao-view may or 
-      may not be updated in the future.  Mostly you just use 
-      the Log and Device menus.  It has a wonderful display of the incoming 
-      flight data and I am sure you will enjoy what it has to say to you 
+      on a new, cross-platform ground station program.  So ao-view may or
+      may not be updated in the future.  Mostly you just use
+      the Log and Device menus.  It has a wonderful display of the incoming
+      flight data and I am sure you will enjoy what it has to say to you
       once you enable the voice output!
-    </p><div class="section" title="FAQ"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2559795"></a>FAQ</h2></div></div></div><p>
+    </p><div class="section" title="FAQ"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2574950"></a>FAQ</h2></div></div></div><p>
         The altimeter (TeleMetrum) seems to shut off when disconnected from the
         computer.  Make sure the battery is adequately charged.  Remember the
-        unit will pull more power than the USB port can deliver before the 
+        unit will pull more power than the USB port can deliver before the
         GPS enters "locked" mode.  The battery charges best when TeleMetrum
         is turned off.
       </p><p>
         It's impossible to stop the TeleDongle when it's in "p" mode, I have
-        to unplug the USB cable?  Make sure you have tried to "escape out" of 
-        this mode.  If this doesn't work the reboot procedure for the 
-        TeleDongle *is* to simply unplug it. 'cu' however will retain it's 
-        outgoing buffer IF your "escape out" ('~~') does not work. 
+        to unplug the USB cable?  Make sure you have tried to "escape out" of
+        this mode.  If this doesn't work the reboot procedure for the
+        TeleDongle *is* to simply unplug it. 'cu' however will retain it's
+        outgoing buffer IF your "escape out" ('~~') does not work.
         At this point using either 'ao-view' (or possibly
         'cutemon') instead of 'cu' will 'clear' the issue and allow renewed
         communication.
       </p><p>
-        The amber LED (on the TeleMetrum/altimeter) lights up when both 
-        battery and USB are connected. Does this mean it's charging? 
-        Yes, the yellow LED indicates the charging at the 'regular' rate. 
-        If the led is out but the unit is still plugged into a USB port, 
+        The amber LED (on the TeleMetrum/altimeter) lights up when both
+        battery and USB are connected. Does this mean it's charging?
+        Yes, the yellow LED indicates the charging at the 'regular' rate.
+        If the led is out but the unit is still plugged into a USB port,
         then the battery is being charged at a 'trickle' rate.
       </p><p>
         There are no "dit-dah-dah-dit" sound like the manual mentions?
         That's the "pad" mode.  Weak batteries might be the problem.
-        It is also possible that the unit is horizontal and the output 
+        It is also possible that the unit is horizontal and the output
         is instead a "dit-dit" meaning 'idle'.
       </p><p>
-        It's unclear how to use 'ao-view' and other programs when 'cu' 
-        is running. You cannot have more than one program connected to 
-        the TeleDongle at one time without apparent data loss as the 
-        incoming data will not make it to both programs intact. 
+        It's unclear how to use 'ao-view' and other programs when 'cu'
+        is running. You cannot have more than one program connected to
+        the TeleDongle at one time without apparent data loss as the
+        incoming data will not make it to both programs intact.
         Disconnect whatever programs aren't currently being used.
       </p><p>
-        How do I save flight data?   
-        Live telemetry is written to file(s) whenever 'ao-view' is connected 
+        How do I save flight data?
+        Live telemetry is written to file(s) whenever 'ao-view' is connected
         to the TeleDongle.  The file area defaults to ~/altos
-        but is easily changed using the menus in 'ao-view'. The files that 
+        but is easily changed using the menus in 'ao-view'. The files that
         are written end in '.telem'. The after-flight
-        data-dumped files will end in .eeprom and represent continuous data 
-        unlike the rf-linked .telem files that are subject to the 
-        turnarounds/data-packaging time slots in the half-duplex rf data path. 
-        See the above instructions on what and how to save the eeprom stored 
+        data-dumped files will end in .eeprom and represent continuous data
+        unlike the rf-linked .telem files that are subject to the
+        turnarounds/data-packaging time slots in the half-duplex rf data path.
+        See the above instructions on what and how to save the eeprom stored
         data after physically retrieving your TeleMetrum.  Make sure to save
         the on-board data after each flight, as the current firmware will
         over-write any previous flight data during a new flight.
-      </p></div></div><div class="chapter" title="Chapter 3. Specifications"><div class="titlepage"><div><div><h2 class="title"><a name="id2546901"></a>Chapter 3. Specifications</h2></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
+      </p></div></div><div class="chapter" title="Chapter 3. Specifications"><div class="titlepage"><div><div><h2 class="title"><a name="id2562056"></a>Chapter 3. Specifications</h2></div></div></div><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
           Recording altimeter for model rocketry.
         </p></li><li class="listitem"><p>
           Supports dual deployment (can fire 2 ejection charges).
         </p></li><li class="listitem"><p>
           Barometric pressure sensor good to 45k feet MSL.
         </p></li><li class="listitem"><p>
-          1-axis high-g accelerometer for motor characterization, capable of 
+          1-axis high-g accelerometer for motor characterization, capable of
           +/- 50g using default part.
         </p></li><li class="listitem"><p>
           On-board, integrated GPS receiver with 5hz update rate capability.
         </p></li><li class="listitem"><p>
           Fully integrated support for LiPo rechargeable batteries.
         </p></li><li class="listitem"><p>
-          Uses LiPo to fire e-matches, support for optional separate pyro 
+          Uses LiPo to fire e-matches, support for optional separate pyro
           battery if needed.
         </p></li><li class="listitem"><p>
           2.75 x 1 inch board designed to fit inside 29mm airframe coupler tube.
-        </p></li></ul></div></div><div class="chapter" title="Chapter 4. Handling Precautions"><div class="titlepage"><div><div><h2 class="title"><a name="id2574755"></a>Chapter 4. Handling Precautions</h2></div></div></div><p>
+        </p></li></ul></div></div><div class="chapter" title="Chapter 4. Handling Precautions"><div class="titlepage"><div><div><h2 class="title"><a name="id2589910"></a>Chapter 4. Handling Precautions</h2></div></div></div><p>
       TeleMetrum is a sophisticated electronic device.  When handled gently and
       properly installed in an airframe, it will deliver impressive results.
       However, like all electronic devices, there are some precautions you
       must take.
     </p><p>
-      The Lithium Polymer rechargeable batteries used with TeleMetrum have an 
+      The Lithium Polymer rechargeable batteries used with TeleMetrum have an
       extraordinary power density.  This is great because we can fly with
       much less battery mass than if we used alkaline batteries or previous
-      generation rechargeable batteries... but if they are punctured 
-      or their leads are allowed to short, they can and will release their 
+      generation rechargeable batteries... but if they are punctured
+      or their leads are allowed to short, they can and will release their
       energy very rapidly!
-      Thus we recommend that you take some care when handling our batteries 
-      and consider giving them some extra protection in your airframe.  We 
-      often wrap them in suitable scraps of closed-cell packing foam before 
+      Thus we recommend that you take some care when handling our batteries
+      and consider giving them some extra protection in your airframe.  We
+      often wrap them in suitable scraps of closed-cell packing foam before
       strapping them down, for example.
     </p><p>
-      The TeleMetrum barometric sensor is sensitive to sunlight.  In normal 
-      mounting situations, it and all of the other surface mount components 
+      The TeleMetrum barometric sensor is sensitive to sunlight.  In normal
+      mounting situations, it and all of the other surface mount components
       are "down" towards whatever the underlying mounting surface is, so
       this is not normally a problem.  Please consider this, though, when
-      designing an installation, for example, in a 29mm airframe with a 
+      designing an installation, for example, in a 29mm airframe with a
       see-through plastic payload bay.
     </p><p>
-      The TeleMetrum barometric sensor sampling port must be able to 
+      The TeleMetrum barometric sensor sampling port must be able to
       "breathe",
       both by not being covered by foam or tape or other materials that might
       directly block the hole on the top of the sensor, but also by having a
-      suitable static vent to outside air.  
+      suitable static vent to outside air.
     </p><p>
-      As with all other rocketry electronics, TeleMetrum must be protected 
+      As with all other rocketry electronics, TeleMetrum must be protected
       from exposure to corrosive motor exhaust and ejection charge gasses.
-    </p></div><div class="chapter" title="Chapter 5. Hardware Overview"><div class="titlepage"><div><div><h2 class="title"><a name="id2547133"></a>Chapter 5. Hardware Overview</h2></div></div></div><p>
+    </p></div><div class="chapter" title="Chapter 5. Hardware Overview"><div class="titlepage"><div><div><h2 class="title"><a name="id2562288"></a>Chapter 5. Hardware Overview</h2></div></div></div><p>
       TeleMetrum is a 1 inch by 2.75 inch circuit board.  It was designed to
       fit inside coupler for 29mm airframe tubing, but using it in a tube that
-      small in diameter may require some creativity in mounting and wiring 
+      small in diameter may require some creativity in mounting and wiring
       to succeed!  The default 1/4
       wave UHF wire antenna attached to the center of the nose-cone end of
       the board is about 7 inches long, and wiring for a power switch and
-      the e-matches for apogee and main ejection charges depart from the 
-      fin can end of the board.  Given all this, an ideal "simple" avionics 
+      the e-matches for apogee and main ejection charges depart from the
+      fin can end of the board.  Given all this, an ideal "simple" avionics
       bay for TeleMetrum should have at least 10 inches of interior length.
     </p><p>
       A typical TeleMetrum installation using the on-board GPS antenna and
       default wire UHF antenna involves attaching only a suitable
-      Lithium Polymer battery, a single pole switch for power on/off, and 
+      Lithium Polymer battery, a single pole switch for power on/off, and
       two pairs of wires connecting e-matches for the apogee and main ejection
-      charges.  
+      charges.
     </p><p>
       By default, we use the unregulated output of the LiPo battery directly
-      to fire ejection charges.  This works marvelously with standard 
-      low-current e-matches like the J-Tek from MJG Technologies, and with 
+      to fire ejection charges.  This works marvelously with standard
+      low-current e-matches like the J-Tek from MJG Technologies, and with
       Quest Q2G2 igniters.  However, if you
       want or need to use a separate pyro battery, you can do so by adding
       a second 2mm connector to position B2 on the board and cutting the
       the two silk screen marks on the surface mount side of the board shown
       here [insert photo]
     </p><p>
-      We offer two choices of pyro and power switch connector, or you can 
+      We offer two choices of pyro and power switch connector, or you can
       choose neither and solder wires directly to the board.  All three choices
       are reasonable depending on the constraints of your airframe.  Our
       favorite option when there is sufficient room above the board is to use
       the Tyco pin header with polarization and locking.  If you choose this
       option, you crimp individual wires for the power switch and e-matches
       into a mating connector, and installing and removing the TeleMetrum
-      board from an airframe is as easy as plugging or unplugging two 
+      board from an airframe is as easy as plugging or unplugging two
       connectors.  If the airframe will not support this much height or if
       you want to be able to directly attach e-match leads to the board, we
       offer a screw terminal block.  This is very similar to what most other
-      altimeter vendors provide and so may be the most familiar option.  
+      altimeter vendors provide and so may be the most familiar option.
       You'll need a very small straight blade screwdriver to connect
       and disconnect the board in this case, such as you might find in a
       jeweler's screwdriver set.  Finally, you can forego both options and
       solder wires directly to the board, which may be the best choice for
-      minimum diameter and/or minimum mass designs. 
+      minimum diameter and/or minimum mass designs.
     </p><p>
       For most airframes, the integrated GPS antenna and wire UHF antenna are
       a great combination.  However, if you are installing in a carbon-fiber
-      electronics bay which is opaque to RF signals, you may need to use 
+      electronics bay which is opaque to RF signals, you may need to use
       off-board external antennas instead.  In this case, you can order
       TeleMetrum with an SMA connector for the UHF antenna connection, and
-      you can unplug the integrated GPS antenna and select an appropriate 
+      you can unplug the integrated GPS antenna and select an appropriate
       off-board GPS antenna with cable terminating in a U.FL connector.
-    </p></div><div class="chapter" title="Chapter 6. Operation"><div class="titlepage"><div><div><h2 class="title"><a name="id2552998"></a>Chapter 6. Operation</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2556146">Firmware Modes </a></span></dt><dt><span class="section"><a href="#id2557858">GPS </a></span></dt><dt><span class="section"><a href="#id2572262">Ground Testing </a></span></dt><dt><span class="section"><a href="#id2572259">Radio Link </a></span></dt><dt><span class="section"><a href="#id2542980">Configurable Parameters</a></span></dt><dd><dl><dt><span class="section"><a href="#id2563251">Radio Channel</a></span></dt><dt><span class="section"><a href="#id2554165">Apogee Delay</a></span></dt><dt><span class="section"><a href="#id2571971">Main Deployment Altitude</a></span></dt></dl></dd><dt><span class="section"><a href="#id2550600">Calibration</a></span></dt><dd><dl><dt><span class="section"><a href="#id2574322">Radio Frequency</a></span></dt><dt><span class="section"><a href="#id2564433">Accelerometer</a></span></dt></dl></dd></dl></div><div class="section" title="Firmware Modes"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2556146"></a>Firmware Modes </h2></div></div></div><p>
+    </p></div><div class="chapter" title="Chapter 6. System Operation"><div class="titlepage"><div><div><h2 class="title"><a name="id2568154"></a>Chapter 6. System Operation</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2571301">Firmware Modes </a></span></dt><dt><span class="section"><a href="#id2573013">GPS </a></span></dt><dt><span class="section"><a href="#id2587417">Ground Testing </a></span></dt><dt><span class="section"><a href="#id2587414">Radio Link </a></span></dt><dt><span class="section"><a href="#id2558135">Configurable Parameters</a></span></dt><dd><dl><dt><span class="section"><a href="#id2578406">Radio Channel</a></span></dt><dt><span class="section"><a href="#id2569320">Apogee Delay</a></span></dt><dt><span class="section"><a href="#id2587127">Main Deployment Altitude</a></span></dt></dl></dd><dt><span class="section"><a href="#id2565755">Calibration</a></span></dt><dd><dl><dt><span class="section"><a href="#id2589478">Radio Frequency</a></span></dt><dt><span class="section"><a href="#id2579588">Accelerometer</a></span></dt></dl></dd><dt><span class="section"><a href="#id2587826">Updating Device Firmware</a></span></dt><dd><dl><dt><span class="section"><a href="#id2560725">Updating TeleMetrum Firmware</a></span></dt><dt><span class="section"><a href="#id2579530">Updating TeleDongle Firmware</a></span></dt></dl></dd></dl></div><div class="section" title="Firmware Modes"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2571301"></a>Firmware Modes </h2></div></div></div><p>
         The AltOS firmware build for TeleMetrum has two fundamental modes,
         "idle" and "flight".  Which of these modes the firmware operates in
         is determined by the orientation of the rocket (well, actually the
         if the rocket is more or less horizontal, the firmware instead enters
         idle mode.
       </p><p>
-        At power on, you will hear three beeps 
-        ("S" in Morse code for startup) and then a pause while 
+        At power on, you will hear three beeps
+        ("S" in Morse code for startup) and then a pause while
         TeleMetrum completes initialization and self tests, and decides which
         mode to enter next.
       </p><p>
-        In flight or "pad" mode, TeleMetrum turns on the GPS system, 
+        In flight or "pad" mode, TeleMetrum turns on the GPS system,
         engages the flight
-        state machine, goes into transmit-only mode on the RF link sending 
+        state machine, goes into transmit-only mode on the RF link sending
         telemetry, and waits for launch to be detected.  Flight mode is
-        indicated by an audible "di-dah-dah-dit" ("P" for pad) on the 
+        indicated by an audible "di-dah-dah-dit" ("P" for pad) on the
         beeper, followed by
         beeps indicating the state of the pyrotechnic igniter continuity.
         One beep indicates apogee continuity, two beeps indicate
         link when in idle mode for packet mode requests sent from TeleDongle.
         Commands can be issued to a TeleMetrum in idle mode over either
         USB or the RF link equivalently.
-        Idle mode is useful for configuring TeleMetrum, for extracting data 
+        Idle mode is useful for configuring TeleMetrum, for extracting data
         from the on-board storage chip after flight, and for ground testing
         pyro charges.
       </p><p>
         One "neat trick" of particular value when TeleMetrum is used with very
         large airframes, is that you can power the board up while the rocket
-        is horizontal, such that it comes up in idle mode.  Then you can 
+        is horizontal, such that it comes up in idle mode.  Then you can
         raise the airframe to launch position, use a TeleDongle to open
         a packet connection, and issue a 'reset' command which will cause
         TeleMetrum to reboot, realize it's now nose-up, and thus choose
         rickety step-ladder or hanging off the side of a launch tower with
         a screw-driver trying to turn on your avionics before installing
         igniters!
-      </p></div><div class="section" title="GPS"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2557858"></a>GPS </h2></div></div></div><p>
+      </p></div><div class="section" title="GPS"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2573013"></a>GPS </h2></div></div></div><p>
         TeleMetrum includes a complete GPS receiver.  See a later section for
         a brief explanation of how GPS works that will help you understand
         the information in the telemetry stream.  The bottom line is that
-        the TeleMetrum GPS receiver needs to lock onto at least four 
-        satellites to obtain a solid 3 dimensional position fix and know 
+        the TeleMetrum GPS receiver needs to lock onto at least four
+        satellites to obtain a solid 3 dimensional position fix and know
         what time it is!
       </p><p>
         TeleMetrum provides backup power to the GPS chip any time a LiPo
         is turned back on, the GPS system should lock very quickly, typically
         long before igniter installation and return to the flight line are
         complete.
-      </p></div><div class="section" title="Ground Testing"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2572262"></a>Ground Testing </h2></div></div></div><p>
+      </p></div><div class="section" title="Ground Testing"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2587417"></a>Ground Testing </h2></div></div></div><p>
         An important aspect of preparing a rocket using electronic deployment
         for flight is ground testing the recovery system.  Thanks
-        to the bi-directional RF link central to the Altus Metrum system, 
+        to the bi-directional RF link central to the Altus Metrum system,
         this can be accomplished in a TeleMetrum-equipped rocket without as
         much work as you may be accustomed to with other systems.  It can
         even be fun!
       </p><p>
         Just prep the rocket for flight, then power up TeleMetrum while the
-        airframe is horizontal.  This will cause the firmware to go into 
+        airframe is horizontal.  This will cause the firmware to go into
         "idle" mode, in which the normal flight state machine is disabled and
         charges will not fire without manual command.  Then, establish an
-        RF packet connection from a TeleDongle-equipped computer using the 
+        RF packet connection from a TeleDongle-equipped computer using the
         P command from a safe distance.  You can now command TeleMetrum to
         fire the apogee or main charges to complete your testing.
       </p><p>
         In order to reduce the chance of accidental firing of pyrotechnic
         charges, the command to fire a charge is intentionally somewhat
-        difficult to type, and the built-in help is slightly cryptic to 
+        difficult to type, and the built-in help is slightly cryptic to
         prevent accidental echoing of characters from the help text back at
         the board from firing a charge.  The command to fire the apogee
         drogue charge is 'i DoIt drogue' and the command to fire the main
         charge is 'i DoIt main'.
-      </p></div><div class="section" title="Radio Link"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2572259"></a>Radio Link </h2></div></div></div><p>
+      </p></div><div class="section" title="Radio Link"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2587414"></a>Radio Link </h2></div></div></div><p>
         The chip our boards are based on incorporates an RF transceiver, but
         it's not a full duplex system... each end can only be transmitting or
         receiving at any given moment.  So we had to decide how to manage the
         By design, TeleMetrum firmware listens for an RF connection when
         it's in "idle mode" (turned on while the rocket is horizontal), which
         allows us to use the RF link to configure the rocket, do things like
-        ejection tests, and extract data after a flight without having to 
-        crack open the airframe.  However, when the board is in "flight 
-        mode" (turned on when the rocket is vertical) the TeleMetrum only 
-        transmits and doesn't listen at all.  That's because we want to put 
-        ultimate priority on event detection and getting telemetry out of 
+        ejection tests, and extract data after a flight without having to
+        crack open the airframe.  However, when the board is in "flight
+        mode" (turned on when the rocket is vertical) the TeleMetrum only
+        transmits and doesn't listen at all.  That's because we want to put
+        ultimate priority on event detection and getting telemetry out of
         the rocket and out over
         the RF link in case the rocket crashes and we aren't able to extract
-        data later... 
+        data later...
       </p><p>
         We don't use a 'normal packet radio' mode because they're just too
-        inefficient.  The GFSK modulation we use is just FSK with the 
+        inefficient.  The GFSK modulation we use is just FSK with the
         baseband pulses passed through a
         Gaussian filter before they go into the modulator to limit the
         transmitted bandwidth.  When combined with the hardware forward error
         the ground.  We hope to fly boards to higher altitudes soon, and would
         of course appreciate customer feedback on performance in higher
         altitude flights!
-      </p></div><div class="section" title="Configurable Parameters"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2542980"></a>Configurable Parameters</h2></div></div></div><p>
+      </p></div><div class="section" title="Configurable Parameters"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2558135"></a>Configurable Parameters</h2></div></div></div><p>
         Configuring a TeleMetrum board for flight is very simple.  Because we
         have both acceleration and pressure sensors, there is no need to set
         a "mach delay", for example.  The few configurable parameters can all
         be set using a simple terminal program over the USB port or RF link
         via TeleDongle.
-      </p><div class="section" title="Radio Channel"><div class="titlepage"><div><div><h3 class="title"><a name="id2563251"></a>Radio Channel</h3></div></div></div><p>
+      </p><div class="section" title="Radio Channel"><div class="titlepage"><div><div><h3 class="title"><a name="id2578406"></a>Radio Channel</h3></div></div></div><p>
           Our firmware supports 10 channels.  The default channel 0 corresponds
-          to a center frequency of 434.550 Mhz, and channels are spaced every 
+          to a center frequency of 434.550 Mhz, and channels are spaced every
           100 khz.  Thus, channel 1 is 434.650 Mhz, and channel 9 is 435.550 Mhz.
           At any given launch, we highly recommend coordinating who will use
-          each channel and when to avoid interference.  And of course, both 
+          each channel and when to avoid interference.  And of course, both
           TeleMetrum and TeleDongle must be configured to the same channel to
           successfully communicate with each other.
         </p><p>
           To set the radio channel, use the 'c r' command, like 'c r 3' to set
-          channel 3.  
-          As with all 'c' sub-commands, follow this with a 'c w' to write the 
+          channel 3.
+          As with all 'c' sub-commands, follow this with a 'c w' to write the
           change to the parameter block in the on-board DataFlash chip on
           your TeleMetrum board if you want the change to stay in place across reboots.
-        </p></div><div class="section" title="Apogee Delay"><div class="titlepage"><div><div><h3 class="title"><a name="id2554165"></a>Apogee Delay</h3></div></div></div><p>
+        </p></div><div class="section" title="Apogee Delay"><div class="titlepage"><div><div><h3 class="title"><a name="id2569320"></a>Apogee Delay</h3></div></div></div><p>
           Apogee delay is the number of seconds after TeleMetrum detects flight
           apogee that the drogue charge should be fired.  In most cases, this
           should be left at the default of 0.  However, if you are flying
-          redundant electronics such as for an L3 certification, you may wish 
-          to set one of your altimeters to a positive delay so that both 
+          redundant electronics such as for an L3 certification, you may wish
+          to set one of your altimeters to a positive delay so that both
           primary and backup pyrotechnic charges do not fire simultaneously.
         </p><p>
-          To set the apogee delay, use the [FIXME] command.
-          As with all 'c' sub-commands, follow this with a 'c w' to write the 
+          To set the apogee delay, use the 'c d' command.
+          As with all 'c' sub-commands, follow this with a 'c w' to write the
           change to the parameter block in the on-board DataFlash chip.
         </p><p>
           Please note that the TeleMetrum apogee detection algorithm always
           an altimeter like the PerfectFlite MAWD, which only supports selecting
           0 or 1 seconds of apogee delay, you may wish to set the MAWD to 0
           seconds delay and set the TeleMetrum to fire your backup 2 or 3
-          seconds later to avoid any chance of both charges firing 
+          seconds later to avoid any chance of both charges firing
           simultaneously.  We've flown several airframes this way quite happily,
           including Keith's successful L3 cert.
-        </p></div><div class="section" title="Main Deployment Altitude"><div class="titlepage"><div><div><h3 class="title"><a name="id2571971"></a>Main Deployment Altitude</h3></div></div></div><p>
+        </p></div><div class="section" title="Main Deployment Altitude"><div class="titlepage"><div><div><h3 class="title"><a name="id2587127"></a>Main Deployment Altitude</h3></div></div></div><p>
           By default, TeleMetrum will fire the main deployment charge at an
           elevation of 250 meters (about 820 feet) above ground.  We think this
-          is a good elevation for most airframes, but feel free to change this 
+          is a good elevation for most airframes, but feel free to change this
           to suit.  In particular, if you are flying two altimeters, you may
           wish to set the
           deployment elevation for the backup altimeter to be something lower
           than the primary so that both pyrotechnic charges don't fire
           simultaneously.
         </p><p>
-          To set the main deployment altitude, use the [FIXME] command.
-          As with all 'c' sub-commands, follow this with a 'c w' to write the 
+          To set the main deployment altitude, use the 'c m' command.
+          As with all 'c' sub-commands, follow this with a 'c w' to write the
           change to the parameter block in the on-board DataFlash chip.
-        </p></div></div><div class="section" title="Calibration"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2550600"></a>Calibration</h2></div></div></div><p>
+        </p></div></div><div class="section" title="Calibration"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2565755"></a>Calibration</h2></div></div></div><p>
         There are only two calibrations required for a TeleMetrum board, and
         only one for TeleDongle.
-      </p><div class="section" title="Radio Frequency"><div class="titlepage"><div><div><h3 class="title"><a name="id2574322"></a>Radio Frequency</h3></div></div></div><p>
+      </p><div class="section" title="Radio Frequency"><div class="titlepage"><div><div><h3 class="title"><a name="id2589478"></a>Radio Frequency</h3></div></div></div><p>
           The radio frequency is synthesized from a clock based on the 48 Mhz
           crystal on the board.  The actual frequency of this oscillator must be
           measured to generate a calibration constant.  While our GFSK modulation
-          bandwidth is wide enough to allow boards to communicate even when 
+          bandwidth is wide enough to allow boards to communicate even when
           their oscillators are not on exactly the same frequency, performance
           is best when they are closely matched.
           Radio frequency calibration requires a calibrated frequency counter.
           should generally not be required.
         </p><p>
           To calibrate the radio frequency, connect the UHF antenna port to a
-          frequency counter, set the board to channel 0, and use the 'C' 
+          frequency counter, set the board to channel 0, and use the 'C'
           command to generate a CW carrier.  Wait for the transmitter temperature
-          to stabilize and the frequency to settle down.  
-          Then, divide 434.550 Mhz by the 
+          to stabilize and the frequency to settle down.
+          Then, divide 434.550 Mhz by the
           measured frequency and multiply by the current radio cal value show
           in the 'c s' command.  For an unprogrammed board, the default value
           is 1186611.  Take the resulting integer and program it using the 'c f'
           command.  Testing with the 'C' command again should show a carrier
           within a few tens of Hertz of the intended frequency.
-          As with all 'c' sub-commands, follow this with a 'c w' to write the 
+          As with all 'c' sub-commands, follow this with a 'c w' to write the
           change to the parameter block in the on-board DataFlash chip.
-        </p></div><div class="section" title="Accelerometer"><div class="titlepage"><div><div><h3 class="title"><a name="id2564433"></a>Accelerometer</h3></div></div></div><p>
+        </p></div><div class="section" title="Accelerometer"><div class="titlepage"><div><div><h3 class="title"><a name="id2579588"></a>Accelerometer</h3></div></div></div><p>
           The accelerometer we use has its own 5 volt power supply and
           the output must be passed through a resistive voltage divider to match
           the input of our 3.3 volt ADC.  This means that unlike the barometric
-          sensor, the output of the acceleration sensor is not ratiometric to 
-          the ADC converter, and calibration is required.  We also support the 
-          use of any of several accelerometers from a Freescale family that 
+          sensor, the output of the acceleration sensor is not ratiometric to
+          the ADC converter, and calibration is required.  We also support the
+          use of any of several accelerometers from a Freescale family that
           includes at least +/- 40g, 50g, 100g, and 200g parts.  Using gravity,
           a simple 2-point calibration yields acceptable results capturing both
           the different sensitivities and ranges of the different accelerometer
         </p><p>
           To calibrate the acceleration sensor, use the 'c a 0' command.  You
           will be prompted to orient the board vertically with the UHF antenna
-          up and press a key, then to orient the board vertically with the 
+          up and press a key, then to orient the board vertically with the
           UHF antenna down and press a key.
-          As with all 'c' sub-commands, follow this with a 'c w' to write the 
+          As with all 'c' sub-commands, follow this with a 'c w' to write the
           change to the parameter block in the on-board DataFlash chip.
         </p><p>
           The +1g and -1g calibration points are included in each telemetry
           frame and are part of the header extracted by ao-dumplog after flight.
           Note that we always store and return raw ADC samples for each
-          sensor... nothing is permanently "lost" or "damaged" if the 
+          sensor... nothing is permanently "lost" or "damaged" if the
           calibration is poor.
-        </p></div></div></div><div class="chapter" title="Chapter 7. Updating Device Firmware"><div class="titlepage"><div><div><h2 class="title"><a name="id2554553"></a>Chapter 7. Updating Device Firmware</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2569887">Updating TeleMetrum Firmware</a></span></dt><dt><span class="section"><a href="#id2552683">Updating TeleDongle Firmware</a></span></dt></dl></div><p>
+        </p><p>
+         In the unlikely event an accel cal that goes badly, it is possible
+         that TeleMetrum may always come up in 'pad mode' and as such not be
+         listening to either the USB or radio interfaces.  If that happens,
+         there is a special hook in the firmware to force the board back
+         in to 'idle mode' so you can re-do the cal.  To use this hook, you
+         just need to ground the SPI clock pin at power-on.  This pin is
+         available as pin 2 on the 8-pin companion connector, and pin 1 is
+         ground.  So either carefully install a fine-gauge wire jumper
+         between the two pins closest to the index hole end of the 8-pin
+         connector, or plug in the programming cable to the 8-pin connector
+         and use a small screwdriver or similar to short the two pins closest
+         to the index post on the 4-pin end of the programming cable, and
+         power up the board.  It should come up in 'idle mode' (two beeps).
+        </p></div></div><div class="section" title="Updating Device Firmware"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2587826"></a>Updating Device Firmware</h2></div></div></div><p>
       The big conceptual thing to realize is that you have to use a
       TeleDongle as a programmer to update a TeleMetrum, and vice versa.
       Due to limited memory resources in the cc1111, we don't support
       You may wish to begin by ensuring you have current firmware images.
       These are distributed as part of the AltOS software bundle that
       also includes the AltosUI ground station program.  Newer ground
-      station versions typically work fine with older firmware versions, 
-      so you don't need to update your devices just to try out new 
-      software features.  You can always download the most recent 
-      version from http://www.altusmetrum.org/AltOS/.
+      station versions typically work fine with older firmware versions,
+      so you don't need to update your devices just to try out new
+      software features.  You can always download the most recent
+      version from <a class="ulink" href="http://www.altusmetrum.org/AltOS/" target="_top">http://www.altusmetrum.org/AltOS/</a>.
     </p><p>
       We recommend updating TeleMetrum first, before updating TeleDongle.
-    </p><div class="section" title="Updating TeleMetrum Firmware"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2569887"></a>Updating TeleMetrum Firmware</h2></div></div></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"> 
+    </p><div class="section" title="Updating TeleMetrum Firmware"><div class="titlepage"><div><div><h3 class="title"><a name="id2560725"></a>Updating TeleMetrum Firmware</h3></div></div></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
           Find the 'programming cable' that you got as part of the starter
           kit, that has a red 8-pin MicroMaTch connector on one end and a
-          red 4-pin MicroMaTch connector on the other end.  
-        </li><li class="listitem"> 
-          Take the 2 screws out of the TeleDongle case to get access 
-          to the circuit board.  
+          red 4-pin MicroMaTch connector on the other end.
+        </li><li class="listitem">
+          Take the 2 screws out of the TeleDongle case to get access
+          to the circuit board.
         </li><li class="listitem">
           Plug the 8-pin end of the programming cable to the
           matching connector on the TeleDongle, and the 4-pin end to the
-          matching connector on the TeleMetrum.  
+          matching connector on the TeleMetrum.
+         Note that each MicroMaTch connector has an alignment pin that
+         goes through a hole in the PC board when you have the cable
+         oriented correctly.
         </li><li class="listitem">
           Attach a battery to the TeleMetrum board.
         </li><li class="listitem">
-          Plug the TeleDongle into your computer's USB port, and power 
-          up the TeleMetrum. 
+          Plug the TeleDongle into your computer's USB port, and power
+          up the TeleMetrum.
         </li><li class="listitem">
           Run AltosUI, and select 'Flash Image' from the File menu.
         </li><li class="listitem">
-          Pick the TeleDongle device from the list, identifying it as the 
+          Pick the TeleDongle device from the list, identifying it as the
           programming device.
         </li><li class="listitem">
-          Select the image you want put on the TeleMetrum, which should have a 
-          name in the form telemetrum-v1.0-0.7.1.ihx.  It should be visible 
-       in the default directory, if not you may have to poke around 
+          Select the image you want put on the TeleMetrum, which should have a
+          name in the form telemetrum-v1.0-0.7.1.ihx.  It should be visible
+       in the default directory, if not you may have to poke around
        your system to find it.
         </li><li class="listitem">
           Make sure the configuration parameters are reasonable
           looking. If the serial number and/or RF configuration
           values aren't right, you'll need to change them.
         </li><li class="listitem">
-          Hit the 'OK' button and the software should proceed to flash 
+          Hit the 'OK' button and the software should proceed to flash
           the TeleMetrum with new firmware, showing a progress bar.
         </li><li class="listitem">
           Confirm that the TeleMetrum board seems to have updated ok, which you
           the version, etc.
         </li><li class="listitem">
           If something goes wrong, give it another try.
-        </li></ol></div></div><div class="section" title="Updating TeleDongle Firmware"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2552683"></a>Updating TeleDongle Firmware</h2></div></div></div><p>
+        </li></ol></div></div><div class="section" title="Updating TeleDongle Firmware"><div class="titlepage"><div><div><h3 class="title"><a name="id2579530"></a>Updating TeleDongle Firmware</h3></div></div></div><p>
         Updating TeleDongle's firmware is just like updating TeleMetrum
        firmware, but you switch which board is the programmer and which
        is the programming target.
-       </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"> 
+       </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
           Find the 'programming cable' that you got as part of the starter
           kit, that has a red 8-pin MicroMaTch connector on one end and a
-          red 4-pin MicroMaTch connector on the other end.  
+          red 4-pin MicroMaTch connector on the other end.
         </li><li class="listitem">
          Find the USB cable that you got as part of the starter kit, and
          plug the "mini" end in to the mating connector on TeleMetrum.
         </li><li class="listitem">
-          Take the 2 screws out of the TeleDongle case to get access 
-          to the circuit board.  
+          Take the 2 screws out of the TeleDongle case to get access
+          to the circuit board.
         </li><li class="listitem">
           Plug the 8-pin end of the programming cable to the (latching)
           matching connector on the TeleMetrum, and the 4-pin end to the
-          matching connector on the TeleDongle.  
+          matching connector on the TeleDongle.
+         Note that each MicroMaTch connector has an alignment pin that
+         goes through a hole in the PC board when you have the cable
+         oriented correctly.
         </li><li class="listitem">
           Attach a battery to the TeleMetrum board.
         </li><li class="listitem">
-          Plug both TeleMetrum and TeleDongle into your computer's USB 
-         ports, and power up the TeleMetrum. 
+          Plug both TeleMetrum and TeleDongle into your computer's USB
+         ports, and power up the TeleMetrum.
         </li><li class="listitem">
           Run AltosUI, and select 'Flash Image' from the File menu.
         </li><li class="listitem">
-          Pick the TeleMongle device from the list, identifying it as the 
+          Pick the TeleMetrum device from the list, identifying it as the
           programming device.
         </li><li class="listitem">
-          Select the image you want put on the TeleDongle, which should have a 
-          name in the form teledongle-v0.2-0.7.1.ihx.  It should be visible 
-       in the default directory, if not you may have to poke around 
+          Select the image you want put on the TeleDongle, which should have a
+          name in the form teledongle-v0.2-0.7.1.ihx.  It should be visible
+       in the default directory, if not you may have to poke around
        your system to find it.
         </li><li class="listitem">
           Make sure the configuration parameters are reasonable
           looking. If the serial number and/or RF configuration
           values aren't right, you'll need to change them.  The TeleDongle
-         serial number is on the "bottom" of the circuit board, and can 
+         serial number is on the "bottom" of the circuit board, and can
          usually be read through the translucent blue plastic case without
          needing to remove the board from the case.
         </li><li class="listitem">
-          Hit the 'OK' button and the software should proceed to flash 
+          Hit the 'OK' button and the software should proceed to flash
           the TeleDongle with new firmware, showing a progress bar.
         </li><li class="listitem">
           Confirm that the TeleDongle board seems to have updated ok, which you
           can do by plugging in to it over USB and using a terminal program
           to connect to the board and issue the 'v' command to check
           the version, etc.  Once you're happy, remove the programming cable
-         and put the cover back on the TeleDongle.     
+         and put the cover back on the TeleDongle.
         </li><li class="listitem">
           If something goes wrong, give it another try.
         </li></ol></div><p>
         Be careful removing the programming cable from the locking 8-pin
         connector on TeleMetrum.  You'll need a fingernail or perhaps a thin
-        screwdriver or knife blade to gently pry the locking ears out 
-        slightly to extract the connector.  We used a locking connector on 
-        TeleMetrum to help ensure that the cabling to companion boards 
+        screwdriver or knife blade to gently pry the locking ears out
+        slightly to extract the connector.  We used a locking connector on
+        TeleMetrum to help ensure that the cabling to companion boards
         used in a rocket don't ever come loose accidentally in flight.
-      </p></div></div><div class="chapter" title="Chapter 8. Using Altus Metrum Products"><div class="titlepage"><div><div><h2 class="title"><a name="id2539483"></a>Chapter 8. Using Altus Metrum Products</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2558109">Being Legal</a></span></dt><dd><dl><dt><span class="section"><a href="#id2554650">In the Rocket</a></span></dt><dt><span class="section"><a href="#id2572268">On the Ground</a></span></dt><dt><span class="section"><a href="#id2569008">Data Analysis</a></span></dt><dt><span class="section"><a href="#id2563568">Future Plans</a></span></dt></dl></dd><dt><span class="section"><a href="#id2567979">
-        How GPS Works
-      </a></span></dt></dl></div><div class="section" title="Being Legal"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2558109"></a>Being Legal</h2></div></div></div><p>
-        First off, in the US, you need an [amateur radio license](../Radio) or 
+      </p></div></div></div><div class="chapter" title="Chapter 7. AltosUI"><div class="titlepage"><div><div><h2 class="title"><a name="id2576399"></a>Chapter 7. AltosUI</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2576677">Packet Command Mode</a></span></dt><dt><span class="section"><a href="#id2581723">Monitor Flight</a></span></dt><dd><dl><dt><span class="section"><a href="#id2576742">Launch Pad</a></span></dt><dt><span class="section"><a href="#id2571392">Ascent</a></span></dt><dt><span class="section"><a href="#id2578242">Descent</a></span></dt><dt><span class="section"><a href="#id2586734">Landed</a></span></dt><dt><span class="section"><a href="#id2568067">Site Map</a></span></dt></dl></dd><dt><span class="section"><a href="#id2572352">Save Flight Data</a></span></dt><dt><span class="section"><a href="#id2592536">Replay Flight</a></span></dt><dt><span class="section"><a href="#id2579359">Graph Data</a></span></dt><dt><span class="section"><a href="#id2574359">Export Data</a></span></dt><dd><dl><dt><span class="section"><a href="#id2581561">Comma Separated Value Format</a></span></dt><dt><span class="section"><a href="#id2585122">Keyhole Markup Language (for Google Earth)</a></span></dt></dl></dd><dt><span class="section"><a href="#id2576382">Configure TeleMetrum</a></span></dt><dd><dl><dt><span class="section"><a href="#id2565240">Main Deploy Altitude</a></span></dt><dt><span class="section"><a href="#id2558922">Apogee Delay</a></span></dt><dt><span class="section"><a href="#id2588372">Radio Channel</a></span></dt><dt><span class="section"><a href="#id2569947">Radio Calibration</a></span></dt><dt><span class="section"><a href="#id2567826">Callsign</a></span></dt></dl></dd><dt><span class="section"><a href="#id2567986">Configure AltosUI</a></span></dt><dd><dl><dt><span class="section"><a href="#id2554292">Voice Settings</a></span></dt><dt><span class="section"><a href="#id2592599">Log Directory</a></span></dt><dt><span class="section"><a href="#id2559399">Callsign</a></span></dt></dl></dd><dt><span class="section"><a href="#id2579274">Flash Image</a></span></dt><dt><span class="section"><a href="#id2577046">Fire Igniter</a></span></dt></dl></div><p>
+      The AltosUI program provides a graphical user interface for
+      interacting with the Altus Metrum product family, including
+      TeleMetrum and TeleDongle. AltosUI can monitor telemetry data,
+      configure TeleMetrum and TeleDongle devices and many other
+      tasks. The primary interface window provides a selection of
+      buttons, one for each major activity in the system.  This manual
+      is split into chapters, each of which documents one of the tasks
+      provided from the top-level toolbar.
+    </p><div class="section" title="Packet Command Mode"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2576677"></a>Packet Command Mode</h2></div><div><h3 class="subtitle">Controlling TeleMetrum Over The Radio Link</h3></div></div></div><p>
+        One of the unique features of the Altos Metrum environment is
+        the ability to create a two way command link between TeleDongle
+        and TeleMetrum using the digital radio transceivers built into
+        each device. This allows you to interact with TeleMetrum from
+        afar, as if it were directly connected to the computer.
+      </p><p>
+        Any operation which can be performed with TeleMetrum
+        can either be done with TeleMetrum directly connected to
+        the computer via the USB cable, or through the packet
+        link. Simply select the appropriate TeleDongle device when
+        the list of devices is presented and AltosUI will use packet
+        command mode.
+      </p><p>
+       One oddity in the current interface is how AltosUI selects the
+       channel for packet mode communications. Instead of providing
+       an interface to specifically configure the channel, it uses
+       whatever channel was most recently selected for the target
+       TeleDongle device in Monitor Flight mode. If you haven't ever
+       used that mode with the TeleDongle in question, select the
+       Monitor Flight button from the top level UI, pick the
+       appropriate TeleDongle device. Once the flight monitoring
+       window is open, select the desired channel and then close it
+       down again. All Packet Command Mode operations will now use
+       that channel.
+      </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
+            Save Flight Data&#8212;Recover flight data from the rocket without
+            opening it up.
+          </p></li><li class="listitem"><p>
+            Configure TeleMetrum&#8212;Reset apogee delays or main deploy
+            heights to respond to changing launch conditions. You can
+            also 'reboot' the TeleMetrum device. Use this to remotely
+            enable the flight computer by turning TeleMetrum on while
+            horizontal, then once the airframe is oriented for launch,
+            you can reboot TeleMetrum and have it restart in pad mode
+            without having to climb the scary ladder.
+          </p></li><li class="listitem"><p>
+            Fire Igniters&#8212;Test your deployment charges without snaking
+            wires out through holes in the airframe. Simply assembly the
+            rocket as if for flight with the apogee and main charges
+            loaded, then remotely command TeleMetrum to fire the
+            igniters.
+          </p></li></ul></div><p>
+        Packet command mode uses the same RF channels as telemetry
+        mode. Configure the desired TeleDongle channel using the
+        flight monitor window channel selector and then close that
+        window before performing the desired operation.
+      </p><p>
+        TeleMetrum only enables packet command mode in 'idle' mode, so
+        make sure you have TeleMetrum lying horizontally when you turn
+        it on. Otherwise, TeleMetrum will start in 'pad' mode ready for
+        flight and will not be listening for command packets from TeleDongle.
+      </p><p>
+        When packet command mode is enabled, you can monitor the link
+        by watching the lights on the TeleDongle and TeleMetrum
+        devices. The red LED will flash each time TeleDongle or
+        TeleMetrum transmit a packet while the green LED will light up
+        on TeleDongle while it is waiting to receive a packet from
+        TeleMetrum.
+      </p></div><div class="section" title="Monitor Flight"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2581723"></a>Monitor Flight</h2></div><div><h3 class="subtitle">Receive, Record and Display Telemetry Data</h3></div></div></div><p>
+        Selecting this item brings up a dialog box listing all of the
+        connected TeleDongle devices. When you choose one of these,
+        AltosUI will create a window to display telemetry data as
+        received by the selected TeleDongle device.
+      </p><p>
+        All telemetry data received are automatically recorded in
+        suitable log files. The name of the files includes the current
+        date and rocket serial and flight numbers.
+      </p><p>
+        The radio channel being monitored by the TeleDongle device is
+        displayed at the top of the window. You can configure the
+        channel by clicking on the channel box and selecting the desired
+        channel. AltosUI remembers the last channel selected for each
+        TeleDongle and selects that automatically the next time you use
+        that device.
+      </p><p>
+        Below the TeleDongle channel selector, the window contains a few
+        significant pieces of information about the TeleMetrum providing
+        the telemetry data stream:
+      </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>The TeleMetrum callsign</p></li><li class="listitem"><p>The TeleMetrum serial number</p></li><li class="listitem"><p>The flight number. Each TeleMetrum remembers how many
+            times it has flown.
+          </p></li><li class="listitem"><p>
+            The rocket flight state. Each flight passes through several
+            states including Pad, Boost, Fast, Coast, Drogue, Main and
+            Landed.
+          </p></li><li class="listitem"><p>
+            The Received Signal Strength Indicator value. This lets
+            you know how strong a signal TeleDongle is receiving. The
+            radio inside TeleDongle operates down to about -99dBm;
+            weaker signals may not be receiveable. The packet link uses
+            error correction and detection techniques which prevent
+            incorrect data from being reported.
+          </p></li></ul></div><p>
+        Finally, the largest portion of the window contains a set of
+        tabs, each of which contain some information about the rocket.
+        They're arranged in 'flight order' so that as the flight
+        progresses, the selected tab automatically switches to display
+        data relevant to the current state of the flight. You can select
+        other tabs at any time. The final 'table' tab contains all of
+        the telemetry data in one place.
+      </p><div class="section" title="Launch Pad"><div class="titlepage"><div><div><h3 class="title"><a name="id2576742"></a>Launch Pad</h3></div></div></div><p>
+          The 'Launch Pad' tab shows information used to decide when the
+          rocket is ready for flight. The first elements include red/green
+          indicators, if any of these is red, you'll want to evaluate
+          whether the rocket is ready to launch:
+          </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
+                Battery Voltage. This indicates whether the LiPo battery
+                powering the TeleMetrum has sufficient charge to last for
+                the duration of the flight. A value of more than
+                3.7V is required for a 'GO' status.
+              </p></li><li class="listitem"><p>
+                Apogee Igniter Voltage. This indicates whether the apogee
+                igniter has continuity. If the igniter has a low
+                resistance, then the voltage measured here will be close
+                to the LiPo battery voltage. A value greater than 3.2V is
+                required for a 'GO' status.
+              </p></li><li class="listitem"><p>
+                Main Igniter Voltage. This indicates whether the main
+                igniter has continuity. If the igniter has a low
+                resistance, then the voltage measured here will be close
+                to the LiPo battery voltage. A value greater than 3.2V is
+                required for a 'GO' status.
+              </p></li><li class="listitem"><p>
+                GPS Locked. This indicates whether the GPS receiver is
+                currently able to compute position information. GPS requires
+                at least 4 satellites to compute an accurate position.
+              </p></li><li class="listitem"><p>
+                GPS Ready. This indicates whether GPS has reported at least
+                10 consecutive positions without losing lock. This ensures
+                that the GPS receiver has reliable reception from the
+                satellites.
+              </p></li></ul></div><p>
+          </p><p>
+            The LaunchPad tab also shows the computed launch pad position
+            and altitude, averaging many reported positions to improve the
+            accuracy of the fix.
+          </p><p>
+        </p></div><div class="section" title="Ascent"><div class="titlepage"><div><div><h3 class="title"><a name="id2571392"></a>Ascent</h3></div></div></div><p>
+          This tab is shown during Boost, Fast and Coast
+          phases. The information displayed here helps monitor the
+          rocket as it heads towards apogee.
+        </p><p>
+          The height, speed and acceleration are shown along with the
+          maxium values for each of them. This allows you to quickly
+          answer the most commonly asked questions you'll hear during
+          flight.
+        </p><p>
+          The current latitude and longitude reported by the GPS are
+          also shown. Note that under high acceleration, these values
+          may not get updated as the GPS receiver loses position
+          fix. Once the rocket starts coasting, the receiver should
+          start reporting position again.
+        </p><p>
+          Finally, the current igniter voltages are reported as in the
+          Launch Pad tab. This can help diagnose deployment failures
+          caused by wiring which comes loose under high acceleration.
+        </p></div><div class="section" title="Descent"><div class="titlepage"><div><div><h3 class="title"><a name="id2578242"></a>Descent</h3></div></div></div><p>
+          Once the rocket has reached apogee and (we hope) activated the
+          apogee charge, attention switches to tracking the rocket on
+          the way back to the ground, and for dual-deploy flights,
+          waiting for the main charge to fire.
+        </p><p>
+          To monitor whether the apogee charge operated correctly, the
+          current descent rate is reported along with the current
+          height. Good descent rates generally range from 15-30m/s.
+        </p><p>
+          To help locate the rocket in the sky, use the elevation and
+          bearing information to figure out where to look. Elevation is
+          in degrees above the horizon. Bearing is reported in degrees
+          relative to true north. Range can help figure out how big the
+          rocket will appear. Note that all of these values are relative
+          to the pad location. If the elevation is near 90°, the rocket
+          is over the pad, not over you.
+        </p><p>
+          Finally, the igniter voltages are reported in this tab as
+          well, both to monitor the main charge as well as to see what
+          the status of the apogee charge is.
+        </p></div><div class="section" title="Landed"><div class="titlepage"><div><div><h3 class="title"><a name="id2586734"></a>Landed</h3></div></div></div><p>
+          Once the rocket is on the ground, attention switches to
+          recovery. While the radio signal is generally lost once the
+          rocket is on the ground, the last reported GPS position is
+          generally within a short distance of the actual landing location.
+        </p><p>
+          The last reported GPS position is reported both by
+          latitude and longitude as well as a bearing and distance from
+          the launch pad. The distance should give you a good idea of
+          whether you'll want to walk or hitch a ride. Take the reported
+          latitude and longitude and enter them into your handheld GPS
+          unit and have that compute a track to the landing location.
+        </p><p>
+          Finally, the maximum height, speed and acceleration reported
+          during the flight are displayed for your admiring observers.
+        </p></div><div class="section" title="Site Map"><div class="titlepage"><div><div><h3 class="title"><a name="id2568067"></a>Site Map</h3></div></div></div><p>
+          When the rocket gets a GPS fix, the Site Map tab will map
+          the rocket's position to make it easier for you to locate the
+          rocket, both while it is in the air, and when it has landed. The
+          rocket's state is indicated by colour: white for pad, red for
+          boost, pink for fast, yellow for coast, light blue for drogue,
+          dark blue for main, and black for landed.
+        </p><p>
+          The map's scale is approximately 3m (10ft) per pixel. The map
+          can be dragged using the left mouse button. The map will attempt
+          to keep the rocket roughly centred while data is being received.
+        </p><p>
+          Images are fetched automatically via the Google Maps Static API,
+          and are cached for reuse. If map images cannot be downloaded,
+          the rocket's path will be traced on a dark grey background
+          instead.
+        </p></div></div><div class="section" title="Save Flight Data"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2572352"></a>Save Flight Data</h2></div></div></div><p>
+        TeleMetrum records flight data to its internal flash memory.
+        This data is recorded at a much higher rate than the telemetry
+        system can handle, and is not subject to radio drop-outs. As
+        such, it provides a more complete and precise record of the
+        flight. The 'Save Flight Data' button allows you to read the
+        flash memory and write it to disk.
+      </p><p>
+        Clicking on the 'Save Flight Data' button brings up a list of
+        connected TeleMetrum and TeleDongle devices. If you select a
+        TeleMetrum device, the flight data will be downloaded from that
+        device directly. If you select a TeleDongle device, flight data
+        will be downloaded from a TeleMetrum device connected via the
+        packet command link to the specified TeleDongle. See the chapter
+        on Packet Command Mode for more information about this.
+      </p><p>
+        The filename for the data is computed automatically from the recorded
+        flight date, TeleMetrum serial number and flight number
+        information.
+      </p></div><div class="section" title="Replay Flight"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2592536"></a>Replay Flight</h2></div></div></div><p>
+        Select this button and you are prompted to select a flight
+        record file, either a .telem file recording telemetry data or a
+        .eeprom file containing flight data saved from the TeleMetrum
+        flash memory.
+      </p><p>
+        Once a flight record is selected, the flight monitor interface
+        is displayed and the flight is re-enacted in real time. Check
+        the Monitor Flight chapter above to learn how this window operates.
+      </p></div><div class="section" title="Graph Data"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2579359"></a>Graph Data</h2></div></div></div><p>
+        Select this button and you are prompted to select a flight
+        record file, either a .telem file recording telemetry data or a
+        .eeprom file containing flight data saved from the TeleMetrum
+        flash memory.
+      </p><p>
+        Once a flight record is selected, the acceleration (blue),
+        velocity (green) and altitude (red) of the flight are plotted and
+        displayed, measured in metric units.
+      </p><p>
+        The graph can be zoomed into a particular area by clicking and
+        dragging down and to the right. Once zoomed, the graph can be
+        reset by clicking and dragging up and to the left. Holding down
+        control and clicking and dragging allows the graph to be panned.
+        The right mouse button causes a popup menu to be displayed, giving
+        you the option save or print the plot.
+      </p><p>
+        Note that telemetry files will generally produce poor graphs
+        due to the lower sampling rate and missed telemetry packets,
+        and will also often have significant amounts of data received
+        while the rocket was waiting on the pad. Use saved flight data
+        for graphing where possible.
+      </p></div><div class="section" title="Export Data"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2574359"></a>Export Data</h2></div></div></div><p>
+        This tool takes the raw data files and makes them available for
+        external analysis. When you select this button, you are prompted to select a flight
+        data file (either .eeprom or .telem will do, remember that
+        .eeprom files contain higher resolution and more continuous
+        data). Next, a second dialog appears which is used to select
+        where to write the resulting file. It has a selector to choose
+        between CSV and KML file formats.
+      </p><div class="section" title="Comma Separated Value Format"><div class="titlepage"><div><div><h3 class="title"><a name="id2581561"></a>Comma Separated Value Format</h3></div></div></div><p>
+          This is a text file containing the data in a form suitable for
+          import into a spreadsheet or other external data analysis
+          tool. The first few lines of the file contain the version and
+          configuration information from the TeleMetrum device, then
+          there is a single header line which labels all of the
+          fields. All of these lines start with a '#' character which
+          most tools can be configured to skip over.
+        </p><p>
+          The remaining lines of the file contain the data, with each
+          field separated by a comma and at least one space. All of
+          the sensor values are converted to standard units, with the
+          barometric data reported in both pressure, altitude and
+          height above pad units.
+        </p></div><div class="section" title="Keyhole Markup Language (for Google Earth)"><div class="titlepage"><div><div><h3 class="title"><a name="id2585122"></a>Keyhole Markup Language (for Google Earth)</h3></div></div></div><p>
+          This is the format used by
+          Googleearth to provide an overlay within that
+          application. With this, you can use Googleearth to see the
+          whole flight path in 3D.
+        </p></div></div><div class="section" title="Configure TeleMetrum"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2576382"></a>Configure TeleMetrum</h2></div></div></div><p>
+        Select this button and then select either a TeleMetrum or
+        TeleDongle Device from the list provided. Selecting a TeleDongle
+        device will use Packet Comamnd Mode to configure remote
+        TeleMetrum device. Learn how to use this in the Packet Command
+        Mode chapter.
+      </p><p>
+        The first few lines of the dialog provide information about the
+        connected TeleMetrum device, including the product name,
+        software version and hardware serial number. Below that are the
+        individual configuration entries.
+      </p><p>
+        At the bottom of the dialog, there are four buttons:
+      </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>
+            Save. This writes any changes to the TeleMetrum
+            configuration parameter block in flash memory. If you don't
+            press this button, any changes you make will be lost.
+          </p></li><li class="listitem"><p>
+            Reset. This resets the dialog to the most recently saved values,
+            erasing any changes you have made.
+          </p></li><li class="listitem"><p>
+            Reboot. This reboots the TeleMetrum device. Use this to
+            switch from idle to pad mode by rebooting once the rocket is
+            oriented for flight.
+          </p></li><li class="listitem"><p>
+            Close. This closes the dialog. Any unsaved changes will be
+            lost.
+          </p></li></ul></div><p>
+        The rest of the dialog contains the parameters to be configured.
+      </p><div class="section" title="Main Deploy Altitude"><div class="titlepage"><div><div><h3 class="title"><a name="id2565240"></a>Main Deploy Altitude</h3></div></div></div><p>
+          This sets the altitude (above the recorded pad altitude) at
+          which the 'main' igniter will fire. The drop-down menu shows
+          some common values, but you can edit the text directly and
+          choose whatever you like. If the apogee charge fires below
+          this altitude, then the main charge will fire two seconds
+          after the apogee charge fires.
+        </p></div><div class="section" title="Apogee Delay"><div class="titlepage"><div><div><h3 class="title"><a name="id2558922"></a>Apogee Delay</h3></div></div></div><p>
+          When flying redundant electronics, it's often important to
+          ensure that multiple apogee charges don't fire at precisely
+          the same time as that can overpressurize the apogee deployment
+          bay and cause a structural failure of the airframe. The Apogee
+          Delay parameter tells the flight computer to fire the apogee
+          charge a certain number of seconds after apogee has been
+          detected.
+        </p></div><div class="section" title="Radio Channel"><div class="titlepage"><div><div><h3 class="title"><a name="id2588372"></a>Radio Channel</h3></div></div></div><p>
+          This configures which of the 10 radio channels to use for both
+          telemetry and packet command mode. Note that if you set this
+          value via packet command mode, you will have to reconfigure
+          the TeleDongle channel before you will be able to use packet
+          command mode again.
+        </p></div><div class="section" title="Radio Calibration"><div class="titlepage"><div><div><h3 class="title"><a name="id2569947"></a>Radio Calibration</h3></div></div></div><p>
+          The radios in every Altus Metrum device are calibrated at the
+          factory to ensure that they transmit and receive on the
+          specified frequency for each channel. You can adjust that
+          calibration by changing this value. To change the TeleDongle's
+          calibration, you must reprogram the unit completely.
+        </p></div><div class="section" title="Callsign"><div class="titlepage"><div><div><h3 class="title"><a name="id2567826"></a>Callsign</h3></div></div></div><p>
+          This sets the callsign included in each telemetry packet. Set this
+          as needed to conform to your local radio regulations.
+        </p></div></div><div class="section" title="Configure AltosUI"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2567986"></a>Configure AltosUI</h2></div></div></div><p>
+        This button presents a dialog so that you can configure the AltosUI global settings.
+      </p><div class="section" title="Voice Settings"><div class="titlepage"><div><div><h3 class="title"><a name="id2554292"></a>Voice Settings</h3></div></div></div><p>
+          AltosUI provides voice annoucements during flight so that you
+          can keep your eyes on the sky and still get information about
+          the current flight status. However, sometimes you don't want
+          to hear them.
+        </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Enable&#8212;turns all voice announcements on and off</p></li><li class="listitem"><p>
+              Test Voice&#8212;Plays a short message allowing you to verify
+              that the audio systme is working and the volume settings
+              are reasonable
+            </p></li></ul></div></div><div class="section" title="Log Directory"><div class="titlepage"><div><div><h3 class="title"><a name="id2592599"></a>Log Directory</h3></div></div></div><p>
+          AltosUI logs all telemetry data and saves all TeleMetrum flash
+          data to this directory. This directory is also used as the
+          staring point when selecting data files for display or export.
+        </p><p>
+          Click on the directory name to bring up a directory choosing
+          dialog, select a new directory and click 'Select Directory' to
+          change where AltosUI reads and writes data files.
+        </p></div><div class="section" title="Callsign"><div class="titlepage"><div><div><h3 class="title"><a name="id2559399"></a>Callsign</h3></div></div></div><p>
+          This value is used in command packet mode and is transmitted
+          in each packet sent from TeleDongle and received from
+          TeleMetrum. It is not used in telemetry mode as that transmits
+          packets only from TeleMetrum to TeleDongle. Configure this
+          with the AltosUI operators callsign as needed to comply with
+          your local radio regulations.
+        </p></div></div><div class="section" title="Flash Image"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2579274"></a>Flash Image</h2></div></div></div><p>
+        This reprograms any Altus Metrum device by using a TeleMetrum or
+        TeleDongle as a programming dongle. Please read the directions
+        for connecting the programming cable in the main TeleMetrum
+        manual before reading these instructions.
+      </p><p>
+        Once you have the programmer and target devices connected,
+        push the 'Flash Image' button. That will present a dialog box
+        listing all of the connected devices. Carefully select the
+        programmer device, not the device to be programmed.
+      </p><p>
+        Next, select the image to flash to the device. These are named
+        with the product name and firmware version. The file selector
+        will start in the directory containing the firmware included
+        with the AltosUI package. Navigate to the directory containing
+        the desired firmware if it isn't there.
+      </p><p>
+        Next, a small dialog containing the device serial number and
+        RF calibration values should appear. If these values are
+        incorrect (possibly due to a corrupted image in the device),
+        enter the correct values here.
+      </p><p>
+        Finally, a dialog containing a progress bar will follow the
+        programming process.
+      </p><p>
+        When programming is complete, the target device will
+        reboot. Note that if the target device is connected via USB, you
+        will have to unplug it and then plug it back in for the USB
+        connection to reset so that you can communicate with the device
+        again.
+      </p></div><div class="section" title="Fire Igniter"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2577046"></a>Fire Igniter</h2></div></div></div><p>
+       This activates the igniter circuits in TeleMetrum to help test
+       recovery systems deployment. Because this command can operate
+       over the Packet Command Link, you can prepare the rocket as
+       for flight and then test the recovery system without needing
+       to snake wires inside the airframe.
+      </p><p>
+       Selecting the 'Fire Igniter' button brings up the usual device
+       selection dialog. Pick the desired TeleDongle or TeleMetrum
+       device. This brings up another window which shows the current
+       continutity test status for both apogee and main charges.
+      </p><p>
+       Next, select the desired igniter to fire. This will enable the
+       'Arm' button.
+      </p><p>
+       Select the 'Arm' button. This enables the 'Fire' button. The
+       word 'Arm' is replaced by a countdown timer indicating that
+       you have 10 seconds to press the 'Fire' button or the system
+       will deactivate, at which point you start over again at
+       selecting the desired igniter.
+      </p></div></div><div class="chapter" title="Chapter 8. Using Altus Metrum Products"><div class="titlepage"><div><div><h2 class="title"><a name="id2587842"></a>Chapter 8. Using Altus Metrum Products</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id2574948">Being Legal</a></span></dt><dd><dl><dt><span class="section"><a href="#id2561015">In the Rocket</a></span></dt><dt><span class="section"><a href="#id2575161">On the Ground</a></span></dt><dt><span class="section"><a href="#id2581564">Data Analysis</a></span></dt><dt><span class="section"><a href="#id2562286">Future Plans</a></span></dt></dl></dd></dl></div><div class="section" title="Being Legal"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2574948"></a>Being Legal</h2></div></div></div><p>
+        First off, in the US, you need an <a class="ulink" href="http://www.altusmetrum.org/Radio/" target="_top">amateur radio license</a> or
         other authorization to legally operate the radio transmitters that are part
         of our products.
-      </p><div class="section" title="In the Rocket"><div class="titlepage"><div><div><h3 class="title"><a name="id2554650"></a>In the Rocket</h3></div></div></div><p>
-          In the rocket itself, you just need a [TeleMetrum](../TeleMetrum) board and 
-          a LiPo rechargeable battery.  An 860mAh battery weighs less than a 9V 
-          alkaline battery, and will run a [TeleMetrum](../TeleMetrum) for hours.
+      </p><div class="section" title="In the Rocket"><div class="titlepage"><div><div><h3 class="title"><a name="id2561015"></a>In the Rocket</h3></div></div></div><p>
+          In the rocket itself, you just need a <a class="ulink" href="http://www.altusmetrum.org/TeleMetrum/" target="_top">TeleMetrum</a> board and
+          a LiPo rechargeable battery.  An 860mAh battery weighs less than a 9V
+          alkaline battery, and will run a <a class="ulink" href="http://www.altusmetrum.org/TeleMetrum/" target="_top">TeleMetrum</a> for hours.
         </p><p>
-          By default, we ship TeleMetrum with a simple wire antenna.  If your 
-          electronics bay or the airframe it resides within is made of carbon fiber, 
-          which is opaque to RF signals, you may choose to have an SMA connector 
-          installed so that you can run a coaxial cable to an antenna mounted 
+          By default, we ship TeleMetrum with a simple wire antenna.  If your
+          electronics bay or the airframe it resides within is made of carbon fiber,
+          which is opaque to RF signals, you may choose to have an SMA connector
+          installed so that you can run a coaxial cable to an antenna mounted
           elsewhere in the rocket.
-        </p></div><div class="section" title="On the Ground"><div class="titlepage"><div><div><h3 class="title"><a name="id2572268"></a>On the Ground</h3></div></div></div><p>
-          To receive the data stream from the rocket, you need an antenna and short 
-          feedline connected to one of our [TeleDongle](../TeleDongle) units.  The
-          TeleDongle in turn plugs directly into the USB port on a notebook 
+        </p></div><div class="section" title="On the Ground"><div class="titlepage"><div><div><h3 class="title"><a name="id2575161"></a>On the Ground</h3></div></div></div><p>
+          To receive the data stream from the rocket, you need an antenna and short
+          feedline connected to one of our <a class="ulink" href="http://www.altusmetrum.org/TeleDongle/" target="_top">TeleDongle</a> units.  The
+          TeleDongle in turn plugs directly into the USB port on a notebook
           computer.  Because TeleDongle looks like a simple serial port, your computer
           does not require special device drivers... just plug it in.
         </p><p>
-          Right now, all of our application software is written for Linux.  However, 
-          because we understand that many people run Windows or MacOS, we are working 
-          on a new ground station program written in Java that should work on all
-          operating systems.
+         The GUI tool, AltosUI, is written in Java and runs across
+         Linux, Mac OS and Windows. There's also a suite of C tools
+         for Linux which can perform most of the same tasks.
         </p><p>
-          After the flight, you can use the RF link to extract the more detailed data 
-          logged in the rocket, or you can use a mini USB cable to plug into the 
+          After the flight, you can use the RF link to extract the more detailed data
+          logged in the rocket, or you can use a mini USB cable to plug into the
           TeleMetrum board directly.  Pulling out the data without having to open up
-          the rocket is pretty cool!  A USB cable is also how you charge the LiPo 
-          battery, so you'll want one of those anyway... the same cable used by lots 
+          the rocket is pretty cool!  A USB cable is also how you charge the LiPo
+          battery, so you'll want one of those anyway... the same cable used by lots
           of digital cameras and other modern electronic stuff will work fine.
         </p><p>
-          If your rocket lands out of sight, you may enjoy having a hand-held GPS 
-          receiver, so that you can put in a waypoint for the last reported rocket 
-          position before touch-down.  This makes looking for your rocket a lot like 
+          If your rocket lands out of sight, you may enjoy having a hand-held GPS
+          receiver, so that you can put in a waypoint for the last reported rocket
+          position before touch-down.  This makes looking for your rocket a lot like
           Geo-Cacheing... just go to the waypoint and look around starting from there.
         </p><p>
-          You may also enjoy having a ham radio "HT" that covers the 70cm band... you 
-          can use that with your antenna to direction-find the rocket on the ground 
-          the same way you can use a Walston or Beeline tracker.  This can be handy 
-          if the rocket is hiding in sage brush or a tree, or if the last GPS position 
-          doesn't get you close enough because the rocket dropped into a canyon, or 
+          You may also enjoy having a ham radio "HT" that covers the 70cm band... you
+          can use that with your antenna to direction-find the rocket on the ground
+          the same way you can use a Walston or Beeline tracker.  This can be handy
+          if the rocket is hiding in sage brush or a tree, or if the last GPS position
+          doesn't get you close enough because the rocket dropped into a canyon, or
           the wind is blowing it across a dry lake bed, or something like that...  Keith
           and Bdale both currently own and use the Yaesu VX-7R at launches.
         </p><p>
           So, to recap, on the ground the hardware you'll need includes:
-          </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"> 
+          </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
               an antenna and feedline
-            </li><li class="listitem"> 
+            </li><li class="listitem">
               a TeleDongle
-            </li><li class="listitem"> 
+            </li><li class="listitem">
               a notebook computer
-            </li><li class="listitem"> 
+            </li><li class="listitem">
               optionally, a handheld GPS receiver
-            </li><li class="listitem"> 
+            </li><li class="listitem">
               optionally, an HT or receiver covering 435 Mhz
             </li></ol></div><p>
         </p><p>
-          The best hand-held commercial directional antennas we've found for radio 
-          direction finding rockets are from 
+          The best hand-held commercial directional antennas we've found for radio
+          direction finding rockets are from
           <a class="ulink" href="http://www.arrowantennas.com/" target="_top">
             Arrow Antennas.
           </a>
-          The 440-3 and 440-5 are both good choices for finding a 
-          TeleMetrum-equipped rocket when used with a suitable 70cm HT.  
-        </p></div><div class="section" title="Data Analysis"><div class="titlepage"><div><div><h3 class="title"><a name="id2569008"></a>Data Analysis</h3></div></div></div><p>
-          Our software makes it easy to log the data from each flight, both the 
+          The 440-3 and 440-5 are both good choices for finding a
+          TeleMetrum-equipped rocket when used with a suitable 70cm HT.
+        </p></div><div class="section" title="Data Analysis"><div class="titlepage"><div><div><h3 class="title"><a name="id2581564"></a>Data Analysis</h3></div></div></div><p>
+          Our software makes it easy to log the data from each flight, both the
           telemetry received over the RF link during the flight itself, and the more
-          complete data log recorded in the DataFlash memory on the TeleMetrum 
+          complete data log recorded in the DataFlash memory on the TeleMetrum
           board.  Once this data is on your computer, our postflight tools make it
-          easy to quickly get to the numbers everyone wants, like apogee altitude, 
-          max acceleration, and max velocity.  You can also generate and view a 
+          easy to quickly get to the numbers everyone wants, like apogee altitude,
+          max acceleration, and max velocity.  You can also generate and view a
           standard set of plots showing the altitude, acceleration, and
-          velocity of the rocket during flight.  And you can even export a data file 
-          useable with Google Maps and Google Earth for visualizing the flight path 
+          velocity of the rocket during flight.  And you can even export a data file
+          useable with Google Maps and Google Earth for visualizing the flight path
           in two or three dimensions!
         </p><p>
           Our ultimate goal is to emit a set of files for each flight that can be
-          published as a web page per flight, or just viewed on your local disk with 
+          published as a web page per flight, or just viewed on your local disk with
           a web browser.
-        </p></div><div class="section" title="Future Plans"><div class="titlepage"><div><div><h3 class="title"><a name="id2563568"></a>Future Plans</h3></div></div></div><p>
+        </p></div><div class="section" title="Future Plans"><div class="titlepage"><div><div><h3 class="title"><a name="id2562286"></a>Future Plans</h3></div></div></div><p>
           In the future, we intend to offer "companion boards" for the rocket that will
           plug in to TeleMetrum to collect additional data, provide more pyro channels,
           and so forth.  A reference design for a companion board will be documented
         </p><p>
           Because all of our work is open, both the hardware designs and the software,
           if you have some great idea for an addition to the current Altus Metrum family,
-          feel free to dive in and help!  Or let us know what you'd like to see that 
-          we aren't already working on, and maybe we'll get excited about it too... 
-        </p></div></div><div class="section" title="How GPS Works"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2567979"></a>
-        How GPS Works
-      </h2></div></div></div><p>
-        Placeholder.
-      </p></div></div></div></body></html>
+          feel free to dive in and help!  Or let us know what you'd like to see that
+          we aren't already working on, and maybe we'll get excited about it too...
+        </p></div></div></div></div></body></html>
index a2ab575f7f2c56fb7fd8dae78b06d41b3519d3c2..20edfa8789ad436c1f6205f9bc3c482ec9c1ae2a 100644 (file)
Binary files a/AltOS/doc/altusmetrum.pdf and b/AltOS/doc/altusmetrum.pdf differ