From d0c0dec140b8fa847704c9a22a39d254445188b9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 22 Jul 2020 08:57:05 -0700 Subject: [PATCH] altos: Use state transitions to directly drive igniters Instead of a separate igniter API, have the igniter code monitor flight state changes to trigger igniter events. This simplifes the code while allowing further changes in the igniter code. Signed-off-by: Keith Packard --- src/kernel/ao.h | 3 -- src/kernel/ao_flight.c | 33 +++++------------ src/kernel/ao_ignite.c | 84 +++++++++++++++--------------------------- 3 files changed, 39 insertions(+), 81 deletions(-) diff --git a/src/kernel/ao.h b/src/kernel/ao.h index fb7af24d..f44b0e9e 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -749,9 +749,6 @@ enum ao_igniter { ao_igniter_main = 1 }; -void -ao_ignite(enum ao_igniter igniter); - enum ao_igniter_status { ao_igniter_unknown, /* unknown status (ambiguous voltage) */ ao_igniter_ready, /* continuity detected */ diff --git a/src/kernel/ao_flight.c b/src/kernel/ao_flight.c index c5069158..2142546c 100644 --- a/src/kernel/ao_flight.c +++ b/src/kernel/ao_flight.c @@ -222,6 +222,8 @@ ao_flight(void) ) { ao_flight_state = ao_flight_boost; + ao_wakeup(&ao_flight_state); + ao_launch_tick = ao_boost_tick = ao_sample_tick; /* start logging data */ @@ -242,8 +244,6 @@ ao_flight(void) ao_gps_new = AO_GPS_NEW_DATA | AO_GPS_NEW_TRACKING; ao_wakeup(&ao_gps_new); #endif - - ao_wakeup(&ao_flight_state); } break; case ao_flight_boost: @@ -278,8 +278,8 @@ ao_flight(void) #else ao_flight_state = ao_flight_coast; #endif - ++ao_motor_number; ao_wakeup(&ao_flight_state); + ++ao_motor_number; } break; #if HAS_ACCEL && HAS_BARO @@ -327,11 +327,9 @@ ao_flight(void) #endif ) { -#if HAS_IGNITE - /* ignite the drogue charge */ - ao_ignite(ao_igniter_drogue); -#endif - + /* enter drogue state */ + ao_flight_state = ao_flight_drogue; + ao_wakeup(&ao_flight_state); #if HAS_TELEMETRY /* slow down the telemetry system */ ao_telemetry_set_interval(AO_TELEMETRY_INTERVAL_RECOVER); @@ -339,10 +337,6 @@ ao_flight(void) /* Turn the RDF beacon back on */ ao_rdf_set(1); #endif - - /* and enter drogue state */ - ao_flight_state = ao_flight_drogue; - ao_wakeup(&ao_flight_state); } else #else /* not HAS_BARO */ @@ -362,12 +356,11 @@ ao_flight(void) ao_interval_max_accel_through - ao_interval_min_accel_through <= ao_data_accel_to_sample(MAX_QUIET_ACCEL)) { ao_flight_state = ao_flight_landed; + ao_wakeup(&ao_flight_state); #if HAS_ADC /* turn off the ADC capture */ ao_timer_set_adc_interval(0); #endif - - ao_wakeup(&ao_flight_state); } /* Reset interval values */ @@ -410,9 +403,8 @@ ao_flight(void) */ if (ao_height <= ao_config.main_deploy) { -#if HAS_IGNITE - ao_ignite(ao_igniter_main); -#endif + ao_flight_state = ao_flight_main; + ao_wakeup(&ao_flight_state); /* * Start recording min/max height @@ -423,9 +415,6 @@ ao_flight(void) ao_interval_end = ao_sample_tick + AO_INTERVAL_TICKS; ao_interval_min_height = ao_interval_max_height = ao_avg_height; - - ao_flight_state = ao_flight_main; - ao_wakeup(&ao_flight_state); } break; @@ -445,13 +434,11 @@ ao_flight(void) if (ao_interval_max_height - ao_interval_min_height <= AO_M_TO_HEIGHT(4)) { ao_flight_state = ao_flight_landed; - + ao_wakeup(&ao_flight_state); #if HAS_ADC /* turn off the ADC capture */ ao_timer_set_adc_interval(0); #endif - - ao_wakeup(&ao_flight_state); } ao_interval_min_height = ao_interval_max_height = ao_avg_height; ao_interval_end = ao_sample_tick + AO_INTERVAL_TICKS; diff --git a/src/kernel/ao_ignite.c b/src/kernel/ao_ignite.c index 71c99a61..692460d0 100644 --- a/src/kernel/ao_ignite.c +++ b/src/kernel/ao_ignite.c @@ -25,15 +25,6 @@ #if HAS_IGNITE struct ao_ignition ao_ignition[2]; -void -ao_ignite(enum ao_igniter igniter) -{ - ao_arch_block_interrupts(); - ao_ignition[igniter].request = 1; - ao_wakeup(&ao_ignition); - ao_arch_release_interrupts(); -} - #ifndef AO_SENSE_DROGUE #define AO_SENSE_DROGUE(p) ((p)->adc.sense_d) #define AO_SENSE_MAIN(p) ((p)->adc.sense_m) @@ -86,73 +77,56 @@ ao_igniter_status(enum ao_igniter igniter) static void ao_igniter_fire(enum ao_igniter igniter) { - ao_ignition[igniter].firing = 1; - switch(ao_config.ignite_mode) { - case AO_IGNITE_MODE_DUAL: - switch (igniter) { - case ao_igniter_drogue: - AO_IGNITER_SET_DROGUE(1); - ao_delay(AO_IGNITER_FIRE_TIME); - AO_IGNITER_SET_DROGUE(0); - break; - case ao_igniter_main: - AO_IGNITER_SET_MAIN(1); - ao_delay(AO_IGNITER_FIRE_TIME); - AO_IGNITER_SET_MAIN(0); - break; - } - break; - case AO_IGNITE_MODE_APOGEE: + if (!ao_ignition[igniter].fired) { + ao_ignition[igniter].firing = 1; + ao_ignition[igniter].fired = 1; switch (igniter) { case ao_igniter_drogue: AO_IGNITER_SET_DROGUE(1); ao_delay(AO_IGNITER_FIRE_TIME); AO_IGNITER_SET_DROGUE(0); - ao_delay(AO_IGNITER_CHARGE_TIME); - AO_IGNITER_SET_MAIN(1); - ao_delay(AO_IGNITER_FIRE_TIME); - AO_IGNITER_SET_MAIN(0); break; - default: - break; - } - break; - case AO_IGNITE_MODE_MAIN: - switch (igniter) { case ao_igniter_main: - AO_IGNITER_SET_DROGUE(1); - ao_delay(AO_IGNITER_FIRE_TIME); - AO_IGNITER_SET_DROGUE(0); - ao_delay(AO_IGNITER_CHARGE_TIME); AO_IGNITER_SET_MAIN(1); ao_delay(AO_IGNITER_FIRE_TIME); AO_IGNITER_SET_MAIN(0); break; - default: - break; } - break; + ao_ignition[igniter].firing = 0; + ao_delay(AO_IGNITER_CHARGE_TIME); } - ao_ignition[igniter].firing = 0; } static void ao_igniter(void) { - enum ao_igniter igniter; - ao_config_get(); for (;;) { - ao_sleep(&ao_ignition); - for (igniter = ao_igniter_drogue; igniter <= ao_igniter_main; igniter++) { - if (ao_ignition[igniter].request && !ao_ignition[igniter].fired) { - if (igniter == ao_igniter_drogue && ao_config.apogee_delay) - ao_delay(AO_SEC_TO_TICKS(ao_config.apogee_delay)); - - ao_igniter_fire(igniter); - ao_delay(AO_IGNITER_CHARGE_TIME); - ao_ignition[igniter].fired = 1; + /* Wait for flight state change */ + ao_sleep(&ao_flight_state); + + /* Fire any igniters that are supposed to be triggered + * in this new state + */ + switch(ao_config.ignite_mode) { + case AO_IGNITE_MODE_DUAL: + if (ao_flight_drogue <= ao_flight_state && ao_flight_state < ao_flight_landed) + ao_igniter_fire(ao_igniter_drogue); + if (ao_flight_main <= ao_flight_state && ao_flight_state < ao_flight_landed) + ao_igniter_fire(ao_igniter_main); + break; + case AO_IGNITE_MODE_APOGEE: + if (ao_flight_drogue <= ao_flight_state && ao_flight_state < ao_flight_landed) { + ao_igniter_fire(ao_igniter_drogue); + ao_igniter_fire(ao_igniter_main); + } + break; + case AO_IGNITE_MODE_MAIN: + if (ao_flight_main <= ao_flight_state && ao_flight_state < ao_flight_landed) { + ao_igniter_fire(ao_igniter_drogue); + ao_igniter_fire(ao_igniter_main); } + break; } } } -- 2.30.2