From 0673344289772ed89483948184d6608c272c7c26 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 18:20:55 -0800 Subject: altos/stm: Semantic error in STM usb disable caused it to not work The USB enable register wasn't actually getting rewritten with the enable bit turned off, so the USB device was still powered on in flight. Signed-off-by: Keith Packard --- src/stm/ao_usb_stm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stm/ao_usb_stm.c b/src/stm/ao_usb_stm.c index b00390ec..28a9f9f3 100644 --- a/src/stm/ao_usb_stm.c +++ b/src/stm/ao_usb_stm.c @@ -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(); } -- cgit v1.2.3 From 1bf84ec28a41f7bd1b11ba45b4639856266227bc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 20:30:58 -0800 Subject: doc: Add tables describing AltOS beeps and flashes Provide a convenient place to reference when listening to the device. Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 223 insertions(+), 9 deletions(-) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index dfe89438..c71e08a7 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -835,17 +835,144 @@ NAR #88757, TRA #12200 the altimeter completes initialization and self test, and decides which mode to enter next. + + 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. + + AltOS Modes + + + + + + + + + Mode Name + Abbreviation + Beeps + Description + + + + + Startup + S + dit dit dit + + + Calibrating sensors, detecting orientation. + + + + + Idle + I + dit dit + + + Ready to accept commands over USB or radio link. + + + + + Pad + P + dit dah dah dit + + + Waiting for launch. Not listening for commands. + + + + + Boost + B + dah dit dit dit + + + Accelerating upwards. + + + + + Fast + F + dit dit dah dit + + + Decellerating, but moving faster than 200m/s. + + + + + Coast + C + dah dit dah dit + + + Decellerating, moving slower than 200m/s + + + + + Drogue + D + dah dit dit + + + Descending after apogee. Above main height. + + + + + Main + M + dah dah + + + Descending. Below main height. + + + + + Landed + L + dit dah dit dit + + + Stable altitude for at least ten seconds. + + + + + Sensor error + X + dah dit dit dah + + + Error detected during sensor calibration. + + + + + +
+
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. + + 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”) + + + Here's a summary of all of the “pad” and “idle” mode indications. + + Pad/Idle Indications + + + + + + + + Name + Beeps + Description + + + + + Neither + brap + + + No continuity detected on either apogee or main + igniters. + + + + + Apogee + dit + + + Continuity detected only on apogee igniter. + + + + + Main + dit dit + + + Continuity detected only on main igniter. + + + + + Both + dit dit dit + + + Continuity detected on both igniters. + + + + + Storage Full + warble + + + 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. + + + + + +
+
+ + 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. + 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 -- cgit v1.2.3 From ee4279613b4757453d0d8f8afc06037c61eeb520 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 18 Dec 2013 20:32:05 -0800 Subject: altos: Try IMU self-test 10 times before giving up This should keep the device from failing to boot unless the IMU is actually broken. Oh, and if self test does fail, this places the flight computer in 'Invalid' state rather than panic. Signed-off-by: Keith Packard --- src/core/ao_flight.c | 8 ++++ src/core/ao_flight.h | 4 ++ src/drivers/ao_mpu6000.c | 104 ++++++++++++++++++++++++-------------------- src/telemega-v0.1/ao_pins.h | 1 + src/telemega-v1.0/ao_pins.h | 3 +- 5 files changed, 70 insertions(+), 50 deletions(-) diff --git a/src/core/ao_flight.c b/src/core/ao_flight.c index 4a53bdc6..463ff4a2 100644 --- a/src/core/ao_flight.c +++ b/src/core/ao_flight.c @@ -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) { diff --git a/src/core/ao_flight.h b/src/core/ao_flight.h index ac3e9cfb..c7c02ccf 100644 --- a/src/core/ao_flight.h +++ b/src/core/ao_flight.h @@ -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; diff --git a/src/drivers/ao_mpu6000.c b/src/drivers/ao_mpu6000.c index 5e75b78a..f8ce7346 100644 --- a/src/drivers/ao_mpu6000.c +++ b/src/drivers/ao_mpu6000.c @@ -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, diff --git a/src/telemega-v0.1/ao_pins.h b/src/telemega-v0.1/ao_pins.h index 7ba3a1a7..daeb9f17 100644 --- a/src/telemega-v0.1/ao_pins.h +++ b/src/telemega-v0.1/ao_pins.h @@ -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 diff --git a/src/telemega-v1.0/ao_pins.h b/src/telemega-v1.0/ao_pins.h index 7ff676ea..95644dae 100644 --- a/src/telemega-v1.0/ao_pins.h +++ b/src/telemega-v1.0/ao_pins.h @@ -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 -- cgit v1.2.3