Line data Source code
1 : /*------------------------------------------------------------------------------ 2 : -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW), 3 : -- This file is a part of the LFR FSW 4 : -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS 5 : -- 6 : -- This program is free software; you can redistribute it and/or modify 7 : -- it under the terms of the GNU General Public License as published by 8 : -- the Free Software Foundation; either version 2 of the License, or 9 : -- (at your option) any later version. 10 : -- 11 : -- This program is distributed in the hope that it will be useful, 12 : -- but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : -- GNU General Public License for more details. 15 : -- 16 : -- You should have received a copy of the GNU General Public License 17 : -- along with this program; if not, write to the Free Software 18 : -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 : -------------------------------------------------------------------------------*/ 20 : /*-- Author : Paul Leroy 21 : -- Contact : Alexis Jeandet 22 : -- Mail : alexis.jeandet@lpp.polytechnique.fr 23 : ----------------------------------------------------------------------------*/ 24 : 25 : /** Functions to send TM packets related to TC parsing and execution. 26 : * 27 : * @file 28 : * @author P. LEROY 29 : * 30 : * A group of functions to send appropriate TM packets after parsing and execution: 31 : * - TM_LFR_TC_EXE_SUCCESS 32 : * - TM_LFR_TC_EXE_INCONSISTENT 33 : * - TM_LFR_TC_EXE_NOT_EXECUTABLE 34 : * - TM_LFR_TC_EXE_NOT_IMPLEMENTED 35 : * - TM_LFR_TC_EXE_ERROR 36 : * - TM_LFR_TC_EXE_CORRUPTED 37 : * 38 : */ 39 : 40 : #include "tc_tm/tm_lfr_tc_exe.h" 41 : #include "fsw_debug.h" 42 : #include "hw/lfr_regs.h" 43 : 44 85 : int send_tm_lfr_tc_exe_success(const ccsdsTelecommandPacket_t* const TC, rtems_id queue_id) 45 : { 46 : /** This function sends a TM_LFR_TC_EXE_SUCCESS packet in the dedicated RTEMS message queue. 47 : * 48 : * @param TC points to the TeleCommand packet that is being processed 49 : * @param queue_id is the id of the queue which handles TM 50 : * 51 : * @return RTEMS directive status code: 52 : * - RTEMS_SUCCESSFUL - message sent successfully 53 : * - RTEMS_INVALID_ID - invalid queue id 54 : * - RTEMS_INVALID_SIZE - invalid message size 55 : * - RTEMS_INVALID_ADDRESS - buffer is NULL 56 : * - RTEMS_UNSATISFIED - out of message buffers 57 : * - RTEMS_TOO_MANY - queue s limit has been reached 58 : * 59 : */ 60 : 61 : rtems_status_code status; 62 : Packet_TM_LFR_TC_EXE_SUCCESS_t TM; 63 : 64 85 : TM.targetLogicalAddress = CCSDS_DESTINATION_ID; 65 85 : TM.protocolIdentifier = CCSDS_PROTOCOLE_ID; 66 85 : TM.reserved = DEFAULT_RESERVED; 67 85 : TM.userApplication = CCSDS_USER_APP; 68 : // PACKET HEADER 69 85 : TM.packetID[0] = (unsigned char)(APID_TM_TC_EXE >> SHIFT_1_BYTE); 70 85 : TM.packetID[1] = (unsigned char)(APID_TM_TC_EXE); 71 85 : increment_seq_counter_destination_id(TM.packetSequenceControl, TC->sourceID); 72 85 : TM.packetLength[0] = (unsigned char)(PACKET_LENGTH_TC_EXE_SUCCESS >> SHIFT_1_BYTE); 73 85 : TM.packetLength[1] = (unsigned char)(PACKET_LENGTH_TC_EXE_SUCCESS); 74 : // DATA FIELD HEADER 75 85 : TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2; 76 85 : TM.serviceType = TM_TYPE_TC_EXE; 77 85 : TM.serviceSubType = TM_SUBTYPE_EXE_OK; 78 85 : TM.destinationID = TC->sourceID; 79 85 : TM.time[BYTE_0] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_3_BYTES); 80 85 : TM.time[BYTE_1] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_2_BYTES); 81 85 : TM.time[BYTE_2] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_1_BYTE); 82 85 : TM.time[BYTE_3] = (unsigned char)(time_management_regs->coarse_time); 83 85 : TM.time[BYTE_4] = (unsigned char)(time_management_regs->fine_time >> SHIFT_1_BYTE); 84 85 : TM.time[BYTE_5] = (unsigned char)(time_management_regs->fine_time); 85 : // 86 85 : TM.telecommand_pkt_id[0] = TC->packetID[0]; 87 85 : TM.telecommand_pkt_id[1] = TC->packetID[1]; 88 85 : TM.pkt_seq_control[0] = TC->packetSequenceControl[0]; 89 85 : TM.pkt_seq_control[1] = TC->packetSequenceControl[1]; 90 : 91 : // SEND DATA 92 85 : status = rtems_message_queue_send(queue_id, &TM, sizeof(TM)); 93 : DEBUG_CHECK_STATUS(status); 94 : 95 : // UPDATE HK FIELDS 96 85 : update_last_TC_exe(TC, TM.time); 97 : 98 85 : return status; 99 : } 100 : 101 0 : int send_tm_lfr_tc_exe_inconsistent(const ccsdsTelecommandPacket_t* const TC, rtems_id queue_id, 102 : unsigned char byte_position, unsigned char rcv_value) 103 : { 104 : /** This function sends a TM_LFR_TC_EXE_INCONSISTENT packet in the dedicated RTEMS message 105 : * queue. 106 : * 107 : * @param TC points to the TeleCommand packet that is being processed 108 : * @param queue_id is the id of the queue which handles TM 109 : * @param byte_position is the byte position of the MSB of the parameter that has been seen as 110 : * inconsistent 111 : * @param rcv_value is the value of the LSB of the parameter that has been detected as 112 : * inconsistent 113 : * 114 : * @return RTEMS directive status code: 115 : * - RTEMS_SUCCESSFUL - message sent successfully 116 : * - RTEMS_INVALID_ID - invalid queue id 117 : * - RTEMS_INVALID_SIZE - invalid message size 118 : * - RTEMS_INVALID_ADDRESS - buffer is NULL 119 : * - RTEMS_UNSATISFIED - out of message buffers 120 : * - RTEMS_TOO_MANY - queue s limit has been reached 121 : * 122 : */ 123 : 124 : rtems_status_code status; 125 : Packet_TM_LFR_TC_EXE_INCONSISTENT_t TM; 126 : 127 0 : TM.targetLogicalAddress = CCSDS_DESTINATION_ID; 128 0 : TM.protocolIdentifier = CCSDS_PROTOCOLE_ID; 129 0 : TM.reserved = DEFAULT_RESERVED; 130 0 : TM.userApplication = CCSDS_USER_APP; 131 : // PACKET HEADER 132 0 : TM.packetID[0] = (unsigned char)(APID_TM_TC_EXE >> SHIFT_1_BYTE); 133 0 : TM.packetID[1] = (unsigned char)(APID_TM_TC_EXE); 134 0 : increment_seq_counter_destination_id(TM.packetSequenceControl, TC->sourceID); 135 0 : TM.packetLength[0] = (unsigned char)(PACKET_LENGTH_TC_EXE_INCONSISTENT >> SHIFT_1_BYTE); 136 0 : TM.packetLength[1] = (unsigned char)(PACKET_LENGTH_TC_EXE_INCONSISTENT); 137 : // DATA FIELD HEADER 138 0 : TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2; 139 0 : TM.serviceType = TM_TYPE_TC_EXE; 140 0 : TM.serviceSubType = TM_SUBTYPE_EXE_NOK; 141 0 : TM.destinationID = TC->sourceID; 142 0 : TM.time[BYTE_0] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_3_BYTES); 143 0 : TM.time[BYTE_1] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_2_BYTES); 144 0 : TM.time[BYTE_2] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_1_BYTE); 145 0 : TM.time[BYTE_3] = (unsigned char)(time_management_regs->coarse_time); 146 0 : TM.time[BYTE_4] = (unsigned char)(time_management_regs->fine_time >> SHIFT_1_BYTE); 147 0 : TM.time[BYTE_5] = (unsigned char)(time_management_regs->fine_time); 148 : // 149 0 : TM.tc_failure_code[0] = (char)(WRONG_APP_DATA >> SHIFT_1_BYTE); 150 0 : TM.tc_failure_code[1] = (char)(WRONG_APP_DATA); 151 0 : TM.telecommand_pkt_id[0] = TC->packetID[0]; 152 0 : TM.telecommand_pkt_id[1] = TC->packetID[1]; 153 0 : TM.pkt_seq_control[0] = TC->packetSequenceControl[0]; 154 0 : TM.pkt_seq_control[1] = TC->packetSequenceControl[1]; 155 0 : TM.tc_service = TC->serviceType; // type of the rejected TC 156 0 : TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC 157 0 : TM.byte_position = byte_position; 158 0 : TM.rcv_value = rcv_value; 159 : 160 : // SEND DATA 161 0 : status = rtems_message_queue_send(queue_id, &TM, sizeof(TM)); 162 : DEBUG_CHECK_STATUS(status); 163 : 164 : // UPDATE HK FIELDS 165 0 : update_last_TC_rej(TC, TM.time); 166 : 167 0 : return status; 168 : } 169 : 170 4 : int send_tm_lfr_tc_exe_not_executable(const ccsdsTelecommandPacket_t* const TC, rtems_id queue_id) 171 : { 172 : /** This function sends a TM_LFR_TC_EXE_NOT_EXECUTABLE packet in the dedicated RTEMS message 173 : * queue. 174 : * 175 : * @param TC points to the TeleCommand packet that is being processed 176 : * @param queue_id is the id of the queue which handles TM 177 : * 178 : * @return RTEMS directive status code: 179 : * - RTEMS_SUCCESSFUL - message sent successfully 180 : * - RTEMS_INVALID_ID - invalid queue id 181 : * - RTEMS_INVALID_SIZE - invalid message size 182 : * - RTEMS_INVALID_ADDRESS - buffer is NULL 183 : * - RTEMS_UNSATISFIED - out of message buffers 184 : * - RTEMS_TOO_MANY - queue s limit has been reached 185 : * 186 : */ 187 : 188 : rtems_status_code status; 189 : Packet_TM_LFR_TC_EXE_NOT_EXECUTABLE_t TM; 190 : 191 4 : TM.targetLogicalAddress = CCSDS_DESTINATION_ID; 192 4 : TM.protocolIdentifier = CCSDS_PROTOCOLE_ID; 193 4 : TM.reserved = DEFAULT_RESERVED; 194 4 : TM.userApplication = CCSDS_USER_APP; 195 : // PACKET HEADER 196 4 : TM.packetID[0] = (unsigned char)(APID_TM_TC_EXE >> SHIFT_1_BYTE); 197 4 : TM.packetID[1] = (unsigned char)(APID_TM_TC_EXE); 198 4 : increment_seq_counter_destination_id(TM.packetSequenceControl, TC->sourceID); 199 4 : TM.packetLength[0] = (unsigned char)(PACKET_LENGTH_TC_EXE_NOT_EXECUTABLE >> SHIFT_1_BYTE); 200 4 : TM.packetLength[1] = (unsigned char)(PACKET_LENGTH_TC_EXE_NOT_EXECUTABLE); 201 : // DATA FIELD HEADER 202 4 : TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2; 203 4 : TM.serviceType = TM_TYPE_TC_EXE; 204 4 : TM.serviceSubType = TM_SUBTYPE_EXE_NOK; 205 4 : TM.destinationID = TC->sourceID; // default destination id 206 4 : TM.time[BYTE_0] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_3_BYTES); 207 4 : TM.time[BYTE_1] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_2_BYTES); 208 4 : TM.time[BYTE_2] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_1_BYTE); 209 4 : TM.time[BYTE_3] = (unsigned char)(time_management_regs->coarse_time); 210 4 : TM.time[BYTE_4] = (unsigned char)(time_management_regs->fine_time >> SHIFT_1_BYTE); 211 4 : TM.time[BYTE_5] = (unsigned char)(time_management_regs->fine_time); 212 : // 213 4 : TM.tc_failure_code[0] = (char)(TC_NOT_EXE >> SHIFT_1_BYTE); 214 4 : TM.tc_failure_code[1] = (char)(TC_NOT_EXE); 215 4 : TM.telecommand_pkt_id[0] = TC->packetID[0]; 216 4 : TM.telecommand_pkt_id[1] = TC->packetID[1]; 217 4 : TM.pkt_seq_control[0] = TC->packetSequenceControl[0]; 218 4 : TM.pkt_seq_control[1] = TC->packetSequenceControl[1]; 219 4 : TM.tc_service = TC->serviceType; // type of the rejected TC 220 4 : TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC 221 4 : TM.lfr_status_word[0] = housekeeping_packet.lfr_status_word[0]; 222 4 : TM.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1]; 223 : 224 : // SEND DATA 225 4 : status = rtems_message_queue_send(queue_id, &TM, sizeof(TM)); 226 : DEBUG_CHECK_STATUS(status); 227 : 228 : // UPDATE HK FIELDS 229 4 : update_last_TC_rej(TC, TM.time); 230 : 231 4 : return status; 232 : } 233 : 234 0 : int send_tm_lfr_tc_exe_error(const ccsdsTelecommandPacket_t* const TC, rtems_id queue_id) 235 : { 236 : /** This function sends a TM_LFR_TC_EXE_ERROR packet in the dedicated RTEMS message queue. 237 : * 238 : * @param TC points to the TeleCommand packet that is being processed 239 : * @param queue_id is the id of the queue which handles TM 240 : * 241 : * @return RTEMS directive status code: 242 : * - RTEMS_SUCCESSFUL - message sent successfully 243 : * - RTEMS_INVALID_ID - invalid queue id 244 : * - RTEMS_INVALID_SIZE - invalid message size 245 : * - RTEMS_INVALID_ADDRESS - buffer is NULL 246 : * - RTEMS_UNSATISFIED - out of message buffers 247 : * - RTEMS_TOO_MANY - queue s limit has been reached 248 : * 249 : */ 250 : 251 : rtems_status_code status; 252 : Packet_TM_LFR_TC_EXE_ERROR_t TM; 253 : 254 0 : TM.targetLogicalAddress = CCSDS_DESTINATION_ID; 255 0 : TM.protocolIdentifier = CCSDS_PROTOCOLE_ID; 256 0 : TM.reserved = DEFAULT_RESERVED; 257 0 : TM.userApplication = CCSDS_USER_APP; 258 : // PACKET HEADER 259 0 : TM.packetID[0] = (unsigned char)(APID_TM_TC_EXE >> SHIFT_1_BYTE); 260 0 : TM.packetID[1] = (unsigned char)(APID_TM_TC_EXE); 261 0 : increment_seq_counter_destination_id(TM.packetSequenceControl, TC->sourceID); 262 0 : TM.packetLength[0] = (unsigned char)(PACKET_LENGTH_TC_EXE_ERROR >> SHIFT_1_BYTE); 263 0 : TM.packetLength[1] = (unsigned char)(PACKET_LENGTH_TC_EXE_ERROR); 264 : // DATA FIELD HEADER 265 0 : TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2; 266 0 : TM.serviceType = TM_TYPE_TC_EXE; 267 0 : TM.serviceSubType = TM_SUBTYPE_EXE_NOK; 268 0 : TM.destinationID = TC->sourceID; // default destination id 269 0 : TM.time[BYTE_0] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_3_BYTES); 270 0 : TM.time[BYTE_1] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_2_BYTES); 271 0 : TM.time[BYTE_2] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_1_BYTE); 272 0 : TM.time[BYTE_3] = (unsigned char)(time_management_regs->coarse_time); 273 0 : TM.time[BYTE_4] = (unsigned char)(time_management_regs->fine_time >> SHIFT_1_BYTE); 274 0 : TM.time[BYTE_5] = (unsigned char)(time_management_regs->fine_time); 275 : // 276 0 : TM.tc_failure_code[0] = (char)(FAIL_DETECTED >> SHIFT_1_BYTE); 277 0 : TM.tc_failure_code[1] = (char)(FAIL_DETECTED); 278 0 : TM.telecommand_pkt_id[0] = TC->packetID[0]; 279 0 : TM.telecommand_pkt_id[1] = TC->packetID[1]; 280 0 : TM.pkt_seq_control[0] = TC->packetSequenceControl[0]; 281 0 : TM.pkt_seq_control[1] = TC->packetSequenceControl[1]; 282 0 : TM.tc_service = TC->serviceType; // type of the rejected TC 283 0 : TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC 284 : 285 : // SEND DATA 286 0 : status = rtems_message_queue_send(queue_id, &TM, sizeof(TM)); 287 : DEBUG_CHECK_STATUS(status); 288 : 289 : // UPDATE HK FIELDS 290 0 : update_last_TC_rej(TC, TM.time); 291 : 292 0 : return status; 293 : } 294 : 295 0 : int send_tm_lfr_tc_exe_corrupted(const ccsdsTelecommandPacket_t* const TC, rtems_id queue_id, 296 : const unsigned char* const computed_CRC, const unsigned char* const currentTC_LEN_RCV, 297 : unsigned char destinationID) 298 : { 299 : /** This function sends a TM_LFR_TC_EXE_CORRUPTED packet in the dedicated RTEMS message queue. 300 : * 301 : * @param TC points to the TeleCommand packet that is being processed 302 : * @param queue_id is the id of the queue which handles TM 303 : * @param computed_CRC points to a buffer of two bytes containing the CRC computed during the 304 : * parsing of the TeleCommand 305 : * @param currentTC_LEN_RCV points to a buffer of two bytes containing a packet size field 306 : * computed on the received data 307 : * 308 : * @return RTEMS directive status code: 309 : * - RTEMS_SUCCESSFUL - message sent successfully 310 : * - RTEMS_INVALID_ID - invalid queue id 311 : * - RTEMS_INVALID_SIZE - invalid message size 312 : * - RTEMS_INVALID_ADDRESS - buffer is NULL 313 : * - RTEMS_UNSATISFIED - out of message buffers 314 : * - RTEMS_TOO_MANY - queue s limit has been reached 315 : * 316 : */ 317 : 318 : rtems_status_code status; 319 : Packet_TM_LFR_TC_EXE_CORRUPTED_t TM; 320 : 321 : unsigned int estimatedPacketLength 322 0 : = (unsigned int)((currentTC_LEN_RCV[0] * CONST_256) + currentTC_LEN_RCV[1]); 323 : const unsigned char* const packetDataField 324 0 : = &TC->headerFlag_pusVersion_Ack; // get the beginning of the data field 325 : 326 : 327 0 : TM.targetLogicalAddress = CCSDS_DESTINATION_ID; 328 0 : TM.protocolIdentifier = CCSDS_PROTOCOLE_ID; 329 0 : TM.reserved = DEFAULT_RESERVED; 330 0 : TM.userApplication = CCSDS_USER_APP; 331 : // PACKET HEADER 332 0 : TM.packetID[0] = (unsigned char)(APID_TM_TC_EXE >> SHIFT_1_BYTE); 333 0 : TM.packetID[1] = (unsigned char)(APID_TM_TC_EXE); 334 0 : increment_seq_counter_destination_id(TM.packetSequenceControl, TC->sourceID); 335 0 : TM.packetLength[0] = (unsigned char)(PACKET_LENGTH_TC_EXE_CORRUPTED >> SHIFT_1_BYTE); 336 0 : TM.packetLength[1] = (unsigned char)(PACKET_LENGTH_TC_EXE_CORRUPTED); 337 : // DATA FIELD HEADER 338 0 : TM.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2; 339 0 : TM.serviceType = TM_TYPE_TC_EXE; 340 0 : TM.serviceSubType = TM_SUBTYPE_EXE_NOK; 341 0 : TM.destinationID = destinationID; 342 0 : TM.time[BYTE_0] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_3_BYTES); 343 0 : TM.time[BYTE_1] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_2_BYTES); 344 0 : TM.time[BYTE_2] = (unsigned char)(time_management_regs->coarse_time >> SHIFT_1_BYTE); 345 0 : TM.time[BYTE_3] = (unsigned char)(time_management_regs->coarse_time); 346 0 : TM.time[BYTE_4] = (unsigned char)(time_management_regs->fine_time >> SHIFT_1_BYTE); 347 0 : TM.time[BYTE_5] = (unsigned char)(time_management_regs->fine_time); 348 : // 349 0 : TM.tc_failure_code[0] = (unsigned char)(CORRUPTED >> SHIFT_1_BYTE); 350 0 : TM.tc_failure_code[1] = (unsigned char)(CORRUPTED); 351 0 : TM.telecommand_pkt_id[0] = TC->packetID[0]; 352 0 : TM.telecommand_pkt_id[1] = TC->packetID[1]; 353 0 : TM.pkt_seq_control[0] = TC->packetSequenceControl[0]; 354 0 : TM.pkt_seq_control[1] = TC->packetSequenceControl[1]; 355 0 : TM.tc_service = TC->serviceType; // type of the rejected TC 356 0 : TM.tc_subtype = TC->serviceSubType; // subtype of the rejected TC 357 0 : TM.pkt_len_rcv_value[0] = TC->packetLength[0]; 358 0 : TM.pkt_len_rcv_value[1] = TC->packetLength[1]; 359 0 : TM.pkt_datafieldsize_cnt[0] = currentTC_LEN_RCV[0]; 360 0 : TM.pkt_datafieldsize_cnt[1] = currentTC_LEN_RCV[1]; 361 0 : TM.rcv_crc[0] = packetDataField[estimatedPacketLength - 1]; 362 0 : TM.rcv_crc[1] = packetDataField[estimatedPacketLength]; 363 0 : TM.computed_crc[0] = computed_CRC[0]; 364 0 : TM.computed_crc[1] = computed_CRC[1]; 365 : 366 : // SEND DATA 367 0 : status = rtems_message_queue_send(queue_id, &TM, sizeof(TM)); 368 : DEBUG_CHECK_STATUS(status); 369 : 370 : // UPDATE HK FIELDS 371 0 : update_last_TC_rej(TC, TM.time); 372 : 373 0 : return status; 374 : } 375 : 376 89 : void increment_seq_counter_destination_id( 377 : unsigned char* packet_sequence_control, unsigned char destination_id) 378 : { 379 : /** This function increment the packet sequence control parameter of a TC, depending on its 380 : * destination ID. 381 : * 382 : * @param packet_sequence_control points to the packet sequence control which will be 383 : * incremented 384 : * @param destination_id is the destination ID of the TM, there is one counter by destination ID 385 : * 386 : * If the destination ID is not known, a dedicated counter is incremented. 387 : * 388 : */ 389 : 390 : unsigned short sequence_cnt; 391 : unsigned short segmentation_grouping_flag; 392 : unsigned short new_packet_sequence_control; 393 : unsigned char i; 394 : 395 89 : switch (destination_id) 396 : { 397 : case SID_TC_GROUND: 398 0 : i = GROUND; 399 0 : break; 400 : case SID_TC_MISSION_TIMELINE: 401 89 : i = MISSION_TIMELINE; 402 89 : break; 403 : case SID_TC_TC_SEQUENCES: 404 0 : i = TC_SEQUENCES; 405 0 : break; 406 : case SID_TC_RECOVERY_ACTION_CMD: 407 0 : i = RECOVERY_ACTION_CMD; 408 0 : break; 409 : case SID_TC_BACKUP_MISSION_TIMELINE: 410 0 : i = BACKUP_MISSION_TIMELINE; 411 0 : break; 412 : case SID_TC_DIRECT_CMD: 413 0 : i = DIRECT_CMD; 414 0 : break; 415 : case SID_TC_SPARE_GRD_SRC1: 416 0 : i = SPARE_GRD_SRC1; 417 0 : break; 418 : case SID_TC_SPARE_GRD_SRC2: 419 0 : i = SPARE_GRD_SRC2; 420 0 : break; 421 : case SID_TC_OBCP: 422 0 : i = OBCP; 423 0 : break; 424 : case SID_TC_SYSTEM_CONTROL: 425 0 : i = SYSTEM_CONTROL; 426 0 : break; 427 : case SID_TC_AOCS: 428 0 : i = AOCS; 429 0 : break; 430 : case SID_TC_RPW_INTERNAL: 431 0 : i = RPW_INTERNAL; 432 0 : break; 433 : default: 434 0 : i = GROUND; 435 : break; 436 : } 437 : 438 89 : segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << SHIFT_1_BYTE; 439 89 : sequence_cnt = sequenceCounters_TC_EXE[i] & SEQ_CNT_MASK; 440 : 441 89 : new_packet_sequence_control = segmentation_grouping_flag | sequence_cnt; 442 : 443 89 : packet_sequence_control[0] = (unsigned char)(new_packet_sequence_control >> SHIFT_1_BYTE); 444 89 : packet_sequence_control[1] = (unsigned char)(new_packet_sequence_control); 445 : 446 : // increment the sequence counter 447 89 : if (sequenceCounters_TC_EXE[i] < SEQ_CNT_MAX) 448 : { 449 89 : sequenceCounters_TC_EXE[i] = sequenceCounters_TC_EXE[i] + 1; 450 : } 451 : else 452 : { 453 0 : sequenceCounters_TC_EXE[i] = 0; 454 : } 455 89 : }