doc: Convert telemetry and companion docs to asciidoc
authorKeith Packard <keithp@keithp.com>
Sun, 1 Nov 2015 06:36:03 +0000 (23:36 -0700)
committerKeith Packard <keithp@keithp.com>
Sun, 1 Nov 2015 14:02:14 +0000 (06:02 -0800)
Signed-off-by: Keith Packard <keithp@keithp.com>
doc/companion-docinfo.xml [new file with mode: 0644]
doc/companion.txt [new file with mode: 0644]
doc/companion.xsl [deleted file]
doc/telemetry-docinfo.xml [new file with mode: 0644]
doc/telemetry.txt [new file with mode: 0644]
doc/telemetry.xsl [deleted file]

diff --git a/doc/companion-docinfo.xml b/doc/companion-docinfo.xml
new file mode 100644 (file)
index 0000000..2e0bc56
--- /dev/null
@@ -0,0 +1,27 @@
+<subtitle>Protocol Definitions</subtitle>
+<author>
+  <firstname>Keith</firstname>
+  <surname>Packard</surname>
+  <email>keithp@keithp.com</email>
+</author>
+<date>13 January 2012</date>
+<copyright>
+  <year>2012</year>
+  <holder>Keith Packard</holder>
+</copyright>
+<legalnotice>
+  <para>
+    This document is released under the terms of the
+    <ulink url="http://creativecommons.org/licenses/by-sa/3.0/">
+      Creative Commons ShareAlike 3.0
+    </ulink>
+    license.
+  </para>
+</legalnotice>
+<revhistory>
+  <revision>
+    <revnumber>0.1</revnumber>
+    <date>13 January 2012</date>
+    <revremark>Initial content</revremark>
+  </revision>
+</revhistory>
diff --git a/doc/companion.txt b/doc/companion.txt
new file mode 100644 (file)
index 0000000..75ffa22
--- /dev/null
@@ -0,0 +1,241 @@
+= AltOS Companion Port
+:doctype: article
+:toc:
+
+== Companion Port
+
+       Many Altus Metrum products come with an eight pin Micro MaTch
+       connector, called the Companion Port. This is often used to
+       program devices using a programming cable. However, it can
+       also be used to connect TeleMetrum to external companion
+       boards (hence the name).
+
+       The Companion Port provides two different functions:
+      
+       * Power. Both battery-level and 3.3V regulated power are
+         available. Note that the amount of regulated power is not
+         huge; TeleMetrum contains a 150mA regulator and uses, at
+         peak, about 120mA or so. For applications needing more than
+         a few dozen mA, placing a separate regulator on them and
+         using the battery for power is probably a good idea.
+
+       
+       * SPI. The flight computer operates as a SPI master, using
+         a protocol defined in this document. Companion boards
+         provide a matching SPI slave implementation which supplies
+         telemetry information for the radio downlink during flight
+  
+== Companion SPI Protocol
+
+       The flight computer implements a SPI master communications
+       channel over the companion port, and uses this to get
+       information about a connected companion board and then to get
+       telemetry data for transmission during flight.
+
+       At startup time, the flight computer sends a setup request
+       packet, and the companion board returns a board identifier,
+       the desired telemetry update period and the number of data
+       channels provided. The flight computer doesn't interpret the
+       telemetry data at all, simply packing it up and sending it
+       over the link.  Telemetry packets are 32 bytes long, and
+       companion packets use 8 bytes as a header leaving room for a
+       maximum of 12 16-bit data values.
+
+       Because of the limits of the AVR processors used in the first
+       two companion boards, the SPI data rate is set to 187.5kbaud.
+
+== SPI Message Formats
+
+       This section first defines the command message format sent from
+       the flight computer to the companion board, and then the various
+       reply message formats for each type of command message.
+
+       .Companion Command Message
+       [options="border",cols="1,3,3,9"]
+       |====
+       |Offset
+       |Data Type
+       |Name
+       |Description
+
+       |0
+       |uint8_t
+       |command
+       |Command identifier
+
+       |1
+       |uint8_t
+       |flight_state
+       |Current flight computer state
+
+       |2
+       |uint16_t
+       |tick
+       |Flight computer clock (100 ticks/second)
+
+       |4
+       |uint16_t
+       |serial
+       |Flight computer serial number
+
+       |6
+       |uint16_t
+       |flight
+       |Flight number
+
+       |8
+       |
+       |
+       |
+       
+       |====  
+
+       .Companion Command Identifiers
+       [options="border",cols="1,3,9"]
+       |====
+       |Value
+       |Name
+       |Description
+
+       |1
+       |SETUP
+       |Supply the flight computer with companion
+       information
+
+       |2
+       |FETCH
+       |Return telemetry information
+
+       |3
+       |NOTIFY
+       |Tell companion board when flight state changes
+       |====
+
+       The flight computer will send a SETUP message shortly after
+       power-up and will then send FETCH messages no more often than
+       the rate specified in the SETUP reply. NOTIFY messages will be
+       sent whenever the flight state changes.
+
+       'flight_state' records the current state of the flight,
+       whether on the pad, under power, coasting to apogee or
+       descending on the drogue or main chute.
+
+       'tick' provides the current flight computer clock, which
+       be used to synchronize data recorded on the flight computer
+       with that recorded on the companion board in post-flight analysis.
+
+       'serial' is the product serial number of the flight computer,
+       'flight' is the flight sequence number. Together, these two
+       uniquely identify the flight and can be recorded with any
+       companion board data logging to associate the companion data
+       with the proper flight.
+
+       NOTIFY commands require no reply at all, they are used solely
+       to inform the companion board when the state of the flight, as
+       computed by the flight computer, changes. Companion boards can
+       use this to change data collection parameters, disabling data
+       logging until the flight starts and terminating it when the
+       flight ends.
+
+       === SETUP reply message
+
+               .SETUP reply contents
+               [options="border",cols="1,3,3,9"]
+               |====
+               |Offset
+               |Data Type
+               |Name
+               |Description
+
+               |0
+               |uint16_t
+               |board_id
+               |Board identifier
+
+               |2
+               |uint16_t
+               |board_id_inverse
+               |~board_id—used to tell if a board is present
+
+               |4
+               |uint8_t
+               |update_period
+               |Minimum time (in 100Hz ticks) between FETCH commands
+
+               |5
+               |uint8_t
+               |channels
+               |Number of data channels to retrieve in FETCH command
+
+               |6
+               |
+               |
+               |
+               |====
+
+               The SETUP reply contains enough information to uniquely
+               identify the companion board to the end user as well as for
+               the flight computer to know how many data values to expect in
+               reply to a FETCH command, and how often to fetch that data.
+
+               To detect the presence of a companion board, the flight
+               computer checks to make sure that board_id_inverse is the
+               bit-wise inverse of board_id. Current companion boards use
+               USB product ID as the board_id, but the flight computer does
+               not interpret this data and so it can be any value.
+
+       === FETCH reply message
+
+               .FETCH reply contents
+               [options="border",cols="1,3,3,9"]
+               |====
+               |Offset
+               |Data Type
+               |Name
+               |Description
+
+               |0
+               |uint16_t
+               |data0
+               |0th data item
+
+               |2
+               |uint16_t
+               |data1
+               |1st data item
+
+               |...
+               |
+               |
+               |
+               |====
+
+               The FETCH reply contains arbitrary data to be reported
+               over the flight computer telemetry link. The number of
+               16-bit data items must match the 'channels' value
+               provided in the SETUP reply message.
+  
+== History and Motivation
+
+       To allow cross-programming, the original TeleMetrum and
+       TeleDongle designs needed to include some kind of
+       connector. With that in place, adding the ability to connect
+       external cards to TeleMetrum was fairly simple. We set the
+       software piece of this puzzle aside until we had a companion
+       board to use.
+
+       The first companion board was TeleScience. Designed to collect
+       temperature data from the nose and fin of the airframe, the main
+       requirement for the companion port was that it be able to report
+       telemetry data during flight as a back-up in case the
+       TeleScience on-board data was lost.
+
+       The second companion board, TelePyro, provides 8 additional
+       channels for deployment, staging or other activities. To avoid
+       re-programming the TeleMetrum to use TelePyro, we decided to
+       provide enough information over the companion link for it to
+       independently control those channels.
+
+       Providing a standard, constant interface between the flight
+       computer and companion boards allows for the base flight
+       computer firmware to include support for companion boards.
diff --git a/doc/companion.xsl b/doc/companion.xsl
deleted file mode 100644 (file)
index 14e2194..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"/usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd">
-
-<article>
-  <articleinfo>
-    <title>AltOS Companion Port</title>
-    <subtitle>Protocol Definitions</subtitle>
-    <author>
-      <firstname>Keith</firstname>
-      <surname>Packard</surname>
-    </author>
-    <copyright>
-      <year>2012</year>
-      <holder>Keith Packard</holder>
-    </copyright>
-    <legalnotice>
-      <para>
-       This document is released under the terms of the
-       <ulink url="http://creativecommons.org/licenses/by-sa/3.0/">
-         Creative Commons ShareAlike 3.0
-       </ulink>
-       license.
-      </para>
-    </legalnotice>
-    <revhistory>
-      <revision>
-       <revnumber>0.1</revnumber>
-       <date>13 January 2012</date>
-       <revremark>Initial content</revremark>
-      </revision>
-    </revhistory>
-  </articleinfo>
-  <section>
-    <title>Companion Port</title>
-    <para>
-      Many Altus Metrum products come with an eight pin Micro MaTch
-      connector, called the Companion Port. This is often used to
-      program devices using a programming cable. However, it can also
-      be used to connect TeleMetrum to external companion boards
-      (hence the name).
-    </para>
-    <para>
-      The Companion Port provides two different functions:
-      <itemizedlist>
-       <listitem>
-         <para>
-         Power. Both battery-level and 3.3V regulated power are
-         available. Note that the amount of regulated power is not
-         huge; TeleMetrum contains a 150mA regulator and uses, at
-         peak, about 120mA or so. For applications needing more than
-         a few dozen mA, placing a separate regulator on them and
-         using the battery for power is probably a good idea.
-         </para>
-       </listitem>
-       <listitem>
-         <para>
-         SPI. The flight computer operates as a SPI master, using
-         a protocol defined in this document. Companion boards
-         provide a matching SPI slave implementation which supplies
-         telemetry information for the radio downlink during flight
-         </para>
-       </listitem>
-      </itemizedlist>
-    </para>
-  </section>
-  <section>
-    <title>Companion SPI Protocol</title>
-    <para>
-      The flight computer implements a SPI master communications
-      channel over the companion port, and uses this to get
-      information about a connected companion board and then to get
-      telemetry data for transmission during flight.
-    </para>
-    <para>
-      At startup time, the flight computer sends a setup request
-      packet, and the companion board returns a board identifier, the
-      desired telemetry update period and the number of data channels
-      provided. The flight computer doesn't interpret the telemetry
-      data at all, simply packing it up and sending it over the link.
-      Telemetry packets are 32 bytes long, and companion packets use 8
-      bytes as a header leaving room for a maximum of 12 16-bit data
-      values.
-    </para>
-    <para>
-      Because of the limits of the AVR processors used in the first
-      two companion boards, the SPI data rate is set to 187.5kbaud.
-    </para>
-  </section>
-  <section>
-    <title>SPI Message Formats</title>
-    <para>
-    This section first defines the command message format sent from
-    the flight computer to the companion board, and then the various
-    reply message formats for each type of command message.
-    </para>
-    <section>
-      <title>Command Message</title>
-      <table frame='all'>
-       <title>Companion Command Message</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0</entry>
-             <entry>uint8_t</entry>
-             <entry>command</entry>
-             <entry>Command identifier</entry>
-           </row>
-           <row>
-             <entry>1</entry>
-             <entry>uint8_t</entry>
-             <entry>flight_state</entry>
-             <entry>Current flight computer state</entry>
-           </row>
-           <row>
-             <entry>2</entry>
-             <entry>uint16_t</entry>
-             <entry>tick</entry>
-             <entry>Flight computer clock (100 ticks/second)</entry>
-           </row>
-           <row>
-             <entry>4</entry>
-             <entry>uint16_t</entry>
-             <entry>serial</entry>
-             <entry>Flight computer serial number</entry>
-           </row>
-           <row>
-             <entry>6</entry>
-             <entry>uint16_t</entry>
-             <entry>flight</entry>
-             <entry>Flight number</entry>
-           </row>
-           <row>
-             <entry>8</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-      <table frame='all'>
-       <title>Companion Command Identifiers</title>
-       <tgroup cols='3' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Value'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry>Value</entry>
-             <entry>Name</entry>
-             <entry>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>1</entry>
-             <entry>SETUP</entry>
-             <entry>Supply the flight computer with companion
-             information</entry>
-           </row>
-           <row>
-             <entry>2</entry>
-             <entry>FETCH</entry>
-             <entry>Return telemetry information</entry>
-           </row>
-           <row>
-             <entry>3</entry>
-             <entry>NOTIFY</entry>
-             <entry>Tell companion board when flight state
-             changes</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-      <para>
-       The flight computer will send a SETUP message shortly after
-       power-up and will then send FETCH messages no more often than
-       the rate specified in the SETUP reply. NOTIFY messages will be
-       sent whenever the flight state changes.
-      </para>
-      <para>
-       'flight_state' records the current state of the flight,
-       whether on the pad, under power, coasting to apogee or
-       descending on the drogue or main chute.
-      </para>
-      <para>
-       'tick' provides the current flight computer clock, which 
-       be used to synchronize data recorded on the flight computer
-       with that recorded on the companion board in post-flight analysis.
-      </para>
-      <para>
-       'serial' is the product serial number of the flight computer,
-       'flight' is the flight sequence number. Together, these two
-       uniquely identify the flight and can be recorded with any
-       companion board data logging to associate the companion data
-       with the proper flight.
-      </para>
-      <para>
-       NOTIFY commands require no reply at all, they are used solely
-       to inform the companion board when the state of the flight, as
-       computed by the flight computer, changes. Companion boards can
-       use this to change data collection parameters, disabling data
-       logging until the flight starts and terminating it when the
-       flight ends.
-      </para>
-    </section>
-    <section>
-      <title>SETUP reply message</title>
-      <table frame='all'>
-       <title>SETUP reply contents</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0</entry>
-             <entry>uint16_t</entry>
-             <entry>board_id</entry>
-             <entry>Board identifier</entry>
-           </row>
-           <row>
-             <entry>2</entry>
-             <entry>uint16_t</entry>
-             <entry>board_id_inverse</entry>
-             <entry>~board_id—used to tell if a board is present</entry>
-           </row>
-           <row>
-             <entry>4</entry>
-             <entry>uint8_t</entry>
-             <entry>update_period</entry>
-             <entry>Minimum time (in 100Hz ticks) between FETCH commands</entry>
-           </row>
-           <row>
-             <entry>5</entry>
-             <entry>uint8_t</entry>
-             <entry>channels</entry>
-             <entry>Number of data channels to retrieve in FETCH command</entry>
-           </row>
-           <row>
-             <entry>6</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-      <para>
-       The SETUP reply contains enough information to uniquely
-       identify the companion board to the end user as well as for
-       the flight computer to know how many data values to expect in
-       reply to a FETCH command, and how often to fetch that data.
-      </para>
-      <para>
-       To detect the presence of a companion board, the flight
-       computer checks to make sure that board_id_inverse is the
-       bit-wise inverse of board_id. Current companion boards use
-       USB product ID as the board_id, but the flight computer does
-       not interpret this data and so it can be any value.
-      </para>
-    </section>
-    <section>
-      <title>FETCH reply message</title>
-      <table frame='all'>
-       <title>FETCH reply contents</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0</entry>
-             <entry>uint16_t</entry>
-             <entry>data0</entry>
-             <entry>0th data item</entry>
-           </row>
-           <row>
-             <entry>2</entry>
-             <entry>uint16_t</entry>
-             <entry>data1</entry>
-             <entry>1st data item</entry>
-           </row>
-           <row>
-             <entry>...</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-      <para>
-       The FETCH reply contains arbitrary data to be reported over
-       the flight computer telemetry link. The number of 16-bit data items
-       must match the 'channels' value provided in the SETUP reply
-       message.
-      </para>
-    </section>
-  </section>
-  <section>
-    <title>History and Motivation</title>
-    <para>
-      To allow cross-programming, the original TeleMetrum and
-      TeleDongle designs needed to include some kind of
-      connector. With that in place, adding the ability to connect
-      external cards to TeleMetrum was fairly simple. We set the
-      software piece of this puzzle aside until we had a companion
-      board to use.
-    </para>
-    <para>
-      The first companion board was TeleScience. Designed to collect
-      temperature data from the nose and fin of the airframe, the main
-      requirement for the companion port was that it be able to report
-      telemetry data during flight as a back-up in case the
-      TeleScience on-board data was lost.
-    </para>
-    <para>
-      The second companion board, TelePyro, provides 8 additional
-      channels for deployment, staging or other activities. To avoid
-      re-programming the TeleMetrum to use TelePyro, we decided to
-      provide enough information over the companion link for it to
-      independently control those channels.
-    </para>
-    <para>
-      Providing a standard, constant interface between the flight
-      computer and companion boards allows for the base flight
-      computer firmware to include support for companion boards.
-    </para>
-  </section>
-</article>
diff --git a/doc/telemetry-docinfo.xml b/doc/telemetry-docinfo.xml
new file mode 100644 (file)
index 0000000..c7b1f06
--- /dev/null
@@ -0,0 +1,27 @@
+<subtitle>Packet Definitions</subtitle>
+<author>
+  <firstname>Keith</firstname>
+  <surname>Packard</surname>
+  <email>keithp@keithp.com</email>
+</author>
+<date>1 July 2011</date>
+<copyright>
+  <year>2011</year>
+  <holder>Keith Packard</holder>
+</copyright>
+<legalnotice>
+  <para>
+    This document is released under the terms of the
+    <ulink url="http://creativecommons.org/licenses/by-sa/3.0/">
+      Creative Commons ShareAlike 3.0
+    </ulink>
+    license.
+  </para>
+</legalnotice>
+<revhistory>
+  <revision>
+    <revnumber>0.1</revnumber>
+    <date>1 July 2011</date>
+    <revremark>Initial content</revremark>
+  </revision>
+</revhistory>
diff --git a/doc/telemetry.txt b/doc/telemetry.txt
new file mode 100644 (file)
index 0000000..36d2edb
--- /dev/null
@@ -0,0 +1,571 @@
+= AltOS Telemetry
+:doctype: article
+:toc:
+:numbered:
+
+== Packet Format Design
+
+       AltOS telemetry data is split into multiple different packets,
+       all the same size, but each includs an identifier so that the
+       ground station can distinguish among different types. A single
+       flight board will transmit multiple packet types, each type on
+       a different schedule. The ground software need look for only a
+       single packet size, and then decode the information within the
+       packet and merge data from multiple packets to construct the
+       full flight computer state.
+
+       Each AltOS packet is 32 bytes long. This size was chosen based
+       on the known telemetry data requirements. The power of two
+       size allows them to be stored easily in flash memory without
+       having them split across blocks or leaving gaps at the end.
+
+       All packet types start with a five byte header which encodes
+       the device serial number, device clock value and the packet
+       type. The remaining 27 bytes encode type-specific data.
+
+== Packet Formats
+
+      This section first defines the packet header common to all packets
+      and then the per-packet data layout.
+
+       === Packet Header
+
+               .Telemetry Packet Header
+               [options="border",cols="2,3,3,9"]
+               |====
+               |Offset |Data Type      |Name   |Description
+               |0      |uint16_t       |serial |Device serial Number
+               |2      |uint16_t       |tick   |Device time in 100ths of a second
+               |4      |uint8_t        |type   |Packet type
+               |5
+               |====
+
+               Each packet starts with these five bytes which serve to identify
+               which device has transmitted the packet, when it was transmitted
+               and what the rest of the packet contains.
+
+       === TeleMetrum v1.x, TeleMini and TeleNano Sensor Data
+
+               .Sensor Packet Type
+               [options="border",cols="1,3"]
+               |====
+               |Type   |Description
+               |0x01   |TeleMetrum v1.x Sensor Data
+               |0x02   |TeleMini Sensor Data
+               |0x03   |TeleNano Sensor Data
+               |====
+
+               TeleMetrum v1.x, TeleMini and TeleNano share this same
+               packet format for sensor data. Each uses a distinct
+               packet type so that the receiver knows which data
+               values are valid and which are undefined.
+
+               Sensor Data packets are transmitted once per second on
+               the ground, 10 times per second during ascent and once
+               per second during descent and landing
+
+               .Sensor Packet Contents
+               [options="border",cols="2,3,3,9"]
+               |====
+               |Offset |Data Type      |Name           |Description
+               |5      |uint8_t        |state          |Flight state
+               |6      |int16_t        |accel          |accelerometer (TM only)
+               |8      |int16_t        |pres           |pressure sensor
+               |10     |int16_t        |temp           |temperature sensor
+               |12     |int16_t        |v_batt         |battery voltage
+               |14     |int16_t        |sense_d        |drogue continuity sense (TM/Tm)
+               |16     |int16_t        |sense_m        |main continuity sense (TM/Tm)
+               |18     |int16_t        |acceleration   |m/s² * 16
+               |20     |int16_t        |speed          |m/s * 16
+               |22     |int16_t        |height         |m
+               |24     |int16_t        |ground_pres    |Average barometer reading on ground
+               |26     |int16_t        |ground_accel   |TM
+               |28     |int16_t        |accel_plus_g   |TM
+               |30     |int16_t        |accel_minus_g  |TM
+               |32
+               |====
+
+       === TeleMega Sensor Data
+
+               .TeleMega Packet Type
+               [options="border",cols="1,3"]
+               |====
+               |Type   |Description
+               |0x08   |TeleMega IMU Sensor Data
+               |0x09   |TeleMega Kalman and Voltage Data
+               |====
+
+               TeleMega has a lot of sensors, and so it splits the sensor
+               data into two packets. The raw IMU data are sent more often;
+               the voltage values don't change very fast, and the Kalman
+               values can be reconstructed from the IMU data.
+
+               IMU Sensor Data packets are transmitted once per second on the
+               ground, 10 times per second during ascent and once per second
+               during descent and landing
+
+               Kalman and Voltage Data packets are transmitted once per second on the
+               ground, 5 times per second during ascent and once per second
+               during descent and landing
+
+               The high-g accelerometer is reported separately from the data
+               for the 9-axis IMU (accel/gyro/mag). The 9-axis IMU is mounted
+               so that the X axis is "across" the board (along the short
+               axis0, the Y axis is "along" the board (along the long axis,
+               with the high-g accelerometer) and the Z axis is "through" the
+               board (perpendicular to the board). Rotation measurements are
+               around the respective axis, so Y rotation measures the spin
+               rate of the rocket while X and Z rotation measure the tilt
+               rate.
+
+               The overall tilt angle of the rocket is computed by first
+               measuring the orientation of the rocket on the pad using the 3
+               axis accelerometer, and then integrating the overall tilt rate
+               from the 3 axis gyroscope to compute the total orientation
+               change of the airframe since liftoff.
+
+               .TeleMega IMU Sensor Packet Contents
+               [options="border",cols="2,3,3,9"]
+               |====
+               |Offset |Data Type      |Name           |Description
+               |5      |uint8_t        |orient         |Angle from vertical in degrees
+               |6      |int16_t        |accel          |High G accelerometer
+               |8      |int32_t        |pres           |pressure (Pa * 10)
+               |12     |int16_t        |temp           |temperature (°C * 100)
+               |14     |int16_t        |accel_x        |X axis acceleration (across)
+               |16     |int16_t        |accel_y        |Y axis acceleration (along)
+               |18     |int16_t        |accel_z        |Z axis acceleration (through)
+               |20     |int16_t        |gyro_x         |X axis rotation (across)
+               |22     |int16_t        |gyro_y         |Y axis rotation (along)
+               |24     |int16_t        |gyro_z         |Z axis rotation (through)
+               |26     |int16_t        |mag_x          |X field strength (across)
+               |28     |int16_t        |mag_y          |Y field strength (along)
+               |30     |int16_t        |mag_z          |Z field strength (through)
+               |32
+               |====
+
+               .TeleMega Kalman and Voltage Data Packet Contents
+               [options="border",cols="2,3,3,9"]
+               |====
+               |Offset |Data Type      |Name           |Description
+               |5      |uint8_t        |state          |Flight state
+               |6      |int16_t        |v_batt         |battery voltage
+               |8      |int16_t        |v_pyro         |pyro battery voltage
+               |10     |int8_t[6]      |sense          |pyro continuity sense
+               |16     |int32_t        |ground_pres    |Average barometer reading on ground
+               |20     |int16_t        |ground_accel   |Average accelerometer reading on ground
+               |22     |int16_t        |accel_plus_g   |Accel calibration at +1g
+               |24     |int16_t        |accel_minus_g  |Accel calibration at -1g
+               |26     |int16_t        |acceleration   |m/s² * 16
+               |28     |int16_t        |speed          |m/s * 16
+               |30     |int16_t        |height         |m
+               |32
+               |====
+
+       === TeleMetrum v2 Sensor Data
+
+               .TeleMetrum v2 Packet Type
+               [options="border",cols="1,3"]
+               |====
+               |Type   |Description
+               |0x0A   |TeleMetrum v2 Sensor Data
+               |0x0B   |TeleMetrum v2 Calibration Data
+               |====
+
+               TeleMetrum v2 has higher resolution barometric data than
+               TeleMetrum v1, and so the constant calibration data is
+               split out into a separate packet.
+
+               TeleMetrum v2 Sensor Data packets are transmitted once per second on the
+               ground, 10 times per second during ascent and once per second
+               during descent and landing
+
+               TeleMetrum v2 Calibration Data packets are always transmitted once per second.
+
+               .TeleMetrum v2 Sensor Packet Contents
+               [options="border",cols="2,3,3,9"]
+               |====
+               |Offset |Data Type      |Name           |Description
+               |5      |uint8_t        |state          |Flight state
+               |6      |int16_t        |accel          |accelerometer
+               |8      |int32_t        |pres           |pressure sensor (Pa * 10)
+               |12     |int16_t        |temp           |temperature sensor (°C * 100)
+               |14     |int16_t        |acceleration   |m/s² * 16
+               |16     |int16_t        |speed          |m/s * 16
+               |18     |int16_t        |height         |m
+               |20     |int16_t        |v_batt         |battery voltage
+               |22     |int16_t        |sense_d        |drogue continuity sense
+               |24     |int16_t        |sense_m        |main continuity sense
+               |26     |pad[6]         |pad bytes      |
+               |32
+               |====
+
+               .TeleMetrum v2 Calibration Data Packet Contents
+               [options="border",cols="2,3,3,9"]
+               |====
+               |Offset |Data Type      |Name           |Description
+               |5      |pad[3]         |pad bytes      |
+               |8      |int32_t        |ground_pres    |Average barometer reading on ground
+               |12     |int16_t        |ground_accel   |Average accelerometer reading on ground
+               |14     |int16_t        |accel_plus_g   |Accel calibration at +1g
+               |16     |int16_t        |accel_minus_g  |Accel calibration at -1g
+               |18     |pad[14]        |pad bytes      |
+               |32
+               |====
+
+       === Configuration Data
+
+               .Configuration Packet Type
+               [options="border",cols="1,3"]
+               |====
+               |Type   |Description
+               |0x04   |Configuration Data
+               |====
+
+               This provides a description of the software installed on the
+               flight computer as well as any user-specified configuration data.
+
+               Configuration data packets are transmitted once per second
+               during all phases of the flight
+
+               .Configuration Packet Contents
+               [options="border",cols="2,3,3,9"]
+               |====
+               |Offset |Data Type      |Name           |Description
+               |5      |uint8_t        |type           |Device type
+               |6      |uint16_t       |flight         |Flight number
+               |8      |uint8_t        |config_major   |Config major version
+               |9      |uint8_t        |config_minor   |Config minor version
+               |10     |uint16_t       |apogee_delay   |Apogee deploy delay in seconds
+               |12     |uint16_t       |main_deploy    |Main deploy alt in meters
+               |14     |uint16_t       |flight_log_max |Maximum flight log size (kB)
+               |16     |char           |callsign[8]    |Radio operator identifier
+               |24     |char           |version[8]     |Software version identifier
+               |32
+               |====
+
+       === GPS Location
+
+               .GPS Packet Type
+               [options="border",cols="1,3"]
+               |====
+               |Type   |Description
+               |0x05   |GPS Location
+               |====
+
+               This packet provides all of the information available from the
+               GPS receiver—position, time, speed and precision
+               estimates.
+
+               GPS Location packets are transmitted once per second during
+               all phases of the flight
+
+               .GPS Location Packet Contents
+               [options="border",cols="2,3,3,9"]
+               |====
+               |Offset |Data Type      |Name           |Description
+               |5      |uint8_t        |flags          |See GPS Flags table below
+               |6      |int16_t        |altitude       |m
+               |8      |int32_t        |latitude       |degrees * 107
+               |12     |int32_t        |longitude      |degrees * 107
+               |16     |uint8_t        |year           |
+               |17     |uint8_t        |month          |
+               |18     |uint8_t        |day            |
+               |19     |uint8_t        |hour           |
+               |20     |uint8_t        |minute         |
+               |21     |uint8_t        |second         |
+               |22     |uint8_t        |pdop           |* 5
+               |23     |uint8_t        |hdop           |* 5
+               |24     |uint8_t        |vdop           |* 5
+               |25     |uint8_t        |mode           |See GPS Mode table below
+               |26     |uint16_t       |ground_speed   |cm/s
+               |28     |int16_t        |climb_rate     |cm/s
+               |30     |uint8_t        |course         |/ 2
+               |31     |uint8_t        |unused[1]      |
+               |32
+               |====
+
+               Packed into a one byte field are status flags and the
+               count of satellites used to compute the position
+               fix. Note that this number may be lower than the
+               number of satellites being tracked; the receiver will
+               not use information from satellites with weak signals
+               or which are close enough to the horizon to have
+               significantly degraded position accuracy.
+
+               .GPS Flags
+               [options="border",cols="1,2,7"]
+               |====
+               |Bits   |Name           |Description
+               |0-3    |nsats          |Number of satellites in solution
+               |4      |valid          |GPS solution is valid
+               |5      |running        |GPS receiver is operational
+               |6      |date_valid     |Reported date is valid
+               |7      |course_valid   |ground speed, course and climb rates are valid
+               |====
+
+               Here are all of the valid GPS operational modes. Altus
+               Metrum products will only ever report 'N' (not valid),
+               'A' (Autonomous) modes or 'E' (Estimated). The
+               remaining modes are either testing modes or require
+               additional data.
+
+               .GPS Mode
+               [options="border",cols="1,3,7"]
+               |====
+               |Mode           |Name                   |Description
+               |N              |Not Valid              |All data are invalid
+               |A              |Autonomous mode        |
+                 Data are derived from satellite data
+
+               |D              |Differential Mode      |
+                 Data are augmented with differential data from a
+                 known ground station. The SkyTraq unit in TeleMetrum
+                 does not support this mode
+
+               |E              |Estimated              |
+                 Data are estimated using dead reckoning from the
+                 last known data
+
+               |M              |Manual                 |
+                 Data were entered manually
+
+               |S              |Simulated              |
+                 GPS receiver testing mode
+
+               |====
+
+       === GPS Satellite Data
+
+               .GPS Satellite Data Packet Type
+               [options="border",cols="1,3"]
+               |====
+               |Type           |Description
+               |0x06           |GPS Satellite Data
+               |====
+
+               This packet provides space vehicle identifiers and
+               signal quality information in the form of a C/N1
+               number for up to 12 satellites. The order of the svids
+               is not specified.
+
+               GPS Satellite data are transmitted once per second
+               during all phases of the flight.
+
+               .GPS Satellite Data Contents
+               [options="border",cols="2,3,3,9"]
+               |====
+               |Offset |Data Type      |Name           |Description
+               |5      |uint8_t        |channels       |Number of reported satellite information
+               |6      |sat_info_t     |sats[12]       |See Per-Satellite data table below
+               |30     |uint8_t        |unused[2]      |
+               |32
+               |====
+
+               .GPS Per-Satellite data (sat_info_t)
+               [options="border",cols="2,3,3,9"]
+               |====
+               |Offset |Data Type      |Name           |Description
+               |0      |uint8_t        |svid           |Space Vehicle Identifier
+               |1      |uint8_t        |c_n_1          |C/N1 signal quality indicator
+               |2
+               |====
+
+       === Companion Data
+
+               .Companion Data Packet Type
+               [options="border",cols="1,3"]
+               |====
+               |Type   |Description
+               |0x07   |Companion Data
+               |====
+
+               When a companion board is attached to TeleMega or
+               TeleMetrum, it can provide telemetry data to be
+               included in the downlink. The companion board can
+               provide up to 12 16-bit data values.
+
+               The companion board itself specifies the transmission
+               rate. On the ground and during descent, that rate is
+               limited to one packet per second. During ascent, that
+               rate is limited to 10 packets per second.
+
+               .Companion Data Contents
+               [options="border",cols="2,3,3,9"]
+               |====
+               |Offset |Data Type      |Name           |Description
+               |5      |uint8_t        |board_id       |Type of companion board attached
+               |6      |uint8_t        |update_period  |How often telemetry is sent, in 1/100ths of a second
+               |7      |uint8_t        |channels       |Number of data channels supplied
+               |8      |uint16_t[12]   |companion_data |Up to 12 channels of 16-bit companion data
+               |32
+               |====
+
+== Data Transmission
+
+       Altus Metrum devices use Texas Instruments sub-GHz digital
+       radio products. Ground stations use parts with HW FEC while
+       some flight computers perform FEC in software. TeleGPS is
+       transmit-only.
+
+       .Altus Metrum Radio Parts
+       [options="border",cols="1,4,4"]
+       |====
+       |Part Number    |Description    |Used in
+
+       |CC1111
+       |10mW transceiver with integrated SoC
+       |TeleDongle v0.2, TeleBT v1.0, TeleMetrum v1.x, TeleMini
+
+       |CC1120
+       |35mW transceiver with SW FEC
+       |TeleMetrum v2, TeleMega
+
+       |CC1200
+       |35mW transceiver with HW FEC
+       |TeleDongle v3.0, TeleBT v3.0
+
+       |CC115L
+       |14mW transmitter with SW FEC
+       |TeleGPS
+
+       |====
+
+       === Modulation Scheme
+
+               Texas Instruments provides a tool for computing
+               modulation parameters given a desired modulation
+               format and basic bit rate.
+
+               While we might like to use something with better
+               low-signal performance like BPSK, the radios we use
+               don't support that, but do support Gaussian frequency
+               shift keying (GFSK). Regular frequency shift keying
+               (FSK) encodes the signal by switching the carrier
+               between two frequencies. The Gaussian version is
+               essentially the same, but the shift between
+               frequencies gently follows a gaussian curve, rather
+               than switching immediately. This tames the bandwidth
+               of the signal without affecting the ability to
+               transmit data.
+
+               For AltOS, there are three available bit rates,
+               38.4kBaud, 9.6kBaud and 2.4kBaud resulting in the
+               following signal parmeters:
+
+               .Modulation Scheme
+               [options="border",cols="1,1,1"]
+               |====
+               |Rate           |Deviation      |Receiver Bandwidth
+               |38.4kBaud      |20.5kHz        |100kHz
+               |9.6kBaud       |5.125kHz       |25kHz
+               |2.4kBaud       |1.5kHz         |5kHz
+               |====
+
+       === Error Correction
+
+               The cc1111 and cc1200 provide forward error correction
+               in hardware; on the cc1120 and cc115l that's done in
+               software. AltOS uses this to improve reception of weak
+               signals. As it's a rate 1/2 encoding, each bit of data
+               takes two bits when transmitted, so the effective data
+               rate is half of the raw transmitted bit rate.
+
+               .Error Correction
+               [options="border",cols="1,1,1"]
+               |====
+               |Parameter      |Value  |Description
+
+               |Error Correction
+               |Convolutional coding
+               |1/2 rate, constraint length m=4
+
+               |Interleaving
+               |4 x 4
+               |Reduce effect of noise burst
+
+               |Data Whitening
+               |XOR with 9-bit PNR
+               |Rotate right with bit 8 = bit 0 xor bit 5, initial value 111111111
+
+               |====
+
+== TeleDongle serial packet format
+
+       TeleDongle does not do any interpretation of the packet data,
+       instead it is configured to receive packets of a specified
+       length (32 bytes in this case). For each received packet,
+       TeleDongle produces a single line of text. This line starts with
+       the string "TELEM " and is followed by a list of hexadecimal
+       encoded bytes.
+
+       ....
+       TELEM 224f01080b05765e00701f1a1bbeb8d7b60b070605140c000600000000000000003fa988
+       ....
+
+       The hexadecimal encoded string of bytes contains a length byte,
+       the packet data, two bytes added by the cc1111 radio receiver
+       hardware and finally a checksum so that the host software can
+       validate that the line was transmitted without any errors.
+
+       .TeleDongle serial Packet Format
+
+       [options="border",cols="2,1,1,5"]
+       |====
+       |Offset |Name   |Example        |Description
+
+       |0
+       |length
+       |22
+       |Total length of data bytes in the line. Note that
+        this includes the added RSSI and status bytes
+
+       |1 ·· length-3
+       |packet
+       |4f ·· 00
+       |Bytes of actual packet data
+
+       |length-2
+       |rssi
+       |3f
+       |Received signal strength. dBm = rssi / 2 - 74
+
+       |length-1
+       |lqi
+       |a9
+       |Link Quality Indicator and CRC status. Bit 7
+        is set when the CRC is correct
+
+       |length
+       |checksum
+       |88
+       |(0x5a + sum(bytes 1 ·· length-1)) % 256
+
+       |====
+
+== History and Motivation
+
+      The original AltoOS telemetry mechanism encoded everything
+      available piece of information on the TeleMetrum hardware into a
+      single unified packet. Initially, the packets contained very
+      little data—some raw sensor readings along with the current GPS
+      coordinates when a GPS receiver was connected. Over time, the
+      amount of data grew to include sensor calibration data, GPS
+      satellite information and a host of internal state information
+      designed to help diagnose flight failures in case of a loss of
+      the on-board flight data.
+
+      Because every packet contained all of the data, packets were
+      huge—95 bytes long. Much of the information was also specific to
+      the TeleMetrum hardware. With the introduction of the TeleMini
+      flight computer, most of the data contained in the telemetry
+      packets was unavailable. Initially, a shorter, but still
+      comprehensive packet was implemented. This required that the
+      ground station be pre-configured as to which kind of packet to
+      expect.
+
+      The development of several companion boards also made the
+      shortcomings evident—each companion board would want to include
+      telemetry data in the radio link; with the original design, the
+      packet would have to hold the new data as well, requiring
+      additional TeleMetrum and ground station changes.
diff --git a/doc/telemetry.xsl b/doc/telemetry.xsl
deleted file mode 100644 (file)
index 2e0b3ea..0000000
+++ /dev/null
@@ -1,1230 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"/usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd">
-
-<article>
-  <articleinfo>
-    <title>AltOS Telemetry</title>
-    <subtitle>Packet Definitions</subtitle>
-    <author>
-      <firstname>Keith</firstname>
-      <surname>Packard</surname>
-    </author>
-    <copyright>
-      <year>2011</year>
-      <holder>Keith Packard</holder>
-    </copyright>
-    <legalnotice>
-      <para>
-       This document is released under the terms of the
-       <ulink url="http://creativecommons.org/licenses/by-sa/3.0/">
-         Creative Commons ShareAlike 3.0
-       </ulink>
-       license.
-      </para>
-    </legalnotice>
-    <revhistory>
-      <revision>
-       <revnumber>0.1</revnumber>
-       <date>01 July 2011</date>
-       <revremark>Initial content</revremark>
-      </revision>
-    </revhistory>
-  </articleinfo>
-  <section>
-    <title>Packet Format Design</title>
-    <para>
-      AltOS telemetry data is split into multiple different packets,
-      all the same size, but each includs an identifier so that the
-      ground station can distinguish among different types. A single
-      flight board will transmit multiple packet types, each type on a
-      different schedule. The ground software need look for only a
-      single packet size, and then decode the information within the
-      packet and merge data from multiple packets to construct the
-      full flight computer state.
-    </para>
-    <para>
-      Each AltOS packet is 32 bytes long. This size was chosen based
-      on the known telemetry data requirements. The power of two size
-      allows them to be stored easily in flash memory without having
-      them split across blocks or leaving gaps at the end.
-    </para>
-    <para>
-      All packet types start with a five byte header which encodes the
-      device serial number, device clock value and the packet
-      type. The remaining 27 bytes encode type-specific data.
-    </para>
-  </section>
-  <section>
-    <title>Packet Formats</title>
-    <para>
-      This section first defines the packet header common to all packets
-      and then the per-packet data layout.
-    </para>
-    <section>
-      <title>Packet Header</title>
-      <table frame='all'>
-       <title>Telemetry Packet Header</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0</entry>
-             <entry>uint16_t</entry>
-             <entry>serial</entry>
-             <entry>Device serial Number</entry>
-           </row>
-           <row>
-             <entry>2</entry>
-             <entry>uint16_t</entry>
-             <entry>tick</entry>
-             <entry>Device time in 100ths of a second</entry>
-           </row>
-           <row>
-             <entry>4</entry>
-             <entry>uint8_t</entry>
-             <entry>type</entry>
-             <entry>Packet type</entry>
-           </row>
-           <row>
-             <entry>5</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-      <para>
-      Each packet starts with these five bytes which serve to identify
-      which device has transmitted the packet, when it was transmitted
-      and what the rest of the packet contains.
-      </para>
-    </section>
-    <section>
-      <title>TeleMetrum v1.x, TeleMini and TeleNano Sensor Data</title>
-      <informaltable frame='none' label='' tocentry='0'>
-       <tgroup cols='2' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='left' colwidth='3*' colname='Description'/>
-         <thead>
-           <row>
-             <entry>Type</entry>
-             <entry>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0x01</entry>
-             <entry>TeleMetrum v1.x Sensor Data</entry>
-           </row>
-           <row>
-             <entry>0x02</entry>
-             <entry>TeleMini Sensor Data</entry>
-           </row>
-           <row>
-             <entry>0x03</entry>
-             <entry>TeleNano Sensor Data</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </informaltable>
-      <para>
-       TeleMetrum v1.x, TeleMini and TeleNano share this same packet
-       format for sensor data. Each uses a distinct packet type so
-       that the receiver knows which data values are valid and which
-       are undefined.
-      </para>
-      <para>
-       Sensor Data packets are transmitted once per second on the
-       ground, 10 times per second during ascent and once per second
-       during descent and landing
-      </para>
-      <table frame='all'>
-       <title>Sensor Packet Contents</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>5</entry><entry>uint8_t</entry><entry>state</entry><entry>Flight state</entry>
-           </row>
-           <row>
-             <entry>6</entry><entry>int16_t</entry><entry>accel</entry><entry>accelerometer (TM only)</entry>
-           </row>
-           <row>
-             <entry>8</entry><entry>int16_t</entry><entry>pres</entry><entry>pressure sensor</entry>
-           </row>
-           <row>
-             <entry>10</entry><entry>int16_t</entry><entry>temp</entry><entry>temperature sensor</entry>
-           </row>
-           <row>
-             <entry>12</entry><entry>int16_t</entry><entry>v_batt</entry><entry>battery voltage</entry>
-           </row>
-           <row>
-             <entry>14</entry><entry>int16_t</entry><entry>sense_d</entry><entry>drogue continuity sense (TM/Tm)</entry>
-           </row>
-           <row>
-             <entry>16</entry><entry>int16_t</entry><entry>sense_m</entry><entry>main continuity sense (TM/Tm)</entry>
-           </row>
-           <row>
-             <entry>18</entry><entry>int16_t</entry><entry>acceleration</entry><entry>m/s² * 16</entry>
-           </row>
-           <row>
-             <entry>20</entry><entry>int16_t</entry><entry>speed</entry><entry>m/s * 16</entry>
-           </row>
-           <row>
-             <entry>22</entry><entry>int16_t</entry><entry>height</entry><entry>m</entry>
-           </row>
-           <row>
-             <entry>24</entry><entry>int16_t</entry><entry>ground_pres</entry><entry>Average barometer reading on ground</entry>
-           </row>
-           <row>
-             <entry>26</entry><entry>int16_t</entry><entry>ground_accel</entry><entry>TM</entry>
-           </row>
-           <row>
-             <entry>28</entry><entry>int16_t</entry><entry>accel_plus_g</entry><entry>TM</entry>
-           </row>
-           <row>
-             <entry>30</entry><entry>int16_t</entry><entry>accel_minus_g</entry><entry>TM</entry>
-           </row>
-           <row>
-             <entry>32</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-    </section>
-    <section>
-      <title>TeleMega Sensor  Data</title>
-      <informaltable frame='none' label='' tocentry='0'>
-       <tgroup cols='2' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='left' colwidth='3*' colname='Description'/>
-         <thead>
-           <row>
-             <entry>Type</entry>
-             <entry>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0x08</entry>
-             <entry>TeleMega IMU Sensor Data</entry>
-           </row>
-           <row>
-             <entry>0x09</entry>
-             <entry>TeleMega Kalman and Voltage Data</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </informaltable>
-      <para>
-       TeleMega has a lot of sensors, and so it splits the sensor
-       data into two packets. The raw IMU data are sent more often;
-       the voltage values don't change very fast, and the Kalman
-       values can be reconstructed from the IMU data.
-      </para>
-      <para>
-       IMU Sensor Data packets are transmitted once per second on the
-       ground, 10 times per second during ascent and once per second
-       during descent and landing
-      </para>
-      <para>
-       Kalman and Voltage Data packets are transmitted once per second on the
-       ground, 5 times per second during ascent and once per second
-       during descent and landing
-      </para>
-      <para>
-       The high-g accelerometer is reported separately from the data
-       for the 9-axis IMU (accel/gyro/mag). The 9-axis IMU is mounted
-       so that the X axis is "across" the board (along the short
-       axis0, the Y axis is "along" the board (along the long axis,
-       with the high-g accelerometer) and the Z axis is "through" the
-       board (perpendicular to the board). Rotation measurements are
-       around the respective axis, so Y rotation measures the spin
-       rate of the rocket while X and Z rotation measure the tilt
-       rate.
-      </para>
-      <para>
-       The overall tilt angle of the rocket is computed by first
-       measuring the orientation of the rocket on the pad using the 3
-       axis accelerometer, and then integrating the overall tilt rate
-       from the 3 axis gyroscope to compute the total orientation
-       change of the airframe since liftoff.
-      </para>
-      <table frame='all'>
-       <title>TeleMega IMU Sensor Packet Contents</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>5</entry><entry>uint8_t</entry><entry>orient</entry><entry>Angle from vertical in degrees</entry>
-           </row>
-           <row>
-             <entry>6</entry><entry>int16_t</entry><entry>accel</entry><entry>High G accelerometer</entry>
-           </row>
-           <row>
-             <entry>8</entry><entry>int32_t</entry><entry>pres</entry><entry>pressure (Pa * 10)</entry>
-           </row>
-           <row>
-             <entry>12</entry><entry>int16_t</entry><entry>temp</entry><entry>temperature (°C * 100)</entry>
-           </row>
-           <row>
-             <entry>14</entry><entry>int16_t</entry><entry>accel_x</entry><entry>X axis acceleration (across)</entry>
-           </row>
-           <row>
-             <entry>16</entry><entry>int16_t</entry><entry>accel_y</entry><entry>Y axis acceleration (along)</entry>
-           </row>
-           <row>
-             <entry>18</entry><entry>int16_t</entry><entry>accel_z</entry><entry>Z axis acceleration (through)</entry>
-           </row>
-           <row>
-             <entry>20</entry><entry>int16_t</entry><entry>gyro_x</entry><entry>X axis rotation (across)</entry>
-           </row>
-           <row>
-             <entry>22</entry><entry>int16_t</entry><entry>gyro_y</entry><entry>Y axis rotation (along)</entry>
-           </row>
-           <row>
-             <entry>24</entry><entry>int16_t</entry><entry>gyro_z</entry><entry>Z axis rotation (through)</entry>
-           </row>
-           <row>
-             <entry>26</entry><entry>int16_t</entry><entry>mag_x</entry><entry>X field strength (across)</entry>
-           </row>
-           <row>
-             <entry>28</entry><entry>int16_t</entry><entry>mag_y</entry><entry>Y field strength (along)</entry>
-           </row>
-           <row>
-             <entry>30</entry><entry>int16_t</entry><entry>mag_z</entry><entry>Z field strength (through)</entry>
-           </row>
-           <row>
-             <entry>32</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-      <table frame='all'>
-       <title>TeleMega Kalman and Voltage Data Packet Contents</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>5</entry><entry>uint8_t</entry><entry>state</entry><entry>Flight state</entry>
-           </row>
-           <row>
-             <entry>6</entry><entry>int16_t</entry><entry>v_batt</entry><entry>battery voltage</entry>
-           </row>
-           <row>
-             <entry>8</entry><entry>int16_t</entry><entry>v_pyro</entry><entry>pyro battery voltage</entry>
-           </row>
-           <row>
-             <entry>10</entry><entry>int8_t[6]</entry><entry>sense</entry><entry>pyro continuity sense</entry>
-           </row>
-           <row>
-             <entry>16</entry><entry>int32_t</entry><entry>ground_pres</entry><entry>Average barometer reading on ground</entry>
-           </row>
-           <row>
-             <entry>20</entry><entry>int16_t</entry><entry>ground_accel</entry><entry>Average accelerometer reading on ground</entry>
-           </row>
-           <row>
-             <entry>22</entry><entry>int16_t</entry><entry>accel_plus_g</entry><entry>Accel calibration at +1g</entry>
-           </row>
-           <row>
-             <entry>24</entry><entry>int16_t</entry><entry>accel_minus_g</entry><entry>Accel calibration at -1g</entry>
-           </row>
-           <row>
-             <entry>26</entry><entry>int16_t</entry><entry>acceleration</entry><entry>m/s² * 16</entry>
-           </row>
-           <row>
-             <entry>28</entry><entry>int16_t</entry><entry>speed</entry><entry>m/s * 16</entry>
-           </row>
-           <row>
-             <entry>30</entry><entry>int16_t</entry><entry>height</entry><entry>m</entry>
-           </row>
-           <row>
-             <entry>32</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-    </section>
-    <section>
-      <title>TeleMetrum v2 Sensor  Data</title>
-      <informaltable frame='none' label='' tocentry='0'>
-       <tgroup cols='2' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='left' colwidth='3*' colname='Description'/>
-         <thead>
-           <row>
-             <entry>Type</entry>
-             <entry>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0x0A</entry>
-             <entry>TeleMetrum v2 Sensor Data</entry>
-           </row>
-           <row>
-             <entry>0x0B</entry>
-             <entry>TeleMetrum v2 Calibration Data</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </informaltable>
-      <para>
-       TeleMetrum v2 has higher resolution barometric data than
-       TeleMetrum v1, and so the constant calibration data is
-       split out into a separate packet.
-      </para>
-      <para>
-       TeleMetrum v2 Sensor Data packets are transmitted once per second on the
-       ground, 10 times per second during ascent and once per second
-       during descent and landing
-      </para>
-      <para>
-       TeleMetrum v2 Calibration Data packets are always transmitted once per second.
-      </para>
-      <table frame='all'>
-       <title>TeleMetrum v2 Sensor Packet Contents</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>5</entry><entry>uint8_t</entry><entry>state</entry><entry>Flight state</entry>
-           </row>
-           <row>
-             <entry>6</entry><entry>int16_t</entry><entry>accel</entry><entry>accelerometer</entry>
-           </row>
-           <row>
-             <entry>8</entry><entry>int32_t</entry><entry>pres</entry><entry>pressure sensor (Pa * 10)</entry>
-           </row>
-           <row>
-             <entry>12</entry><entry>int16_t</entry><entry>temp</entry><entry>temperature sensor (°C * 100)</entry>
-           </row>
-
-           <row>
-             <entry>14</entry><entry>int16_t</entry><entry>acceleration</entry><entry>m/s² * 16</entry>
-           </row>
-           <row>
-             <entry>16</entry><entry>int16_t</entry><entry>speed</entry><entry>m/s * 16</entry>
-           </row>
-           <row>
-             <entry>18</entry><entry>int16_t</entry><entry>height</entry><entry>m</entry>
-           </row>
-
-           <row>
-             <entry>20</entry><entry>int16_t</entry><entry>v_batt</entry><entry>battery voltage</entry>
-           </row>
-           <row>
-             <entry>22</entry><entry>int16_t</entry><entry>sense_d</entry><entry>drogue continuity sense</entry>
-           </row>
-           <row>
-             <entry>24</entry><entry>int16_t</entry><entry>sense_m</entry><entry>main continuity sense</entry>
-           </row>
-           <row>
-             <entry>26</entry><entry>pad[6]</entry><entry>pad bytes</entry><entry></entry>
-           </row>
-           <row>
-             <entry>32</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-      <table frame='all'>
-       <title>TeleMetrum v2 Calibration Data Packet Contents</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>5</entry><entry>pad[3]</entry><entry>pad bytes</entry><entry></entry>
-           </row>
-           <row>
-             <entry>8</entry><entry>int32_t</entry><entry>ground_pres</entry><entry>Average barometer reading on ground</entry>
-           </row>
-           <row>
-             <entry>12</entry><entry>int16_t</entry><entry>ground_accel</entry><entry>Average accelerometer reading on ground</entry>
-           </row>
-           <row>
-             <entry>14</entry><entry>int16_t</entry><entry>accel_plus_g</entry><entry>Accel calibration at +1g</entry>
-           </row>
-           <row>
-             <entry>16</entry><entry>int16_t</entry><entry>accel_minus_g</entry><entry>Accel calibration at -1g</entry>
-           </row>
-           <row>
-             <entry>18</entry><entry>pad[14]</entry><entry>pad bytes</entry><entry></entry>
-           </row>
-           <row>
-             <entry>32</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-    </section>
-    <section>
-      <title>Configuration Data</title>
-      <informaltable frame='none' label='' tocentry='0'>
-       <tgroup cols='2' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='left' colwidth='3*' colname='Description'/>
-         <thead>
-           <row>
-             <entry>Type</entry>
-             <entry>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0x04</entry>
-             <entry>Configuration Data</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </informaltable>
-      <para>
-       This provides a description of the software installed on the
-       flight computer as well as any user-specified configuration data.
-      </para>
-      <para>
-       Configuration data packets are transmitted once per second
-       during all phases of the flight
-      </para>
-      <table frame='all'>
-       <title>Sensor Packet Contents</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>5</entry><entry>uint8_t</entry><entry>type</entry><entry>Device type</entry>
-           </row>
-           <row>
-             <entry>6</entry><entry>uint16_t</entry><entry>flight</entry><entry>Flight number</entry>
-           </row>
-           <row>
-             <entry>8</entry><entry>uint8_t</entry><entry>config_major</entry><entry>Config major version</entry>
-           </row>
-           <row>
-             <entry>9</entry><entry>uint8_t</entry><entry>config_minor</entry><entry>Config minor version</entry>
-           </row>
-           <row>
-             <entry>10</entry><entry>uint16_t</entry><entry>apogee_delay</entry>
-             <entry>Apogee deploy delay in seconds</entry>
-           </row>
-           <row>
-             <entry>12</entry><entry>uint16_t</entry><entry>main_deploy</entry><entry>Main deploy alt in meters</entry>
-           </row>
-           <row>
-             <entry>14</entry><entry>uint16_t</entry><entry>flight_log_max</entry>
-             <entry>Maximum flight log size (kB)</entry>
-           </row>
-           <row>
-             <entry>16</entry><entry>char</entry><entry>callsign[8]</entry><entry>Radio operator identifier</entry>
-           </row>
-           <row>
-             <entry>24</entry><entry>char</entry><entry>version[8]</entry><entry>Software version identifier</entry>
-           </row>
-           <row>
-             <entry>32</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-    </section>
-    <section>
-      <title>GPS Location</title>
-      <informaltable frame='none' label='' tocentry='0'>
-       <tgroup cols='2' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='left' colwidth='3*' colname='Description'/>
-         <thead>
-           <row>
-             <entry>Type</entry>
-             <entry>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0x05</entry>
-             <entry>GPS Location</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </informaltable>
-      <para>
-       This packet provides all of the information available from the
-       GPS receiver—position, time, speed and precision
-       estimates. 
-      </para>
-      <para>
-       GPS Location packets are transmitted once per second during
-       all phases of the flight
-      </para>
-      <table frame='all'>
-       <title>GPS Location Packet Contents</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>5</entry><entry>uint8_t</entry><entry>flags</entry>
-             <entry>See GPS Flags table below</entry>
-           </row>
-           <row>
-             <entry>6</entry><entry>int16_t</entry><entry>altitude</entry><entry>m</entry>
-           </row>
-           <row>
-             <entry>8</entry><entry>int32_t</entry><entry>latitude</entry><entry>degrees * 10<superscript>7</superscript></entry>
-           </row>
-           <row>
-             <entry>12</entry><entry>int32_t</entry><entry>longitude</entry><entry>degrees * 10<superscript>7</superscript></entry>
-           </row>
-           <row>
-             <entry>16</entry><entry>uint8_t</entry><entry>year</entry>
-           </row>
-           <row>
-             <entry>17</entry><entry>uint8_t</entry><entry>month</entry>
-           </row>
-           <row>
-             <entry>18</entry><entry>uint8_t</entry><entry>day</entry>
-           </row>
-           <row>
-             <entry>19</entry><entry>uint8_t</entry><entry>hour</entry>
-           </row>
-           <row>
-             <entry>20</entry><entry>uint8_t</entry><entry>minute</entry>
-           </row>
-           <row>
-             <entry>21</entry><entry>uint8_t</entry><entry>second</entry>
-           </row>
-           <row>
-             <entry>22</entry><entry>uint8_t</entry><entry>pdop</entry><entry>* 5</entry>
-           </row>
-           <row>
-             <entry>23</entry><entry>uint8_t</entry><entry>hdop</entry><entry>* 5</entry>
-           </row>
-           <row>
-             <entry>24</entry><entry>uint8_t</entry><entry>vdop</entry><entry>* 5</entry>
-           </row>
-           <row>
-             <entry>25</entry><entry>uint8_t</entry><entry>mode</entry>
-             <entry>See GPS Mode table below</entry>
-           </row>
-           <row>
-             <entry>26</entry><entry>uint16_t</entry><entry>ground_speed</entry><entry>cm/s</entry>
-           </row>
-           <row>
-             <entry>28</entry><entry>int16_t</entry><entry>climb_rate</entry><entry>cm/s</entry>
-           </row>
-           <row>
-             <entry>30</entry><entry>uint8_t</entry><entry>course</entry><entry>/ 2</entry>
-           </row>
-           <row>
-             <entry>31</entry><entry>uint8_t</entry><entry>unused[1]</entry>
-           </row>
-           <row>
-             <entry>32</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-      <para>
-       Packed into a one byte field are status flags and the count of
-       satellites used to compute the position fix. Note that this
-       number may be lower than the number of satellites being
-       tracked; the receiver will not use information from satellites
-       with weak signals or which are close enough to the horizon to
-       have significantly degraded position accuracy.
-      </para>
-      <table frame='all'>
-       <title>GPS Flags</title>
-       <tgroup cols='3' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='bits'/>
-         <colspec align='left' colwidth='2*' colname='name'/>
-         <colspec align='left' colwidth='7*' colname='description'/>
-         <thead>
-           <row>
-             <entry align='center'>Bits</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0-3</entry>
-             <entry>nsats</entry>
-             <entry>Number of satellites in solution</entry>
-           </row>
-           <row>
-             <entry>4</entry>
-             <entry>valid</entry>
-             <entry>GPS solution is valid</entry>
-           </row>
-           <row>
-             <entry>5</entry>
-             <entry>running</entry>
-             <entry>GPS receiver is operational</entry>
-           </row>
-           <row>
-             <entry>6</entry>
-             <entry>date_valid</entry>
-             <entry>Reported date is valid</entry>
-           </row>
-           <row>
-             <entry>7</entry>
-             <entry>course_valid</entry>
-             <entry>ground speed, course and climb rates are valid</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-      <para>
-       Here are all of the valid GPS operational modes. Altus Metrum
-       products will only ever report 'N' (not valid), 'A'
-       (Autonomous) modes or 'E' (Estimated). The remaining modes
-       are either testing modes or require additional data.
-      </para>
-      <table frame='all'>
-       <title>GPS Mode</title>
-       <tgroup cols='3' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='value'/>
-         <colspec align='center' colwidth='3*' colname='name'/>
-         <colspec align='left' colwidth='7*' colname='description'/>
-         <thead>
-           <row>
-             <entry align='center'>Mode</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Decsription</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>N</entry>
-             <entry>Not Valid</entry>
-             <entry>All data are invalid</entry>
-           </row>
-           <row>
-             <entry>A</entry>
-             <entry>Autonomous mode</entry>
-             <entry>Data are derived from satellite data</entry>
-           </row>
-           <row>
-             <entry>D</entry>
-             <entry>Differential Mode</entry>
-             <entry>
-                 Data are augmented with differential data from a
-                 known ground station. The SkyTraq unit in TeleMetrum
-                 does not support this mode
-               </entry>
-           </row>
-           <row>
-             <entry>E</entry>
-             <entry>Estimated</entry>
-             <entry>
-                 Data are estimated using dead reckoning from the
-                 last known data
-               </entry>
-           </row>
-           <row>
-             <entry>M</entry>
-             <entry>Manual</entry>
-             <entry>Data were entered manually</entry>
-           </row>
-           <row>
-             <entry>S</entry>
-             <entry>Simulated</entry>
-             <entry>GPS receiver testing mode</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-    </section>
-    <section>
-      <title>GPS Satellite Data</title>
-      <informaltable frame='none' label='' tocentry='0'>
-       <tgroup cols='2' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='left' colwidth='3*' colname='Description'/>
-         <thead>
-           <row>
-             <entry>Type</entry>
-             <entry>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0x06</entry>
-             <entry>GPS Satellite Data</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </informaltable>
-      <para>
-       This packet provides space vehicle identifiers and signal
-       quality information in the form of a C/N1 number for up to 12
-       satellites. The order of the svids is not specified.
-      </para>
-      <para>
-       GPS Satellite data are transmitted once per second during all
-       phases of the flight.
-      </para>
-      <table frame='all'>
-       <title>GPS Satellite Data Contents</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='right' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>5</entry><entry>uint8_t</entry><entry>channels</entry>
-             <entry>Number of reported satellite information</entry>
-           </row>
-           <row>
-             <entry>6</entry><entry>sat_info_t</entry><entry>sats[12]</entry>
-             <entry>See Per-Satellite data table below</entry>
-           </row>
-           <row>
-             <entry>30</entry><entry>uint8_t</entry><entry>unused[2]</entry>
-           </row>
-           <row>
-             <entry>32</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-      <table frame='all'>
-       <title>GPS Per-Satellite data (sat_info_t)</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='right' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0</entry><entry>uint8_t</entry><entry>svid</entry>
-             <entry>Space Vehicle Identifier</entry>
-           </row>
-           <row>
-             <entry>1</entry><entry>uint8_t</entry><entry>c_n_1</entry>
-             <entry>C/N1 signal quality indicator</entry>
-           </row>
-           <row>
-             <entry>2</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-    </section>
-    <section>
-      <title>Companion Data Data</title>
-      <informaltable frame='none' label='' tocentry='0'>
-       <tgroup cols='2' align='center' colsep='1' rowsep='1'>
-         <colspec align='center' colwidth='*' colname='Offset'/>
-         <colspec align='left' colwidth='3*' colname='Description'/>
-         <thead>
-           <row>
-             <entry>Type</entry>
-             <entry>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>0x07</entry>
-             <entry>Companion Data Data</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </informaltable>
-      <para>
-       When a companion board is attached to TeleMega or TeleMetrum,
-       it can provide telemetry data to be included in the
-       downlink. The companion board can provide up to 12 16-bit data
-       values.
-      </para>
-      <para>
-       The companion board itself specifies the transmission rate. On
-       the ground and during descent, that rate is limited to one
-       packet per second. During ascent, that rate is limited to 10
-       packets per second.
-      </para>
-      <table frame='all'>
-       <title>Companion Data Contents</title>
-       <tgroup cols='4' align='center' colsep='1' rowsep='1'>
-         <colspec align='right' colwidth='*' colname='Offset'/>
-         <colspec align='center' colwidth='3*' colname='Data Type'/>
-         <colspec align='left' colwidth='3*' colname='Name'/>
-         <colspec align='left' colwidth='9*' colname='Description'/>
-         <thead>
-           <row>
-             <entry align='center'>Offset</entry>
-             <entry align='center'>Data Type</entry>
-             <entry align='center'>Name</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>5</entry><entry>uint8_t</entry><entry>board_id</entry>
-             <entry>Type of companion board attached</entry>
-           </row>
-           <row>
-             <entry>6</entry><entry>uint8_t</entry><entry>update_period</entry>
-             <entry>How often telemetry is sent, in 1/100ths of a second</entry>
-           </row>
-           <row>
-             <entry>7</entry><entry>uint8_t</entry><entry>channels</entry>
-             <entry>Number of data channels supplied</entry>
-           </row>
-           <row>
-             <entry>8</entry><entry>uint16_t[12]</entry><entry>companion_data</entry>
-             <entry>Up to 12 channels of 16-bit companion data</entry>
-           </row>
-           <row>
-             <entry>32</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-    </section>
-  </section>
-  <section>
-    <title>Data Transmission</title>
-    <para>
-      Altus Metrum devices use Texas Instruments sub-GHz digital radio
-      products. Ground stations use parts with HW FEC while some
-      flight computers perform FEC in software. TeleGPS is
-      transmit-only.
-    </para>
-    <table>
-      <title>Altus Metrum Radio Parts</title>
-      <tgroup cols='3'>
-       <colspec align="center" colwidth="*" colname="Part Number"/>
-       <colspec align="center" colwidth="*" colname="Description"/>
-       <colspec align="left" colwidth="*" colname="Used in"/>
-       <thead>
-         <row>
-           <entry align="center">Part Number</entry>
-           <entry align="center">Description</entry>
-           <entry align="center">Used in</entry>
-         </row>
-       </thead>
-       <tbody>
-         <row>
-           <entry>CC1111</entry><entry>10mW transceiver with integrated SoC</entry>
-           <entry>TeleDongle v0.2, TeleBT v1.0, TeleMetrum v1.x, TeleMini</entry>
-         </row>
-         <row>
-           <entry>CC1120</entry><entry>35mW transceiver with SW FEC</entry>
-           <entry>TeleMetrum v2, TeleMega</entry>
-         </row>
-         <row>
-           <entry>CC1200</entry><entry>35mW transceiver with HW FEC</entry>
-           <entry>TeleDongle v3.0, TeleBT v3.0</entry>
-         </row>
-         <row>
-           <entry>CC115L</entry><entry>14mW transmitter with SW FEC</entry>
-           <entry>TeleGPS</entry>
-         </row>
-       </tbody>
-      </tgroup>
-    </table>
-    <section>
-      <title>Modulation Scheme</title>
-      <para>
-       Texas Instruments provides a tool for computing modulation
-       parameters given a desired modulation format and basic bit
-       rate.
-
-       While we might like to use something with better low-signal
-       performance like BPSK, the radios we use don't support that,
-       but do support Gaussian frequency shift keying (GFSK). Regular
-       frequency shift keying (FSK) encodes the signal by switching
-       the carrier between two frequencies. The Gaussian version is
-       essentially the same, but the shift between frequencies gently
-       follows a gaussian curve, rather than switching
-       immediately. This tames the bandwidth of the signal without
-       affecting the ability to transmit data.
-
-       For AltOS, there are three available bit rates, 38.4kBaud,
-       9.6kBaud and 2.4kBaud resulting in the following signal
-       parmeters:
-
-      </para>
-      <table>
-       <title>Modulation Scheme</title>
-       <tgroup cols='3'>
-         <colspec align="center" colwidth="*" colname="rate"/>
-         <colspec align="center" colwidth="*" colname="deviation"/>
-         <colspec align="center" colwidth="*" colname="bandwidth"/>
-         <thead>
-           <row>
-             <entry align='center'>Rate</entry>
-             <entry align='center'>Deviation</entry>
-             <entry align='center'>Receiver Bandwidth</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>38.4kBaud</entry>
-             <entry>20.5kHz</entry>
-             <entry>100kHz</entry>
-           </row>
-           <row>
-             <entry>9.6kBaud</entry>
-             <entry>5.125kHz</entry>
-             <entry>25kHz</entry>
-           </row>
-           <row>
-             <entry>2.4kBaud</entry>
-             <entry>1.5kHz</entry>
-             <entry>5kHz</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-    </section>
-    <section>
-      <title>Error Correction</title>
-      <para>
-       The cc1111 and cc1200 provide forward error correction in
-       hardware; on the cc1120 and cc115l that's done in
-       software. AltOS uses this to improve reception of weak
-       signals. As it's a rate 1/2 encoding, each bit of data takes
-       two bits when transmitted, so the effective data rate is half
-       of the raw transmitted bit rate.
-      </para>
-      <table>
-       <title>Error Correction</title>
-       <tgroup cols='3'>
-         <colspec align="center" colwidth="*" colname="parameter"/>
-         <colspec align="center" colwidth="*" colname="value"/>
-         <colspec align="center" colwidth="*" colname="description"/>
-         <thead>
-           <row>
-             <entry align='center'>Parameter</entry>
-             <entry align='center'>Value</entry>
-             <entry align='center'>Description</entry>
-           </row>
-         </thead>
-         <tbody>
-           <row>
-             <entry>Error Correction</entry>
-             <entry>Convolutional coding</entry>
-             <entry>1/2 rate, constraint length m=4</entry>
-           </row>
-           <row>
-             <entry>Interleaving</entry>
-             <entry>4 x 4</entry>
-             <entry>Reduce effect of noise burst</entry>
-           </row>
-           <row>
-             <entry>Data Whitening</entry>
-             <entry>XOR with 9-bit PNR</entry>
-             <entry>Rotate right with bit 8 = bit 0 xor bit 5, initial
-             value 111111111</entry>
-           </row>
-         </tbody>
-       </tgroup>
-      </table>
-    </section>
-  </section>
-  <section>
-    <title>TeleDongle packet format</title>
-    <para>
-      TeleDongle does not do any interpretation of the packet data,
-      instead it is configured to receive packets of a specified
-      length (32 bytes in this case). For each received packet,
-      TeleDongle produces a single line of text. This line starts with
-      the string "TELEM " and is followed by a list of hexadecimal
-      encoded bytes.
-    </para>
-    <programlisting>TELEM 224f01080b05765e00701f1a1bbeb8d7b60b070605140c000600000000000000003fa988</programlisting>
-    <para>
-      The hexadecimal encoded string of bytes contains a length byte,
-      the packet data, two bytes added by the cc1111 radio receiver
-      hardware and finally a checksum so that the host software can
-      validate that the line was transmitted without any errors.
-    </para>
-    <table>
-      <title>Packet Format</title>
-      <tgroup cols='4'>
-       <colspec align="center" colwidth="2*" colname="offset"/>
-       <colspec align="center" colwidth="*" colname="name"/>
-       <colspec align="center" colwidth="*" colname="value"/>
-       <colspec align="center" colwidth="5*" colname="description"/>
-       <thead>
-         <row>
-           <entry align='center'>Offset</entry>
-           <entry align='center'>Name</entry>
-           <entry align='center'>Example</entry>
-           <entry align='center'>Description</entry>
-         </row>
-       </thead>
-       <tbody>
-         <row>
-           <entry>0</entry>
-           <entry>length</entry>
-           <entry>22</entry>
-           <entry>Total length of data bytes in the line. Note that
-           this includes the added RSSI and status bytes</entry>
-         </row>
-         <row>
-           <entry>1 ·· length-3</entry>
-           <entry>packet</entry>
-           <entry>4f ·· 00</entry>
-           <entry>Bytes of actual packet data</entry>
-         </row>
-         <row>
-           <entry>length-2</entry>
-           <entry>rssi</entry>
-           <entry>3f</entry>
-           <entry>Received signal strength. dBm = rssi / 2 - 74</entry>
-         </row>
-         <row>
-           <entry>length-1</entry>
-           <entry>lqi</entry>
-           <entry>a9</entry>
-           <entry>Link Quality Indicator and CRC status. Bit 7
-           is set when the CRC is correct</entry>
-         </row>
-         <row>
-           <entry>length</entry>
-           <entry>checksum</entry>
-           <entry>88</entry>
-           <entry>(0x5a + sum(bytes 1 ·· length-1)) % 256</entry>
-         </row>
-       </tbody>
-      </tgroup>
-    </table>
-  </section>
-  <section>
-    <title>History and Motivation</title>
-    <para>
-      The original AltoOS telemetry mechanism encoded everything
-      available piece of information on the TeleMetrum hardware into a
-      single unified packet. Initially, the packets contained very
-      little data—some raw sensor readings along with the current GPS
-      coordinates when a GPS receiver was connected. Over time, the
-      amount of data grew to include sensor calibration data, GPS
-      satellite information and a host of internal state information
-      designed to help diagnose flight failures in case of a loss of
-      the on-board flight data.
-    </para>
-    <para>
-      Because every packet contained all of the data, packets were
-      huge—95 bytes long. Much of the information was also specific to
-      the TeleMetrum hardware. With the introduction of the TeleMini
-      flight computer, most of the data contained in the telemetry
-      packets was unavailable. Initially, a shorter, but still
-      comprehensive packet was implemented. This required that the
-      ground station be pre-configured as to which kind of packet to
-      expect.
-    </para>
-    <para>
-      The development of several companion boards also made the
-      shortcomings evident—each companion board would want to include
-      telemetry data in the radio link; with the original design, the
-      packet would have to hold the new data as well, requiring
-      additional TeleMetrum and ground station changes.
-    </para>
-  </section>
-</article>