mod/telemetry/telemetry.c
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /** | ||
| 2 | ****************************************************************************** | ||
| 3 | * @file : telemetry.c | ||
| 4 | * @brief : Module for LoRa (wireless) communication. | ||
| 5 | ****************************************************************************** | ||
| 6 | * @copyright | ||
| 7 | * | ||
| 8 | * Copyright (c) 2025 Sun Devil Rocketry. | ||
| 9 | * All rights reserved. | ||
| 10 | * | ||
| 11 | * This software is licensed under terms that can be found in the LICENSE | ||
| 12 | * file in the root directory of this software component. | ||
| 13 | * If no LICENSE file comes with this software, it is covered under the | ||
| 14 | * BSD-3-Clause. | ||
| 15 | * | ||
| 16 | * https://opensource.org/license/bsd-3-clause | ||
| 17 | * | ||
| 18 | ****************************************************************************** | ||
| 19 | */ | ||
| 20 | |||
| 21 | /*------------------------------------------------------------------------------ | ||
| 22 | Standard Includes | ||
| 23 | ------------------------------------------------------------------------------*/ | ||
| 24 | #include <stdint.h> | ||
| 25 | #include <stdbool.h> | ||
| 26 | #include <string.h> | ||
| 27 | |||
| 28 | /*------------------------------------------------------------------------------ | ||
| 29 | Project Includes | ||
| 30 | ------------------------------------------------------------------------------*/ | ||
| 31 | #include "main.h" | ||
| 32 | #include "math_sdr.h" | ||
| 33 | #include "commands.h" | ||
| 34 | #include "error_sdr.h" | ||
| 35 | #include "debug_sdr.h" | ||
| 36 | #include "telemetry.h" | ||
| 37 | #include "lora.h" | ||
| 38 | |||
| 39 | /*------------------------------------------------------------------------------ | ||
| 40 | Global Variables | ||
| 41 | ------------------------------------------------------------------------------*/ | ||
| 42 | extern PRESET_DATA preset_data; /* Struct with preset data */ | ||
| 43 | extern SENSOR_DATA sensor_data; /* Struct with all sensor */ | ||
| 44 | |||
| 45 | static uint32_t message_idx = 0; | ||
| 46 | |||
| 47 | /*------------------------------------------------------------------------------ | ||
| 48 | Statics | ||
| 49 | ------------------------------------------------------------------------------*/ | ||
| 50 | |||
| 51 | static void telemetry_build_msg_vehicle_id | ||
| 52 | ( | ||
| 53 | TELEMETRY_MESSAGE* msg_buf | ||
| 54 | ); | ||
| 55 | |||
| 56 | |||
| 57 | static void telemetry_build_msg_calibration | ||
| 58 | ( | ||
| 59 | TELEMETRY_MESSAGE* msg_buf | ||
| 60 | ); | ||
| 61 | |||
| 62 | |||
| 63 | static void telemetry_build_msg_dashboard_dump | ||
| 64 | ( | ||
| 65 | TELEMETRY_MESSAGE* msg_buf | ||
| 66 | ); | ||
| 67 | |||
| 68 | /*------------------------------------------------------------------------------ | ||
| 69 | Public APIs | ||
| 70 | ------------------------------------------------------------------------------*/ | ||
| 71 | |||
| 72 | /** | ||
| 73 | * @brief Selects and constructs the next scheduled telemetry message. | ||
| 74 | * @param payload Telemetry message buffer to fill. | ||
| 75 | */ | ||
| 76 | ✗ | void telemetry_get_next_message | |
| 77 | ( | ||
| 78 | TELEMETRY_MESSAGE* payload /* o: constructed telemetry message */ | ||
| 79 | ) | ||
| 80 | { | ||
| 81 | ✗ | TELEMETRY_MESSAGE_TYPES msg_type; | |
| 82 | |||
| 83 | /* Determine which payload to send */ | ||
| 84 | ✗ | if( ( message_idx % 3 == 0 ) | |
| 85 | ✗ | && ( get_fc_state() == FC_STATE_LAUNCH_DETECT ) ) | |
| 86 | { | ||
| 87 | msg_type = TELEMETRY_MSG_VEHICLE_ID; | ||
| 88 | } | ||
| 89 | ✗ | else if( ( message_idx % 3 == 1 ) | |
| 90 | ✗ | && ( get_fc_state() == FC_STATE_LAUNCH_DETECT ) ) | |
| 91 | { | ||
| 92 | msg_type = TELEMETRY_MSG_CALIBRATION; | ||
| 93 | } | ||
| 94 | else | ||
| 95 | { | ||
| 96 | msg_type = TELEMETRY_MSG_DASHBOARD_DATA; | ||
| 97 | } | ||
| 98 | ✗ | telemetry_build_payload(payload, msg_type); | |
| 99 | ✗ | message_idx++; | |
| 100 | |||
| 101 | ✗ | } /* telemetry_get_next_message */ | |
| 102 | |||
| 103 | |||
| 104 | /** | ||
| 105 | * @brief Builds the requested telemetry payload and fills its message header. | ||
| 106 | * @param msg_buf Telemetry message buffer to fill. | ||
| 107 | * @param message_type Type of telemetry message to build. | ||
| 108 | */ | ||
| 109 | ✗ | void telemetry_build_payload | |
| 110 | ( | ||
| 111 | TELEMETRY_MESSAGE* msg_buf, /* o: buffer passed by caller */ | ||
| 112 | TELEMETRY_MESSAGE_TYPES message_type /* i: what kind of message */ | ||
| 113 | ) | ||
| 114 | { | ||
| 115 | /*------------------------------------------------------------------------------ | ||
| 116 | Construct Header | ||
| 117 | ------------------------------------------------------------------------------*/ | ||
| 118 | ✗ | memset(msg_buf, 0, TELEMETRY_MESSAGE_SIZE); | |
| 119 | ✗ | msg_buf->header.mid = message_type; | |
| 120 | ✗ | msg_buf->header.timestamp = HAL_GetTick(); | |
| 121 | |||
| 122 | /*------------------------------------------------------------------------------ | ||
| 123 | Build Payload | ||
| 124 | ------------------------------------------------------------------------------*/ | ||
| 125 | ✗ | switch( message_type ) | |
| 126 | { | ||
| 127 | ✗ | case TELEMETRY_MSG_VEHICLE_ID: | |
| 128 | { | ||
| 129 | ✗ | telemetry_build_msg_vehicle_id(msg_buf); | |
| 130 | ✗ | break; | |
| 131 | } | ||
| 132 | ✗ | case TELEMETRY_MSG_DASHBOARD_DATA: | |
| 133 | { | ||
| 134 | ✗ | telemetry_build_msg_dashboard_dump(msg_buf); | |
| 135 | ✗ | break; | |
| 136 | } | ||
| 137 | ✗ | case TELEMETRY_MSG_CALIBRATION: | |
| 138 | { | ||
| 139 | ✗ | telemetry_build_msg_calibration(msg_buf); | |
| 140 | ✗ | break; | |
| 141 | } | ||
| 142 | default: | ||
| 143 | { | ||
| 144 | /** In order to support projects with safety critical | ||
| 145 | * requirements, mod does not throw fail-fast errors. | ||
| 146 | * Thus, this should nop on release builds. | ||
| 147 | * | ||
| 148 | * This ensures that the library will only fail fast in | ||
| 149 | * the event of a hardfault and enables it to offload | ||
| 150 | * FHA requirements to the project that integrates it, | ||
| 151 | * if needed. | ||
| 152 | * | ||
| 153 | * GCOVR_EXCL_START | ||
| 154 | * | ||
| 155 | * A coverage hole is reported here because the debug-mode | ||
| 156 | * emulator tests have an actual function call here while | ||
| 157 | * release does not. This branch *is* tested in the release | ||
| 158 | * configuration. | ||
| 159 | */ | ||
| 160 | − | debug_assert( false, ERROR_RECORD_FLIGHT_EVENTS_ERROR ); | |
| 161 | − | break; | |
| 162 | /* GCOVR_EXCL_STOP */ | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | /*------------------------------------------------------------------------------ | ||
| 167 | Encrypt Message | ||
| 168 | ------------------------------------------------------------------------------*/ | ||
| 169 | /* not yet ready */ | ||
| 170 | |||
| 171 | // ETS Temp: This may not be done by v2.6.0. I'm happy to commit to dropping | ||
| 172 | // encryption for this release since our comms are one-way | ||
| 173 | // flight critical --> non-critical, so the flight critical element is never | ||
| 174 | // receiving outside data in-flight. | ||
| 175 | |||
| 176 | ✗ | } /* telemetry_build_payload */ | |
| 177 | |||
| 178 | /*------------------------------------------------------------------------------ | ||
| 179 | State Functions | ||
| 180 | ------------------------------------------------------------------------------*/ | ||
| 181 | |||
| 182 | /*------------------------------------------------------------------------------ | ||
| 183 | Telemetry Message Constructors | ||
| 184 | ------------------------------------------------------------------------------*/ | ||
| 185 | |||
| 186 | /** | ||
| 187 | * @brief Builds a payload containing the vehicle identification and version. | ||
| 188 | * @param msg_buf Telemetry message buffer to fill. | ||
| 189 | */ | ||
| 190 | ✗ | static void telemetry_build_msg_vehicle_id | |
| 191 | ( | ||
| 192 | TELEMETRY_MESSAGE* msg_buf | ||
| 193 | ) | ||
| 194 | { | ||
| 195 | /* hardware & firmware identifiers */ | ||
| 196 | ✗ | msg_buf->payload.vehicle_id.hw_opcode = PING_RESPONSE_CODE; | |
| 197 | ✗ | msg_buf->payload.vehicle_id.fw_opcode = FIRMWARE_APPA; | |
| 198 | ✗ | get_uid( &(msg_buf->payload.vehicle_id.uid) ); | |
| 199 | |||
| 200 | /* version string */ | ||
| 201 | ✗ | msg_buf->payload.vehicle_id.version |= ( VERSION_HARDWARE << 24 ); | |
| 202 | ✗ | msg_buf->payload.vehicle_id.version |= ( VERSION_FIRMWARE_MAJOR << 16 ); | |
| 203 | ✗ | msg_buf->payload.vehicle_id.version |= ( VERSION_FIRMWARE_PATCH << 8 ); | |
| 204 | ✗ | msg_buf->payload.vehicle_id.version |= ( VERSION_PRERELEASE_NUMBER ); | |
| 205 | |||
| 206 | /* flight id (not yet implemented) */ | ||
| 207 | ✗ | strncpy( msg_buf->payload.vehicle_id.flight_id, "AVIONICS_TEST", 16 ); | |
| 208 | |||
| 209 | ✗ | } /* telemetry_build_msg_vehicle_id */ | |
| 210 | |||
| 211 | |||
| 212 | /** | ||
| 213 | * @brief Builds a payload containing calibration data and QFE elevation. | ||
| 214 | * @param msg_buf Telemetry message buffer to fill. | ||
| 215 | */ | ||
| 216 | ✗ | static void telemetry_build_msg_calibration | |
| 217 | ( | ||
| 218 | TELEMETRY_MESSAGE* msg_buf | ||
| 219 | ) | ||
| 220 | { | ||
| 221 | /*------------------------------------------------------------------------------ | ||
| 222 | Local Variables | ||
| 223 | ------------------------------------------------------------------------------*/ | ||
| 224 | ✗ | SENSOR_DATA qfe_sensor_data; | |
| 225 | |||
| 226 | ✗ | memset( &qfe_sensor_data, 0, sizeof( SENSOR_DATA ) ); | |
| 227 | |||
| 228 | /*------------------------------------------------------------------------------ | ||
| 229 | Construct known elements from preset data | ||
| 230 | ------------------------------------------------------------------------------*/ | ||
| 231 | ✗ | msg_buf->payload.calibration.imu_offset = preset_data.imu_offset; | |
| 232 | ✗ | msg_buf->payload.calibration.baro_preset = preset_data.baro_preset; | |
| 233 | ✗ | msg_buf->payload.calibration.servo_preset = preset_data.servo_preset; | |
| 234 | |||
| 235 | /*------------------------------------------------------------------------------ | ||
| 236 | Determine QFE reference elevation | ||
| 237 | ------------------------------------------------------------------------------*/ | ||
| 238 | ✗ | qfe_sensor_data.baro_pressure = preset_data.baro_preset.baro_pres; | |
| 239 | ✗ | qfe_sensor_data.baro_temp = preset_data.baro_preset.baro_temp; | |
| 240 | ✗ | sensor_baro_alt( &qfe_sensor_data ); | |
| 241 | |||
| 242 | ✗ | msg_buf->payload.calibration.qfe_elevation = qfe_sensor_data.baro_alt; | |
| 243 | |||
| 244 | ✗ | } /* telemetry_build_msg_calibration */ | |
| 245 | |||
| 246 | |||
| 247 | /** | ||
| 248 | * @brief Builds a payload containing the current flight state and dashboard data. | ||
| 249 | * @param msg_buf Telemetry message buffer to fill. | ||
| 250 | */ | ||
| 251 | ✗ | static void telemetry_build_msg_dashboard_dump | |
| 252 | ( | ||
| 253 | TELEMETRY_MESSAGE* msg_buf | ||
| 254 | ) | ||
| 255 | { | ||
| 256 | ✗ | msg_buf->payload.dashboard_dump.fsm_state = get_fc_state(); | |
| 257 | ✗ | dashboard_construct_dump( &(msg_buf->payload.dashboard_dump.data) ); | |
| 258 | |||
| 259 | ✗ | } /* telemetry_build_msg_dashboard_dump */ | |
| 260 |