void ao_report(void) { ao_report_state = ao_flight_state; for(;;) { #if HAS_BATTERY_REPORT if (ao_flight_state == ao_flight_startup) ao_report_battery(); else #endif ao_report_beep(); if (ao_flight_state == ao_flight_landed) { ao_report_altitude(); #if HAS_FLIGHT ao_delay(AO_SEC_TO_TICKS(5)); continue; #endif } #if HAS_IGNITE_REPORT if (ao_flight_state == ao_flight_idle) ao_report_continuity(); while (ao_flight_state == ao_flight_pad) { uint8_t c; ao_report_continuity(); c = 50; while (c-- && ao_flight_state == ao_flight_pad) pause(AO_MS_TO_TICKS(100)); } #endif while (ao_report_state == ao_flight_state) ao_sleep(DATA_TO_XDATA(&ao_flight_state)); ao_report_state = ao_flight_state; } }
/* * A thread to initialize the bluetooth device and * hang around to blink the LED when connected */ void ao_btm(void) { /* * Wait for the bluetooth device to boot */ ao_delay(AO_SEC_TO_TICKS(3)); /* * The first time we connect, the BTM-180 comes up at 19200 baud. * After that, it will remember and come up at 57600 baud. So, see * if it is already running at 57600 baud, and if that doesn't work * then tell it to switch to 57600 from 19200 baud. */ while (!ao_btm_try_speed(AO_SERIAL_SPEED_57600)) { ao_delay(AO_SEC_TO_TICKS(1)); if (ao_btm_try_speed(AO_SERIAL_SPEED_19200)) ao_btm_cmd("ATL4\r"); ao_delay(AO_SEC_TO_TICKS(1)); } /* Disable echo */ ao_btm_cmd("ATE0\r"); /* Enable flow control */ ao_btm_cmd("ATC1\r"); /* Set the reported name to something we can find on the host */ ao_btm_set_name(); /* Turn off status reporting */ ao_btm_cmd("ATQ1\r"); ao_btm_stdio = ao_add_stdio(_ao_serial_btm_pollchar, ao_serial_btm_putchar, NULL); ao_btm_echo(0); for (;;) { while (!ao_btm_connected) ao_sleep(&ao_btm_connected); while (ao_btm_connected) { ao_led_for(AO_BT_LED, AO_MS_TO_TICKS(20)); ao_delay(AO_SEC_TO_TICKS(3)); } } }
void ao_rssi(void) { for (;;) { while ((int16_t) (ao_time() - ao_rssi_time) > AO_SEC_TO_TICKS(3)) ao_sleep(&ao_rssi_time); ao_led_for(ao_rssi_led, AO_MS_TO_TICKS(100)); ao_delay(ao_rssi_delay); } }
void beep(void) { static __xdata struct ao_adc adc; for (;;) { ao_delay(AO_SEC_TO_TICKS(1)); ao_adc_get(&adc); if (adc.temp > 7400) ao_beep_for(AO_BEEP_LOW, AO_MS_TO_TICKS(50)); } }
static void ao_launch_status(void) { uint8_t i; for (;;) { ao_delay(AO_SEC_TO_TICKS(1)); if (ao_igniter_status(ao_igniter_drogue) == ao_igniter_ready) { if (ao_igniter_status(ao_igniter_main) == ao_igniter_ready) { for (i = 0; i < 5; i++) { ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(50)); ao_delay(AO_MS_TO_TICKS(100)); } } else { ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); } } } }
static void ao_launch(void) { static __xdata struct ao_launch_command command; static __xdata struct ao_launch_query query; int16_t time_difference; ao_led_off(AO_LED_RED); ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); for (;;) { flush(); if (ao_radio_cmac_recv(&command, sizeof (command), 0) != AO_RADIO_CMAC_OK) continue; PRINTD ("tick %d serial %d cmd %d channel %d\n", command.tick, command.serial, command.cmd, command.channel); switch (command.cmd) { case AO_LAUNCH_QUERY: if (command.serial != ao_serial_number) { PRINTD ("serial number mismatch\n"); break; } if (command.channel == 0) { query.valid = 1; query.arm_status = ao_igniter_status(ao_igniter_drogue); query.igniter_status = ao_igniter_status(ao_igniter_main); } else { query.valid = 0; } query.tick = ao_time(); query.serial = ao_serial_number; query.channel = command.channel; PRINTD ("query tick %d serial %d channel %d valid %d arm %d igniter %d\n", query.tick, query.serial, query.channel, query.valid, query.arm_status, query.igniter_status); ao_radio_cmac_send(&query, sizeof (query)); break; case AO_LAUNCH_ARM: if (command.serial != ao_serial_number) { PRINTD ("serial number mismatch\n"); break; } if (command.channel != 0) break; time_difference = command.tick - ao_time(); PRINTD ("arm tick %d local tick %d\n", command.tick, ao_time()); if (time_difference < 0) time_difference = -time_difference; if (time_difference > 10) { PRINTD ("time difference too large %d\n", time_difference); break; } PRINTD ("armed\n"); ao_launch_armed = 1; ao_launch_arm_time = ao_time(); break; case AO_LAUNCH_FIRE: if (!ao_launch_armed) { PRINTD ("not armed\n"); break; } if ((uint16_t) (ao_time() - ao_launch_arm_time) > AO_SEC_TO_TICKS(20)) { PRINTD ("late launch arm_time %d time %d\n", ao_launch_arm_time, ao_time()); break; } time_difference = command.tick - ao_time(); if (time_difference < 0) time_difference = -time_difference; if (time_difference > 10) { PRINTD ("time different too large %d\n", time_difference); break; } PRINTD ("ignite\n"); ao_launch_ignite = 1; ao_wakeup(&ao_launch_ignite); break; } } }