Merge branch 'master' of ssh://git.gag.com/scm/git/fw/altos
authorBdale Garbee <bdale@gag.com>
Thu, 19 Dec 2013 04:53:52 +0000 (21:53 -0700)
committerBdale Garbee <bdale@gag.com>
Thu, 19 Dec 2013 04:53:52 +0000 (21:53 -0700)
doc/altusmetrum.xsl
src/core/ao_flight.c
src/core/ao_flight.h
src/drivers/ao_mpu6000.c
src/stm/ao_usb_stm.c
src/telemega-v0.1/ao_pins.h
src/telemega-v1.0/ao_pins.h

index dfe89438f99398eebbcaf35b3c0a18e7f9641e8b..c71e08a7dc2ddec4530fd9dc7909019675bda403 100644 (file)
@@ -835,17 +835,144 @@ NAR #88757, TRA #12200
         the altimeter completes initialization and self test, and decides 
        which mode to enter next.
       </para>
+      <para>
+       Here's a short summary of all of the modes and the beeping (or
+       flashing, in the case of TeleMini v1) that accompanies each
+       mode. In the description of the beeping pattern, “dit” means a
+       short beep while "dah" means a long beep (three times as
+       long). “Brap” means a long dissonant tone.
+       <table frame='all'>
+         <title>AltOS Modes</title>
+         <?dbfo keep-together="always"?>
+         <tgroup cols='4' align='center' colsep='1' rowsep='1'>
+           <colspec align='center' colwidth='*' colname='Mode Name'/>
+           <colspec align='center' colwidth='*' colname='Letter'/>
+           <colspec align='center' colwidth='*' colname='Beeps'/>
+           <colspec align='center' colwidth='*' colname='Description'/>
+           <thead>
+             <row>
+               <entry>Mode Name</entry>
+               <entry>Abbreviation</entry>
+               <entry>Beeps</entry>
+               <entry>Description</entry>
+             </row>
+           </thead>
+           <tbody>
+             <row>
+               <entry>Startup</entry>
+               <entry>S</entry>
+               <entry>dit dit dit</entry>
+               <entry>
+                 <para>
+                   Calibrating sensors, detecting orientation.
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Idle</entry>
+               <entry>I</entry>
+               <entry>dit dit</entry>
+               <entry>
+                 <para>
+                   Ready to accept commands over USB or radio link.
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Pad</entry>
+               <entry>P</entry>
+               <entry>dit dah dah dit</entry>
+               <entry>
+                 <para>
+                   Waiting for launch. Not listening for commands.
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Boost</entry>
+               <entry>B</entry>
+               <entry>dah dit dit dit</entry>
+               <entry>
+                 <para>
+                   Accelerating upwards.
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Fast</entry>
+               <entry>F</entry>
+               <entry>dit dit dah dit</entry>
+               <entry>
+                 <para>
+                   Decellerating, but moving faster than 200m/s.
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Coast</entry>
+               <entry>C</entry>
+               <entry>dah dit dah dit</entry>
+               <entry>
+                 <para>
+                   Decellerating, moving slower than 200m/s
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Drogue</entry>
+               <entry>D</entry>
+               <entry>dah dit dit</entry>
+               <entry>
+                 <para>
+                   Descending after apogee. Above main height.
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Main</entry>
+               <entry>M</entry>
+               <entry>dah dah</entry>
+               <entry>
+                 <para>
+                   Descending. Below main height.
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Landed</entry>
+               <entry>L</entry>
+               <entry>dit dah dit dit</entry>
+               <entry>
+                 <para>
+                   Stable altitude for at least ten seconds.
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Sensor error</entry>
+               <entry>X</entry>
+               <entry>dah dit dit dah</entry>
+               <entry>
+                 <para>
+                   Error detected during sensor calibration.
+                 </para>
+               </entry>
+             </row>
+           </tbody>
+         </tgroup>
+       </table>
+      </para>
       <para>
         In flight or “pad” mode, the altimeter engages the flight
-        state machine, goes into transmit-only mode to
-        send telemetry, and waits for launch to be detected.
-        Flight mode is indicated by an “di-dah-dah-dit” (“P” for pad)
-        on the beeper or lights, followed by beeps or flashes
-        indicating the state of the pyrotechnic igniter continuity.
-        One beep/flash indicates apogee continuity, two beeps/flashes
-        indicate main continuity, three beeps/flashes indicate both
-        apogee and main continuity, and one longer “brap” sound or
-        rapidly alternating lights indicates no continuity.  For a
+        state machine, goes into transmit-only mode to send telemetry,
+        and waits for launch to be detected.  Flight mode is indicated
+        by an “di-dah-dah-dit” (“P” for pad) on the beeper or lights,
+        followed by beeps or flashes indicating the state of the
+        pyrotechnic igniter continuity.  One beep/flash indicates
+        apogee continuity, two beeps/flashes indicate main continuity,
+        three beeps/flashes indicate both apogee and main continuity,
+        and one longer “brap” sound which is made by rapidly
+        alternating between two tones indicates no continuity.  For a
         dual deploy flight, make sure you're getting three beeps or
         flashes before launching!  For apogee-only or motor eject
         flights, do what makes sense.
@@ -862,6 +989,93 @@ NAR #88757, TRA #12200
         data from the on-board storage chip after flight, and for
         ground testing pyro charges.
       </para>
+      <para>
+       In “Idle” and “Pad” modes, once the mode indication
+       beeps/flashes and continuity indication has been sent, if
+       there is no space available to log the flight in on-board
+       memory, the flight computer will emit a warbling tone (much
+       slower than the “no continuity tone”)
+      </para>
+      <para>
+       Here's a summary of all of the “pad” and “idle” mode indications.
+       <table frame='all'>
+         <title>Pad/Idle Indications</title>
+         <?dbfo keep-together="always"?>
+         <tgroup cols='3' align='center' colsep='1' rowsep='1'>
+           <colspec align='center' colwidth='*' colname='Name'/>
+           <colspec align='center' colwidth='*' colname='Beeps'/>
+           <colspec align='center' colwidth='*' colname='Description'/>
+           <thead>
+             <row>
+               <entry>Name</entry>
+               <entry>Beeps</entry>
+               <entry>Description</entry>
+             </row>
+           </thead>
+           <tbody>
+             <row>
+               <entry>Neither</entry>
+               <entry>brap</entry>
+               <entry>
+                 <para>
+                   No continuity detected on either apogee or main
+                   igniters.
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Apogee</entry>
+               <entry>dit</entry>
+               <entry>
+                 <para>
+                   Continuity detected only on apogee igniter.
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Main</entry>
+               <entry>dit dit</entry>
+               <entry>
+                 <para>
+                   Continuity detected only on main igniter.
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Both</entry>
+               <entry>dit dit dit</entry>
+               <entry>
+                 <para>
+                   Continuity detected on both igniters.
+                 </para>
+               </entry>
+             </row>
+             <row>
+               <entry>Storage Full</entry>
+               <entry>warble</entry>
+               <entry>
+                 <para>
+                   On-board data logging storage is full. This will
+                   not prevent the flight computer from safely
+                   controlling the flight or transmitting telemetry
+                   signals, but no record of the flight will be
+                   stored in on-board flash.
+                 </para>
+               </entry>
+             </row>
+           </tbody>
+         </tgroup>
+       </table>
+      </para>
+      <para>
+       Once landed, the flight computer will signal that by emitting
+       the “Landed” sound described above, after which it will beep
+       out the apogee height (in meters). Each digit is represented
+       by a sequence of short “dit” beeps, with a pause between
+       digits. A zero digit is represented with one long “dah”
+       beep. The flight computer will continue to report landed mode
+       and beep out the maximum height until turned off.
+      </para>
       <para>
         One “neat trick” of particular value when TeleMetrum or TeleMega are used with 
         very large air-frames, is that you can power the board up while the 
index 4a53bdc672f7af22deb6c94a0fcfb2b2581e14d5..463ff4a2974b38e045fb2214ca9bc163cd490d28 100644 (file)
@@ -46,6 +46,11 @@ __pdata enum ao_flight_state ao_flight_state;        /* current flight state */
 __pdata uint16_t               ao_boost_tick;          /* time of launch detect */
 __pdata uint16_t               ao_motor_number;        /* number of motors burned so far */
 
+#if HAS_IMU
+/* Any sensor can set this to mark the flight computer as 'broken' */
+__xdata uint8_t                        ao_sensor_errors;
+#endif
+
 /*
  * track min/max data over a long interval to detect
  * resting
@@ -99,6 +104,9 @@ ao_flight(void)
                            ao_config.accel_minus_g == 0 ||
                            ao_ground_accel < ao_config.accel_plus_g - ACCEL_NOSE_UP ||
                            ao_ground_accel > ao_config.accel_minus_g + ACCEL_NOSE_UP ||
+#if HAS_IMU
+                           ao_sensor_errors ||
+#endif
                            ao_ground_height < -1000 ||
                            ao_ground_height > 7000)
                        {
index ac3e9cfb56ab40a4b14fa076f92097a57f12f895..c7c02ccf69cc4166e0549513d5d1b02971a4c078 100644 (file)
@@ -41,6 +41,10 @@ extern __pdata enum ao_flight_state  ao_flight_state;
 extern __pdata uint16_t                        ao_boost_tick;
 extern __pdata uint16_t                        ao_motor_number;
 
+#if HAS_IMU
+extern __xdata uint8_t                 ao_sensor_errors;
+#endif
+
 extern __pdata uint16_t                        ao_launch_time;
 extern __pdata uint8_t                 ao_flight_force_idle;
 
index 5e75b78a13787e8546235bcaeeb44de4c45e0a41..f8ce7346c7149d690228c57445607382ce35c05b 100644 (file)
@@ -137,10 +137,10 @@ ao_mpu6000_accel_check(int16_t normal, int16_t test, char *which)
 {
        int16_t diff = test - normal;
 
-       if (diff < MPU6000_ST_ACCEL(16) / 2) {
+       if (diff < MPU6000_ST_ACCEL(16) / 4) {
                return 1;
        }
-       if (diff > MPU6000_ST_ACCEL(16) * 2) {
+       if (diff > MPU6000_ST_ACCEL(16) * 4) {
                return 1;
        }
        return 0;
@@ -153,10 +153,10 @@ ao_mpu6000_gyro_check(int16_t normal, int16_t test, char *which)
 
        if (diff < 0)
                diff = -diff;
-       if (diff < MPU6000_ST_GYRO(2000) / 2) {
+       if (diff < MPU6000_ST_GYRO(2000) / 4) {
                return 1;
        }
-       if (diff > MPU6000_ST_GYRO(2000) * 2) {
+       if (diff > MPU6000_ST_GYRO(2000) * 4) {
                return 1;
        }
        return 0;
@@ -177,11 +177,14 @@ _ao_mpu6000_wait_alive(void)
                ao_panic(AO_PANIC_SELF_TEST_MPU6000);
 }
 
+#define ST_TRIES       10
+
 static void
 _ao_mpu6000_setup(void)
 {
        struct ao_mpu6000_sample        normal_mode, test_mode;
-       int                             errors =0;
+       int                             errors;
+       int                             st_tries;
 
        if (ao_mpu6000_configured)
                return;
@@ -236,23 +239,6 @@ _ao_mpu6000_setup(void)
                              (MPU6000_CONFIG_EXT_SYNC_SET_DISABLED << MPU6000_CONFIG_EXT_SYNC_SET) |
                              (MPU6000_CONFIG_DLPF_CFG_260_256 << MPU6000_CONFIG_DLPF_CFG));
 
-       /* Configure accelerometer to +/-16G in self-test mode */
-       _ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG,
-                             (1 << MPU600_ACCEL_CONFIG_XA_ST) |
-                             (1 << MPU600_ACCEL_CONFIG_YA_ST) |
-                             (1 << MPU600_ACCEL_CONFIG_ZA_ST) |
-                             (MPU600_ACCEL_CONFIG_AFS_SEL_16G << MPU600_ACCEL_CONFIG_AFS_SEL));
-
-       /* Configure gyro to +/- 2000°/s in self-test mode */
-       _ao_mpu6000_reg_write(MPU6000_GYRO_CONFIG,
-                             (1 << MPU600_GYRO_CONFIG_XG_ST) |
-                             (1 << MPU600_GYRO_CONFIG_YG_ST) |
-                             (1 << MPU600_GYRO_CONFIG_ZG_ST) |
-                             (MPU600_GYRO_CONFIG_FS_SEL_2000 << MPU600_GYRO_CONFIG_FS_SEL));
-
-       ao_delay(AO_MS_TO_TICKS(200));
-       _ao_mpu6000_sample(&test_mode);
-
 #if TRIDGE
        // read the product ID rev c has 1/2 the sensitivity of rev d
        _mpu6000_product_id = _register_read(MPUREG_PRODUCT_ID);
@@ -268,36 +254,58 @@ _ao_mpu6000_setup(void)
                register_write(MPUREG_ACCEL_CONFIG,2<<3);
        }
        hal.scheduler->delay(1);
-
 #endif
 
-       /* Configure accelerometer to +/-16G */
-       _ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG,
-                             (0 << MPU600_ACCEL_CONFIG_XA_ST) |
-                             (0 << MPU600_ACCEL_CONFIG_YA_ST) |
-                             (0 << MPU600_ACCEL_CONFIG_ZA_ST) |
-                             (MPU600_ACCEL_CONFIG_AFS_SEL_16G << MPU600_ACCEL_CONFIG_AFS_SEL));
-
-       /* Configure gyro to +/- 2000°/s */
-       _ao_mpu6000_reg_write(MPU6000_GYRO_CONFIG,
-                             (0 << MPU600_GYRO_CONFIG_XG_ST) |
-                             (0 << MPU600_GYRO_CONFIG_YG_ST) |
-                             (0 << MPU600_GYRO_CONFIG_ZG_ST) |
-                             (MPU600_GYRO_CONFIG_FS_SEL_2000 << MPU600_GYRO_CONFIG_FS_SEL));
-
-       ao_delay(AO_MS_TO_TICKS(10));
-       _ao_mpu6000_sample(&normal_mode);
+       for (st_tries = 0; st_tries < ST_TRIES; st_tries++) {
+               errors = 0;
+
+               /* Configure accelerometer to +/-16G in self-test mode */
+               _ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG,
+                                     (1 << MPU600_ACCEL_CONFIG_XA_ST) |
+                                     (1 << MPU600_ACCEL_CONFIG_YA_ST) |
+                                     (1 << MPU600_ACCEL_CONFIG_ZA_ST) |
+                                     (MPU600_ACCEL_CONFIG_AFS_SEL_16G << MPU600_ACCEL_CONFIG_AFS_SEL));
+
+               /* Configure gyro to +/- 2000°/s in self-test mode */
+               _ao_mpu6000_reg_write(MPU6000_GYRO_CONFIG,
+                                     (1 << MPU600_GYRO_CONFIG_XG_ST) |
+                                     (1 << MPU600_GYRO_CONFIG_YG_ST) |
+                                     (1 << MPU600_GYRO_CONFIG_ZG_ST) |
+                                     (MPU600_GYRO_CONFIG_FS_SEL_2000 << MPU600_GYRO_CONFIG_FS_SEL));
+
+               ao_delay(AO_MS_TO_TICKS(200));
+               _ao_mpu6000_sample(&test_mode);
+
+               /* Configure accelerometer to +/-16G */
+               _ao_mpu6000_reg_write(MPU6000_ACCEL_CONFIG,
+                                     (0 << MPU600_ACCEL_CONFIG_XA_ST) |
+                                     (0 << MPU600_ACCEL_CONFIG_YA_ST) |
+                                     (0 << MPU600_ACCEL_CONFIG_ZA_ST) |
+                                     (MPU600_ACCEL_CONFIG_AFS_SEL_16G << MPU600_ACCEL_CONFIG_AFS_SEL));
+
+               /* Configure gyro to +/- 2000°/s */
+               _ao_mpu6000_reg_write(MPU6000_GYRO_CONFIG,
+                                     (0 << MPU600_GYRO_CONFIG_XG_ST) |
+                                     (0 << MPU600_GYRO_CONFIG_YG_ST) |
+                                     (0 << MPU600_GYRO_CONFIG_ZG_ST) |
+                                     (MPU600_GYRO_CONFIG_FS_SEL_2000 << MPU600_GYRO_CONFIG_FS_SEL));
+
+               ao_delay(AO_MS_TO_TICKS(200));
+               _ao_mpu6000_sample(&normal_mode);
        
-       errors += ao_mpu6000_accel_check(normal_mode.accel_x, test_mode.accel_x, "x");
-       errors += ao_mpu6000_accel_check(normal_mode.accel_y, test_mode.accel_y, "y");
-       errors += ao_mpu6000_accel_check(normal_mode.accel_z, test_mode.accel_z, "z");
-
-       errors += ao_mpu6000_gyro_check(normal_mode.gyro_x, test_mode.gyro_x, "x");
-       errors += ao_mpu6000_gyro_check(normal_mode.gyro_y, test_mode.gyro_y, "y");
-       errors += ao_mpu6000_gyro_check(normal_mode.gyro_z, test_mode.gyro_z, "z");
+               errors += ao_mpu6000_accel_check(normal_mode.accel_x, test_mode.accel_x, "x");
+               errors += ao_mpu6000_accel_check(normal_mode.accel_y, test_mode.accel_y, "y");
+               errors += ao_mpu6000_accel_check(normal_mode.accel_z, test_mode.accel_z, "z");
+
+               errors += ao_mpu6000_gyro_check(normal_mode.gyro_x, test_mode.gyro_x, "x");
+               errors += ao_mpu6000_gyro_check(normal_mode.gyro_y, test_mode.gyro_y, "y");
+               errors += ao_mpu6000_gyro_check(normal_mode.gyro_z, test_mode.gyro_z, "z");
+               if (!errors)
+                       break;
+       }
 
-       if (errors)
-               ao_panic(AO_PANIC_SELF_TEST_MPU6000);
+       if (st_tries == ST_TRIES)
+               ao_sensor_errors = 1;
 
        /* Filter to about 100Hz, which also sets the gyro rate to 1000Hz */
        _ao_mpu6000_reg_write(MPU6000_CONFIG,
index b00390ec0318b14901a68156ad29597df5b08f2f..28a9f9f3e4643beac09b0db8a0dcf6e56c348fc9 100644 (file)
@@ -965,7 +965,7 @@ ao_usb_disable(void)
        stm_usb.cntr = (1 << STM_USB_CNTR_PDWN) | (1 << STM_USB_CNTR_FRES);
 
        /* Disable the interface */
-       stm_rcc.apb1enr &+ ~(1 << STM_RCC_APB1ENR_USBEN);
+       stm_rcc.apb1enr &= ~(1 << STM_RCC_APB1ENR_USBEN);
        ao_arch_release_interrupts();
 }
 
index 7ba3a1a778c6daf74be40f228a4607ec2bdbb774..daeb9f1741d0e08aa6de2be1274dd8ac135a60a1 100644 (file)
@@ -316,6 +316,7 @@ struct ao_adc {
 #define AO_MPU6000_INT_PORT    (&stm_gpioc)
 #define AO_MPU6000_INT_PIN     13
 #define AO_MPU6000_I2C_INDEX   STM_I2C_INDEX(1)
+#define HAS_IMU                        1
 
 /*
  * mma655x
index 7ff676ea624ef143997c44b2ddf4602365d99964..95644dae03a1611b9e00197a980fa48e2af82f65 100644 (file)
@@ -318,8 +318,7 @@ struct ao_adc {
 #define AO_MPU6000_SPI_BUS     AO_SPI_1_PE13_PE14_PE15
 #define AO_MPU6000_SPI_CS_PORT (&stm_gpiod)
 #define AO_MPU6000_SPI_CS_PIN  2
-
-#define HAS_HIGHG_ACCEL                1
+#define HAS_IMU                        1
 
 /*
  * mma655x