##// END OF EJS Templates
TC_LFR_LOAD_PAS_FILTER_PAR added to the authorized telecommands...
paul -
r282:a83f8aeb97a8 R3_plus
parent child
Show More
@@ -1,2 +1,2
1 1 3081d1f9bb20b2b64a192585337a292a9804e0c5 LFR_basic-parameters
2 1f3d7ce688e982a378d739596c8e3f8972f40b9d header/lfr_common_headers
2 c3197ff831df5057bdd145a4efd94ded0618661f header/lfr_common_headers
@@ -1,124 +1,124
1 1 TEMPLATE = app
2 2 # CONFIG += console v8 sim
3 3 # CONFIG options =
4 4 # verbose
5 5 # boot_messages
6 6 # debug_messages
7 7 # cpu_usage_report
8 8 # stack_report
9 9 # vhdl_dev
10 10 # debug_tch
11 11 # lpp_dpu_destid /!\ REMOVE BEFORE DELIVERY TO LESIA /!\
12 12 # debug_watchdog
13 13 CONFIG += console verbose lpp_dpu_destid
14 14 CONFIG -= qt
15 15
16 16 include(./sparc.pri)
17 17
18 18 # flight software version
19 19 SWVERSION=-1-0
20 20 DEFINES += SW_VERSION_N1=3 # major
21 DEFINES += SW_VERSION_N2=0 # minor
21 DEFINES += SW_VERSION_N2=1 # minor
22 22 DEFINES += SW_VERSION_N3=0 # patch
23 DEFINES += SW_VERSION_N4=22 # internal
23 DEFINES += SW_VERSION_N4=0 # internal
24 24
25 25 # <GCOV>
26 26 #QMAKE_CFLAGS_RELEASE += -fprofile-arcs -ftest-coverage
27 27 #LIBS += -lgcov /opt/GCOV/01A/lib/overload.o -lc
28 28 # </GCOV>
29 29
30 30 # <CHANGE BEFORE FLIGHT>
31 31 contains( CONFIG, lpp_dpu_destid ) {
32 32 DEFINES += LPP_DPU_DESTID
33 33 }
34 34 # </CHANGE BEFORE FLIGHT>
35 35
36 36 contains( CONFIG, debug_tch ) {
37 37 DEFINES += DEBUG_TCH
38 38 }
39 39 DEFINES += MSB_FIRST_TCH
40 40
41 41 contains( CONFIG, vhdl_dev ) {
42 42 DEFINES += VHDL_DEV
43 43 }
44 44
45 45 contains( CONFIG, verbose ) {
46 46 DEFINES += PRINT_MESSAGES_ON_CONSOLE
47 47 }
48 48
49 49 contains( CONFIG, debug_messages ) {
50 50 DEFINES += DEBUG_MESSAGES
51 51 }
52 52
53 53 contains( CONFIG, cpu_usage_report ) {
54 54 DEFINES += PRINT_TASK_STATISTICS
55 55 }
56 56
57 57 contains( CONFIG, stack_report ) {
58 58 DEFINES += PRINT_STACK_REPORT
59 59 }
60 60
61 61 contains( CONFIG, boot_messages ) {
62 62 DEFINES += BOOT_MESSAGES
63 63 }
64 64
65 65 contains( CONFIG, debug_watchdog ) {
66 66 DEFINES += DEBUG_WATCHDOG
67 67 }
68 68
69 69 #doxygen.target = doxygen
70 70 #doxygen.commands = doxygen ../doc/Doxyfile
71 71 #QMAKE_EXTRA_TARGETS += doxygen
72 72
73 73 TARGET = fsw
74 74
75 75 INCLUDEPATH += \
76 76 $${PWD}/../src \
77 77 $${PWD}/../header \
78 78 $${PWD}/../header/lfr_common_headers \
79 79 $${PWD}/../header/processing \
80 80 $${PWD}/../LFR_basic-parameters
81 81
82 82 SOURCES += \
83 83 ../src/wf_handler.c \
84 84 ../src/tc_handler.c \
85 85 ../src/fsw_misc.c \
86 86 ../src/fsw_init.c \
87 87 ../src/fsw_globals.c \
88 88 ../src/fsw_spacewire.c \
89 89 ../src/tc_load_dump_parameters.c \
90 90 ../src/tm_lfr_tc_exe.c \
91 91 ../src/tc_acceptance.c \
92 92 ../src/processing/fsw_processing.c \
93 93 ../src/processing/avf0_prc0.c \
94 94 ../src/processing/avf1_prc1.c \
95 95 ../src/processing/avf2_prc2.c \
96 96 ../src/lfr_cpu_usage_report.c \
97 97 ../LFR_basic-parameters/basic_parameters.c
98 98
99 99 HEADERS += \
100 100 ../header/wf_handler.h \
101 101 ../header/tc_handler.h \
102 102 ../header/grlib_regs.h \
103 103 ../header/fsw_misc.h \
104 104 ../header/fsw_init.h \
105 105 ../header/fsw_spacewire.h \
106 106 ../header/tc_load_dump_parameters.h \
107 107 ../header/tm_lfr_tc_exe.h \
108 108 ../header/tc_acceptance.h \
109 109 ../header/processing/fsw_processing.h \
110 110 ../header/processing/avf0_prc0.h \
111 111 ../header/processing/avf1_prc1.h \
112 112 ../header/processing/avf2_prc2.h \
113 113 ../header/fsw_params_wf_handler.h \
114 114 ../header/lfr_cpu_usage_report.h \
115 115 ../header/lfr_common_headers/ccsds_types.h \
116 116 ../header/lfr_common_headers/fsw_params.h \
117 117 ../header/lfr_common_headers/fsw_params_nb_bytes.h \
118 118 ../header/lfr_common_headers/fsw_params_processing.h \
119 119 ../header/lfr_common_headers/TC_types.h \
120 120 ../header/lfr_common_headers/tm_byte_positions.h \
121 121 ../LFR_basic-parameters/basic_parameters.h \
122 122 ../LFR_basic-parameters/basic_parameters_params.h \
123 123 ../header/GscMemoryLPP.hpp
124 124
@@ -1,72 +1,76
1 1 #ifndef TC_LOAD_DUMP_PARAMETERS_H
2 2 #define TC_LOAD_DUMP_PARAMETERS_H
3 3
4 4 #include <rtems.h>
5 5 #include <stdio.h>
6 6
7 7 #include "fsw_params.h"
8 8 #include "wf_handler.h"
9 9 #include "tm_lfr_tc_exe.h"
10 10 #include "fsw_misc.h"
11 11 #include "basic_parameters_params.h"
12 12 #include "avf0_prc0.h"
13 13
14 14 #define FLOAT_EQUAL_ZERO 0.001
15 15
16 16 extern unsigned short sequenceCounterParameterDump;
17 17 extern unsigned short sequenceCounters_TM_DUMP[];
18 18 extern float k_coeff_intercalib_f0_norm[ ];
19 19 extern float k_coeff_intercalib_f0_sbm[ ];
20 20 extern float k_coeff_intercalib_f1_norm[ ];
21 21 extern float k_coeff_intercalib_f1_sbm[ ];
22 22 extern float k_coeff_intercalib_f2[ ];
23 23
24 24 int action_load_common_par( ccsdsTelecommandPacket_t *TC );
25 25 int action_load_normal_par(ccsdsTelecommandPacket_t *TC, rtems_id queue_id , unsigned char *time);
26 26 int action_load_burst_par(ccsdsTelecommandPacket_t *TC, rtems_id queue_id , unsigned char *time);
27 27 int action_load_sbm1_par(ccsdsTelecommandPacket_t *TC, rtems_id queue_id , unsigned char *time);
28 28 int action_load_sbm2_par(ccsdsTelecommandPacket_t *TC, rtems_id queue_id , unsigned char *time);
29 29 int action_load_kcoefficients(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time);
30 30 int action_load_fbins_mask(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time);
31 int action_load_pas_filter_par(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time);
31 32 int action_dump_kcoefficients(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time);
32 33 int action_dump_par(ccsdsTelecommandPacket_t *TC, rtems_id queue_id );
33 34
34 35 // NORMAL
35 36 int check_normal_par_consistency( ccsdsTelecommandPacket_t *TC, rtems_id queue_id );
36 37 int set_sy_lfr_n_swf_l( ccsdsTelecommandPacket_t *TC );
37 38 int set_sy_lfr_n_swf_p( ccsdsTelecommandPacket_t *TC );
38 39 int set_sy_lfr_n_asm_p( ccsdsTelecommandPacket_t *TC );
39 40 int set_sy_lfr_n_bp_p0( ccsdsTelecommandPacket_t *TC );
40 41 int set_sy_lfr_n_bp_p1( ccsdsTelecommandPacket_t *TC );
41 42 int set_sy_lfr_n_cwf_long_f3( ccsdsTelecommandPacket_t *TC );
42 43
43 44 // BURST
44 45 int set_sy_lfr_b_bp_p0( ccsdsTelecommandPacket_t *TC );
45 46 int set_sy_lfr_b_bp_p1( ccsdsTelecommandPacket_t *TC );
46 47
47 48 // SBM1
48 49 int set_sy_lfr_s1_bp_p0( ccsdsTelecommandPacket_t *TC );
49 50 int set_sy_lfr_s1_bp_p1( ccsdsTelecommandPacket_t *TC );
50 51
51 52 // SBM2
52 53 int set_sy_lfr_s2_bp_p0( ccsdsTelecommandPacket_t *TC );
53 54 int set_sy_lfr_s2_bp_p1( ccsdsTelecommandPacket_t *TC );
54 55
55 56 // TC_LFR_UPDATE_INFO
56 57 unsigned int check_update_info_hk_lfr_mode( unsigned char mode );
57 58 unsigned int check_update_info_hk_tds_mode( unsigned char mode );
58 59 unsigned int check_update_info_hk_thr_mode( unsigned char mode );
59 60
60 61 // FBINS_MASK
61 62 int set_sy_lfr_fbins( ccsdsTelecommandPacket_t *TC );
62 63
64 // TC_LFR_LOAD_PARS_FILTER_PAR
65 int check_sy_lfr_pas_filter_parameters( ccsdsTelecommandPacket_t *TC, rtems_id queue_id );
66
63 67 // KCOEFFICIENTS
64 68 int set_sy_lfr_kcoeff(ccsdsTelecommandPacket_t *TC , rtems_id queue_id);
65 69 void copyFloatByChar( unsigned char *destination, unsigned char *source );
66 70
67 71 void init_parameter_dump( void );
68 72 void init_kcoefficients_dump( void );
69 73 void init_kcoefficients_dump_packet( Packet_TM_LFR_KCOEFFICIENTS_DUMP_t *kcoefficients_dump, unsigned char pkt_nr, unsigned char blk_nr );
70 74 void increment_seq_counter_destination_id_dump( unsigned char *packet_sequence_control, unsigned char destination_id );
71 75
72 76 #endif // TC_LOAD_DUMP_PARAMETERS_H
@@ -1,465 +1,474
1 1 /** Functions related to TeleCommand acceptance.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * A group of functions to handle TeleCommands parsing.\n
7 7 *
8 8 */
9 9
10 10 #include "tc_acceptance.h"
11 11 #include <stdio.h>
12 12
13 13 unsigned int lookUpTableForCRC[256];
14 14
15 15 //**********************
16 16 // GENERAL USE FUNCTIONS
17 17 unsigned int Crc_opt( unsigned char D, unsigned int Chk)
18 18 {
19 19 /** This function generate the CRC for one byte and returns the value of the new syndrome.
20 20 *
21 21 * @param D is the current byte of data.
22 22 * @param Chk is the current syndrom value.
23 23 *
24 24 * @return the value of the new syndrome on two bytes.
25 25 *
26 26 */
27 27
28 28 return(((Chk << 8) & 0xff00)^lookUpTableForCRC [(((Chk >> 8)^D) & 0x00ff)]);
29 29 }
30 30
31 31 void initLookUpTableForCRC( void )
32 32 {
33 33 /** This function is used to initiates the look-up table for fast CRC computation.
34 34 *
35 35 * The global table lookUpTableForCRC[256] is initiated.
36 36 *
37 37 */
38 38
39 39 unsigned int i;
40 40 unsigned int tmp;
41 41
42 42 for (i=0; i<256; i++)
43 43 {
44 44 tmp = 0;
45 45 if((i & 1) != 0) {
46 46 tmp = tmp ^ 0x1021;
47 47 }
48 48 if((i & 2) != 0) {
49 49 tmp = tmp ^ 0x2042;
50 50 }
51 51 if((i & 4) != 0) {
52 52 tmp = tmp ^ 0x4084;
53 53 }
54 54 if((i & 8) != 0) {
55 55 tmp = tmp ^ 0x8108;
56 56 }
57 57 if((i & 16) != 0) {
58 58 tmp = tmp ^ 0x1231;
59 59 }
60 60 if((i & 32) != 0) {
61 61 tmp = tmp ^ 0x2462;
62 62 }
63 63 if((i & 64) != 0) {
64 64 tmp = tmp ^ 0x48c4;
65 65 }
66 66 if((i & 128) != 0) {
67 67 tmp = tmp ^ 0x9188;
68 68 }
69 69 lookUpTableForCRC[i] = tmp;
70 70 }
71 71 }
72 72
73 73 void GetCRCAsTwoBytes(unsigned char* data, unsigned char* crcAsTwoBytes, unsigned int sizeOfData)
74 74 {
75 75 /** This function calculates a two bytes Cyclic Redundancy Code.
76 76 *
77 77 * @param data points to a buffer containing the data on which to compute the CRC.
78 78 * @param crcAsTwoBytes points points to a two bytes buffer in which the CRC is stored.
79 79 * @param sizeOfData is the number of bytes of *data* used to compute the CRC.
80 80 *
81 81 * The specification of the Cyclic Redundancy Code is described in the following document: ECSS-E-70-41-A.
82 82 *
83 83 */
84 84
85 85 unsigned int Chk;
86 86 int j;
87 87 Chk = 0xffff; // reset the syndrom to all ones
88 88 for (j=0; j<sizeOfData; j++) {
89 89 Chk = Crc_opt(data[j], Chk);
90 90 }
91 91 crcAsTwoBytes[0] = (unsigned char) (Chk >> 8);
92 92 crcAsTwoBytes[1] = (unsigned char) (Chk & 0x00ff);
93 93 }
94 94
95 95 //*********************
96 96 // ACCEPTANCE FUNCTIONS
97 97 int tc_parser(ccsdsTelecommandPacket_t * TCPacket, unsigned int estimatedPacketLength, unsigned char *computed_CRC)
98 98 {
99 99 /** This function parses TeleCommands.
100 100 *
101 101 * @param TC points to the TeleCommand that will be parsed.
102 102 * @param estimatedPacketLength is the PACKET_LENGTH field calculated from the effective length of the received packet.
103 103 *
104 104 * @return Status code of the parsing.
105 105 *
106 106 * The parsing checks:
107 107 * - process id
108 108 * - category
109 109 * - length: a global check is performed and a per subtype check also
110 110 * - type
111 111 * - subtype
112 112 * - crc
113 113 *
114 114 */
115 115
116 116 int status;
117 117 int status_crc;
118 118 unsigned char pid;
119 119 unsigned char category;
120 120 unsigned int packetLength;
121 121 unsigned char packetType;
122 122 unsigned char packetSubtype;
123 123 unsigned char sid;
124 124
125 125 status = CCSDS_TM_VALID;
126 126
127 127 // APID check *** APID on 2 bytes
128 128 pid = ((TCPacket->packetID[0] & 0x07)<<4) + ( (TCPacket->packetID[1]>>4) & 0x0f ); // PID = 11 *** 7 bits xxxxx210 7654xxxx
129 129 category = (TCPacket->packetID[1] & 0x0f); // PACKET_CATEGORY = 12 *** 4 bits xxxxxxxx xxxx3210
130 130 packetLength = (TCPacket->packetLength[0] * 256) + TCPacket->packetLength[1];
131 131 packetType = TCPacket->serviceType;
132 132 packetSubtype = TCPacket->serviceSubType;
133 133 sid = TCPacket->sourceID;
134 134
135 135 if ( pid != CCSDS_PROCESS_ID ) // CHECK THE PROCESS ID
136 136 {
137 137 status = ILLEGAL_APID;
138 138 }
139 139 if (status == CCSDS_TM_VALID) // CHECK THE CATEGORY
140 140 {
141 141 if ( category != CCSDS_PACKET_CATEGORY )
142 142 {
143 143 status = ILLEGAL_APID;
144 144 }
145 145 }
146 146 if (status == CCSDS_TM_VALID) // CHECK THE PACKET_LENGTH FIELD AND THE ESTIMATED PACKET_LENGTH COMPLIANCE
147 147 {
148 148 if (packetLength != estimatedPacketLength ) {
149 149 status = WRONG_LEN_PKT;
150 150 }
151 151 }
152 152 if (status == CCSDS_TM_VALID) // CHECK THAT THE PACKET DOES NOT EXCEED THE MAX SIZE
153 153 {
154 154 if ( packetLength >= CCSDS_TC_PKT_MAX_SIZE ) {
155 155 status = WRONG_LEN_PKT;
156 156 }
157 157 }
158 158 if (status == CCSDS_TM_VALID) // CHECK THE TYPE
159 159 {
160 160 status = tc_check_type( packetType );
161 161 }
162 162 if (status == CCSDS_TM_VALID) // CHECK THE SUBTYPE
163 163 {
164 164 status = tc_check_type_subtype( packetType, packetSubtype );
165 165 }
166 166 if (status == CCSDS_TM_VALID) // CHECK THE SID
167 167 {
168 168 status = tc_check_sid( sid );
169 169 }
170 170 if (status == CCSDS_TM_VALID) // CHECK THE SUBTYPE AND LENGTH COMPLIANCE
171 171 {
172 172 status = tc_check_length( packetSubtype, packetLength );
173 173 }
174 174 status_crc = tc_check_crc( TCPacket, estimatedPacketLength, computed_CRC );
175 175 if (status == CCSDS_TM_VALID ) // CHECK CRC
176 176 {
177 177 status = status_crc;
178 178 }
179 179
180 180 return status;
181 181 }
182 182
183 183 int tc_check_type( unsigned char packetType )
184 184 {
185 185 /** This function checks that the type of a TeleCommand is valid.
186 186 *
187 187 * @param packetType is the type to check.
188 188 *
189 189 * @return Status code CCSDS_TM_VALID or ILL_TYPE.
190 190 *
191 191 */
192 192
193 193 int status;
194 194
195 195 if ( (packetType == TC_TYPE_GEN) || (packetType == TC_TYPE_TIME))
196 196 {
197 197 status = CCSDS_TM_VALID;
198 198 }
199 199 else
200 200 {
201 201 status = ILL_TYPE;
202 202 }
203 203
204 204 return status;
205 205 }
206 206
207 207 int tc_check_type_subtype( unsigned char packetType, unsigned char packetSubType )
208 208 {
209 209 /** This function checks that the subtype of a TeleCommand is valid and coherent with the type.
210 210 *
211 211 * @param packetType is the type of the TC.
212 212 * @param packetSubType is the subtype to check.
213 213 *
214 214 * @return Status code CCSDS_TM_VALID or ILL_SUBTYPE.
215 215 *
216 216 */
217 217
218 218 int status;
219 219
220 220 switch(packetType)
221 221 {
222 222 case TC_TYPE_GEN:
223 223 if ( (packetSubType == TC_SUBTYPE_RESET)
224 224 || (packetSubType == TC_SUBTYPE_LOAD_COMM)
225 225 || (packetSubType == TC_SUBTYPE_LOAD_NORM) || (packetSubType == TC_SUBTYPE_LOAD_BURST)
226 226 || (packetSubType == TC_SUBTYPE_LOAD_SBM1) || (packetSubType == TC_SUBTYPE_LOAD_SBM2)
227 227 || (packetSubType == TC_SUBTYPE_DUMP)
228 228 || (packetSubType == TC_SUBTYPE_ENTER)
229 229 || (packetSubType == TC_SUBTYPE_UPDT_INFO)
230 230 || (packetSubType == TC_SUBTYPE_EN_CAL) || (packetSubType == TC_SUBTYPE_DIS_CAL)
231 231 || (packetSubType == TC_SUBTYPE_LOAD_K) || (packetSubType == TC_SUBTYPE_DUMP_K)
232 || (packetSubType == TC_SUBTYPE_LOAD_FBINS) )
232 || (packetSubType == TC_SUBTYPE_LOAD_FBINS)
233 || (packetSubType == TC_SUBTYPE_LOAD_PAS_FILTER_PAR))
233 234 {
234 235 status = CCSDS_TM_VALID;
235 236 }
236 237 else
237 238 {
238 239 status = ILL_SUBTYPE;
239 240 }
240 241 break;
241 242
242 243 case TC_TYPE_TIME:
243 244 if (packetSubType == TC_SUBTYPE_UPDT_TIME)
244 245 {
245 246 status = CCSDS_TM_VALID;
246 247 }
247 248 else
248 249 {
249 250 status = ILL_SUBTYPE;
250 251 }
251 252 break;
252 253
253 254 default:
254 255 status = ILL_SUBTYPE;
255 256 break;
256 257 }
257 258
258 259 return status;
259 260 }
260 261
261 262 int tc_check_sid( unsigned char sid )
262 263 {
263 264 /** This function checks that the sid of a TeleCommand is valid.
264 265 *
265 266 * @param sid is the sid to check.
266 267 *
267 268 * @return Status code CCSDS_TM_VALID or CORRUPTED.
268 269 *
269 270 */
270 271
271 272 int status;
272 273
273 274 if ( (sid == SID_TC_MISSION_TIMELINE) || (sid == SID_TC_TC_SEQUENCES) || (sid == SID_TC_RECOVERY_ACTION_CMD)
274 275 || (sid == SID_TC_BACKUP_MISSION_TIMELINE)
275 276 || (sid == SID_TC_DIRECT_CMD) || (sid == SID_TC_SPARE_GRD_SRC1) || (sid == SID_TC_SPARE_GRD_SRC2)
276 277 || (sid == SID_TC_OBCP) || (sid == SID_TC_SYSTEM_CONTROL) || (sid == SID_TC_AOCS)
277 278 || (sid == SID_TC_RPW_INTERNAL))
278 279 {
279 280 status = CCSDS_TM_VALID;
280 281 }
281 282 else
282 283 {
283 284 status = WRONG_SRC_ID;
284 285 }
285 286
286 287 return status;
287 288 }
288 289
289 290 int tc_check_length( unsigned char packetSubType, unsigned int length )
290 291 {
291 292 /** This function checks that the subtype and the length are compliant.
292 293 *
293 294 * @param packetSubType is the subtype to check.
294 295 * @param length is the length to check.
295 296 *
296 297 * @return Status code CCSDS_TM_VALID or ILL_TYPE.
297 298 *
298 299 */
299 300
300 301 int status;
301 302
302 303 status = LFR_SUCCESSFUL;
303 304
304 305 switch(packetSubType)
305 306 {
306 307 case TC_SUBTYPE_RESET:
307 308 if (length!=(TC_LEN_RESET-CCSDS_TC_TM_PACKET_OFFSET)) {
308 309 status = WRONG_LEN_PKT;
309 310 }
310 311 else {
311 312 status = CCSDS_TM_VALID;
312 313 }
313 314 break;
314 315 case TC_SUBTYPE_LOAD_COMM:
315 316 if (length!=(TC_LEN_LOAD_COMM-CCSDS_TC_TM_PACKET_OFFSET)) {
316 317 status = WRONG_LEN_PKT;
317 318 }
318 319 else {
319 320 status = CCSDS_TM_VALID;
320 321 }
321 322 break;
322 323 case TC_SUBTYPE_LOAD_NORM:
323 324 if (length!=(TC_LEN_LOAD_NORM-CCSDS_TC_TM_PACKET_OFFSET)) {
324 325 status = WRONG_LEN_PKT;
325 326 }
326 327 else {
327 328 status = CCSDS_TM_VALID;
328 329 }
329 330 break;
330 331 case TC_SUBTYPE_LOAD_BURST:
331 332 if (length!=(TC_LEN_LOAD_BURST-CCSDS_TC_TM_PACKET_OFFSET)) {
332 333 status = WRONG_LEN_PKT;
333 334 }
334 335 else {
335 336 status = CCSDS_TM_VALID;
336 337 }
337 338 break;
338 339 case TC_SUBTYPE_LOAD_SBM1:
339 340 if (length!=(TC_LEN_LOAD_SBM1-CCSDS_TC_TM_PACKET_OFFSET)) {
340 341 status = WRONG_LEN_PKT;
341 342 }
342 343 else {
343 344 status = CCSDS_TM_VALID;
344 345 }
345 346 break;
346 347 case TC_SUBTYPE_LOAD_SBM2:
347 348 if (length!=(TC_LEN_LOAD_SBM2-CCSDS_TC_TM_PACKET_OFFSET)) {
348 349 status = WRONG_LEN_PKT;
349 350 }
350 351 else {
351 352 status = CCSDS_TM_VALID;
352 353 }
353 354 break;
354 355 case TC_SUBTYPE_DUMP:
355 356 if (length!=(TC_LEN_DUMP-CCSDS_TC_TM_PACKET_OFFSET)) {
356 357 status = WRONG_LEN_PKT;
357 358 }
358 359 else {
359 360 status = CCSDS_TM_VALID;
360 361 }
361 362 break;
362 363 case TC_SUBTYPE_ENTER:
363 364 if (length!=(TC_LEN_ENTER-CCSDS_TC_TM_PACKET_OFFSET)) {
364 365 status = WRONG_LEN_PKT;
365 366 }
366 367 else {
367 368 status = CCSDS_TM_VALID;
368 369 }
369 370 break;
370 371 case TC_SUBTYPE_UPDT_INFO:
371 372 if (length!=(TC_LEN_UPDT_INFO-CCSDS_TC_TM_PACKET_OFFSET)) {
372 373 status = WRONG_LEN_PKT;
373 374 }
374 375 else {
375 376 status = CCSDS_TM_VALID;
376 377 }
377 378 break;
378 379 case TC_SUBTYPE_EN_CAL:
379 380 if (length!=(TC_LEN_EN_CAL-CCSDS_TC_TM_PACKET_OFFSET)) {
380 381 status = WRONG_LEN_PKT;
381 382 }
382 383 else {
383 384 status = CCSDS_TM_VALID;
384 385 }
385 386 break;
386 387 case TC_SUBTYPE_DIS_CAL:
387 388 if (length!=(TC_LEN_DIS_CAL-CCSDS_TC_TM_PACKET_OFFSET)) {
388 389 status = WRONG_LEN_PKT;
389 390 }
390 391 else {
391 392 status = CCSDS_TM_VALID;
392 393 }
393 394 break;
394 395 case TC_SUBTYPE_LOAD_K:
395 396 if (length!=(TC_LEN_LOAD_K-CCSDS_TC_TM_PACKET_OFFSET)) {
396 397 status = WRONG_LEN_PKT;
397 398 }
398 399 else {
399 400 status = CCSDS_TM_VALID;
400 401 }
401 402 break;
402 403 case TC_SUBTYPE_DUMP_K:
403 404 if (length!=(TC_LEN_DUMP_K-CCSDS_TC_TM_PACKET_OFFSET)) {
404 405 status = WRONG_LEN_PKT;
405 406 }
406 407 else {
407 408 status = CCSDS_TM_VALID;
408 409 }
409 410 break;
410 411 case TC_SUBTYPE_LOAD_FBINS:
411 412 if (length!=(TC_LEN_LOAD_FBINS-CCSDS_TC_TM_PACKET_OFFSET)) {
412 413 status = WRONG_LEN_PKT;
413 414 }
414 415 else {
415 416 status = CCSDS_TM_VALID;
416 417 }
417 418 break;
419 case TC_SUBTYPE_LOAD_PAS_FILTER_PAR:
420 if (length!=(TC_LEN_LOAD_PAS_FILTER_PAR-CCSDS_TC_TM_PACKET_OFFSET)) {
421 status = WRONG_LEN_PKT;
422 }
423 else {
424 status = CCSDS_TM_VALID;
425 }
426 break;
418 427 case TC_SUBTYPE_UPDT_TIME:
419 428 if (length!=(TC_LEN_UPDT_TIME-CCSDS_TC_TM_PACKET_OFFSET)) {
420 429 status = WRONG_LEN_PKT;
421 430 }
422 431 else {
423 432 status = CCSDS_TM_VALID;
424 433 }
425 434 break;
426 435 default: // if the subtype is not a legal value, return ILL_SUBTYPE
427 436 status = ILL_SUBTYPE;
428 437 break ;
429 438 }
430 439
431 440 return status;
432 441 }
433 442
434 443 int tc_check_crc( ccsdsTelecommandPacket_t * TCPacket, unsigned int length, unsigned char *computed_CRC )
435 444 {
436 445 /** This function checks the CRC validity of the corresponding TeleCommand packet.
437 446 *
438 447 * @param TCPacket points to the TeleCommand packet to check.
439 448 * @param length is the length of the TC packet.
440 449 *
441 450 * @return Status code CCSDS_TM_VALID or INCOR_CHECKSUM.
442 451 *
443 452 */
444 453
445 454 int status;
446 455 unsigned char * CCSDSContent;
447 456
448 457 CCSDSContent = (unsigned char*) TCPacket->packetID;
449 458 GetCRCAsTwoBytes(CCSDSContent, computed_CRC, length + CCSDS_TC_TM_PACKET_OFFSET - 2); // 2 CRC bytes removed from the calculation of the CRC
450 459
451 460 if (computed_CRC[0] != CCSDSContent[length + CCSDS_TC_TM_PACKET_OFFSET -2]) {
452 461 status = INCOR_CHECKSUM;
453 462 }
454 463 else if (computed_CRC[1] != CCSDSContent[length + CCSDS_TC_TM_PACKET_OFFSET -1]) {
455 464 status = INCOR_CHECKSUM;
456 465 }
457 466 else {
458 467 status = CCSDS_TM_VALID;
459 468 }
460 469
461 470 return status;
462 471 }
463 472
464 473
465 474
@@ -1,1632 +1,1636
1 1 /** Functions and tasks related to TeleCommand handling.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * A group of functions to handle TeleCommands:\n
7 7 * action launching\n
8 8 * TC parsing\n
9 9 * ...
10 10 *
11 11 */
12 12
13 13 #include "tc_handler.h"
14 14 #include "math.h"
15 15
16 16 //***********
17 17 // RTEMS TASK
18 18
19 19 rtems_task actn_task( rtems_task_argument unused )
20 20 {
21 21 /** This RTEMS task is responsible for launching actions upton the reception of valid TeleCommands.
22 22 *
23 23 * @param unused is the starting argument of the RTEMS task
24 24 *
25 25 * The ACTN task waits for data coming from an RTEMS msesage queue. When data arrives, it launches specific actions depending
26 26 * on the incoming TeleCommand.
27 27 *
28 28 */
29 29
30 30 int result;
31 31 rtems_status_code status; // RTEMS status code
32 32 ccsdsTelecommandPacket_t TC; // TC sent to the ACTN task
33 33 size_t size; // size of the incoming TC packet
34 34 unsigned char subtype; // subtype of the current TC packet
35 35 unsigned char time[6];
36 36 rtems_id queue_rcv_id;
37 37 rtems_id queue_snd_id;
38 38
39 39 status = get_message_queue_id_recv( &queue_rcv_id );
40 40 if (status != RTEMS_SUCCESSFUL)
41 41 {
42 42 PRINTF1("in ACTN *** ERR get_message_queue_id_recv %d\n", status)
43 43 }
44 44
45 45 status = get_message_queue_id_send( &queue_snd_id );
46 46 if (status != RTEMS_SUCCESSFUL)
47 47 {
48 48 PRINTF1("in ACTN *** ERR get_message_queue_id_send %d\n", status)
49 49 }
50 50
51 51 result = LFR_SUCCESSFUL;
52 52 subtype = 0; // subtype of the current TC packet
53 53
54 54 BOOT_PRINTF("in ACTN *** \n")
55 55
56 56 while(1)
57 57 {
58 58 status = rtems_message_queue_receive( queue_rcv_id, (char*) &TC, &size,
59 59 RTEMS_WAIT, RTEMS_NO_TIMEOUT);
60 60 getTime( time ); // set time to the current time
61 61 if (status!=RTEMS_SUCCESSFUL)
62 62 {
63 63 PRINTF1("ERR *** in task ACTN *** error receiving a message, code %d \n", status)
64 64 }
65 65 else
66 66 {
67 67 subtype = TC.serviceSubType;
68 68 switch(subtype)
69 69 {
70 70 case TC_SUBTYPE_RESET:
71 71 result = action_reset( &TC, queue_snd_id, time );
72 72 close_action( &TC, result, queue_snd_id );
73 73 break;
74 74 case TC_SUBTYPE_LOAD_COMM:
75 75 result = action_load_common_par( &TC );
76 76 close_action( &TC, result, queue_snd_id );
77 77 break;
78 78 case TC_SUBTYPE_LOAD_NORM:
79 79 result = action_load_normal_par( &TC, queue_snd_id, time );
80 80 close_action( &TC, result, queue_snd_id );
81 81 break;
82 82 case TC_SUBTYPE_LOAD_BURST:
83 83 result = action_load_burst_par( &TC, queue_snd_id, time );
84 84 close_action( &TC, result, queue_snd_id );
85 85 break;
86 86 case TC_SUBTYPE_LOAD_SBM1:
87 87 result = action_load_sbm1_par( &TC, queue_snd_id, time );
88 88 close_action( &TC, result, queue_snd_id );
89 89 break;
90 90 case TC_SUBTYPE_LOAD_SBM2:
91 91 result = action_load_sbm2_par( &TC, queue_snd_id, time );
92 92 close_action( &TC, result, queue_snd_id );
93 93 break;
94 94 case TC_SUBTYPE_DUMP:
95 95 result = action_dump_par( &TC, queue_snd_id );
96 96 close_action( &TC, result, queue_snd_id );
97 97 break;
98 98 case TC_SUBTYPE_ENTER:
99 99 result = action_enter_mode( &TC, queue_snd_id );
100 100 close_action( &TC, result, queue_snd_id );
101 101 break;
102 102 case TC_SUBTYPE_UPDT_INFO:
103 103 result = action_update_info( &TC, queue_snd_id );
104 104 close_action( &TC, result, queue_snd_id );
105 105 break;
106 106 case TC_SUBTYPE_EN_CAL:
107 107 result = action_enable_calibration( &TC, queue_snd_id, time );
108 108 close_action( &TC, result, queue_snd_id );
109 109 break;
110 110 case TC_SUBTYPE_DIS_CAL:
111 111 result = action_disable_calibration( &TC, queue_snd_id, time );
112 112 close_action( &TC, result, queue_snd_id );
113 113 break;
114 114 case TC_SUBTYPE_LOAD_K:
115 115 result = action_load_kcoefficients( &TC, queue_snd_id, time );
116 116 close_action( &TC, result, queue_snd_id );
117 117 break;
118 118 case TC_SUBTYPE_DUMP_K:
119 119 result = action_dump_kcoefficients( &TC, queue_snd_id, time );
120 120 close_action( &TC, result, queue_snd_id );
121 121 break;
122 122 case TC_SUBTYPE_LOAD_FBINS:
123 123 result = action_load_fbins_mask( &TC, queue_snd_id, time );
124 124 close_action( &TC, result, queue_snd_id );
125 125 break;
126 case TC_SUBTYPE_LOAD_PAS_FILTER_PAR:
127 result = action_load_pas_filter_par( &TC, queue_snd_id, time );
128 close_action( &TC, result, queue_snd_id );
129 break;
126 130 case TC_SUBTYPE_UPDT_TIME:
127 131 result = action_update_time( &TC );
128 132 close_action( &TC, result, queue_snd_id );
129 133 break;
130 134 default:
131 135 break;
132 136 }
133 137 }
134 138 }
135 139 }
136 140
137 141 //***********
138 142 // TC ACTIONS
139 143
140 144 int action_reset(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
141 145 {
142 146 /** This function executes specific actions when a TC_LFR_RESET TeleCommand has been received.
143 147 *
144 148 * @param TC points to the TeleCommand packet that is being processed
145 149 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
146 150 *
147 151 */
148 152
149 153 PRINTF("this is the end!!!\n");
150 154 exit(0);
151 155
152 156 send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time );
153 157
154 158 return LFR_DEFAULT;
155 159 }
156 160
157 161 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
158 162 {
159 163 /** This function executes specific actions when a TC_LFR_ENTER_MODE TeleCommand has been received.
160 164 *
161 165 * @param TC points to the TeleCommand packet that is being processed
162 166 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
163 167 *
164 168 */
165 169
166 170 rtems_status_code status;
167 171 unsigned char requestedMode;
168 172 unsigned int *transitionCoarseTime_ptr;
169 173 unsigned int transitionCoarseTime;
170 174 unsigned char * bytePosPtr;
171 175
172 176 bytePosPtr = (unsigned char *) &TC->packetID;
173 177
174 178 requestedMode = bytePosPtr[ BYTE_POS_CP_MODE_LFR_SET ];
175 179 transitionCoarseTime_ptr = (unsigned int *) ( &bytePosPtr[ BYTE_POS_CP_LFR_ENTER_MODE_TIME ] );
176 180 transitionCoarseTime = (*transitionCoarseTime_ptr) & 0x7fffffff;
177 181
178 182 status = check_mode_value( requestedMode );
179 183
180 184 if ( status != LFR_SUCCESSFUL ) // the mode value is inconsistent
181 185 {
182 186 send_tm_lfr_tc_exe_inconsistent( TC, queue_id, BYTE_POS_CP_MODE_LFR_SET, requestedMode );
183 187 }
184 188
185 189 else // the mode value is valid, check the transition
186 190 {
187 191 status = check_mode_transition(requestedMode);
188 192 if (status != LFR_SUCCESSFUL)
189 193 {
190 194 PRINTF("ERR *** in action_enter_mode *** check_mode_transition\n")
191 195 send_tm_lfr_tc_exe_not_executable( TC, queue_id );
192 196 }
193 197 }
194 198
195 199 if ( status == LFR_SUCCESSFUL ) // the transition is valid, check the date
196 200 {
197 201 status = check_transition_date( transitionCoarseTime );
198 202 if (status != LFR_SUCCESSFUL)
199 203 {
200 204 PRINTF("ERR *** in action_enter_mode *** check_transition_date\n");
201 205 send_tm_lfr_tc_exe_not_executable(TC, queue_id );
202 206 }
203 207 }
204 208
205 209 if ( status == LFR_SUCCESSFUL ) // the date is valid, enter the mode
206 210 {
207 211 PRINTF1("OK *** in action_enter_mode *** enter mode %d\n", requestedMode);
208 212
209 213 switch(requestedMode)
210 214 {
211 215 case LFR_MODE_STANDBY:
212 216 status = enter_mode_standby();
213 217 break;
214 218 case LFR_MODE_NORMAL:
215 219 status = enter_mode_normal( transitionCoarseTime );
216 220 break;
217 221 case LFR_MODE_BURST:
218 222 status = enter_mode_burst( transitionCoarseTime );
219 223 break;
220 224 case LFR_MODE_SBM1:
221 225 status = enter_mode_sbm1( transitionCoarseTime );
222 226 break;
223 227 case LFR_MODE_SBM2:
224 228 status = enter_mode_sbm2( transitionCoarseTime );
225 229 break;
226 230 default:
227 231 break;
228 232 }
229 233
230 234 if (status != RTEMS_SUCCESSFUL)
231 235 {
232 236 status = LFR_EXE_ERROR;
233 237 }
234 238 }
235 239
236 240 return status;
237 241 }
238 242
239 243 int action_update_info(ccsdsTelecommandPacket_t *TC, rtems_id queue_id)
240 244 {
241 245 /** This function executes specific actions when a TC_LFR_UPDATE_INFO TeleCommand has been received.
242 246 *
243 247 * @param TC points to the TeleCommand packet that is being processed
244 248 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
245 249 *
246 250 * @return LFR directive status code:
247 251 * - LFR_DEFAULT
248 252 * - LFR_SUCCESSFUL
249 253 *
250 254 */
251 255
252 256 unsigned int val;
253 257 int result;
254 258 unsigned int status;
255 259 unsigned char mode;
256 260 unsigned char * bytePosPtr;
257 261
258 262 bytePosPtr = (unsigned char *) &TC->packetID;
259 263
260 264 // check LFR mode
261 265 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET5 ] & 0x1e) >> 1;
262 266 status = check_update_info_hk_lfr_mode( mode );
263 267 if (status == LFR_SUCCESSFUL) // check TDS mode
264 268 {
265 269 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & 0xf0) >> 4;
266 270 status = check_update_info_hk_tds_mode( mode );
267 271 }
268 272 if (status == LFR_SUCCESSFUL) // check THR mode
269 273 {
270 274 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & 0x0f);
271 275 status = check_update_info_hk_thr_mode( mode );
272 276 }
273 277 if (status == LFR_SUCCESSFUL) // if the parameter check is successful
274 278 {
275 279 val = housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * 256
276 280 + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
277 281 val++;
278 282 housekeeping_packet.hk_lfr_update_info_tc_cnt[0] = (unsigned char) (val >> 8);
279 283 housekeeping_packet.hk_lfr_update_info_tc_cnt[1] = (unsigned char) (val);
280 284 }
281 285
282 286 // pa_bia_status_info
283 287 // => pa_bia_mode_mux_set 3 bits
284 288 // => pa_bia_mode_hv_enabled 1 bit
285 289 // => pa_bia_mode_bias1_enabled 1 bit
286 290 // => pa_bia_mode_bias2_enabled 1 bit
287 291 // => pa_bia_mode_bias3_enabled 1 bit
288 292 // => pa_bia_on_off (cp_dpu_bias_on_off)
289 293 pa_bia_status_info = bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET2 ] & 0xfe; // [1111 1110]
290 294 pa_bia_status_info = pa_bia_status_info
291 295 | (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET1 ] & 0x1);
292 296
293 297 result = status;
294 298
295 299 return result;
296 300 }
297 301
298 302 int action_enable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
299 303 {
300 304 /** This function executes specific actions when a TC_LFR_ENABLE_CALIBRATION TeleCommand has been received.
301 305 *
302 306 * @param TC points to the TeleCommand packet that is being processed
303 307 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
304 308 *
305 309 */
306 310
307 311 int result;
308 312
309 313 result = LFR_DEFAULT;
310 314
311 315 setCalibration( true );
312 316
313 317 result = LFR_SUCCESSFUL;
314 318
315 319 return result;
316 320 }
317 321
318 322 int action_disable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
319 323 {
320 324 /** This function executes specific actions when a TC_LFR_DISABLE_CALIBRATION TeleCommand has been received.
321 325 *
322 326 * @param TC points to the TeleCommand packet that is being processed
323 327 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
324 328 *
325 329 */
326 330
327 331 int result;
328 332
329 333 result = LFR_DEFAULT;
330 334
331 335 setCalibration( false );
332 336
333 337 result = LFR_SUCCESSFUL;
334 338
335 339 return result;
336 340 }
337 341
338 342 int action_update_time(ccsdsTelecommandPacket_t *TC)
339 343 {
340 344 /** This function executes specific actions when a TC_LFR_UPDATE_TIME TeleCommand has been received.
341 345 *
342 346 * @param TC points to the TeleCommand packet that is being processed
343 347 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
344 348 *
345 349 * @return LFR_SUCCESSFUL
346 350 *
347 351 */
348 352
349 353 unsigned int val;
350 354
351 355 time_management_regs->coarse_time_load = (TC->dataAndCRC[0] << 24)
352 356 + (TC->dataAndCRC[1] << 16)
353 357 + (TC->dataAndCRC[2] << 8)
354 358 + TC->dataAndCRC[3];
355 359
356 360 val = housekeeping_packet.hk_lfr_update_time_tc_cnt[0] * 256
357 361 + housekeeping_packet.hk_lfr_update_time_tc_cnt[1];
358 362 val++;
359 363 housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char) (val >> 8);
360 364 housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char) (val);
361 365
362 366 oneTcLfrUpdateTimeReceived = 1;
363 367
364 368 return LFR_SUCCESSFUL;
365 369 }
366 370
367 371 //*******************
368 372 // ENTERING THE MODES
369 373 int check_mode_value( unsigned char requestedMode )
370 374 {
371 375 int status;
372 376
373 377 if ( (requestedMode != LFR_MODE_STANDBY)
374 378 && (requestedMode != LFR_MODE_NORMAL) && (requestedMode != LFR_MODE_BURST)
375 379 && (requestedMode != LFR_MODE_SBM1) && (requestedMode != LFR_MODE_SBM2) )
376 380 {
377 381 status = LFR_DEFAULT;
378 382 }
379 383 else
380 384 {
381 385 status = LFR_SUCCESSFUL;
382 386 }
383 387
384 388 return status;
385 389 }
386 390
387 391 int check_mode_transition( unsigned char requestedMode )
388 392 {
389 393 /** This function checks the validity of the transition requested by the TC_LFR_ENTER_MODE.
390 394 *
391 395 * @param requestedMode is the mode requested by the TC_LFR_ENTER_MODE
392 396 *
393 397 * @return LFR directive status codes:
394 398 * - LFR_SUCCESSFUL - the transition is authorized
395 399 * - LFR_DEFAULT - the transition is not authorized
396 400 *
397 401 */
398 402
399 403 int status;
400 404
401 405 switch (requestedMode)
402 406 {
403 407 case LFR_MODE_STANDBY:
404 408 if ( lfrCurrentMode == LFR_MODE_STANDBY ) {
405 409 status = LFR_DEFAULT;
406 410 }
407 411 else
408 412 {
409 413 status = LFR_SUCCESSFUL;
410 414 }
411 415 break;
412 416 case LFR_MODE_NORMAL:
413 417 if ( lfrCurrentMode == LFR_MODE_NORMAL ) {
414 418 status = LFR_DEFAULT;
415 419 }
416 420 else {
417 421 status = LFR_SUCCESSFUL;
418 422 }
419 423 break;
420 424 case LFR_MODE_BURST:
421 425 if ( lfrCurrentMode == LFR_MODE_BURST ) {
422 426 status = LFR_DEFAULT;
423 427 }
424 428 else {
425 429 status = LFR_SUCCESSFUL;
426 430 }
427 431 break;
428 432 case LFR_MODE_SBM1:
429 433 if ( lfrCurrentMode == LFR_MODE_SBM1 ) {
430 434 status = LFR_DEFAULT;
431 435 }
432 436 else {
433 437 status = LFR_SUCCESSFUL;
434 438 }
435 439 break;
436 440 case LFR_MODE_SBM2:
437 441 if ( lfrCurrentMode == LFR_MODE_SBM2 ) {
438 442 status = LFR_DEFAULT;
439 443 }
440 444 else {
441 445 status = LFR_SUCCESSFUL;
442 446 }
443 447 break;
444 448 default:
445 449 status = LFR_DEFAULT;
446 450 break;
447 451 }
448 452
449 453 return status;
450 454 }
451 455
452 456 void update_last_valid_transition_date( unsigned int transitionCoarseTime )
453 457 {
454 458 if (transitionCoarseTime == 0)
455 459 {
456 460 lastValidEnterModeTime = time_management_regs->coarse_time + 1;
457 461 PRINTF1("lastValidEnterModeTime = 0x%x (transitionCoarseTime = 0 => coarse_time+1)\n", lastValidEnterModeTime);
458 462 }
459 463 else
460 464 {
461 465 lastValidEnterModeTime = transitionCoarseTime;
462 466 PRINTF1("lastValidEnterModeTime = 0x%x\n", transitionCoarseTime);
463 467 }
464 468 }
465 469
466 470 int check_transition_date( unsigned int transitionCoarseTime )
467 471 {
468 472 int status;
469 473 unsigned int localCoarseTime;
470 474 unsigned int deltaCoarseTime;
471 475
472 476 status = LFR_SUCCESSFUL;
473 477
474 478 if (transitionCoarseTime == 0) // transition time = 0 means an instant transition
475 479 {
476 480 status = LFR_SUCCESSFUL;
477 481 }
478 482 else
479 483 {
480 484 localCoarseTime = time_management_regs->coarse_time & 0x7fffffff;
481 485
482 486 PRINTF2("localTime = %x, transitionTime = %x\n", localCoarseTime, transitionCoarseTime);
483 487
484 488 if ( transitionCoarseTime <= localCoarseTime ) // SSS-CP-EQS-322
485 489 {
486 490 status = LFR_DEFAULT;
487 491 PRINTF("ERR *** in check_transition_date *** transitionCoarseTime <= localCoarseTime\n");
488 492 }
489 493
490 494 if (status == LFR_SUCCESSFUL)
491 495 {
492 496 deltaCoarseTime = transitionCoarseTime - localCoarseTime;
493 497 if ( deltaCoarseTime > 3 ) // SSS-CP-EQS-323
494 498 {
495 499 status = LFR_DEFAULT;
496 500 PRINTF1("ERR *** in check_transition_date *** deltaCoarseTime = %x\n", deltaCoarseTime)
497 501 }
498 502 }
499 503 }
500 504
501 505 return status;
502 506 }
503 507
504 508 int restart_asm_activities( unsigned char lfrRequestedMode )
505 509 {
506 510 rtems_status_code status;
507 511
508 512 status = stop_spectral_matrices();
509 513
510 514 thisIsAnASMRestart = 1;
511 515
512 516 status = restart_asm_tasks( lfrRequestedMode );
513 517
514 518 launch_spectral_matrix();
515 519
516 520 return status;
517 521 }
518 522
519 523 int stop_spectral_matrices( void )
520 524 {
521 525 /** This function stops and restarts the current mode average spectral matrices activities.
522 526 *
523 527 * @return RTEMS directive status codes:
524 528 * - RTEMS_SUCCESSFUL - task restarted successfully
525 529 * - RTEMS_INVALID_ID - task id invalid
526 530 * - RTEMS_ALREADY_SUSPENDED - task already suspended
527 531 *
528 532 */
529 533
530 534 rtems_status_code status;
531 535
532 536 status = RTEMS_SUCCESSFUL;
533 537
534 538 // (1) mask interruptions
535 539 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // mask spectral matrix interrupt
536 540
537 541 // (2) reset spectral matrices registers
538 542 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
539 543 reset_sm_status();
540 544
541 545 // (3) clear interruptions
542 546 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
543 547
544 548 // suspend several tasks
545 549 if (lfrCurrentMode != LFR_MODE_STANDBY) {
546 550 status = suspend_asm_tasks();
547 551 }
548 552
549 553 if (status != RTEMS_SUCCESSFUL)
550 554 {
551 555 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
552 556 }
553 557
554 558 return status;
555 559 }
556 560
557 561 int stop_current_mode( void )
558 562 {
559 563 /** This function stops the current mode by masking interrupt lines and suspending science tasks.
560 564 *
561 565 * @return RTEMS directive status codes:
562 566 * - RTEMS_SUCCESSFUL - task restarted successfully
563 567 * - RTEMS_INVALID_ID - task id invalid
564 568 * - RTEMS_ALREADY_SUSPENDED - task already suspended
565 569 *
566 570 */
567 571
568 572 rtems_status_code status;
569 573
570 574 status = RTEMS_SUCCESSFUL;
571 575
572 576 // (1) mask interruptions
573 577 LEON_Mask_interrupt( IRQ_WAVEFORM_PICKER ); // mask waveform picker interrupt
574 578 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
575 579
576 580 // (2) reset waveform picker registers
577 581 reset_wfp_burst_enable(); // reset burst and enable bits
578 582 reset_wfp_status(); // reset all the status bits
579 583
580 584 // (3) reset spectral matrices registers
581 585 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
582 586 reset_sm_status();
583 587
584 588 // reset lfr VHDL module
585 589 reset_lfr();
586 590
587 591 reset_extractSWF(); // reset the extractSWF flag to false
588 592
589 593 // (4) clear interruptions
590 594 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER ); // clear waveform picker interrupt
591 595 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
592 596
593 597 // suspend several tasks
594 598 if (lfrCurrentMode != LFR_MODE_STANDBY) {
595 599 status = suspend_science_tasks();
596 600 }
597 601
598 602 if (status != RTEMS_SUCCESSFUL)
599 603 {
600 604 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
601 605 }
602 606
603 607 return status;
604 608 }
605 609
606 610 int enter_mode_standby( void )
607 611 {
608 612 /** This function is used to put LFR in the STANDBY mode.
609 613 *
610 614 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
611 615 *
612 616 * @return RTEMS directive status codes:
613 617 * - RTEMS_SUCCESSFUL - task restarted successfully
614 618 * - RTEMS_INVALID_ID - task id invalid
615 619 * - RTEMS_INCORRECT_STATE - task never started
616 620 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
617 621 *
618 622 * The STANDBY mode does not depends on a specific transition date, the effect of the TC_LFR_ENTER_MODE
619 623 * is immediate.
620 624 *
621 625 */
622 626
623 627 int status;
624 628
625 629 status = stop_current_mode(); // STOP THE CURRENT MODE
626 630
627 631 #ifdef PRINT_TASK_STATISTICS
628 632 rtems_cpu_usage_report();
629 633 #endif
630 634
631 635 #ifdef PRINT_STACK_REPORT
632 636 PRINTF("stack report selected\n")
633 637 rtems_stack_checker_report_usage();
634 638 #endif
635 639
636 640 return status;
637 641 }
638 642
639 643 int enter_mode_normal( unsigned int transitionCoarseTime )
640 644 {
641 645 /** This function is used to start the NORMAL mode.
642 646 *
643 647 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
644 648 *
645 649 * @return RTEMS directive status codes:
646 650 * - RTEMS_SUCCESSFUL - task restarted successfully
647 651 * - RTEMS_INVALID_ID - task id invalid
648 652 * - RTEMS_INCORRECT_STATE - task never started
649 653 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
650 654 *
651 655 * The way the NORMAL mode is started depends on the LFR current mode. If LFR is in SBM1 or SBM2,
652 656 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected.
653 657 *
654 658 */
655 659
656 660 int status;
657 661
658 662 #ifdef PRINT_TASK_STATISTICS
659 663 rtems_cpu_usage_reset();
660 664 #endif
661 665
662 666 status = RTEMS_UNSATISFIED;
663 667
664 668 switch( lfrCurrentMode )
665 669 {
666 670 case LFR_MODE_STANDBY:
667 671 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart science tasks
668 672 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
669 673 {
670 674 launch_spectral_matrix( );
671 675 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
672 676 }
673 677 break;
674 678 case LFR_MODE_BURST:
675 679 status = stop_current_mode(); // stop the current mode
676 680 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart the science tasks
677 681 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
678 682 {
679 683 launch_spectral_matrix( );
680 684 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
681 685 }
682 686 break;
683 687 case LFR_MODE_SBM1:
684 688 status = restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
685 689 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
686 690 update_last_valid_transition_date( transitionCoarseTime );
687 691 break;
688 692 case LFR_MODE_SBM2:
689 693 status = restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
690 694 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
691 695 update_last_valid_transition_date( transitionCoarseTime );
692 696 break;
693 697 default:
694 698 break;
695 699 }
696 700
697 701 if (status != RTEMS_SUCCESSFUL)
698 702 {
699 703 PRINTF1("ERR *** in enter_mode_normal *** status = %d\n", status)
700 704 status = RTEMS_UNSATISFIED;
701 705 }
702 706
703 707 return status;
704 708 }
705 709
706 710 int enter_mode_burst( unsigned int transitionCoarseTime )
707 711 {
708 712 /** This function is used to start the BURST mode.
709 713 *
710 714 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
711 715 *
712 716 * @return RTEMS directive status codes:
713 717 * - RTEMS_SUCCESSFUL - task restarted successfully
714 718 * - RTEMS_INVALID_ID - task id invalid
715 719 * - RTEMS_INCORRECT_STATE - task never started
716 720 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
717 721 *
718 722 * The way the BURST mode is started does not depend on the LFR current mode.
719 723 *
720 724 */
721 725
722 726
723 727 int status;
724 728
725 729 #ifdef PRINT_TASK_STATISTICS
726 730 rtems_cpu_usage_reset();
727 731 #endif
728 732
729 733 status = stop_current_mode(); // stop the current mode
730 734 status = restart_science_tasks( LFR_MODE_BURST ); // restart the science tasks
731 735 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
732 736 {
733 737 launch_spectral_matrix( );
734 738 launch_waveform_picker( LFR_MODE_BURST, transitionCoarseTime );
735 739 }
736 740
737 741 if (status != RTEMS_SUCCESSFUL)
738 742 {
739 743 PRINTF1("ERR *** in enter_mode_burst *** status = %d\n", status)
740 744 status = RTEMS_UNSATISFIED;
741 745 }
742 746
743 747 return status;
744 748 }
745 749
746 750 int enter_mode_sbm1( unsigned int transitionCoarseTime )
747 751 {
748 752 /** This function is used to start the SBM1 mode.
749 753 *
750 754 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
751 755 *
752 756 * @return RTEMS directive status codes:
753 757 * - RTEMS_SUCCESSFUL - task restarted successfully
754 758 * - RTEMS_INVALID_ID - task id invalid
755 759 * - RTEMS_INCORRECT_STATE - task never started
756 760 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
757 761 *
758 762 * The way the SBM1 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM2,
759 763 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
760 764 * cases, the acquisition is completely restarted.
761 765 *
762 766 */
763 767
764 768 int status;
765 769
766 770 #ifdef PRINT_TASK_STATISTICS
767 771 rtems_cpu_usage_reset();
768 772 #endif
769 773
770 774 status = RTEMS_UNSATISFIED;
771 775
772 776 switch( lfrCurrentMode )
773 777 {
774 778 case LFR_MODE_STANDBY:
775 779 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart science tasks
776 780 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
777 781 {
778 782 launch_spectral_matrix( );
779 783 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
780 784 }
781 785 break;
782 786 case LFR_MODE_NORMAL: // lfrCurrentMode will be updated after the execution of close_action
783 787 status = restart_asm_activities( LFR_MODE_SBM1 );
784 788 status = LFR_SUCCESSFUL;
785 789 update_last_valid_transition_date( transitionCoarseTime );
786 790 break;
787 791 case LFR_MODE_BURST:
788 792 status = stop_current_mode(); // stop the current mode
789 793 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart the science tasks
790 794 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
791 795 {
792 796 launch_spectral_matrix( );
793 797 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
794 798 }
795 799 break;
796 800 case LFR_MODE_SBM2:
797 801 status = restart_asm_activities( LFR_MODE_SBM1 );
798 802 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
799 803 update_last_valid_transition_date( transitionCoarseTime );
800 804 break;
801 805 default:
802 806 break;
803 807 }
804 808
805 809 if (status != RTEMS_SUCCESSFUL)
806 810 {
807 811 PRINTF1("ERR *** in enter_mode_sbm1 *** status = %d\n", status);
808 812 status = RTEMS_UNSATISFIED;
809 813 }
810 814
811 815 return status;
812 816 }
813 817
814 818 int enter_mode_sbm2( unsigned int transitionCoarseTime )
815 819 {
816 820 /** This function is used to start the SBM2 mode.
817 821 *
818 822 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
819 823 *
820 824 * @return RTEMS directive status codes:
821 825 * - RTEMS_SUCCESSFUL - task restarted successfully
822 826 * - RTEMS_INVALID_ID - task id invalid
823 827 * - RTEMS_INCORRECT_STATE - task never started
824 828 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
825 829 *
826 830 * The way the SBM2 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM1,
827 831 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
828 832 * cases, the acquisition is completely restarted.
829 833 *
830 834 */
831 835
832 836 int status;
833 837
834 838 #ifdef PRINT_TASK_STATISTICS
835 839 rtems_cpu_usage_reset();
836 840 #endif
837 841
838 842 status = RTEMS_UNSATISFIED;
839 843
840 844 switch( lfrCurrentMode )
841 845 {
842 846 case LFR_MODE_STANDBY:
843 847 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart science tasks
844 848 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
845 849 {
846 850 launch_spectral_matrix( );
847 851 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
848 852 }
849 853 break;
850 854 case LFR_MODE_NORMAL:
851 855 status = restart_asm_activities( LFR_MODE_SBM2 );
852 856 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
853 857 update_last_valid_transition_date( transitionCoarseTime );
854 858 break;
855 859 case LFR_MODE_BURST:
856 860 status = stop_current_mode(); // stop the current mode
857 861 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart the science tasks
858 862 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
859 863 {
860 864 launch_spectral_matrix( );
861 865 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
862 866 }
863 867 break;
864 868 case LFR_MODE_SBM1:
865 869 status = restart_asm_activities( LFR_MODE_SBM2 );
866 870 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
867 871 update_last_valid_transition_date( transitionCoarseTime );
868 872 break;
869 873 default:
870 874 break;
871 875 }
872 876
873 877 if (status != RTEMS_SUCCESSFUL)
874 878 {
875 879 PRINTF1("ERR *** in enter_mode_sbm2 *** status = %d\n", status)
876 880 status = RTEMS_UNSATISFIED;
877 881 }
878 882
879 883 return status;
880 884 }
881 885
882 886 int restart_science_tasks( unsigned char lfrRequestedMode )
883 887 {
884 888 /** This function is used to restart all science tasks.
885 889 *
886 890 * @return RTEMS directive status codes:
887 891 * - RTEMS_SUCCESSFUL - task restarted successfully
888 892 * - RTEMS_INVALID_ID - task id invalid
889 893 * - RTEMS_INCORRECT_STATE - task never started
890 894 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
891 895 *
892 896 * Science tasks are AVF0, PRC0, WFRM, CWF3, CW2, CWF1
893 897 *
894 898 */
895 899
896 900 rtems_status_code status[10];
897 901 rtems_status_code ret;
898 902
899 903 ret = RTEMS_SUCCESSFUL;
900 904
901 905 status[0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
902 906 if (status[0] != RTEMS_SUCCESSFUL)
903 907 {
904 908 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[0])
905 909 }
906 910
907 911 status[1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
908 912 if (status[1] != RTEMS_SUCCESSFUL)
909 913 {
910 914 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[1])
911 915 }
912 916
913 917 status[2] = rtems_task_restart( Task_id[TASKID_WFRM],1 );
914 918 if (status[2] != RTEMS_SUCCESSFUL)
915 919 {
916 920 PRINTF1("in restart_science_task *** WFRM ERR %d\n", status[2])
917 921 }
918 922
919 923 status[3] = rtems_task_restart( Task_id[TASKID_CWF3],1 );
920 924 if (status[3] != RTEMS_SUCCESSFUL)
921 925 {
922 926 PRINTF1("in restart_science_task *** CWF3 ERR %d\n", status[3])
923 927 }
924 928
925 929 status[4] = rtems_task_restart( Task_id[TASKID_CWF2],1 );
926 930 if (status[4] != RTEMS_SUCCESSFUL)
927 931 {
928 932 PRINTF1("in restart_science_task *** CWF2 ERR %d\n", status[4])
929 933 }
930 934
931 935 status[5] = rtems_task_restart( Task_id[TASKID_CWF1],1 );
932 936 if (status[5] != RTEMS_SUCCESSFUL)
933 937 {
934 938 PRINTF1("in restart_science_task *** CWF1 ERR %d\n", status[5])
935 939 }
936 940
937 941 status[6] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
938 942 if (status[6] != RTEMS_SUCCESSFUL)
939 943 {
940 944 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[6])
941 945 }
942 946
943 947 status[7] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
944 948 if (status[7] != RTEMS_SUCCESSFUL)
945 949 {
946 950 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[7])
947 951 }
948 952
949 953 status[8] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
950 954 if (status[8] != RTEMS_SUCCESSFUL)
951 955 {
952 956 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[8])
953 957 }
954 958
955 959 status[9] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
956 960 if (status[9] != RTEMS_SUCCESSFUL)
957 961 {
958 962 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[9])
959 963 }
960 964
961 965 if ( (status[0] != RTEMS_SUCCESSFUL) || (status[1] != RTEMS_SUCCESSFUL) ||
962 966 (status[2] != RTEMS_SUCCESSFUL) || (status[3] != RTEMS_SUCCESSFUL) ||
963 967 (status[4] != RTEMS_SUCCESSFUL) || (status[5] != RTEMS_SUCCESSFUL) ||
964 968 (status[6] != RTEMS_SUCCESSFUL) || (status[7] != RTEMS_SUCCESSFUL) ||
965 969 (status[8] != RTEMS_SUCCESSFUL) || (status[9] != RTEMS_SUCCESSFUL) )
966 970 {
967 971 ret = RTEMS_UNSATISFIED;
968 972 }
969 973
970 974 return ret;
971 975 }
972 976
973 977 int restart_asm_tasks( unsigned char lfrRequestedMode )
974 978 {
975 979 /** This function is used to restart average spectral matrices tasks.
976 980 *
977 981 * @return RTEMS directive status codes:
978 982 * - RTEMS_SUCCESSFUL - task restarted successfully
979 983 * - RTEMS_INVALID_ID - task id invalid
980 984 * - RTEMS_INCORRECT_STATE - task never started
981 985 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
982 986 *
983 987 * ASM tasks are AVF0, PRC0, AVF1, PRC1, AVF2 and PRC2
984 988 *
985 989 */
986 990
987 991 rtems_status_code status[6];
988 992 rtems_status_code ret;
989 993
990 994 ret = RTEMS_SUCCESSFUL;
991 995
992 996 status[0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
993 997 if (status[0] != RTEMS_SUCCESSFUL)
994 998 {
995 999 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[0])
996 1000 }
997 1001
998 1002 status[1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
999 1003 if (status[1] != RTEMS_SUCCESSFUL)
1000 1004 {
1001 1005 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[1])
1002 1006 }
1003 1007
1004 1008 status[2] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
1005 1009 if (status[2] != RTEMS_SUCCESSFUL)
1006 1010 {
1007 1011 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[2])
1008 1012 }
1009 1013
1010 1014 status[3] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
1011 1015 if (status[3] != RTEMS_SUCCESSFUL)
1012 1016 {
1013 1017 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[3])
1014 1018 }
1015 1019
1016 1020 status[4] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
1017 1021 if (status[4] != RTEMS_SUCCESSFUL)
1018 1022 {
1019 1023 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[4])
1020 1024 }
1021 1025
1022 1026 status[5] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
1023 1027 if (status[5] != RTEMS_SUCCESSFUL)
1024 1028 {
1025 1029 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[5])
1026 1030 }
1027 1031
1028 1032 if ( (status[0] != RTEMS_SUCCESSFUL) || (status[1] != RTEMS_SUCCESSFUL) ||
1029 1033 (status[2] != RTEMS_SUCCESSFUL) || (status[3] != RTEMS_SUCCESSFUL) ||
1030 1034 (status[4] != RTEMS_SUCCESSFUL) || (status[5] != RTEMS_SUCCESSFUL) )
1031 1035 {
1032 1036 ret = RTEMS_UNSATISFIED;
1033 1037 }
1034 1038
1035 1039 return ret;
1036 1040 }
1037 1041
1038 1042 int suspend_science_tasks( void )
1039 1043 {
1040 1044 /** This function suspends the science tasks.
1041 1045 *
1042 1046 * @return RTEMS directive status codes:
1043 1047 * - RTEMS_SUCCESSFUL - task restarted successfully
1044 1048 * - RTEMS_INVALID_ID - task id invalid
1045 1049 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1046 1050 *
1047 1051 */
1048 1052
1049 1053 rtems_status_code status;
1050 1054
1051 1055 PRINTF("in suspend_science_tasks\n")
1052 1056
1053 1057 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1054 1058 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1055 1059 {
1056 1060 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1057 1061 }
1058 1062 else
1059 1063 {
1060 1064 status = RTEMS_SUCCESSFUL;
1061 1065 }
1062 1066 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1063 1067 {
1064 1068 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1065 1069 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1066 1070 {
1067 1071 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1068 1072 }
1069 1073 else
1070 1074 {
1071 1075 status = RTEMS_SUCCESSFUL;
1072 1076 }
1073 1077 }
1074 1078 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1075 1079 {
1076 1080 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1077 1081 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1078 1082 {
1079 1083 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1080 1084 }
1081 1085 else
1082 1086 {
1083 1087 status = RTEMS_SUCCESSFUL;
1084 1088 }
1085 1089 }
1086 1090 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1087 1091 {
1088 1092 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1089 1093 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1090 1094 {
1091 1095 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1092 1096 }
1093 1097 else
1094 1098 {
1095 1099 status = RTEMS_SUCCESSFUL;
1096 1100 }
1097 1101 }
1098 1102 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1099 1103 {
1100 1104 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1101 1105 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1102 1106 {
1103 1107 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1104 1108 }
1105 1109 else
1106 1110 {
1107 1111 status = RTEMS_SUCCESSFUL;
1108 1112 }
1109 1113 }
1110 1114 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1111 1115 {
1112 1116 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1113 1117 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1114 1118 {
1115 1119 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1116 1120 }
1117 1121 else
1118 1122 {
1119 1123 status = RTEMS_SUCCESSFUL;
1120 1124 }
1121 1125 }
1122 1126 if (status == RTEMS_SUCCESSFUL) // suspend WFRM
1123 1127 {
1124 1128 status = rtems_task_suspend( Task_id[TASKID_WFRM] );
1125 1129 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1126 1130 {
1127 1131 PRINTF1("in suspend_science_task *** WFRM ERR %d\n", status)
1128 1132 }
1129 1133 else
1130 1134 {
1131 1135 status = RTEMS_SUCCESSFUL;
1132 1136 }
1133 1137 }
1134 1138 if (status == RTEMS_SUCCESSFUL) // suspend CWF3
1135 1139 {
1136 1140 status = rtems_task_suspend( Task_id[TASKID_CWF3] );
1137 1141 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1138 1142 {
1139 1143 PRINTF1("in suspend_science_task *** CWF3 ERR %d\n", status)
1140 1144 }
1141 1145 else
1142 1146 {
1143 1147 status = RTEMS_SUCCESSFUL;
1144 1148 }
1145 1149 }
1146 1150 if (status == RTEMS_SUCCESSFUL) // suspend CWF2
1147 1151 {
1148 1152 status = rtems_task_suspend( Task_id[TASKID_CWF2] );
1149 1153 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1150 1154 {
1151 1155 PRINTF1("in suspend_science_task *** CWF2 ERR %d\n", status)
1152 1156 }
1153 1157 else
1154 1158 {
1155 1159 status = RTEMS_SUCCESSFUL;
1156 1160 }
1157 1161 }
1158 1162 if (status == RTEMS_SUCCESSFUL) // suspend CWF1
1159 1163 {
1160 1164 status = rtems_task_suspend( Task_id[TASKID_CWF1] );
1161 1165 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1162 1166 {
1163 1167 PRINTF1("in suspend_science_task *** CWF1 ERR %d\n", status)
1164 1168 }
1165 1169 else
1166 1170 {
1167 1171 status = RTEMS_SUCCESSFUL;
1168 1172 }
1169 1173 }
1170 1174
1171 1175 return status;
1172 1176 }
1173 1177
1174 1178 int suspend_asm_tasks( void )
1175 1179 {
1176 1180 /** This function suspends the science tasks.
1177 1181 *
1178 1182 * @return RTEMS directive status codes:
1179 1183 * - RTEMS_SUCCESSFUL - task restarted successfully
1180 1184 * - RTEMS_INVALID_ID - task id invalid
1181 1185 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1182 1186 *
1183 1187 */
1184 1188
1185 1189 rtems_status_code status;
1186 1190
1187 1191 PRINTF("in suspend_science_tasks\n")
1188 1192
1189 1193 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1190 1194 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1191 1195 {
1192 1196 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1193 1197 }
1194 1198 else
1195 1199 {
1196 1200 status = RTEMS_SUCCESSFUL;
1197 1201 }
1198 1202
1199 1203 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1200 1204 {
1201 1205 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1202 1206 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1203 1207 {
1204 1208 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1205 1209 }
1206 1210 else
1207 1211 {
1208 1212 status = RTEMS_SUCCESSFUL;
1209 1213 }
1210 1214 }
1211 1215
1212 1216 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1213 1217 {
1214 1218 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1215 1219 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1216 1220 {
1217 1221 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1218 1222 }
1219 1223 else
1220 1224 {
1221 1225 status = RTEMS_SUCCESSFUL;
1222 1226 }
1223 1227 }
1224 1228
1225 1229 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1226 1230 {
1227 1231 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1228 1232 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1229 1233 {
1230 1234 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1231 1235 }
1232 1236 else
1233 1237 {
1234 1238 status = RTEMS_SUCCESSFUL;
1235 1239 }
1236 1240 }
1237 1241
1238 1242 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1239 1243 {
1240 1244 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1241 1245 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1242 1246 {
1243 1247 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1244 1248 }
1245 1249 else
1246 1250 {
1247 1251 status = RTEMS_SUCCESSFUL;
1248 1252 }
1249 1253 }
1250 1254
1251 1255 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1252 1256 {
1253 1257 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1254 1258 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1255 1259 {
1256 1260 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1257 1261 }
1258 1262 else
1259 1263 {
1260 1264 status = RTEMS_SUCCESSFUL;
1261 1265 }
1262 1266 }
1263 1267
1264 1268 return status;
1265 1269 }
1266 1270
1267 1271 void launch_waveform_picker( unsigned char mode, unsigned int transitionCoarseTime )
1268 1272 {
1269 1273
1270 1274 WFP_reset_current_ring_nodes();
1271 1275
1272 1276 reset_waveform_picker_regs();
1273 1277
1274 1278 set_wfp_burst_enable_register( mode );
1275 1279
1276 1280 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER );
1277 1281 LEON_Unmask_interrupt( IRQ_WAVEFORM_PICKER );
1278 1282
1279 1283 if (transitionCoarseTime == 0)
1280 1284 {
1281 1285 // instant transition means transition on the next valid date
1282 1286 // this is mandatory to have a good snapshot period and a good correction of the snapshot period
1283 1287 waveform_picker_regs->start_date = time_management_regs->coarse_time + 1;
1284 1288 }
1285 1289 else
1286 1290 {
1287 1291 waveform_picker_regs->start_date = transitionCoarseTime;
1288 1292 }
1289 1293
1290 1294 update_last_valid_transition_date(waveform_picker_regs->start_date);
1291 1295
1292 1296 }
1293 1297
1294 1298 void launch_spectral_matrix( void )
1295 1299 {
1296 1300 SM_reset_current_ring_nodes();
1297 1301
1298 1302 reset_spectral_matrix_regs();
1299 1303
1300 1304 reset_nb_sm();
1301 1305
1302 1306 set_sm_irq_onNewMatrix( 1 );
1303 1307
1304 1308 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX );
1305 1309 LEON_Unmask_interrupt( IRQ_SPECTRAL_MATRIX );
1306 1310
1307 1311 }
1308 1312
1309 1313 void set_sm_irq_onNewMatrix( unsigned char value )
1310 1314 {
1311 1315 if (value == 1)
1312 1316 {
1313 1317 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x01;
1314 1318 }
1315 1319 else
1316 1320 {
1317 1321 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffe; // 1110
1318 1322 }
1319 1323 }
1320 1324
1321 1325 void set_sm_irq_onError( unsigned char value )
1322 1326 {
1323 1327 if (value == 1)
1324 1328 {
1325 1329 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x02;
1326 1330 }
1327 1331 else
1328 1332 {
1329 1333 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffd; // 1101
1330 1334 }
1331 1335 }
1332 1336
1333 1337 //*****************************
1334 1338 // CONFIGURE CALIBRATION SIGNAL
1335 1339 void setCalibrationPrescaler( unsigned int prescaler )
1336 1340 {
1337 1341 // prescaling of the master clock (25 MHz)
1338 1342 // master clock is divided by 2^prescaler
1339 1343 time_management_regs->calPrescaler = prescaler;
1340 1344 }
1341 1345
1342 1346 void setCalibrationDivisor( unsigned int divisionFactor )
1343 1347 {
1344 1348 // division of the prescaled clock by the division factor
1345 1349 time_management_regs->calDivisor = divisionFactor;
1346 1350 }
1347 1351
1348 1352 void setCalibrationData( void ){
1349 1353 unsigned int k;
1350 1354 unsigned short data;
1351 1355 float val;
1352 1356 float f0;
1353 1357 float f1;
1354 1358 float fs;
1355 1359 float Ts;
1356 1360 float scaleFactor;
1357 1361
1358 1362 f0 = 625;
1359 1363 f1 = 10000;
1360 1364 fs = 160256.410;
1361 1365 Ts = 1. / fs;
1362 1366 scaleFactor = 0.250 / 0.000654; // 191, 500 mVpp, 2 sinus waves => 500 mVpp each, amplitude = 250 mV
1363 1367
1364 1368 time_management_regs->calDataPtr = 0x00;
1365 1369
1366 1370 // build the signal for the SCM calibration
1367 1371 for (k=0; k<256; k++)
1368 1372 {
1369 1373 val = sin( 2 * pi * f0 * k * Ts )
1370 1374 + sin( 2 * pi * f1 * k * Ts );
1371 1375 data = (unsigned short) ((val * scaleFactor) + 2048);
1372 1376 time_management_regs->calData = data & 0xfff;
1373 1377 }
1374 1378 }
1375 1379
1376 1380 void setCalibrationDataInterleaved( void ){
1377 1381 unsigned int k;
1378 1382 float val;
1379 1383 float f0;
1380 1384 float f1;
1381 1385 float fs;
1382 1386 float Ts;
1383 1387 unsigned short data[384];
1384 1388 unsigned char *dataPtr;
1385 1389
1386 1390 f0 = 625;
1387 1391 f1 = 10000;
1388 1392 fs = 240384.615;
1389 1393 Ts = 1. / fs;
1390 1394
1391 1395 time_management_regs->calDataPtr = 0x00;
1392 1396
1393 1397 // build the signal for the SCM calibration
1394 1398 for (k=0; k<384; k++)
1395 1399 {
1396 1400 val = sin( 2 * pi * f0 * k * Ts )
1397 1401 + sin( 2 * pi * f1 * k * Ts );
1398 1402 data[k] = (unsigned short) (val * 512 + 2048);
1399 1403 }
1400 1404
1401 1405 // write the signal in interleaved mode
1402 1406 for (k=0; k<128; k++)
1403 1407 {
1404 1408 dataPtr = (unsigned char*) &data[k*3 + 2];
1405 1409 time_management_regs->calData = (data[k*3] & 0xfff)
1406 1410 + ( (dataPtr[0] & 0x3f) << 12);
1407 1411 time_management_regs->calData = (data[k*3 + 1] & 0xfff)
1408 1412 + ( (dataPtr[1] & 0x3f) << 12);
1409 1413 }
1410 1414 }
1411 1415
1412 1416 void setCalibrationReload( bool state)
1413 1417 {
1414 1418 if (state == true)
1415 1419 {
1416 1420 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000010; // [0001 0000]
1417 1421 }
1418 1422 else
1419 1423 {
1420 1424 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffef; // [1110 1111]
1421 1425 }
1422 1426 }
1423 1427
1424 1428 void setCalibrationEnable( bool state )
1425 1429 {
1426 1430 // this bit drives the multiplexer
1427 1431 if (state == true)
1428 1432 {
1429 1433 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000040; // [0100 0000]
1430 1434 }
1431 1435 else
1432 1436 {
1433 1437 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffbf; // [1011 1111]
1434 1438 }
1435 1439 }
1436 1440
1437 1441 void setCalibrationInterleaved( bool state )
1438 1442 {
1439 1443 // this bit drives the multiplexer
1440 1444 if (state == true)
1441 1445 {
1442 1446 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000020; // [0010 0000]
1443 1447 }
1444 1448 else
1445 1449 {
1446 1450 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffdf; // [1101 1111]
1447 1451 }
1448 1452 }
1449 1453
1450 1454 void setCalibration( bool state )
1451 1455 {
1452 1456 if (state == true)
1453 1457 {
1454 1458 setCalibrationEnable( true );
1455 1459 setCalibrationReload( false );
1456 1460 set_hk_lfr_calib_enable( true );
1457 1461 }
1458 1462 else
1459 1463 {
1460 1464 setCalibrationEnable( false );
1461 1465 setCalibrationReload( true );
1462 1466 set_hk_lfr_calib_enable( false );
1463 1467 }
1464 1468 }
1465 1469
1466 1470 void configureCalibration( bool interleaved )
1467 1471 {
1468 1472 setCalibration( false );
1469 1473 if ( interleaved == true )
1470 1474 {
1471 1475 setCalibrationInterleaved( true );
1472 1476 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1473 1477 setCalibrationDivisor( 26 ); // => 240 384
1474 1478 setCalibrationDataInterleaved();
1475 1479 }
1476 1480 else
1477 1481 {
1478 1482 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1479 1483 setCalibrationDivisor( 38 ); // => 160 256 (39 - 1)
1480 1484 setCalibrationData();
1481 1485 }
1482 1486 }
1483 1487
1484 1488 //****************
1485 1489 // CLOSING ACTIONS
1486 1490 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC, unsigned char * time )
1487 1491 {
1488 1492 /** This function is used to update the HK packets statistics after a successful TC execution.
1489 1493 *
1490 1494 * @param TC points to the TC being processed
1491 1495 * @param time is the time used to date the TC execution
1492 1496 *
1493 1497 */
1494 1498
1495 1499 unsigned int val;
1496 1500
1497 1501 housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
1498 1502 housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
1499 1503 housekeeping_packet.hk_lfr_last_exe_tc_type[0] = 0x00;
1500 1504 housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
1501 1505 housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = 0x00;
1502 1506 housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
1503 1507 housekeeping_packet.hk_lfr_last_exe_tc_time[0] = time[0];
1504 1508 housekeeping_packet.hk_lfr_last_exe_tc_time[1] = time[1];
1505 1509 housekeeping_packet.hk_lfr_last_exe_tc_time[2] = time[2];
1506 1510 housekeeping_packet.hk_lfr_last_exe_tc_time[3] = time[3];
1507 1511 housekeeping_packet.hk_lfr_last_exe_tc_time[4] = time[4];
1508 1512 housekeeping_packet.hk_lfr_last_exe_tc_time[5] = time[5];
1509 1513
1510 1514 val = housekeeping_packet.hk_lfr_exe_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
1511 1515 val++;
1512 1516 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> 8);
1513 1517 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
1514 1518 }
1515 1519
1516 1520 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC, unsigned char * time )
1517 1521 {
1518 1522 /** This function is used to update the HK packets statistics after a TC rejection.
1519 1523 *
1520 1524 * @param TC points to the TC being processed
1521 1525 * @param time is the time used to date the TC rejection
1522 1526 *
1523 1527 */
1524 1528
1525 1529 unsigned int val;
1526 1530
1527 1531 housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
1528 1532 housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
1529 1533 housekeeping_packet.hk_lfr_last_rej_tc_type[0] = 0x00;
1530 1534 housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
1531 1535 housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = 0x00;
1532 1536 housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
1533 1537 housekeeping_packet.hk_lfr_last_rej_tc_time[0] = time[0];
1534 1538 housekeeping_packet.hk_lfr_last_rej_tc_time[1] = time[1];
1535 1539 housekeeping_packet.hk_lfr_last_rej_tc_time[2] = time[2];
1536 1540 housekeeping_packet.hk_lfr_last_rej_tc_time[3] = time[3];
1537 1541 housekeeping_packet.hk_lfr_last_rej_tc_time[4] = time[4];
1538 1542 housekeeping_packet.hk_lfr_last_rej_tc_time[5] = time[5];
1539 1543
1540 1544 val = housekeeping_packet.hk_lfr_rej_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
1541 1545 val++;
1542 1546 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> 8);
1543 1547 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
1544 1548 }
1545 1549
1546 1550 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id )
1547 1551 {
1548 1552 /** This function is the last step of the TC execution workflow.
1549 1553 *
1550 1554 * @param TC points to the TC being processed
1551 1555 * @param result is the result of the TC execution (LFR_SUCCESSFUL / LFR_DEFAULT)
1552 1556 * @param queue_id is the id of the RTEMS message queue used to send TM packets
1553 1557 * @param time is the time used to date the TC execution
1554 1558 *
1555 1559 */
1556 1560
1557 1561 unsigned char requestedMode;
1558 1562
1559 1563 if (result == LFR_SUCCESSFUL)
1560 1564 {
1561 1565 if ( !( (TC->serviceType==TC_TYPE_TIME) & (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
1562 1566 &
1563 1567 !( (TC->serviceType==TC_TYPE_GEN) & (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
1564 1568 )
1565 1569 {
1566 1570 send_tm_lfr_tc_exe_success( TC, queue_id );
1567 1571 }
1568 1572 if ( (TC->serviceType == TC_TYPE_GEN) & (TC->serviceSubType == TC_SUBTYPE_ENTER) )
1569 1573 {
1570 1574 //**********************************
1571 1575 // UPDATE THE LFRMODE LOCAL VARIABLE
1572 1576 requestedMode = TC->dataAndCRC[1];
1573 1577 updateLFRCurrentMode( requestedMode );
1574 1578 }
1575 1579 }
1576 1580 else if (result == LFR_EXE_ERROR)
1577 1581 {
1578 1582 send_tm_lfr_tc_exe_error( TC, queue_id );
1579 1583 }
1580 1584 }
1581 1585
1582 1586 //***************************
1583 1587 // Interrupt Service Routines
1584 1588 rtems_isr commutation_isr1( rtems_vector_number vector )
1585 1589 {
1586 1590 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1587 1591 PRINTF("In commutation_isr1 *** Error sending event to DUMB\n")
1588 1592 }
1589 1593 }
1590 1594
1591 1595 rtems_isr commutation_isr2( rtems_vector_number vector )
1592 1596 {
1593 1597 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1594 1598 PRINTF("In commutation_isr2 *** Error sending event to DUMB\n")
1595 1599 }
1596 1600 }
1597 1601
1598 1602 //****************
1599 1603 // OTHER FUNCTIONS
1600 1604 void updateLFRCurrentMode( unsigned char requestedMode )
1601 1605 {
1602 1606 /** This function updates the value of the global variable lfrCurrentMode.
1603 1607 *
1604 1608 * lfrCurrentMode is a parameter used by several functions to know in which mode LFR is running.
1605 1609 *
1606 1610 */
1607 1611
1608 1612 // update the local value of lfrCurrentMode with the value contained in the housekeeping_packet structure
1609 1613 housekeeping_packet.lfr_status_word[0] = (unsigned char) ((requestedMode << 4) + 0x0d);
1610 1614 lfrCurrentMode = requestedMode;
1611 1615 }
1612 1616
1613 1617 void set_lfr_soft_reset( unsigned char value )
1614 1618 {
1615 1619 if (value == 1)
1616 1620 {
1617 1621 time_management_regs->ctrl = time_management_regs->ctrl | 0x00000004; // [0100]
1618 1622 }
1619 1623 else
1620 1624 {
1621 1625 time_management_regs->ctrl = time_management_regs->ctrl & 0xfffffffb; // [1011]
1622 1626 }
1623 1627 }
1624 1628
1625 1629 void reset_lfr( void )
1626 1630 {
1627 1631 set_lfr_soft_reset( 1 );
1628 1632
1629 1633 set_lfr_soft_reset( 0 );
1630 1634
1631 1635 set_hk_lfr_sc_potential_flag( true );
1632 1636 }
@@ -1,1201 +1,1280
1 1 /** Functions to load and dump parameters in the LFR registers.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * A group of functions to handle TC related to parameter loading and dumping.\n
7 7 * TC_LFR_LOAD_COMMON_PAR\n
8 8 * TC_LFR_LOAD_NORMAL_PAR\n
9 9 * TC_LFR_LOAD_BURST_PAR\n
10 10 * TC_LFR_LOAD_SBM1_PAR\n
11 11 * TC_LFR_LOAD_SBM2_PAR\n
12 12 *
13 13 */
14 14
15 15 #include "tc_load_dump_parameters.h"
16 16
17 17 Packet_TM_LFR_KCOEFFICIENTS_DUMP_t kcoefficients_dump_1;
18 18 Packet_TM_LFR_KCOEFFICIENTS_DUMP_t kcoefficients_dump_2;
19 19 ring_node kcoefficient_node_1;
20 20 ring_node kcoefficient_node_2;
21 21
22 22 int action_load_common_par(ccsdsTelecommandPacket_t *TC)
23 23 {
24 24 /** This function updates the LFR registers with the incoming common parameters.
25 25 *
26 26 * @param TC points to the TeleCommand packet that is being processed
27 27 *
28 28 *
29 29 */
30 30
31 31 parameter_dump_packet.sy_lfr_common_parameters_spare = TC->dataAndCRC[0];
32 32 parameter_dump_packet.sy_lfr_common_parameters = TC->dataAndCRC[1];
33 33 set_wfp_data_shaping( );
34 34 return LFR_SUCCESSFUL;
35 35 }
36 36
37 37 int action_load_normal_par(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
38 38 {
39 39 /** This function updates the LFR registers with the incoming normal parameters.
40 40 *
41 41 * @param TC points to the TeleCommand packet that is being processed
42 42 * @param queue_id is the id of the queue which handles TM related to this execution step
43 43 *
44 44 */
45 45
46 46 int result;
47 47 int flag;
48 48 rtems_status_code status;
49 49
50 50 flag = LFR_SUCCESSFUL;
51 51
52 52 if ( (lfrCurrentMode == LFR_MODE_NORMAL) ||
53 53 (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) {
54 54 status = send_tm_lfr_tc_exe_not_executable( TC, queue_id );
55 55 flag = LFR_DEFAULT;
56 56 }
57 57
58 58 // CHECK THE PARAMETERS SET CONSISTENCY
59 59 if (flag == LFR_SUCCESSFUL)
60 60 {
61 61 flag = check_normal_par_consistency( TC, queue_id );
62 62 }
63 63
64 64 // SET THE PARAMETERS IF THEY ARE CONSISTENT
65 65 if (flag == LFR_SUCCESSFUL)
66 66 {
67 67 result = set_sy_lfr_n_swf_l( TC );
68 68 result = set_sy_lfr_n_swf_p( TC );
69 69 result = set_sy_lfr_n_bp_p0( TC );
70 70 result = set_sy_lfr_n_bp_p1( TC );
71 71 result = set_sy_lfr_n_asm_p( TC );
72 72 result = set_sy_lfr_n_cwf_long_f3( TC );
73 73 }
74 74
75 75 return flag;
76 76 }
77 77
78 78 int action_load_burst_par(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
79 79 {
80 80 /** This function updates the LFR registers with the incoming burst parameters.
81 81 *
82 82 * @param TC points to the TeleCommand packet that is being processed
83 83 * @param queue_id is the id of the queue which handles TM related to this execution step
84 84 *
85 85 */
86 86
87 87 int flag;
88 88 rtems_status_code status;
89 89 unsigned char sy_lfr_b_bp_p0;
90 90 unsigned char sy_lfr_b_bp_p1;
91 91 float aux;
92 92
93 93 flag = LFR_SUCCESSFUL;
94 94
95 95 if ( lfrCurrentMode == LFR_MODE_BURST ) {
96 96 status = send_tm_lfr_tc_exe_not_executable( TC, queue_id );
97 97 flag = LFR_DEFAULT;
98 98 }
99 99
100 100 sy_lfr_b_bp_p0 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_B_BP_P0 ];
101 101 sy_lfr_b_bp_p1 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_B_BP_P1 ];
102 102
103 103 // sy_lfr_b_bp_p0 shall not be lower than its default value
104 104 if (flag == LFR_SUCCESSFUL)
105 105 {
106 106 if (sy_lfr_b_bp_p0 < DEFAULT_SY_LFR_B_BP_P0 )
107 107 {
108 108 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_B_BP_P0+10, sy_lfr_b_bp_p0 );
109 109 flag = WRONG_APP_DATA;
110 110 }
111 111 }
112 112 // sy_lfr_b_bp_p1 shall not be lower than its default value
113 113 if (flag == LFR_SUCCESSFUL)
114 114 {
115 115 if (sy_lfr_b_bp_p1 < DEFAULT_SY_LFR_B_BP_P1 )
116 116 {
117 117 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_B_BP_P1+10, sy_lfr_b_bp_p1 );
118 118 flag = WRONG_APP_DATA;
119 119 }
120 120 }
121 121 //****************************************************************
122 122 // check the consistency between sy_lfr_b_bp_p0 and sy_lfr_b_bp_p1
123 123 if (flag == LFR_SUCCESSFUL)
124 124 {
125 125 sy_lfr_b_bp_p0 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_B_BP_P0 ];
126 126 sy_lfr_b_bp_p1 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_B_BP_P1 ];
127 127 aux = ( (float ) sy_lfr_b_bp_p1 / sy_lfr_b_bp_p0 ) - floor(sy_lfr_b_bp_p1 / sy_lfr_b_bp_p0);
128 128 if (aux > FLOAT_EQUAL_ZERO)
129 129 {
130 130 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_B_BP_P0+10, sy_lfr_b_bp_p0 );
131 131 flag = LFR_DEFAULT;
132 132 }
133 133 }
134 134
135 135 // SET THE PARAMETERS
136 136 if (flag == LFR_SUCCESSFUL)
137 137 {
138 138 flag = set_sy_lfr_b_bp_p0( TC );
139 139 flag = set_sy_lfr_b_bp_p1( TC );
140 140 }
141 141
142 142 return flag;
143 143 }
144 144
145 145 int action_load_sbm1_par(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
146 146 {
147 147 /** This function updates the LFR registers with the incoming sbm1 parameters.
148 148 *
149 149 * @param TC points to the TeleCommand packet that is being processed
150 150 * @param queue_id is the id of the queue which handles TM related to this execution step
151 151 *
152 152 */
153 153
154 154 int flag;
155 155 rtems_status_code status;
156 156 unsigned char sy_lfr_s1_bp_p0;
157 157 unsigned char sy_lfr_s1_bp_p1;
158 158 float aux;
159 159
160 160 flag = LFR_SUCCESSFUL;
161 161
162 162 if ( lfrCurrentMode == LFR_MODE_SBM1 ) {
163 163 status = send_tm_lfr_tc_exe_not_executable( TC, queue_id );
164 164 flag = LFR_DEFAULT;
165 165 }
166 166
167 167 sy_lfr_s1_bp_p0 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_S1_BP_P0 ];
168 168 sy_lfr_s1_bp_p1 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_S1_BP_P1 ];
169 169
170 170 // sy_lfr_s1_bp_p0
171 171 if (flag == LFR_SUCCESSFUL)
172 172 {
173 173 if (sy_lfr_s1_bp_p0 < DEFAULT_SY_LFR_S1_BP_P0 )
174 174 {
175 175 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_S1_BP_P0+10, sy_lfr_s1_bp_p0 );
176 176 flag = WRONG_APP_DATA;
177 177 }
178 178 }
179 179 // sy_lfr_s1_bp_p1
180 180 if (flag == LFR_SUCCESSFUL)
181 181 {
182 182 if (sy_lfr_s1_bp_p1 < DEFAULT_SY_LFR_S1_BP_P1 )
183 183 {
184 184 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_S1_BP_P1+10, sy_lfr_s1_bp_p1 );
185 185 flag = WRONG_APP_DATA;
186 186 }
187 187 }
188 188 //******************************************************************
189 189 // check the consistency between sy_lfr_s1_bp_p0 and sy_lfr_s1_bp_p1
190 190 if (flag == LFR_SUCCESSFUL)
191 191 {
192 192 aux = ( (float ) sy_lfr_s1_bp_p1 / (sy_lfr_s1_bp_p0*0.25) ) - floor(sy_lfr_s1_bp_p1 / (sy_lfr_s1_bp_p0*0.25));
193 193 if (aux > FLOAT_EQUAL_ZERO)
194 194 {
195 195 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_S1_BP_P0+10, sy_lfr_s1_bp_p0 );
196 196 flag = LFR_DEFAULT;
197 197 }
198 198 }
199 199
200 200 // SET THE PARAMETERS
201 201 if (flag == LFR_SUCCESSFUL)
202 202 {
203 203 flag = set_sy_lfr_s1_bp_p0( TC );
204 204 flag = set_sy_lfr_s1_bp_p1( TC );
205 205 }
206 206
207 207 return flag;
208 208 }
209 209
210 210 int action_load_sbm2_par(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
211 211 {
212 212 /** This function updates the LFR registers with the incoming sbm2 parameters.
213 213 *
214 214 * @param TC points to the TeleCommand packet that is being processed
215 215 * @param queue_id is the id of the queue which handles TM related to this execution step
216 216 *
217 217 */
218 218
219 219 int flag;
220 220 rtems_status_code status;
221 221 unsigned char sy_lfr_s2_bp_p0;
222 222 unsigned char sy_lfr_s2_bp_p1;
223 223 float aux;
224 224
225 225 flag = LFR_SUCCESSFUL;
226 226
227 227 if ( lfrCurrentMode == LFR_MODE_SBM2 ) {
228 228 status = send_tm_lfr_tc_exe_not_executable( TC, queue_id );
229 229 flag = LFR_DEFAULT;
230 230 }
231 231
232 232 sy_lfr_s2_bp_p0 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_S2_BP_P0 ];
233 233 sy_lfr_s2_bp_p1 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_S2_BP_P1 ];
234 234
235 235 // sy_lfr_s2_bp_p0
236 236 if (flag == LFR_SUCCESSFUL)
237 237 {
238 238 if (sy_lfr_s2_bp_p0 < DEFAULT_SY_LFR_S2_BP_P0 )
239 239 {
240 240 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_S2_BP_P0+10, sy_lfr_s2_bp_p0 );
241 241 flag = WRONG_APP_DATA;
242 242 }
243 243 }
244 244 // sy_lfr_s2_bp_p1
245 245 if (flag == LFR_SUCCESSFUL)
246 246 {
247 247 if (sy_lfr_s2_bp_p1 < DEFAULT_SY_LFR_S2_BP_P1 )
248 248 {
249 249 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_S2_BP_P1+10, sy_lfr_s2_bp_p1 );
250 250 flag = WRONG_APP_DATA;
251 251 }
252 252 }
253 253 //******************************************************************
254 254 // check the consistency between sy_lfr_s2_bp_p0 and sy_lfr_s2_bp_p1
255 255 if (flag == LFR_SUCCESSFUL)
256 256 {
257 257 sy_lfr_s2_bp_p0 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_S2_BP_P0 ];
258 258 sy_lfr_s2_bp_p1 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_S2_BP_P1 ];
259 259 aux = ( (float ) sy_lfr_s2_bp_p1 / sy_lfr_s2_bp_p0 ) - floor(sy_lfr_s2_bp_p1 / sy_lfr_s2_bp_p0);
260 260 if (aux > FLOAT_EQUAL_ZERO)
261 261 {
262 262 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_S2_BP_P0+10, sy_lfr_s2_bp_p0 );
263 263 flag = LFR_DEFAULT;
264 264 }
265 265 }
266 266
267 267 // SET THE PARAMETERS
268 268 if (flag == LFR_SUCCESSFUL)
269 269 {
270 270 flag = set_sy_lfr_s2_bp_p0( TC );
271 271 flag = set_sy_lfr_s2_bp_p1( TC );
272 272 }
273 273
274 274 return flag;
275 275 }
276 276
277 277 int action_load_kcoefficients(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
278 278 {
279 279 /** This function updates the LFR registers with the incoming sbm2 parameters.
280 280 *
281 281 * @param TC points to the TeleCommand packet that is being processed
282 282 * @param queue_id is the id of the queue which handles TM related to this execution step
283 283 *
284 284 */
285 285
286 286 int flag;
287 287
288 288 flag = LFR_DEFAULT;
289 289
290 290 flag = set_sy_lfr_kcoeff( TC, queue_id );
291 291
292 292 return flag;
293 293 }
294 294
295 295 int action_load_fbins_mask(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
296 296 {
297 297 /** This function updates the LFR registers with the incoming sbm2 parameters.
298 298 *
299 299 * @param TC points to the TeleCommand packet that is being processed
300 300 * @param queue_id is the id of the queue which handles TM related to this execution step
301 301 *
302 302 */
303 303
304 304 int flag;
305 305
306 306 flag = LFR_DEFAULT;
307 307
308 308 flag = set_sy_lfr_fbins( TC );
309 309
310 310 return flag;
311 311 }
312 312
313 int action_load_pas_filter_par(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
314 {
315 /** This function updates the LFR registers with the incoming sbm2 parameters.
316 *
317 * @param TC points to the TeleCommand packet that is being processed
318 * @param queue_id is the id of the queue which handles TM related to this execution step
319 *
320 */
321
322 int flag;
323
324 flag = LFR_DEFAULT;
325
326 flag = check_sy_lfr_pas_filter_parameters( TC, queue_id );
327
328 if (flag == LFR_SUCCESSFUL)
329 {
330 parameter_dump_packet.spare_sy_lfr_pas_filter_enabled = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_PAS_FILTER_ENABLED ];
331 parameter_dump_packet.sy_lfr_pas_filter_modulus = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_PAS_FILTER_MODULUS ];
332 parameter_dump_packet.sy_lfr_pas_filter_nstd = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_PAS_FILTER_NSTD ];
333 parameter_dump_packet.sy_lfr_pas_filter_offset = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_PAS_FILTER_OFFSET ];
334 }
335
336 return flag;
337 }
338
313 339 int action_dump_kcoefficients(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
314 340 {
315 341 /** This function updates the LFR registers with the incoming sbm2 parameters.
316 342 *
317 343 * @param TC points to the TeleCommand packet that is being processed
318 344 * @param queue_id is the id of the queue which handles TM related to this execution step
319 345 *
320 346 */
321 347
322 348 unsigned int address;
323 349 rtems_status_code status;
324 350 unsigned int freq;
325 351 unsigned int bin;
326 352 unsigned int coeff;
327 353 unsigned char *kCoeffPtr;
328 354 unsigned char *kCoeffDumpPtr;
329 355
330 356 // for each sy_lfr_kcoeff_frequency there is 32 kcoeff
331 357 // F0 => 11 bins
332 358 // F1 => 13 bins
333 359 // F2 => 12 bins
334 360 // 36 bins to dump in two packets (30 bins max per packet)
335 361
336 362 //*********
337 363 // PACKET 1
338 364 // 11 F0 bins, 13 F1 bins and 6 F2 bins
339 365 kcoefficients_dump_1.destinationID = TC->sourceID;
340 366 increment_seq_counter_destination_id_dump( kcoefficients_dump_1.packetSequenceControl, TC->sourceID );
341 367 for( freq=0;
342 368 freq<NB_BINS_COMPRESSED_SM_F0;
343 369 freq++ )
344 370 {
345 371 kcoefficients_dump_1.kcoeff_blks[ freq*KCOEFF_BLK_SIZE + 1] = freq;
346 372 bin = freq;
347 373 // printKCoefficients( freq, bin, k_coeff_intercalib_f0_norm);
348 374 for ( coeff=0; coeff<NB_K_COEFF_PER_BIN; coeff++ )
349 375 {
350 376 kCoeffDumpPtr = (unsigned char*) &kcoefficients_dump_1.kcoeff_blks[ freq*KCOEFF_BLK_SIZE + coeff*NB_BYTES_PER_FLOAT + 2 ]; // 2 for the kcoeff_frequency
351 377 kCoeffPtr = (unsigned char*) &k_coeff_intercalib_f0_norm[ (bin*NB_K_COEFF_PER_BIN) + coeff ];
352 378 copyFloatByChar( kCoeffDumpPtr, kCoeffPtr );
353 379 }
354 380 }
355 381 for( freq=NB_BINS_COMPRESSED_SM_F0;
356 382 freq<(NB_BINS_COMPRESSED_SM_F0+NB_BINS_COMPRESSED_SM_F1);
357 383 freq++ )
358 384 {
359 385 kcoefficients_dump_1.kcoeff_blks[ freq*KCOEFF_BLK_SIZE + 1 ] = freq;
360 386 bin = freq - NB_BINS_COMPRESSED_SM_F0;
361 387 // printKCoefficients( freq, bin, k_coeff_intercalib_f1_norm);
362 388 for ( coeff=0; coeff<NB_K_COEFF_PER_BIN; coeff++ )
363 389 {
364 390 kCoeffDumpPtr = (unsigned char*) &kcoefficients_dump_1.kcoeff_blks[ freq*KCOEFF_BLK_SIZE + coeff*NB_BYTES_PER_FLOAT + 2 ]; // 2 for the kcoeff_frequency
365 391 kCoeffPtr = (unsigned char*) &k_coeff_intercalib_f1_norm[ (bin*NB_K_COEFF_PER_BIN) + coeff ];
366 392 copyFloatByChar( kCoeffDumpPtr, kCoeffPtr );
367 393 }
368 394 }
369 395 for( freq=(NB_BINS_COMPRESSED_SM_F0+NB_BINS_COMPRESSED_SM_F1);
370 396 freq<(NB_BINS_COMPRESSED_SM_F0+NB_BINS_COMPRESSED_SM_F1+6);
371 397 freq++ )
372 398 {
373 399 kcoefficients_dump_1.kcoeff_blks[ freq*KCOEFF_BLK_SIZE + 1 ] = freq;
374 400 bin = freq - (NB_BINS_COMPRESSED_SM_F0+NB_BINS_COMPRESSED_SM_F1);
375 401 // printKCoefficients( freq, bin, k_coeff_intercalib_f2);
376 402 for ( coeff=0; coeff<NB_K_COEFF_PER_BIN; coeff++ )
377 403 {
378 404 kCoeffDumpPtr = (unsigned char*) &kcoefficients_dump_1.kcoeff_blks[ freq*KCOEFF_BLK_SIZE + coeff*NB_BYTES_PER_FLOAT + 2 ]; // 2 for the kcoeff_frequency
379 405 kCoeffPtr = (unsigned char*) &k_coeff_intercalib_f2[ (bin*NB_K_COEFF_PER_BIN) + coeff ];
380 406 copyFloatByChar( kCoeffDumpPtr, kCoeffPtr );
381 407 }
382 408 }
383 409 kcoefficients_dump_1.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
384 410 kcoefficients_dump_1.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
385 411 kcoefficients_dump_1.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
386 412 kcoefficients_dump_1.time[3] = (unsigned char) (time_management_regs->coarse_time);
387 413 kcoefficients_dump_1.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
388 414 kcoefficients_dump_1.time[5] = (unsigned char) (time_management_regs->fine_time);
389 415 // SEND DATA
390 416 kcoefficient_node_1.status = 1;
391 417 address = (unsigned int) &kcoefficient_node_1;
392 418 status = rtems_message_queue_send( queue_id, &address, sizeof( ring_node* ) );
393 419 if (status != RTEMS_SUCCESSFUL) {
394 420 PRINTF1("in action_dump_kcoefficients *** ERR sending packet 1 , code %d", status)
395 421 }
396 422
397 423 //********
398 424 // PACKET 2
399 425 // 6 F2 bins
400 426 kcoefficients_dump_2.destinationID = TC->sourceID;
401 427 increment_seq_counter_destination_id_dump( kcoefficients_dump_2.packetSequenceControl, TC->sourceID );
402 428 for( freq=0; freq<6; freq++ )
403 429 {
404 430 kcoefficients_dump_2.kcoeff_blks[ freq*KCOEFF_BLK_SIZE + 1 ] = NB_BINS_COMPRESSED_SM_F0 + NB_BINS_COMPRESSED_SM_F1 + 6 + freq;
405 431 bin = freq + 6;
406 432 // printKCoefficients( freq, bin, k_coeff_intercalib_f2);
407 433 for ( coeff=0; coeff<NB_K_COEFF_PER_BIN; coeff++ )
408 434 {
409 435 kCoeffDumpPtr = (unsigned char*) &kcoefficients_dump_2.kcoeff_blks[ freq*KCOEFF_BLK_SIZE + coeff*NB_BYTES_PER_FLOAT + 2 ]; // 2 for the kcoeff_frequency
410 436 kCoeffPtr = (unsigned char*) &k_coeff_intercalib_f2[ (bin*NB_K_COEFF_PER_BIN) + coeff ];
411 437 copyFloatByChar( kCoeffDumpPtr, kCoeffPtr );
412 438 }
413 439 }
414 440 kcoefficients_dump_2.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
415 441 kcoefficients_dump_2.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
416 442 kcoefficients_dump_2.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
417 443 kcoefficients_dump_2.time[3] = (unsigned char) (time_management_regs->coarse_time);
418 444 kcoefficients_dump_2.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
419 445 kcoefficients_dump_2.time[5] = (unsigned char) (time_management_regs->fine_time);
420 446 // SEND DATA
421 447 kcoefficient_node_2.status = 1;
422 448 address = (unsigned int) &kcoefficient_node_2;
423 449 status = rtems_message_queue_send( queue_id, &address, sizeof( ring_node* ) );
424 450 if (status != RTEMS_SUCCESSFUL) {
425 451 PRINTF1("in action_dump_kcoefficients *** ERR sending packet 2, code %d", status)
426 452 }
427 453
428 454 return status;
429 455 }
430 456
431 457 int action_dump_par( ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
432 458 {
433 459 /** This function dumps the LFR parameters by sending the appropriate TM packet to the dedicated RTEMS message queue.
434 460 *
435 461 * @param queue_id is the id of the queue which handles TM related to this execution step.
436 462 *
437 463 * @return RTEMS directive status codes:
438 464 * - RTEMS_SUCCESSFUL - message sent successfully
439 465 * - RTEMS_INVALID_ID - invalid queue id
440 466 * - RTEMS_INVALID_SIZE - invalid message size
441 467 * - RTEMS_INVALID_ADDRESS - buffer is NULL
442 468 * - RTEMS_UNSATISFIED - out of message buffers
443 469 * - RTEMS_TOO_MANY - queue s limit has been reached
444 470 *
445 471 */
446 472
447 473 int status;
448 474
449 475 increment_seq_counter_destination_id_dump( parameter_dump_packet.packetSequenceControl, TC->sourceID );
450 476 parameter_dump_packet.destinationID = TC->sourceID;
451 477
452 478 // UPDATE TIME
453 479 parameter_dump_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
454 480 parameter_dump_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
455 481 parameter_dump_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
456 482 parameter_dump_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
457 483 parameter_dump_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
458 484 parameter_dump_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
459 485 // SEND DATA
460 486 status = rtems_message_queue_send( queue_id, &parameter_dump_packet,
461 487 PACKET_LENGTH_PARAMETER_DUMP + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
462 488 if (status != RTEMS_SUCCESSFUL) {
463 489 PRINTF1("in action_dump *** ERR sending packet, code %d", status)
464 490 }
465 491
466 492 return status;
467 493 }
468 494
469 495 //***********************
470 496 // NORMAL MODE PARAMETERS
471 497
472 498 int check_normal_par_consistency( ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
473 499 {
474 500 unsigned char msb;
475 501 unsigned char lsb;
476 502 int flag;
477 503 float aux;
478 504 rtems_status_code status;
479 505
480 506 unsigned int sy_lfr_n_swf_l;
481 507 unsigned int sy_lfr_n_swf_p;
482 508 unsigned int sy_lfr_n_asm_p;
483 509 unsigned char sy_lfr_n_bp_p0;
484 510 unsigned char sy_lfr_n_bp_p1;
485 511 unsigned char sy_lfr_n_cwf_long_f3;
486 512
487 513 flag = LFR_SUCCESSFUL;
488 514
489 515 //***************
490 516 // get parameters
491 517 msb = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_SWF_L ];
492 518 lsb = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_SWF_L+1 ];
493 519 sy_lfr_n_swf_l = msb * 256 + lsb;
494 520
495 521 msb = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_SWF_P ];
496 522 lsb = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_SWF_P+1 ];
497 523 sy_lfr_n_swf_p = msb * 256 + lsb;
498 524
499 525 msb = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_ASM_P ];
500 526 lsb = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_ASM_P+1 ];
501 527 sy_lfr_n_asm_p = msb * 256 + lsb;
502 528
503 529 sy_lfr_n_bp_p0 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_BP_P0 ];
504 530
505 531 sy_lfr_n_bp_p1 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_BP_P1 ];
506 532
507 533 sy_lfr_n_cwf_long_f3 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_CWF_LONG_F3 ];
508 534
509 535 //******************
510 536 // check consistency
511 537 // sy_lfr_n_swf_l
512 538 if (sy_lfr_n_swf_l != 2048)
513 539 {
514 540 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_N_SWF_L+10, sy_lfr_n_swf_l );
515 541 flag = WRONG_APP_DATA;
516 542 }
517 543 // sy_lfr_n_swf_p
518 544 if (flag == LFR_SUCCESSFUL)
519 545 {
520 546 if ( sy_lfr_n_swf_p < 22 )
521 547 {
522 548 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_N_SWF_P+10, sy_lfr_n_swf_p );
523 549 flag = WRONG_APP_DATA;
524 550 }
525 551 }
526 552 // sy_lfr_n_bp_p0
527 553 if (flag == LFR_SUCCESSFUL)
528 554 {
529 555 if (sy_lfr_n_bp_p0 < DFLT_SY_LFR_N_BP_P0)
530 556 {
531 557 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_N_BP_P0+10, sy_lfr_n_bp_p0 );
532 558 flag = WRONG_APP_DATA;
533 559 }
534 560 }
535 561 // sy_lfr_n_asm_p
536 562 if (flag == LFR_SUCCESSFUL)
537 563 {
538 564 if (sy_lfr_n_asm_p == 0)
539 565 {
540 566 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_N_ASM_P+10, sy_lfr_n_asm_p );
541 567 flag = WRONG_APP_DATA;
542 568 }
543 569 }
544 570 // sy_lfr_n_asm_p shall be a whole multiple of sy_lfr_n_bp_p0
545 571 if (flag == LFR_SUCCESSFUL)
546 572 {
547 573 aux = ( (float ) sy_lfr_n_asm_p / sy_lfr_n_bp_p0 ) - floor(sy_lfr_n_asm_p / sy_lfr_n_bp_p0);
548 574 if (aux > FLOAT_EQUAL_ZERO)
549 575 {
550 576 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_N_ASM_P+10, sy_lfr_n_asm_p );
551 577 flag = WRONG_APP_DATA;
552 578 }
553 579 }
554 580 // sy_lfr_n_bp_p1
555 581 if (flag == LFR_SUCCESSFUL)
556 582 {
557 583 if (sy_lfr_n_bp_p1 < DFLT_SY_LFR_N_BP_P1)
558 584 {
559 585 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_N_BP_P1+10, sy_lfr_n_bp_p1 );
560 586 flag = WRONG_APP_DATA;
561 587 }
562 588 }
563 589 // sy_lfr_n_bp_p1 shall be a whole multiple of sy_lfr_n_bp_p0
564 590 if (flag == LFR_SUCCESSFUL)
565 591 {
566 592 aux = ( (float ) sy_lfr_n_bp_p1 / sy_lfr_n_bp_p0 ) - floor(sy_lfr_n_bp_p1 / sy_lfr_n_bp_p0);
567 593 if (aux > FLOAT_EQUAL_ZERO)
568 594 {
569 595 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_N_BP_P1+10, sy_lfr_n_bp_p1 );
570 596 flag = LFR_DEFAULT;
571 597 }
572 598 }
573 599 // sy_lfr_n_cwf_long_f3
574 600
575 601 return flag;
576 602 }
577 603
578 604 int set_sy_lfr_n_swf_l( ccsdsTelecommandPacket_t *TC )
579 605 {
580 606 /** This function sets the number of points of a snapshot (sy_lfr_n_swf_l).
581 607 *
582 608 * @param TC points to the TeleCommand packet that is being processed
583 609 * @param queue_id is the id of the queue which handles TM related to this execution step
584 610 *
585 611 */
586 612
587 613 int result;
588 614
589 615 result = LFR_SUCCESSFUL;
590 616
591 617 parameter_dump_packet.sy_lfr_n_swf_l[0] = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_SWF_L ];
592 618 parameter_dump_packet.sy_lfr_n_swf_l[1] = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_SWF_L+1 ];
593 619
594 620 return result;
595 621 }
596 622
597 623 int set_sy_lfr_n_swf_p(ccsdsTelecommandPacket_t *TC )
598 624 {
599 625 /** This function sets the time between two snapshots, in s (sy_lfr_n_swf_p).
600 626 *
601 627 * @param TC points to the TeleCommand packet that is being processed
602 628 * @param queue_id is the id of the queue which handles TM related to this execution step
603 629 *
604 630 */
605 631
606 632 int result;
607 633
608 634 result = LFR_SUCCESSFUL;
609 635
610 636 parameter_dump_packet.sy_lfr_n_swf_p[0] = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_SWF_P ];
611 637 parameter_dump_packet.sy_lfr_n_swf_p[1] = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_SWF_P+1 ];
612 638
613 639 return result;
614 640 }
615 641
616 642 int set_sy_lfr_n_asm_p( ccsdsTelecommandPacket_t *TC )
617 643 {
618 644 /** This function sets the time between two full spectral matrices transmission, in s (SY_LFR_N_ASM_P).
619 645 *
620 646 * @param TC points to the TeleCommand packet that is being processed
621 647 * @param queue_id is the id of the queue which handles TM related to this execution step
622 648 *
623 649 */
624 650
625 651 int result;
626 652
627 653 result = LFR_SUCCESSFUL;
628 654
629 655 parameter_dump_packet.sy_lfr_n_asm_p[0] = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_ASM_P ];
630 656 parameter_dump_packet.sy_lfr_n_asm_p[1] = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_ASM_P+1 ];
631 657
632 658 return result;
633 659 }
634 660
635 661 int set_sy_lfr_n_bp_p0( ccsdsTelecommandPacket_t *TC )
636 662 {
637 663 /** This function sets the time between two basic parameter sets, in s (DFLT_SY_LFR_N_BP_P0).
638 664 *
639 665 * @param TC points to the TeleCommand packet that is being processed
640 666 * @param queue_id is the id of the queue which handles TM related to this execution step
641 667 *
642 668 */
643 669
644 670 int status;
645 671
646 672 status = LFR_SUCCESSFUL;
647 673
648 674 parameter_dump_packet.sy_lfr_n_bp_p0 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_BP_P0 ];
649 675
650 676 return status;
651 677 }
652 678
653 679 int set_sy_lfr_n_bp_p1(ccsdsTelecommandPacket_t *TC )
654 680 {
655 681 /** This function sets the time between two basic parameter sets (autocorrelation + crosscorrelation), in s (sy_lfr_n_bp_p1).
656 682 *
657 683 * @param TC points to the TeleCommand packet that is being processed
658 684 * @param queue_id is the id of the queue which handles TM related to this execution step
659 685 *
660 686 */
661 687
662 688 int status;
663 689
664 690 status = LFR_SUCCESSFUL;
665 691
666 692 parameter_dump_packet.sy_lfr_n_bp_p1 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_BP_P1 ];
667 693
668 694 return status;
669 695 }
670 696
671 697 int set_sy_lfr_n_cwf_long_f3(ccsdsTelecommandPacket_t *TC )
672 698 {
673 699 /** This function allows to switch from CWF_F3 packets to CWF_LONG_F3 packets.
674 700 *
675 701 * @param TC points to the TeleCommand packet that is being processed
676 702 * @param queue_id is the id of the queue which handles TM related to this execution step
677 703 *
678 704 */
679 705
680 706 int status;
681 707
682 708 status = LFR_SUCCESSFUL;
683 709
684 710 parameter_dump_packet.sy_lfr_n_cwf_long_f3 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_N_CWF_LONG_F3 ];
685 711
686 712 return status;
687 713 }
688 714
689 715 //**********************
690 716 // BURST MODE PARAMETERS
691 717 int set_sy_lfr_b_bp_p0(ccsdsTelecommandPacket_t *TC)
692 718 {
693 719 /** This function sets the time between two basic parameter sets, in s (SY_LFR_B_BP_P0).
694 720 *
695 721 * @param TC points to the TeleCommand packet that is being processed
696 722 * @param queue_id is the id of the queue which handles TM related to this execution step
697 723 *
698 724 */
699 725
700 726 int status;
701 727
702 728 status = LFR_SUCCESSFUL;
703 729
704 730 parameter_dump_packet.sy_lfr_b_bp_p0 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_B_BP_P0 ];
705 731
706 732 return status;
707 733 }
708 734
709 735 int set_sy_lfr_b_bp_p1( ccsdsTelecommandPacket_t *TC )
710 736 {
711 737 /** This function sets the time between two basic parameter sets, in s (SY_LFR_B_BP_P1).
712 738 *
713 739 * @param TC points to the TeleCommand packet that is being processed
714 740 * @param queue_id is the id of the queue which handles TM related to this execution step
715 741 *
716 742 */
717 743
718 744 int status;
719 745
720 746 status = LFR_SUCCESSFUL;
721 747
722 748 parameter_dump_packet.sy_lfr_b_bp_p1 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_B_BP_P1 ];
723 749
724 750 return status;
725 751 }
726 752
727 753 //*********************
728 754 // SBM1 MODE PARAMETERS
729 755 int set_sy_lfr_s1_bp_p0( ccsdsTelecommandPacket_t *TC )
730 756 {
731 757 /** This function sets the time between two basic parameter sets, in s (SY_LFR_S1_BP_P0).
732 758 *
733 759 * @param TC points to the TeleCommand packet that is being processed
734 760 * @param queue_id is the id of the queue which handles TM related to this execution step
735 761 *
736 762 */
737 763
738 764 int status;
739 765
740 766 status = LFR_SUCCESSFUL;
741 767
742 768 parameter_dump_packet.sy_lfr_s1_bp_p0 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_S1_BP_P0 ];
743 769
744 770 return status;
745 771 }
746 772
747 773 int set_sy_lfr_s1_bp_p1( ccsdsTelecommandPacket_t *TC )
748 774 {
749 775 /** This function sets the time between two basic parameter sets, in s (SY_LFR_S1_BP_P1).
750 776 *
751 777 * @param TC points to the TeleCommand packet that is being processed
752 778 * @param queue_id is the id of the queue which handles TM related to this execution step
753 779 *
754 780 */
755 781
756 782 int status;
757 783
758 784 status = LFR_SUCCESSFUL;
759 785
760 786 parameter_dump_packet.sy_lfr_s1_bp_p1 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_S1_BP_P1 ];
761 787
762 788 return status;
763 789 }
764 790
765 791 //*********************
766 792 // SBM2 MODE PARAMETERS
767 793 int set_sy_lfr_s2_bp_p0(ccsdsTelecommandPacket_t *TC)
768 794 {
769 795 /** This function sets the time between two basic parameter sets, in s (SY_LFR_S2_BP_P0).
770 796 *
771 797 * @param TC points to the TeleCommand packet that is being processed
772 798 * @param queue_id is the id of the queue which handles TM related to this execution step
773 799 *
774 800 */
775 801
776 802 int status;
777 803
778 804 status = LFR_SUCCESSFUL;
779 805
780 806 parameter_dump_packet.sy_lfr_s2_bp_p0 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_S2_BP_P0 ];
781 807
782 808 return status;
783 809 }
784 810
785 811 int set_sy_lfr_s2_bp_p1( ccsdsTelecommandPacket_t *TC )
786 812 {
787 813 /** This function sets the time between two basic parameter sets, in s (SY_LFR_S2_BP_P1).
788 814 *
789 815 * @param TC points to the TeleCommand packet that is being processed
790 816 * @param queue_id is the id of the queue which handles TM related to this execution step
791 817 *
792 818 */
793 819
794 820 int status;
795 821
796 822 status = LFR_SUCCESSFUL;
797 823
798 824 parameter_dump_packet.sy_lfr_s2_bp_p1 = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_S2_BP_P1 ];
799 825
800 826 return status;
801 827 }
802 828
803 829 //*******************
804 830 // TC_LFR_UPDATE_INFO
805 831 unsigned int check_update_info_hk_lfr_mode( unsigned char mode )
806 832 {
807 833 unsigned int status;
808 834
809 835 if ( (mode == LFR_MODE_STANDBY) || (mode == LFR_MODE_NORMAL)
810 836 || (mode == LFR_MODE_BURST)
811 837 || (mode == LFR_MODE_SBM1) || (mode == LFR_MODE_SBM2))
812 838 {
813 839 status = LFR_SUCCESSFUL;
814 840 }
815 841 else
816 842 {
817 843 status = LFR_DEFAULT;
818 844 }
819 845
820 846 return status;
821 847 }
822 848
823 849 unsigned int check_update_info_hk_tds_mode( unsigned char mode )
824 850 {
825 851 unsigned int status;
826 852
827 853 if ( (mode == TDS_MODE_STANDBY) || (mode == TDS_MODE_NORMAL)
828 854 || (mode == TDS_MODE_BURST)
829 855 || (mode == TDS_MODE_SBM1) || (mode == TDS_MODE_SBM2)
830 856 || (mode == TDS_MODE_LFM))
831 857 {
832 858 status = LFR_SUCCESSFUL;
833 859 }
834 860 else
835 861 {
836 862 status = LFR_DEFAULT;
837 863 }
838 864
839 865 return status;
840 866 }
841 867
842 868 unsigned int check_update_info_hk_thr_mode( unsigned char mode )
843 869 {
844 870 unsigned int status;
845 871
846 872 if ( (mode == THR_MODE_STANDBY) || (mode == THR_MODE_NORMAL)
847 873 || (mode == THR_MODE_BURST))
848 874 {
849 875 status = LFR_SUCCESSFUL;
850 876 }
851 877 else
852 878 {
853 879 status = LFR_DEFAULT;
854 880 }
855 881
856 882 return status;
857 883 }
858 884
859 885 //***********
860 886 // FBINS MASK
861 887
862 888 int set_sy_lfr_fbins( ccsdsTelecommandPacket_t *TC )
863 889 {
864 890 int status;
865 891 unsigned int k;
866 892 unsigned char *fbins_mask_dump;
867 893 unsigned char *fbins_mask_TC;
868 894
869 895 status = LFR_SUCCESSFUL;
870 896
871 897 fbins_mask_dump = parameter_dump_packet.sy_lfr_fbins_f0_word1;
872 898 fbins_mask_TC = TC->dataAndCRC;
873 899
874 900 for (k=0; k < NB_FBINS_MASKS * NB_BYTES_PER_FBINS_MASK; k++)
875 901 {
876 902 fbins_mask_dump[k] = fbins_mask_TC[k];
877 903 }
878 904 for (k=0; k < NB_FBINS_MASKS; k++)
879 905 {
880 906 unsigned char *auxPtr;
881 907 auxPtr = &parameter_dump_packet.sy_lfr_fbins_f0_word1[k*NB_BYTES_PER_FBINS_MASK];
882 908 }
883 909
884 910
885 911 return status;
886 912 }
887 913
914 //***************************
915 // TC_LFR_LOAD_PAS_FILTER_PAR
916
917 int check_sy_lfr_pas_filter_parameters( ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
918 {
919 int flag;
920 rtems_status_code status;
921
922 unsigned char sy_lfr_pas_filter_enabled;
923 unsigned char sy_lfr_pas_filter_modulus;
924 unsigned char sy_lfr_pas_filter_nstd;
925 unsigned char sy_lfr_pas_filter_offset;
926
927 flag = LFR_SUCCESSFUL;
928
929 //***************
930 // get parameters
931 sy_lfr_pas_filter_enabled = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_PAS_FILTER_ENABLED ] & 0x01; // [0000 0001]
932 sy_lfr_pas_filter_modulus = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_PAS_FILTER_MODULUS ];
933 sy_lfr_pas_filter_nstd = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_PAS_FILTER_NSTD ];
934 sy_lfr_pas_filter_offset = TC->dataAndCRC[ DATAFIELD_POS_SY_LFR_PAS_FILTER_OFFSET ];
935
936 //******************
937 // check consistency
938 // sy_lfr_pas_filter_enabled
939 // sy_lfr_pas_filter_modulus
940 if ( (sy_lfr_pas_filter_modulus < 4) || (sy_lfr_pas_filter_modulus > 8) )
941 {
942 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_PAS_FILTER_MODULUS+10, sy_lfr_pas_filter_modulus );
943 flag = WRONG_APP_DATA;
944 }
945 // sy_lfr_pas_filter_nstd
946 if (flag == LFR_SUCCESSFUL)
947 {
948 if ( sy_lfr_pas_filter_nstd > 8 )
949 {
950 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_PAS_FILTER_NSTD+10, sy_lfr_pas_filter_nstd );
951 flag = WRONG_APP_DATA;
952 }
953 }
954 // sy_lfr_pas_filter_offset
955 if (flag == LFR_SUCCESSFUL)
956 {
957 if (sy_lfr_pas_filter_offset > 7)
958 {
959 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_PAS_FILTER_OFFSET+10, sy_lfr_pas_filter_offset );
960 flag = WRONG_APP_DATA;
961 }
962 }
963
964 return flag;
965 }
966
888 967 //**************
889 968 // KCOEFFICIENTS
890 969 int set_sy_lfr_kcoeff( ccsdsTelecommandPacket_t *TC,rtems_id queue_id )
891 970 {
892 971 unsigned int kcoeff;
893 972 unsigned short sy_lfr_kcoeff_frequency;
894 973 unsigned short bin;
895 974 unsigned short *freqPtr;
896 975 float *kcoeffPtr_norm;
897 976 float *kcoeffPtr_sbm;
898 977 int status;
899 978 unsigned char *kcoeffLoadPtr;
900 979 unsigned char *kcoeffNormPtr;
901 980 unsigned char *kcoeffSbmPtr_a;
902 981 unsigned char *kcoeffSbmPtr_b;
903 982
904 983 status = LFR_SUCCESSFUL;
905 984
906 985 kcoeffPtr_norm = NULL;
907 986 kcoeffPtr_sbm = NULL;
908 987 bin = 0;
909 988
910 989 freqPtr = (unsigned short *) &TC->dataAndCRC[DATAFIELD_POS_SY_LFR_KCOEFF_FREQUENCY];
911 990 sy_lfr_kcoeff_frequency = *freqPtr;
912 991
913 992 if ( sy_lfr_kcoeff_frequency >= NB_BINS_COMPRESSED_SM )
914 993 {
915 994 PRINTF1("ERR *** in set_sy_lfr_kcoeff_frequency *** sy_lfr_kcoeff_frequency = %d\n", sy_lfr_kcoeff_frequency)
916 995 status = send_tm_lfr_tc_exe_inconsistent( TC, queue_id, DATAFIELD_POS_SY_LFR_KCOEFF_FREQUENCY + 10 + 1,
917 996 TC->dataAndCRC[DATAFIELD_POS_SY_LFR_KCOEFF_FREQUENCY + 1] ); // +1 to get the LSB instead of the MSB
918 997 status = LFR_DEFAULT;
919 998 }
920 999 else
921 1000 {
922 1001 if ( ( sy_lfr_kcoeff_frequency >= 0 )
923 1002 && ( sy_lfr_kcoeff_frequency < NB_BINS_COMPRESSED_SM_F0 ) )
924 1003 {
925 1004 kcoeffPtr_norm = k_coeff_intercalib_f0_norm;
926 1005 kcoeffPtr_sbm = k_coeff_intercalib_f0_sbm;
927 1006 bin = sy_lfr_kcoeff_frequency;
928 1007 }
929 1008 else if ( ( sy_lfr_kcoeff_frequency >= NB_BINS_COMPRESSED_SM_F0 )
930 1009 && ( sy_lfr_kcoeff_frequency < (NB_BINS_COMPRESSED_SM_F0 + NB_BINS_COMPRESSED_SM_F1) ) )
931 1010 {
932 1011 kcoeffPtr_norm = k_coeff_intercalib_f1_norm;
933 1012 kcoeffPtr_sbm = k_coeff_intercalib_f1_sbm;
934 1013 bin = sy_lfr_kcoeff_frequency - NB_BINS_COMPRESSED_SM_F0;
935 1014 }
936 1015 else if ( ( sy_lfr_kcoeff_frequency >= (NB_BINS_COMPRESSED_SM_F0 + NB_BINS_COMPRESSED_SM_F1) )
937 1016 && ( sy_lfr_kcoeff_frequency < (NB_BINS_COMPRESSED_SM_F0 + NB_BINS_COMPRESSED_SM_F1 + NB_BINS_COMPRESSED_SM_F2) ) )
938 1017 {
939 1018 kcoeffPtr_norm = k_coeff_intercalib_f2;
940 1019 kcoeffPtr_sbm = NULL;
941 1020 bin = sy_lfr_kcoeff_frequency - (NB_BINS_COMPRESSED_SM_F0 + NB_BINS_COMPRESSED_SM_F1);
942 1021 }
943 1022 }
944 1023
945 1024 if (kcoeffPtr_norm != NULL ) // update K coefficient for NORMAL data products
946 1025 {
947 1026 for (kcoeff=0; kcoeff<NB_K_COEFF_PER_BIN; kcoeff++)
948 1027 {
949 1028 // destination
950 1029 kcoeffNormPtr = (unsigned char*) &kcoeffPtr_norm[ (bin * NB_K_COEFF_PER_BIN) + kcoeff ];
951 1030 // source
952 1031 kcoeffLoadPtr = (unsigned char*) &TC->dataAndCRC[DATAFIELD_POS_SY_LFR_KCOEFF_1 + NB_BYTES_PER_FLOAT * kcoeff];
953 1032 // copy source to destination
954 1033 copyFloatByChar( kcoeffNormPtr, kcoeffLoadPtr );
955 1034 }
956 1035 }
957 1036
958 1037 if (kcoeffPtr_sbm != NULL ) // update K coefficient for SBM data products
959 1038 {
960 1039 for (kcoeff=0; kcoeff<NB_K_COEFF_PER_BIN; kcoeff++)
961 1040 {
962 1041 // destination
963 1042 kcoeffSbmPtr_a= (unsigned char*) &kcoeffPtr_sbm[ ( (bin * NB_K_COEFF_PER_BIN) + kcoeff) * 2 ];
964 1043 kcoeffSbmPtr_b= (unsigned char*) &kcoeffPtr_sbm[ ( (bin * NB_K_COEFF_PER_BIN) + kcoeff) * 2 + 1 ];
965 1044 // source
966 1045 kcoeffLoadPtr = (unsigned char*) &TC->dataAndCRC[DATAFIELD_POS_SY_LFR_KCOEFF_1 + NB_BYTES_PER_FLOAT * kcoeff];
967 1046 // copy source to destination
968 1047 copyFloatByChar( kcoeffSbmPtr_a, kcoeffLoadPtr );
969 1048 copyFloatByChar( kcoeffSbmPtr_b, kcoeffLoadPtr );
970 1049 }
971 1050 }
972 1051
973 1052 // print_k_coeff();
974 1053
975 1054 return status;
976 1055 }
977 1056
978 1057 void copyFloatByChar( unsigned char *destination, unsigned char *source )
979 1058 {
980 1059 destination[0] = source[0];
981 1060 destination[1] = source[1];
982 1061 destination[2] = source[2];
983 1062 destination[3] = source[3];
984 1063 }
985 1064
986 1065 //**********
987 1066 // init dump
988 1067
989 1068 void init_parameter_dump( void )
990 1069 {
991 1070 /** This function initialize the parameter_dump_packet global variable with default values.
992 1071 *
993 1072 */
994 1073
995 1074 unsigned int k;
996 1075
997 1076 parameter_dump_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
998 1077 parameter_dump_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
999 1078 parameter_dump_packet.reserved = CCSDS_RESERVED;
1000 1079 parameter_dump_packet.userApplication = CCSDS_USER_APP;
1001 1080 parameter_dump_packet.packetID[0] = (unsigned char) (APID_TM_PARAMETER_DUMP >> 8);
1002 1081 parameter_dump_packet.packetID[1] = (unsigned char) APID_TM_PARAMETER_DUMP;
1003 1082 parameter_dump_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
1004 1083 parameter_dump_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
1005 1084 parameter_dump_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_PARAMETER_DUMP >> 8);
1006 1085 parameter_dump_packet.packetLength[1] = (unsigned char) PACKET_LENGTH_PARAMETER_DUMP;
1007 1086 // DATA FIELD HEADER
1008 1087 parameter_dump_packet.spare1_pusVersion_spare2 = SPARE1_PUSVERSION_SPARE2;
1009 1088 parameter_dump_packet.serviceType = TM_TYPE_PARAMETER_DUMP;
1010 1089 parameter_dump_packet.serviceSubType = TM_SUBTYPE_PARAMETER_DUMP;
1011 1090 parameter_dump_packet.destinationID = TM_DESTINATION_ID_GROUND;
1012 1091 parameter_dump_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
1013 1092 parameter_dump_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
1014 1093 parameter_dump_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
1015 1094 parameter_dump_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
1016 1095 parameter_dump_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
1017 1096 parameter_dump_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
1018 1097 parameter_dump_packet.sid = SID_PARAMETER_DUMP;
1019 1098
1020 1099 //******************
1021 1100 // COMMON PARAMETERS
1022 1101 parameter_dump_packet.sy_lfr_common_parameters_spare = DEFAULT_SY_LFR_COMMON0;
1023 1102 parameter_dump_packet.sy_lfr_common_parameters = DEFAULT_SY_LFR_COMMON1;
1024 1103
1025 1104 //******************
1026 1105 // NORMAL PARAMETERS
1027 1106 parameter_dump_packet.sy_lfr_n_swf_l[0] = (unsigned char) (DFLT_SY_LFR_N_SWF_L >> 8);
1028 1107 parameter_dump_packet.sy_lfr_n_swf_l[1] = (unsigned char) (DFLT_SY_LFR_N_SWF_L );
1029 1108 parameter_dump_packet.sy_lfr_n_swf_p[0] = (unsigned char) (DFLT_SY_LFR_N_SWF_P >> 8);
1030 1109 parameter_dump_packet.sy_lfr_n_swf_p[1] = (unsigned char) (DFLT_SY_LFR_N_SWF_P );
1031 1110 parameter_dump_packet.sy_lfr_n_asm_p[0] = (unsigned char) (DFLT_SY_LFR_N_ASM_P >> 8);
1032 1111 parameter_dump_packet.sy_lfr_n_asm_p[1] = (unsigned char) (DFLT_SY_LFR_N_ASM_P );
1033 1112 parameter_dump_packet.sy_lfr_n_bp_p0 = (unsigned char) DFLT_SY_LFR_N_BP_P0;
1034 1113 parameter_dump_packet.sy_lfr_n_bp_p1 = (unsigned char) DFLT_SY_LFR_N_BP_P1;
1035 1114 parameter_dump_packet.sy_lfr_n_cwf_long_f3 = (unsigned char) DFLT_SY_LFR_N_CWF_LONG_F3;
1036 1115
1037 1116 //*****************
1038 1117 // BURST PARAMETERS
1039 1118 parameter_dump_packet.sy_lfr_b_bp_p0 = (unsigned char) DEFAULT_SY_LFR_B_BP_P0;
1040 1119 parameter_dump_packet.sy_lfr_b_bp_p1 = (unsigned char) DEFAULT_SY_LFR_B_BP_P1;
1041 1120
1042 1121 //****************
1043 1122 // SBM1 PARAMETERS
1044 1123 parameter_dump_packet.sy_lfr_s1_bp_p0 = (unsigned char) DEFAULT_SY_LFR_S1_BP_P0; // min value is 0.25 s for the period
1045 1124 parameter_dump_packet.sy_lfr_s1_bp_p1 = (unsigned char) DEFAULT_SY_LFR_S1_BP_P1;
1046 1125
1047 1126 //****************
1048 1127 // SBM2 PARAMETERS
1049 1128 parameter_dump_packet.sy_lfr_s2_bp_p0 = (unsigned char) DEFAULT_SY_LFR_S2_BP_P0;
1050 1129 parameter_dump_packet.sy_lfr_s2_bp_p1 = (unsigned char) DEFAULT_SY_LFR_S2_BP_P1;
1051 1130
1052 1131 //************
1053 1132 // FBINS MASKS
1054 1133 for (k=0; k < NB_FBINS_MASKS * NB_BYTES_PER_FBINS_MASK; k++)
1055 1134 {
1056 1135 parameter_dump_packet.sy_lfr_fbins_f0_word1[k] = 0xff;
1057 1136 }
1058 1137 }
1059 1138
1060 1139 void init_kcoefficients_dump( void )
1061 1140 {
1062 1141 init_kcoefficients_dump_packet( &kcoefficients_dump_1, 1, 30 );
1063 1142 init_kcoefficients_dump_packet( &kcoefficients_dump_2, 2, 6 );
1064 1143
1065 1144 kcoefficient_node_1.previous = NULL;
1066 1145 kcoefficient_node_1.next = NULL;
1067 1146 kcoefficient_node_1.sid = TM_CODE_K_DUMP;
1068 1147 kcoefficient_node_1.coarseTime = 0x00;
1069 1148 kcoefficient_node_1.fineTime = 0x00;
1070 1149 kcoefficient_node_1.buffer_address = (int) &kcoefficients_dump_1;
1071 1150 kcoefficient_node_1.status = 0x00;
1072 1151
1073 1152 kcoefficient_node_2.previous = NULL;
1074 1153 kcoefficient_node_2.next = NULL;
1075 1154 kcoefficient_node_2.sid = TM_CODE_K_DUMP;
1076 1155 kcoefficient_node_2.coarseTime = 0x00;
1077 1156 kcoefficient_node_2.fineTime = 0x00;
1078 1157 kcoefficient_node_2.buffer_address = (int) &kcoefficients_dump_2;
1079 1158 kcoefficient_node_2.status = 0x00;
1080 1159 }
1081 1160
1082 1161 void init_kcoefficients_dump_packet( Packet_TM_LFR_KCOEFFICIENTS_DUMP_t *kcoefficients_dump, unsigned char pkt_nr, unsigned char blk_nr )
1083 1162 {
1084 1163 unsigned int k;
1085 1164 unsigned int packetLength;
1086 1165
1087 1166 packetLength = blk_nr * 130 + 20 - CCSDS_TC_TM_PACKET_OFFSET; // 4 bytes for the CCSDS header
1088 1167
1089 1168 kcoefficients_dump->targetLogicalAddress = CCSDS_DESTINATION_ID;
1090 1169 kcoefficients_dump->protocolIdentifier = CCSDS_PROTOCOLE_ID;
1091 1170 kcoefficients_dump->reserved = CCSDS_RESERVED;
1092 1171 kcoefficients_dump->userApplication = CCSDS_USER_APP;
1093 1172 kcoefficients_dump->packetID[0] = (unsigned char) (APID_TM_PARAMETER_DUMP >> 8);;
1094 1173 kcoefficients_dump->packetID[1] = (unsigned char) APID_TM_PARAMETER_DUMP;;
1095 1174 kcoefficients_dump->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
1096 1175 kcoefficients_dump->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
1097 1176 kcoefficients_dump->packetLength[0] = (unsigned char) (packetLength >> 8);
1098 1177 kcoefficients_dump->packetLength[1] = (unsigned char) packetLength;
1099 1178 // DATA FIELD HEADER
1100 1179 kcoefficients_dump->spare1_pusVersion_spare2 = SPARE1_PUSVERSION_SPARE2;
1101 1180 kcoefficients_dump->serviceType = TM_TYPE_K_DUMP;
1102 1181 kcoefficients_dump->serviceSubType = TM_SUBTYPE_K_DUMP;
1103 1182 kcoefficients_dump->destinationID= TM_DESTINATION_ID_GROUND;
1104 1183 kcoefficients_dump->time[0] = 0x00;
1105 1184 kcoefficients_dump->time[1] = 0x00;
1106 1185 kcoefficients_dump->time[2] = 0x00;
1107 1186 kcoefficients_dump->time[3] = 0x00;
1108 1187 kcoefficients_dump->time[4] = 0x00;
1109 1188 kcoefficients_dump->time[5] = 0x00;
1110 1189 kcoefficients_dump->sid = SID_K_DUMP;
1111 1190
1112 1191 kcoefficients_dump->pkt_cnt = 2;
1113 1192 kcoefficients_dump->pkt_nr = pkt_nr;
1114 1193 kcoefficients_dump->blk_nr = blk_nr;
1115 1194
1116 1195 //******************
1117 1196 // SOURCE DATA repeated N times with N in [0 .. PA_LFR_KCOEFF_BLK_NR]
1118 1197 // one blk is 2 + 4 * 32 = 130 bytes, 30 blks max in one packet (30 * 130 = 3900)
1119 1198 for (k=0; k<3900; k++)
1120 1199 {
1121 1200 kcoefficients_dump->kcoeff_blks[k] = 0x00;
1122 1201 }
1123 1202 }
1124 1203
1125 1204 void increment_seq_counter_destination_id_dump( unsigned char *packet_sequence_control, unsigned char destination_id )
1126 1205 {
1127 1206 /** This function increment the packet sequence control parameter of a TC, depending on its destination ID.
1128 1207 *
1129 1208 * @param packet_sequence_control points to the packet sequence control which will be incremented
1130 1209 * @param destination_id is the destination ID of the TM, there is one counter by destination ID
1131 1210 *
1132 1211 * If the destination ID is not known, a dedicated counter is incremented.
1133 1212 *
1134 1213 */
1135 1214
1136 1215 unsigned short sequence_cnt;
1137 1216 unsigned short segmentation_grouping_flag;
1138 1217 unsigned short new_packet_sequence_control;
1139 1218 unsigned char i;
1140 1219
1141 1220 switch (destination_id)
1142 1221 {
1143 1222 case SID_TC_GROUND:
1144 1223 i = GROUND;
1145 1224 break;
1146 1225 case SID_TC_MISSION_TIMELINE:
1147 1226 i = MISSION_TIMELINE;
1148 1227 break;
1149 1228 case SID_TC_TC_SEQUENCES:
1150 1229 i = TC_SEQUENCES;
1151 1230 break;
1152 1231 case SID_TC_RECOVERY_ACTION_CMD:
1153 1232 i = RECOVERY_ACTION_CMD;
1154 1233 break;
1155 1234 case SID_TC_BACKUP_MISSION_TIMELINE:
1156 1235 i = BACKUP_MISSION_TIMELINE;
1157 1236 break;
1158 1237 case SID_TC_DIRECT_CMD:
1159 1238 i = DIRECT_CMD;
1160 1239 break;
1161 1240 case SID_TC_SPARE_GRD_SRC1:
1162 1241 i = SPARE_GRD_SRC1;
1163 1242 break;
1164 1243 case SID_TC_SPARE_GRD_SRC2:
1165 1244 i = SPARE_GRD_SRC2;
1166 1245 break;
1167 1246 case SID_TC_OBCP:
1168 1247 i = OBCP;
1169 1248 break;
1170 1249 case SID_TC_SYSTEM_CONTROL:
1171 1250 i = SYSTEM_CONTROL;
1172 1251 break;
1173 1252 case SID_TC_AOCS:
1174 1253 i = AOCS;
1175 1254 break;
1176 1255 case SID_TC_RPW_INTERNAL:
1177 1256 i = RPW_INTERNAL;
1178 1257 break;
1179 1258 default:
1180 1259 i = GROUND;
1181 1260 break;
1182 1261 }
1183 1262
1184 1263 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << 8;
1185 1264 sequence_cnt = sequenceCounters_TM_DUMP[ i ] & 0x3fff;
1186 1265
1187 1266 new_packet_sequence_control = segmentation_grouping_flag | sequence_cnt ;
1188 1267
1189 1268 packet_sequence_control[0] = (unsigned char) (new_packet_sequence_control >> 8);
1190 1269 packet_sequence_control[1] = (unsigned char) (new_packet_sequence_control );
1191 1270
1192 1271 // increment the sequence counter
1193 1272 if ( sequenceCounters_TM_DUMP[ i ] < SEQ_CNT_MAX )
1194 1273 {
1195 1274 sequenceCounters_TM_DUMP[ i ] = sequenceCounters_TM_DUMP[ i ] + 1;
1196 1275 }
1197 1276 else
1198 1277 {
1199 1278 sequenceCounters_TM_DUMP[ i ] = 0;
1200 1279 }
1201 1280 }
General Comments 0
You need to be logged in to leave comments. Login now