app/rev2/fsm_appa.c
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /******************************************************************************* | ||
| 2 | * * | ||
| 3 | * FILE: * | ||
| 4 | * fsm_appa.c * | ||
| 5 | * * | ||
| 6 | * DESCRIPTION: * | ||
| 7 | * Finite State Machine for APPA. * | ||
| 8 | * * | ||
| 9 | * COPYRIGHT: * | ||
| 10 | * Copyright (c) 2025 Sun Devil Rocketry. * | ||
| 11 | * All rights reserved. * | ||
| 12 | * * | ||
| 13 | * This software is licensed under terms that can be found in the LICENSE * | ||
| 14 | * file in the root directory of this software component. * | ||
| 15 | * If no LICENSE file comes with this software, it is covered under the * | ||
| 16 | * BSD-3-Clause. * | ||
| 17 | * * | ||
| 18 | * https://opensource.org/license/bsd-3-clause * | ||
| 19 | * * | ||
| 20 | *******************************************************************************/ | ||
| 21 | |||
| 22 | |||
| 23 | /*------------------------------------------------------------------------------ | ||
| 24 | Includes | ||
| 25 | ------------------------------------------------------------------------------*/ | ||
| 26 | #include "main.h" | ||
| 27 | #include "led.h" | ||
| 28 | #include "usb.h" | ||
| 29 | #include "math.h" | ||
| 30 | #include "sensor.h" | ||
| 31 | #include "servo.h" | ||
| 32 | #include "buzzer.h" | ||
| 33 | #include "error_sdr.h" | ||
| 34 | #include "ignition.h" | ||
| 35 | #include "debug_sdr.h" | ||
| 36 | |||
| 37 | |||
| 38 | /*------------------------------------------------------------------------------ | ||
| 39 | Global Variables | ||
| 40 | ------------------------------------------------------------------------------*/ | ||
| 41 | extern PID_DATA pid_data; | ||
| 42 | extern SENSOR_DATA sensor_data; | ||
| 43 | extern SERVO_PRESET servo_preset; | ||
| 44 | extern PRESET_DATA preset_data; | ||
| 45 | |||
| 46 | #ifndef UNIT_TEST | ||
| 47 | static FLIGHT_COMP_STATE_TYPE flight_computer_state = FC_STATE_INIT; | ||
| 48 | #else | ||
| 49 | FLIGHT_COMP_STATE_TYPE flight_computer_state = FC_STATE_INIT; | ||
| 50 | #endif | ||
| 51 | |||
| 52 | /* Timing (debug) */ | ||
| 53 | #ifdef DEBUG | ||
| 54 | extern volatile uint32_t debug_previous; | ||
| 55 | extern volatile uint32_t debug_delta; | ||
| 56 | #endif | ||
| 57 | |||
| 58 | /*------------------------------------------------------------------------------ | ||
| 59 | Functions | ||
| 60 | ------------------------------------------------------------------------------*/ | ||
| 61 | |||
| 62 | /******************************************************************************* | ||
| 63 | * * | ||
| 64 | * PROCEDURE: * | ||
| 65 | * fc_state_update * | ||
| 66 | * * | ||
| 67 | * DESCRIPTION: * | ||
| 68 | * Update the flight computer state to next state * | ||
| 69 | * * | ||
| 70 | *******************************************************************************/ | ||
| 71 | 48 | void fc_state_update | |
| 72 | ( | ||
| 73 | FLIGHT_COMP_STATE_TYPE new_state | ||
| 74 | ) | ||
| 75 | { | ||
| 76 | #ifdef DEBUG | ||
| 77 | 7 | char msg[40]; | |
| 78 | 7 | debug_log(msg, snprintf(msg, 40, "State Change: %d->%d", flight_computer_state, new_state), LOG_LVL_INFO); | |
| 79 | #endif | ||
| 80 |
4/6✓ Branch 0 taken 25 times.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 3 taken 19 times.
|
48 | if ( new_state == flight_computer_state + 1 || new_state == flight_computer_state ) |
| 81 | { | ||
| 82 | 29 | flight_computer_state = new_state; | |
| 83 | } | ||
| 84 |
4/4✓ Branch 0 taken 5 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 3 times.
|
19 | else if ( flight_computer_state == FC_STATE_ASCENT && new_state == FC_STATE_APOGEE ) |
| 85 | { | ||
| 86 | 2 | flight_computer_state = new_state; | |
| 87 | } | ||
| 88 | else | ||
| 89 | { | ||
| 90 | 17 | error_fail_fast( ERROR_INVALID_STATE_ERROR ); | |
| 91 | } | ||
| 92 | 43 | } /* fc_state_update */ | |
| 93 | |||
| 94 | |||
| 95 | /******************************************************************************* | ||
| 96 | * * | ||
| 97 | * PROCEDURE: * | ||
| 98 | * get_fc_state * | ||
| 99 | * * | ||
| 100 | * DESCRIPTION: * | ||
| 101 | * Get the current flight computer state * | ||
| 102 | * * | ||
| 103 | *******************************************************************************/ | ||
| 104 | 10058 | FLIGHT_COMP_STATE_TYPE get_fc_state() | |
| 105 | { | ||
| 106 | 10058 | return flight_computer_state; | |
| 107 | |||
| 108 | } /* get_fc_state */ | ||
| 109 | |||
| 110 | |||
| 111 | /******************************************************************************* | ||
| 112 | * * | ||
| 113 | * PROCEDURE: * | ||
| 114 | * appa_fsm * | ||
| 115 | * * | ||
| 116 | * DESCRIPTION: * | ||
| 117 | * Finite State Machine for APPA. * | ||
| 118 | * * | ||
| 119 | *******************************************************************************/ | ||
| 120 | 25 | void appa_fsm | |
| 121 | ( | ||
| 122 | uint8_t firmware_code, | ||
| 123 | FLASH_STATUS* flash_status, | ||
| 124 | HFLASH_BUFFER* flash_handle, | ||
| 125 | uint32_t* flash_address, | ||
| 126 | uint8_t* gps_mesg_byte, | ||
| 127 | SENSOR_STATUS* sensor_status | ||
| 128 | ) | ||
| 129 | { | ||
| 130 | /*------------------------------------------------------------------------------ | ||
| 131 | Local Variables | ||
| 132 | ------------------------------------------------------------------------------*/ | ||
| 133 | 25 | uint32_t launch_detect_start_time = 0; | |
| 134 | 25 | USB_STATUS usb_status = USB_OK; | |
| 135 | |||
| 136 | /*-------------------------------------------------------------------------- | ||
| 137 | FSM Entry | ||
| 138 | --------------------------------------------------------------------------*/ | ||
| 139 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 24 times.
|
25 | if( *flash_status == FLASH_PRESET_NOT_FOUND ) |
| 140 | { | ||
| 141 | 1 | led_set_color( LED_YELLOW ); | |
| 142 | 1 | buzzer_multi_beeps(500, 500, 3); | |
| 143 | } | ||
| 144 | |||
| 145 | 25 | fc_state_update( FC_STATE_IDLE ); | |
| 146 | 25 | led_set_color( LED_GREEN ); | |
| 147 | 25 | buzzer_multi_beeps(50, 50, 2); | |
| 148 | 25 | *sensor_status = sensor_start_IT( &sensor_data ); | |
| 149 | 25 | sensor_init( &preset_data ); | |
| 150 | |||
| 151 | /* servo default position */ | ||
| 152 | 25 | motor_drive( SERVO_1, preset_data.servo_preset.rp_servo1 ); | |
| 153 | 25 | motor_drive( SERVO_2, preset_data.servo_preset.rp_servo2 ); | |
| 154 | 25 | motor_drive( SERVO_3, preset_data.servo_preset.rp_servo3 ); | |
| 155 | 25 | motor_drive( SERVO_4, preset_data.servo_preset.rp_servo4 ); | |
| 156 | |||
| 157 |
2/2✓ Branch 1 taken 2725 times.
✓ Branch 2 taken 18 times.
|
2768 | while( get_fc_state() <= FC_STATE_MAX ) |
| 158 | { | ||
| 159 |
4/6✗ Branch 0 not taken.
✓ Branch 1 taken 1555 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1164 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2725 | switch( get_fc_state() ) |
| 160 | { | ||
| 161 | /*-------------------------------------------------------------------------- | ||
| 162 | Init State | ||
| 163 | main.c - Unreachable but enumerated to catch a warning. | ||
| 164 | --------------------------------------------------------------------------*/ | ||
| 165 | /** | ||
| 166 | * GCOVR_EXCL_START | ||
| 167 | * | ||
| 168 | * Protective case to prevent programmer error. If hit, it will default to | ||
| 169 | * the idle state. | ||
| 170 | */ | ||
| 171 | − | case FC_STATE_INIT: | |
| 172 | − | fc_state_update( FC_STATE_IDLE ); | |
| 173 | − | break; | |
| 174 | /** | ||
| 175 | * GCOVR_EXCL_STOP | ||
| 176 | */ | ||
| 177 | |||
| 178 | /*-------------------------------------------------------------------------- | ||
| 179 | Idle State (Terminal) | ||
| 180 | prelaunch.c - Will loop until switch activation | ||
| 181 | --------------------------------------------------------------------------*/ | ||
| 182 | 1555 | case FC_STATE_IDLE: | |
| 183 | 1555 | usb_status = prelaunch_terminal | |
| 184 | ( | ||
| 185 | firmware_code, | ||
| 186 | flash_status, | ||
| 187 | flash_handle, | ||
| 188 | flash_address, | ||
| 189 | gps_mesg_byte, | ||
| 190 | sensor_status | ||
| 191 | ); | ||
| 192 | |||
| 193 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1549 times.
|
1551 | if( usb_status == USB_FAIL ) |
| 194 | { | ||
| 195 | 2 | error_fail_fast( ERROR_USB_UART_ERROR ); | |
| 196 | } | ||
| 197 | break; | ||
| 198 | |||
| 199 | /*-------------------------------------------------------------------------- | ||
| 200 | Calibration State (FC Arming) | ||
| 201 | flight.c - Will run once and change state | ||
| 202 | --------------------------------------------------------------------------*/ | ||
| 203 | 4 | case FC_STATE_CALIB: | |
| 204 | 4 | flight_calib(gps_mesg_byte, flash_handle, flash_address); | |
| 205 | |||
| 206 | /* Calib implicitly transitions into launch detect */ | ||
| 207 | 4 | buzzer_beep(500); | |
| 208 | 4 | launch_detect_start_time = HAL_GetTick(); | |
| 209 | 4 | break; | |
| 210 | |||
| 211 | /*-------------------------------------------------------------------------- | ||
| 212 | Flight Computer Superloop States | ||
| 213 | flight.c - Transitions handled internally | ||
| 214 | --------------------------------------------------------------------------*/ | ||
| 215 | 1164 | case FC_STATE_LAUNCH_DETECT: | |
| 216 | case FC_STATE_COAST: /* intentional fallthrough */ | ||
| 217 | case FC_STATE_ASCENT: /* intentional fallthrough */ | ||
| 218 | case FC_STATE_DESCENT: /* intentional fallthrough */ | ||
| 219 | case FC_STATE_LANDED: /* intentional fallthrough; landed state not yet implemented */ | ||
| 220 | 1164 | flight_loop | |
| 221 | ( | ||
| 222 | &launch_detect_start_time, | ||
| 223 | sensor_status, | ||
| 224 | flash_status, | ||
| 225 | flash_handle, | ||
| 226 | flash_address | ||
| 227 | ); | ||
| 228 | 1164 | break; | |
| 229 | |||
| 230 | /*-------------------------------------------------------------------------- | ||
| 231 | Apogee State (FC Starting Descent) | ||
| 232 | flight.c - Will run once (until deployment succeeds) | ||
| 233 | --------------------------------------------------------------------------*/ | ||
| 234 | 2 | case FC_STATE_APOGEE: | |
| 235 | 2 | flight_deploy(); | |
| 236 | 2 | break; | |
| 237 | } /* switch( get_fc_state() ) */ | ||
| 238 | } /* while( get_fc_state() <= FC_STATE_MAX ) */ | ||
| 239 | |||
| 240 | /* Unreachable under standard operation. Unrecoverable error. */ | ||
| 241 | 18 | error_fail_fast( ERROR_INVALID_STATE_ERROR ); | |
| 242 | |||
| 243 | 18 | } /* flight_loop() */ | |
| 244 |