Merge branch 'aprs' into 'master'
authorKeith Packard <keithp@keithp.com>
Mon, 17 Dec 2012 00:06:41 +0000 (16:06 -0800)
committerKeith Packard <keithp@keithp.com>
Mon, 17 Dec 2012 00:07:14 +0000 (16:07 -0800)
altoslib/AltosConfigData.java
altoslib/AltosLink.java
altoslib/AltosState.java
doc/altusmetrum.xsl
doc/micropeak.xsl
src/core/ao_convert_pa.c
src/micropeak/Makefile
src/micropeak/ao_micropeak.c
src/micropeak/ao_pins.h
src/micropeak/ao_report_tiny.c

index f940b150710a8743d6e64bd9f44ab417bdb66462..99b8e39d2042e4279605294acafb6c223d72de5d 100644 (file)
@@ -485,13 +485,15 @@ public class AltosConfigData implements Iterable<String> {
                reset();
                link.printf("c s\nf\nv\n");
                read_link(link, "software-version");
+               System.out.printf("Log format %d\n", log_format);
                switch (log_format) {
-               case AltosLib.AO_LOG_FORMAT_TELEMETRY:
-               case AltosLib.AO_LOG_FORMAT_TELESCIENCE:
-                       break;
-               default:
+               case AltosLib.AO_LOG_FORMAT_FULL:
+               case AltosLib.AO_LOG_FORMAT_TINY:
+               case AltosLib.AO_LOG_FORMAT_MEGAMETRUM:
                        link.printf("l\n");
                        read_link(link, "done");
+               default:
+                       break;
                }
        }
 
index 6d510563c5d32622bfbc3cfb854da885c21b4f27..1b722026067b5bccfea4521bfdfb317cd3a5755a 100644 (file)
@@ -284,8 +284,8 @@ public abstract class AltosLink implements Runnable {
                frequency = in_frequency;
                config_data();
                set_radio_frequency(frequency,
-                                   config_data.radio_frequency != 0,
-                                   config_data.radio_setting != 0,
+                                   config_data.radio_frequency > 0,
+                                   config_data.radio_setting > 0,
                                    config_data.radio_calibration);
        }
 
@@ -339,10 +339,10 @@ public abstract class AltosLink implements Runnable {
        public String name;
 
        public void start_remote() throws TimeoutException, InterruptedException {
-               if (debug)
-                       System.out.printf("start remote %7.3f\n", frequency);
                if (frequency == 0.0)
                        frequency = AltosPreferences.frequency(serial);
+               if (debug)
+                       System.out.printf("start remote %7.3f\n", frequency);
                set_radio_frequency(frequency);
                set_callsign(AltosPreferences.callsign());
                printf("p\nE 0\n");
index f28dd1c6609f24070b7ba0fa4ce4e5f8f60205ed..218c598ab5d80d6a4e264b86a1a9d25209b5f933 100644 (file)
@@ -92,6 +92,9 @@ public class AltosState {
        public void init (AltosRecord cur, AltosState prev_state) {
                data = cur;
 
+               /* Discard previous state if it was for a different board */
+               if (prev_state != null && prev_state.data.serial != data.serial)
+                       prev_state = null;
                ground_altitude = data.ground_altitude();
 
                altitude = data.altitude();
index b2677a029ed9c66f3c33b3861fddb0382ece3ee0..e7ab353bbd2ef171107f6f937048cc476845a657 100644 (file)
@@ -277,6 +277,19 @@ NAR #88757, TRA #12200
       apogee and main ejection charges.  All Altus Metrum products are 
       designed for use with single-cell batteries with 3.7 volts nominal.
     </para>
+    <para>
+      The battery connectors are a standard 2-pin JST connector and
+      match batteries sold by Spark Fun. These batteries are
+      single-cell Lithium Polymer batteries that nominally provide 3.7
+      volts.  Other vendors sell similar batteries for RC aircraft
+      using mating connectors, however the polarity for those is
+      generally reversed from the batteries used by Altus Metrum
+      products. In particular, the Tenergy batteries supplied for use
+      in Featherweight flight computers are not compatible with Altus
+      Metrum flight computers or battery chargers. <emphasis>Check
+      polarity and voltage before connecting any battery not purchased
+      from Altus Metrum or Spark Fun.</emphasis>
+    </para>
     <para>
       By default, we use the unregulated output of the Li-Po battery directly
       to fire ejection charges.  This works marvelously with standard
@@ -481,7 +494,7 @@ NAR #88757, TRA #12200
       <para>
         You can monitor the operation of the radio link by watching the 
         lights on the devices. The red LED will flash each time a packet
-        is tramsitted, while the green LED will light up on TeleDongle when 
+        is transmitted, while the green LED will light up on TeleDongle when 
         it is waiting to receive a packet from the altimeter.
       </para>
     </section>
@@ -2199,7 +2212,7 @@ NAR #88757, TRA #12200
        </listitem>
        <listitem>
          <para>
-           RF interface for battery charging, configuration, and data recovery.
+           RF interface for configuration, and data recovery.
          </para>
        </listitem>
        <listitem>
index 284d0fb04a359ff11e7b3f865d9dee5b7f841f78..aa1adaef9f57a2bc64d34033c301abe3662dd3a5 100644 (file)
          Updates for version 1.0 release.
        </revremark>
       </revision>
+      <revision>
+       <revnumber>1.1</revnumber>
+       <date>12 December 2012</date>
+       <revremark>
+         Add comments about EEPROM storage format and programming jig.
+       </revremark>
+      </revision>
     </revhistory>
   </bookinfo>
   <acknowledgements>
@@ -223,10 +230,10 @@ NAR #88757, TRA #12200
        with the negative battery terminal.
       </para>
       <para>
-       Shipping restrictions prevent us from including a CR1025
-       battery with MicroPeak. Many stores carry CR1025 batteries as
-       they are commonly used in small electronic devices such as
-       flash lights.
+       Shipping restrictions may prevent us from including a CR1025
+       battery with MicroPeak. If so, many stores carry CR1025
+       batteries as they are commonly used in small electronic
+       devices such as flash lights.
       </para>
     </section>
     <section>
@@ -272,6 +279,118 @@ NAR #88757, TRA #12200
        serve to further protect the switch from launch forces.
       </para>
     </section>
+    <section>
+      <title>On-board data storage</title>
+      <para>
+       The ATtiny85 has 512 bytes of non-volatile storage, separate
+       from the code storage memory. The MicroPeak firmware uses this
+       to store information about the last completed
+       flight. Barometric measurements from the ground before launch
+       and at apogee are stored, and used at power-on to compute the
+       height of the last flight.
+      </para>
+      <para>
+       In addition to the data used to present the height of the last
+       flight, MicroPeak also stores barometric information sampled
+       at regular intervals during the flight. This information can
+       be extracted from MicroPeak through any AVR programming
+       tool.
+      </para>
+      <table frame='all'>
+       <title>MicroPeak EEPROM Data Storage</title>
+       <tgroup cols='3' align='center' colsep='1' rowsep='1'>
+         <colspec align='center' colwidth='2*' colname='Address'/>
+         <colspec align='center' colwidth='*' colname='Size (bytes)'/>
+         <colspec align='left' colwidth='7*' colname='Description'/>
+         <thead>
+           <row>
+             <entry align='center'>Address</entry>
+             <entry align='center'>Size (bytes)</entry>
+             <entry align='center'>Description</entry>
+           </row>
+         </thead>
+         <tbody>
+           <row>
+             <entry>0x000</entry>
+             <entry>4</entry>
+             <entry>Average ground pressure (Pa)</entry>
+           </row>
+           <row>
+             <entry>0x004</entry>
+             <entry>4</entry>
+             <entry>Minimum flight pressure (Pa)</entry>
+           </row>
+           <row>
+             <entry>0x008</entry>
+             <entry>2</entry>
+             <entry>Number of in-flight samples</entry>
+           </row>
+           <row>
+             <entry>0x00a … 0x1fe</entry>
+             <entry>2</entry>
+             <entry>Instantaneous flight pressure (Pa) low 16 bits</entry>
+           </row>
+         </tbody>
+       </tgroup>
+      </table>
+      <para>
+       All EEPROM data are stored least-significant byte first. The
+       instantaneous flight pressure data are stored without the
+       upper 16 bits of data. The upper bits can be reconstructed
+       from the previous sample, assuming that pressure doesn't
+       change by more more than 32kPa in a single sample
+       interval. Note that this pressure data is <emphasis>not</emphasis>
+       filtered in any way, while both the recorded ground and apogee
+       pressure values are, so you shouldn't expect the minimum
+       instantaneous pressure value to match the recorded minimum
+       pressure value exactly.
+      </para>
+      <para>
+       MicroPeak samples pressure every 96ms, but stores only every
+       other sample in the EEPROM. This provides for 251 pressure
+       samples at 192ms intervals, or 48.192s of storage. The clock
+       used for these samples is a factory calibrated RC circuit
+       built into the ATtiny85 and is accurate only to within ±10% at
+       25°C. So, you can count on the pressure data being accurate,
+       but speed or acceleration data computed from this will be
+       limited by the accuracy of this clock.
+      </para>
+    </section>
+    <section>
+      <title>MicroPeak Programming Interface</title>
+      <para>
+       MicroPeak exposes a standard 6-pin AVR programming interface,
+       but not using the usual 2x3 array of pins on 0.1"
+       centers. Instead, there is a single row of tiny 0.60mm ×
+       0.85mm pads on 1.20mm centers exposed near the edge of the
+       circuit board. We couldn't find any connector that was
+       small enough to include on the circuit board.
+      </para>
+      <para>
+       In lieu of an actual connector, the easiest way to connect to
+       the bare pads is through a set of Pogo pins. These
+       spring-loaded contacts are designed to connect in precisely
+       this way. We've designed a programming jig, the MicroPeak
+       Pogo Pin board which provides a standard AVR interface on one
+       end and a recessed slot for MicroPeak to align the board with
+       the Pogo Pins.
+      </para>
+      <para>
+       The MicroPeak Pogo Pin board is not a complete AVR programmer,
+       it is an interface board that provides a 3.3V regulated power
+       supply to run the MicroPeak via USB and a standard 6-pin AVR
+       programming interface with the usual 2x3 grid of pins on 0.1"
+       centers. This can be connected to any AVR programming
+       dongle.
+      </para>
+      <para>
+       The AVR programming interface cannot run faster than ¼ of the
+       AVR CPU clock frequency. Because MicroPeak runs at 250kHz to
+       save power, you must configure your AVR programming system to
+       clock the AVR programming interface at no faster than
+       62.5kHz, or a clock period of 32µS.
+      </para>
+    </section>
   </chapter>
 </book>
 <!--  LocalWords:  Altusmetrum MicroPeak
index 55fe6e7da0e3a0ad5c4110b41f2722fc756bbc87..fe6e0ef699b803de2b6109e088ee638ac1be0431 100644 (file)
@@ -43,13 +43,13 @@ ao_pa_to_altitude(int32_t pa)
 
        if (pa < 0)
                pa = 0;
-       if (pa > 120000)
-               pa = 120000;
+       if (pa > 120000L)
+               pa = 120000L;
        o = pa >> ALT_SHIFT;
        part = pa & ALT_MASK;
 
-       low = (alt_t) FETCH_ALT(o) * (ALT_SCALE - part);
-       high = (alt_t) FETCH_ALT(o+1) * part + (ALT_SCALE >> 1);
+       low = (int32_t) FETCH_ALT(o) * (ALT_SCALE - part);
+       high = (int32_t) FETCH_ALT(o+1) * part + (ALT_SCALE >> 1);
        return (low + high) >> ALT_SHIFT;
 }
 
index 8cf608bbdd2567eadd89e0f672fa02ed4da25e45..0c48ed66477a3db5b652c05d5da1ceaa8060dcfb 100644 (file)
@@ -11,6 +11,7 @@ DUDECPUTYPE=t85
 #PROGRAMMER=stk500v2 -P usb
 PROGRAMMER=usbtiny
 LOADCMD=avrdude
+LOADSLOW=-i 32 -B 32
 LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w:
 CC=avr-gcc
 OBJCOPY=avr-objcopy
@@ -86,6 +87,9 @@ $(PROG).hex: $(PROG)
 load: $(PROG).hex
        $(LOADCMD) $(LOADARG)$(PROG).hex
 
+load-slow: $(PROG).hex
+       $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PROG).hex
+
 ao_product.h: ao-make-product.5c ../Version
        $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
 
index 10e1d0f9f3246d7a5e8aba35a60605d44a8b8ef3..525cfa42bfe529f14fd7c49647048ca65ba2d58b 100644 (file)
@@ -65,18 +65,40 @@ ao_compute_height(void)
 }
 
 #if !HAS_EEPROM
+
+#define PA_GROUND_OFFSET       0
+#define PA_MIN_OFFSET          4
+#define N_SAMPLES_OFFSET       8
+#define STARTING_LOG_OFFSET    10
+#define MAX_LOG_OFFSET         512
+
+static uint16_t ao_log_offset = STARTING_LOG_OFFSET;
+
 void
 ao_save_flight(void)
 {
-       ao_eeprom_write(0, &pa_ground, sizeof (pa_ground));
-       ao_eeprom_write(sizeof (pa_ground), &pa_min, sizeof (pa_min));
+       uint16_t        n_samples = (ao_log_offset - STARTING_LOG_OFFSET) / sizeof (uint16_t);
+       ao_eeprom_write(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground));
+       ao_eeprom_write(PA_MIN_OFFSET, &pa_min, sizeof (pa_min));
+       ao_eeprom_write(N_SAMPLES_OFFSET, &n_samples, sizeof (n_samples));
 }
 
 void
 ao_restore_flight(void)
 {
-       ao_eeprom_read(0, &pa_ground, sizeof (pa_ground));
-       ao_eeprom_read(sizeof (pa_ground), &pa_min, sizeof (pa_min));
+       ao_eeprom_read(PA_GROUND_OFFSET, &pa_ground, sizeof (pa_ground));
+       ao_eeprom_read(PA_MIN_OFFSET, &pa_min, sizeof (pa_min));
+}
+
+void
+ao_log_micro(void)
+{
+       uint16_t        low_bits = pa;
+
+       if (ao_log_offset < MAX_LOG_OFFSET) {
+               ao_eeprom_write(ao_log_offset, &low_bits, sizeof (low_bits));
+               ao_log_offset += sizeof (low_bits);
+       }
 }
 #endif
 
@@ -110,6 +132,8 @@ main(void)
 #endif
        ao_restore_flight();
        ao_compute_height();
+       /* Give the person a second to get their finger out of the way */
+       ao_delay(AO_MS_TO_TICKS(1000));
        ao_report_altitude();
        
        ao_spi_init();
@@ -178,6 +202,9 @@ main(void)
                        ao_led_off(AO_LED_REPORT);
 #if HAS_EEPROM
                ao_log_micro_data(AO_LOG_MICRO_DATA | pa);
+#else
+               if (sample_count & 1)
+                       ao_log_micro();
 #endif
                pa_avg = pa_avg - (pa_avg >> FILTER_SHIFT) + pa;
                if (pa_avg < pa_min)
index 257b8694bc3c6301ecea048660dd3c1602e90df0..63e9cb1b26663ce0259d2134003d8fa334b54ae0 100644 (file)
@@ -57,8 +57,9 @@
 #define I2C_PIN_SDA            PINB0
 
 #define AO_CONST_ATTRIB                PROGMEM
+typedef int32_t alt_t;
 #define FETCH_ALT(o)           ((alt_t) pgm_read_dword(&altitude_table[o]))
 
-#define AO_ALT_VALUE(x)                ((x) * 10)
+#define AO_ALT_VALUE(x)                ((x) * (alt_t) 10)
 
 #endif /* _AO_PINS_H_ */
index 109af1ed05050f31f2af72bdc3d590587c1f7a1b..0e8e287f63eae1c123988dd26ee12df95c3868ec 100644 (file)
@@ -24,7 +24,7 @@ static void
 ao_report_digit(uint8_t digit) __reentrant
 {
        if (!digit) {
-               mid(AO_MS_TO_TICKS(600));
+               mid(AO_MS_TO_TICKS(1000));
                pause(AO_MS_TO_TICKS(300));
        } else {
                while (digit--) {
@@ -32,14 +32,14 @@ ao_report_digit(uint8_t digit) __reentrant
                        pause(AO_MS_TO_TICKS(300));
                }
        }
-       pause(AO_MS_TO_TICKS(600));
+       pause(AO_MS_TO_TICKS(1000));
 }
 
 void
 ao_report_altitude(void)
 {
-       __pdata int16_t agl = ao_max_height;
-       __xdata uint8_t digits[10];
+       __pdata alt_t   agl = ao_max_height;
+       static __xdata uint8_t  digits[11];
        __pdata uint8_t ndigits, i;
 
        if (agl < 0)