##// END OF EJS Templates
Behaviour changed upon reception of a TC_LFR_ENTER_MODE with a transition...
paul -
r247:c33dcdaef462 R3a
parent child
Show More
@@ -1,1604 +1,1606
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 126 case TC_SUBTYPE_UPDT_TIME:
127 127 result = action_update_time( &TC );
128 128 close_action( &TC, result, queue_snd_id );
129 129 break;
130 130 default:
131 131 break;
132 132 }
133 133 }
134 134 }
135 135 }
136 136
137 137 //***********
138 138 // TC ACTIONS
139 139
140 140 int action_reset(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
141 141 {
142 142 /** This function executes specific actions when a TC_LFR_RESET TeleCommand has been received.
143 143 *
144 144 * @param TC points to the TeleCommand packet that is being processed
145 145 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
146 146 *
147 147 */
148 148
149 149 PRINTF("this is the end!!!\n")
150 150 exit(0);
151 151 send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time );
152 152 return LFR_DEFAULT;
153 153 }
154 154
155 155 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
156 156 {
157 157 /** This function executes specific actions when a TC_LFR_ENTER_MODE TeleCommand has been received.
158 158 *
159 159 * @param TC points to the TeleCommand packet that is being processed
160 160 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
161 161 *
162 162 */
163 163
164 164 rtems_status_code status;
165 165 unsigned char requestedMode;
166 166 unsigned int *transitionCoarseTime_ptr;
167 167 unsigned int transitionCoarseTime;
168 168 unsigned char * bytePosPtr;
169 169
170 170 bytePosPtr = (unsigned char *) &TC->packetID;
171 171
172 172 requestedMode = bytePosPtr[ BYTE_POS_CP_MODE_LFR_SET ];
173 173 transitionCoarseTime_ptr = (unsigned int *) ( &bytePosPtr[ BYTE_POS_CP_LFR_ENTER_MODE_TIME ] );
174 174 transitionCoarseTime = (*transitionCoarseTime_ptr) & 0x7fffffff;
175 175
176 176 status = check_mode_value( requestedMode );
177 177
178 178 if ( status != LFR_SUCCESSFUL ) // the mode value is inconsistent
179 179 {
180 180 send_tm_lfr_tc_exe_inconsistent( TC, queue_id, BYTE_POS_CP_MODE_LFR_SET, requestedMode );
181 181 }
182 182
183 183 else // the mode value is valid, check the transition
184 184 {
185 185 status = check_mode_transition(requestedMode);
186 186 if (status != LFR_SUCCESSFUL)
187 187 {
188 188 PRINTF("ERR *** in action_enter_mode *** check_mode_transition\n")
189 189 send_tm_lfr_tc_exe_not_executable( TC, queue_id );
190 190 }
191 191 }
192 192
193 193 if ( status == LFR_SUCCESSFUL ) // the transition is valid, check the date
194 194 {
195 195 status = check_transition_date( transitionCoarseTime );
196 196 if (status != LFR_SUCCESSFUL)
197 197 {
198 198 PRINTF("ERR *** in action_enter_mode *** check_transition_date\n")
199 199 send_tm_lfr_tc_exe_inconsistent( TC, queue_id,
200 200 BYTE_POS_CP_LFR_ENTER_MODE_TIME,
201 201 bytePosPtr[ BYTE_POS_CP_LFR_ENTER_MODE_TIME + 3 ] );
202 202 }
203 203 }
204 204
205 205 if ( status == LFR_SUCCESSFUL ) // the date is valid, enter the mode
206 206 {
207 207 PRINTF1("OK *** in action_enter_mode *** enter mode %d\n", requestedMode);
208 208
209 209 update_last_valid_transition_date( transitionCoarseTime );
210 210
211 211 switch(requestedMode)
212 212 {
213 213 case LFR_MODE_STANDBY:
214 214 status = enter_mode_standby();
215 215 break;
216 216 case LFR_MODE_NORMAL:
217 217 status = enter_mode_normal( transitionCoarseTime );
218 218 break;
219 219 case LFR_MODE_BURST:
220 220 status = enter_mode_burst( transitionCoarseTime );
221 221 break;
222 222 case LFR_MODE_SBM1:
223 223 status = enter_mode_sbm1( transitionCoarseTime );
224 224 break;
225 225 case LFR_MODE_SBM2:
226 226 status = enter_mode_sbm2( transitionCoarseTime );
227 227 break;
228 228 default:
229 229 break;
230 230 }
231 231 }
232 232
233 233 return status;
234 234 }
235 235
236 236 int action_update_info(ccsdsTelecommandPacket_t *TC, rtems_id queue_id)
237 237 {
238 238 /** This function executes specific actions when a TC_LFR_UPDATE_INFO TeleCommand has been received.
239 239 *
240 240 * @param TC points to the TeleCommand packet that is being processed
241 241 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
242 242 *
243 243 * @return LFR directive status code:
244 244 * - LFR_DEFAULT
245 245 * - LFR_SUCCESSFUL
246 246 *
247 247 */
248 248
249 249 unsigned int val;
250 250 int result;
251 251 unsigned int status;
252 252 unsigned char mode;
253 253 unsigned char * bytePosPtr;
254 254
255 255 bytePosPtr = (unsigned char *) &TC->packetID;
256 256
257 257 // check LFR mode
258 258 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET5 ] & 0x1e) >> 1;
259 259 status = check_update_info_hk_lfr_mode( mode );
260 260 if (status == LFR_SUCCESSFUL) // check TDS mode
261 261 {
262 262 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & 0xf0) >> 4;
263 263 status = check_update_info_hk_tds_mode( mode );
264 264 }
265 265 if (status == LFR_SUCCESSFUL) // check THR mode
266 266 {
267 267 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & 0x0f);
268 268 status = check_update_info_hk_thr_mode( mode );
269 269 }
270 270 if (status == LFR_SUCCESSFUL) // if the parameter check is successful
271 271 {
272 272 val = housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * 256
273 273 + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
274 274 val++;
275 275 housekeeping_packet.hk_lfr_update_info_tc_cnt[0] = (unsigned char) (val >> 8);
276 276 housekeeping_packet.hk_lfr_update_info_tc_cnt[1] = (unsigned char) (val);
277 277 }
278 278
279 279 // pa_bia_status_info
280 280 // => pa_bia_mode_mux_set 3 bits
281 281 // => pa_bia_mode_hv_enabled 1 bit
282 282 // => pa_bia_mode_bias1_enabled 1 bit
283 283 // => pa_bia_mode_bias2_enabled 1 bit
284 284 // => pa_bia_mode_bias3_enabled 1 bit
285 285 // => pa_bia_on_off (cp_dpu_bias_on_off)
286 286 pa_bia_status_info = bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET2 ] & 0xfe; // [1111 1110]
287 287 pa_bia_status_info = pa_bia_status_info
288 288 | (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET1 ] & 0x1);
289 289
290 290 result = status;
291 291
292 292 return result;
293 293 }
294 294
295 295 int action_enable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
296 296 {
297 297 /** This function executes specific actions when a TC_LFR_ENABLE_CALIBRATION TeleCommand has been received.
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 transmission by the SpaceWire driver
301 301 *
302 302 */
303 303
304 304 int result;
305 305
306 306 result = LFR_DEFAULT;
307 307
308 308 setCalibration( true );
309 309
310 310 result = LFR_SUCCESSFUL;
311 311
312 312 return result;
313 313 }
314 314
315 315 int action_disable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
316 316 {
317 317 /** This function executes specific actions when a TC_LFR_DISABLE_CALIBRATION TeleCommand has been received.
318 318 *
319 319 * @param TC points to the TeleCommand packet that is being processed
320 320 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
321 321 *
322 322 */
323 323
324 324 int result;
325 325
326 326 result = LFR_DEFAULT;
327 327
328 328 setCalibration( false );
329 329
330 330 result = LFR_SUCCESSFUL;
331 331
332 332 return result;
333 333 }
334 334
335 335 int action_update_time(ccsdsTelecommandPacket_t *TC)
336 336 {
337 337 /** This function executes specific actions when a TC_LFR_UPDATE_TIME TeleCommand has been received.
338 338 *
339 339 * @param TC points to the TeleCommand packet that is being processed
340 340 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
341 341 *
342 342 * @return LFR_SUCCESSFUL
343 343 *
344 344 */
345 345
346 346 unsigned int val;
347 347
348 348 time_management_regs->coarse_time_load = (TC->dataAndCRC[0] << 24)
349 349 + (TC->dataAndCRC[1] << 16)
350 350 + (TC->dataAndCRC[2] << 8)
351 351 + TC->dataAndCRC[3];
352 352
353 353 val = housekeeping_packet.hk_lfr_update_time_tc_cnt[0] * 256
354 354 + housekeeping_packet.hk_lfr_update_time_tc_cnt[1];
355 355 val++;
356 356 housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char) (val >> 8);
357 357 housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char) (val);
358 358
359 359 return LFR_SUCCESSFUL;
360 360 }
361 361
362 362 //*******************
363 363 // ENTERING THE MODES
364 364 int check_mode_value( unsigned char requestedMode )
365 365 {
366 366 int status;
367 367
368 368 if ( (requestedMode != LFR_MODE_STANDBY)
369 369 && (requestedMode != LFR_MODE_NORMAL) && (requestedMode != LFR_MODE_BURST)
370 370 && (requestedMode != LFR_MODE_SBM1) && (requestedMode != LFR_MODE_SBM2) )
371 371 {
372 372 status = LFR_DEFAULT;
373 373 }
374 374 else
375 375 {
376 376 status = LFR_SUCCESSFUL;
377 377 }
378 378
379 379 return status;
380 380 }
381 381
382 382 int check_mode_transition( unsigned char requestedMode )
383 383 {
384 384 /** This function checks the validity of the transition requested by the TC_LFR_ENTER_MODE.
385 385 *
386 386 * @param requestedMode is the mode requested by the TC_LFR_ENTER_MODE
387 387 *
388 388 * @return LFR directive status codes:
389 389 * - LFR_SUCCESSFUL - the transition is authorized
390 390 * - LFR_DEFAULT - the transition is not authorized
391 391 *
392 392 */
393 393
394 394 int status;
395 395
396 396 switch (requestedMode)
397 397 {
398 398 case LFR_MODE_STANDBY:
399 399 if ( lfrCurrentMode == LFR_MODE_STANDBY ) {
400 400 status = LFR_DEFAULT;
401 401 }
402 402 else
403 403 {
404 404 status = LFR_SUCCESSFUL;
405 405 }
406 406 break;
407 407 case LFR_MODE_NORMAL:
408 408 if ( lfrCurrentMode == LFR_MODE_NORMAL ) {
409 409 status = LFR_DEFAULT;
410 410 }
411 411 else {
412 412 status = LFR_SUCCESSFUL;
413 413 }
414 414 break;
415 415 case LFR_MODE_BURST:
416 416 if ( lfrCurrentMode == LFR_MODE_BURST ) {
417 417 status = LFR_DEFAULT;
418 418 }
419 419 else {
420 420 status = LFR_SUCCESSFUL;
421 421 }
422 422 break;
423 423 case LFR_MODE_SBM1:
424 424 if ( lfrCurrentMode == LFR_MODE_SBM1 ) {
425 425 status = LFR_DEFAULT;
426 426 }
427 427 else {
428 428 status = LFR_SUCCESSFUL;
429 429 }
430 430 break;
431 431 case LFR_MODE_SBM2:
432 432 if ( lfrCurrentMode == LFR_MODE_SBM2 ) {
433 433 status = LFR_DEFAULT;
434 434 }
435 435 else {
436 436 status = LFR_SUCCESSFUL;
437 437 }
438 438 break;
439 439 default:
440 440 status = LFR_DEFAULT;
441 441 break;
442 442 }
443 443
444 444 return status;
445 445 }
446 446
447 447 void update_last_valid_transition_date( unsigned int transitionCoarseTime )
448 448 {
449 449 lastValidEnterModeTime = transitionCoarseTime;
450 450 }
451 451
452 452 int check_transition_date( unsigned int transitionCoarseTime )
453 453 {
454 454 int status;
455 455 unsigned int localCoarseTime;
456 456 unsigned int deltaCoarseTime;
457 457
458 458 status = LFR_SUCCESSFUL;
459 459
460 460 if (transitionCoarseTime == 0) // transition time = 0 means an instant transition
461 461 {
462 462 status = LFR_SUCCESSFUL;
463 463 }
464 464 else
465 465 {
466 466 localCoarseTime = time_management_regs->coarse_time & 0x7fffffff;
467 467
468 468 PRINTF2("localTime = %x, transitionTime = %x\n", localCoarseTime, transitionCoarseTime)
469 469
470 470 if ( transitionCoarseTime <= localCoarseTime ) // SSS-CP-EQS-322
471 471 {
472 472 status = LFR_DEFAULT;
473 473 PRINTF("ERR *** in check_transition_date *** transitionCoarseTime <= localCoarseTime\n")
474 474 }
475 475
476 476 if (status == LFR_SUCCESSFUL)
477 477 {
478 478 deltaCoarseTime = transitionCoarseTime - localCoarseTime;
479 479 if ( deltaCoarseTime > 3 ) // SSS-CP-EQS-323
480 480 {
481 481 status = LFR_DEFAULT;
482 482 PRINTF1("ERR *** in check_transition_date *** deltaCoarseTime = %x\n", deltaCoarseTime)
483 483 }
484 484 }
485 485 }
486 486
487 487 return status;
488 488 }
489 489
490 490 int restart_asm_activities( unsigned char lfrRequestedMode )
491 491 {
492 492 rtems_status_code status;
493 493
494 494 status = stop_spectral_matrices();
495 495
496 496 status = restart_asm_tasks( lfrRequestedMode );
497 497
498 498 launch_spectral_matrix();
499 499
500 500 return status;
501 501 }
502 502
503 503 int stop_spectral_matrices( void )
504 504 {
505 505 /** This function stops and restarts the current mode average spectral matrices activities.
506 506 *
507 507 * @return RTEMS directive status codes:
508 508 * - RTEMS_SUCCESSFUL - task restarted successfully
509 509 * - RTEMS_INVALID_ID - task id invalid
510 510 * - RTEMS_ALREADY_SUSPENDED - task already suspended
511 511 *
512 512 */
513 513
514 514 rtems_status_code status;
515 515
516 516 status = RTEMS_SUCCESSFUL;
517 517
518 518 // (1) mask interruptions
519 519 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
520 520
521 521 // (2) reset spectral matrices registers
522 522 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
523 523 reset_sm_status();
524 524
525 525 // (3) clear interruptions
526 526 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
527 527
528 528 // suspend several tasks
529 529 if (lfrCurrentMode != LFR_MODE_STANDBY) {
530 530 status = suspend_asm_tasks();
531 531 }
532 532
533 533 if (status != RTEMS_SUCCESSFUL)
534 534 {
535 535 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
536 536 }
537 537
538 538 return status;
539 539 }
540 540
541 541 int stop_current_mode( void )
542 542 {
543 543 /** This function stops the current mode by masking interrupt lines and suspending science tasks.
544 544 *
545 545 * @return RTEMS directive status codes:
546 546 * - RTEMS_SUCCESSFUL - task restarted successfully
547 547 * - RTEMS_INVALID_ID - task id invalid
548 548 * - RTEMS_ALREADY_SUSPENDED - task already suspended
549 549 *
550 550 */
551 551
552 552 rtems_status_code status;
553 553
554 554 status = RTEMS_SUCCESSFUL;
555 555
556 556 // (1) mask interruptions
557 557 LEON_Mask_interrupt( IRQ_WAVEFORM_PICKER ); // mask waveform picker interrupt
558 558 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
559 559
560 560 // (2) reset waveform picker registers
561 561 reset_wfp_burst_enable(); // reset burst and enable bits
562 562 reset_wfp_status(); // reset all the status bits
563 563
564 564 // (3) reset spectral matrices registers
565 565 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
566 566 reset_sm_status();
567 567
568 568 // reset lfr VHDL module
569 569 reset_lfr();
570 570
571 571 reset_extractSWF(); // reset the extractSWF flag to false
572 572
573 573 // (4) clear interruptions
574 574 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER ); // clear waveform picker interrupt
575 575 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
576 576
577 577 // suspend several tasks
578 578 if (lfrCurrentMode != LFR_MODE_STANDBY) {
579 579 status = suspend_science_tasks();
580 580 }
581 581
582 582 if (status != RTEMS_SUCCESSFUL)
583 583 {
584 584 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
585 585 }
586 586
587 587 return status;
588 588 }
589 589
590 590 int enter_mode_standby()
591 591 {
592 592 /** This function is used to put LFR in the STANDBY mode.
593 593 *
594 594 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
595 595 *
596 596 * @return RTEMS directive status codes:
597 597 * - RTEMS_SUCCESSFUL - task restarted successfully
598 598 * - RTEMS_INVALID_ID - task id invalid
599 599 * - RTEMS_INCORRECT_STATE - task never started
600 600 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
601 601 *
602 602 * The STANDBY mode does not depends on a specific transition date, the effect of the TC_LFR_ENTER_MODE
603 603 * is immediate.
604 604 *
605 605 */
606 606
607 607 int status;
608 608
609 609 status = stop_current_mode(); // STOP THE CURRENT MODE
610 610
611 611 #ifdef PRINT_TASK_STATISTICS
612 612 rtems_cpu_usage_report();
613 613 #endif
614 614
615 615 #ifdef PRINT_STACK_REPORT
616 616 PRINTF("stack report selected\n")
617 617 rtems_stack_checker_report_usage();
618 618 #endif
619 619
620 620 return status;
621 621 }
622 622
623 623 int enter_mode_normal( unsigned int transitionCoarseTime )
624 624 {
625 625 /** This function is used to start the NORMAL mode.
626 626 *
627 627 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
628 628 *
629 629 * @return RTEMS directive status codes:
630 630 * - RTEMS_SUCCESSFUL - task restarted successfully
631 631 * - RTEMS_INVALID_ID - task id invalid
632 632 * - RTEMS_INCORRECT_STATE - task never started
633 633 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
634 634 *
635 635 * The way the NORMAL mode is started depends on the LFR current mode. If LFR is in SBM1 or SBM2,
636 636 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected.
637 637 *
638 638 */
639 639
640 640 int status;
641 641
642 642 #ifdef PRINT_TASK_STATISTICS
643 643 rtems_cpu_usage_reset();
644 644 #endif
645 645
646 646 status = RTEMS_UNSATISFIED;
647 647
648 648 switch( lfrCurrentMode )
649 649 {
650 650 case LFR_MODE_STANDBY:
651 651 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart science tasks
652 652 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
653 653 {
654 654 launch_spectral_matrix( );
655 655 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
656 656 }
657 657 break;
658 658 case LFR_MODE_BURST:
659 659 status = stop_current_mode(); // stop the current mode
660 660 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart the science tasks
661 661 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
662 662 {
663 663 launch_spectral_matrix( );
664 664 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
665 665 }
666 666 break;
667 667 case LFR_MODE_SBM1:
668 668 restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
669 669 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
670 670 break;
671 671 case LFR_MODE_SBM2:
672 672 restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
673 673 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
674 674 break;
675 675 default:
676 676 break;
677 677 }
678 678
679 679 if (status != RTEMS_SUCCESSFUL)
680 680 {
681 681 PRINTF1("ERR *** in enter_mode_normal *** status = %d\n", status)
682 682 status = RTEMS_UNSATISFIED;
683 683 }
684 684
685 685 return status;
686 686 }
687 687
688 688 int enter_mode_burst( unsigned int transitionCoarseTime )
689 689 {
690 690 /** This function is used to start the BURST mode.
691 691 *
692 692 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
693 693 *
694 694 * @return RTEMS directive status codes:
695 695 * - RTEMS_SUCCESSFUL - task restarted successfully
696 696 * - RTEMS_INVALID_ID - task id invalid
697 697 * - RTEMS_INCORRECT_STATE - task never started
698 698 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
699 699 *
700 700 * The way the BURST mode is started does not depend on the LFR current mode.
701 701 *
702 702 */
703 703
704 704
705 705 int status;
706 706
707 707 #ifdef PRINT_TASK_STATISTICS
708 708 rtems_cpu_usage_reset();
709 709 #endif
710 710
711 711 status = stop_current_mode(); // stop the current mode
712 712 status = restart_science_tasks( LFR_MODE_BURST ); // restart the science tasks
713 713 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
714 714 {
715 715 launch_spectral_matrix( );
716 716 launch_waveform_picker( LFR_MODE_BURST, transitionCoarseTime );
717 717 }
718 718
719 719 if (status != RTEMS_SUCCESSFUL)
720 720 {
721 721 PRINTF1("ERR *** in enter_mode_burst *** status = %d\n", status)
722 722 status = RTEMS_UNSATISFIED;
723 723 }
724 724
725 725 return status;
726 726 }
727 727
728 728 int enter_mode_sbm1( unsigned int transitionCoarseTime )
729 729 {
730 730 /** This function is used to start the SBM1 mode.
731 731 *
732 732 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
733 733 *
734 734 * @return RTEMS directive status codes:
735 735 * - RTEMS_SUCCESSFUL - task restarted successfully
736 736 * - RTEMS_INVALID_ID - task id invalid
737 737 * - RTEMS_INCORRECT_STATE - task never started
738 738 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
739 739 *
740 740 * The way the SBM1 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM2,
741 741 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
742 742 * cases, the acquisition is completely restarted.
743 743 *
744 744 */
745 745
746 746 int status;
747 747
748 748 #ifdef PRINT_TASK_STATISTICS
749 749 rtems_cpu_usage_reset();
750 750 #endif
751 751
752 752 status = RTEMS_UNSATISFIED;
753 753
754 754 switch( lfrCurrentMode )
755 755 {
756 756 case LFR_MODE_STANDBY:
757 757 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart science tasks
758 758 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
759 759 {
760 760 launch_spectral_matrix( );
761 761 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
762 762 }
763 763 break;
764 764 case LFR_MODE_NORMAL: // lfrCurrentMode will be updated after the execution of close_action
765 765 restart_asm_activities( LFR_MODE_SBM1 );
766 766 status = LFR_SUCCESSFUL;
767 767 break;
768 768 case LFR_MODE_BURST:
769 769 status = stop_current_mode(); // stop the current mode
770 770 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart the science tasks
771 771 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
772 772 {
773 773 launch_spectral_matrix( );
774 774 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
775 775 }
776 776 break;
777 777 case LFR_MODE_SBM2:
778 778 restart_asm_activities( LFR_MODE_SBM1 );
779 779 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
780 780 break;
781 781 default:
782 782 break;
783 783 }
784 784
785 785 if (status != RTEMS_SUCCESSFUL)
786 786 {
787 787 PRINTF1("ERR *** in enter_mode_sbm1 *** status = %d\n", status)
788 788 status = RTEMS_UNSATISFIED;
789 789 }
790 790
791 791 return status;
792 792 }
793 793
794 794 int enter_mode_sbm2( unsigned int transitionCoarseTime )
795 795 {
796 796 /** This function is used to start the SBM2 mode.
797 797 *
798 798 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
799 799 *
800 800 * @return RTEMS directive status codes:
801 801 * - RTEMS_SUCCESSFUL - task restarted successfully
802 802 * - RTEMS_INVALID_ID - task id invalid
803 803 * - RTEMS_INCORRECT_STATE - task never started
804 804 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
805 805 *
806 806 * The way the SBM2 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM1,
807 807 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
808 808 * cases, the acquisition is completely restarted.
809 809 *
810 810 */
811 811
812 812 int status;
813 813
814 814 #ifdef PRINT_TASK_STATISTICS
815 815 rtems_cpu_usage_reset();
816 816 #endif
817 817
818 818 status = RTEMS_UNSATISFIED;
819 819
820 820 switch( lfrCurrentMode )
821 821 {
822 822 case LFR_MODE_STANDBY:
823 823 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart science tasks
824 824 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
825 825 {
826 826 launch_spectral_matrix( );
827 827 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
828 828 }
829 829 break;
830 830 case LFR_MODE_NORMAL:
831 831 restart_asm_activities( LFR_MODE_SBM2 );
832 832 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
833 833 break;
834 834 case LFR_MODE_BURST:
835 835 status = stop_current_mode(); // stop the current mode
836 836 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart the science tasks
837 837 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
838 838 {
839 839 launch_spectral_matrix( );
840 840 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
841 841 }
842 842 break;
843 843 case LFR_MODE_SBM1:
844 844 restart_asm_activities( LFR_MODE_SBM2 );
845 845 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
846 846 break;
847 847 default:
848 848 break;
849 849 }
850 850
851 851 if (status != RTEMS_SUCCESSFUL)
852 852 {
853 853 PRINTF1("ERR *** in enter_mode_sbm2 *** status = %d\n", status)
854 854 status = RTEMS_UNSATISFIED;
855 855 }
856 856
857 857 return status;
858 858 }
859 859
860 860 int restart_science_tasks( unsigned char lfrRequestedMode )
861 861 {
862 862 /** This function is used to restart all science tasks.
863 863 *
864 864 * @return RTEMS directive status codes:
865 865 * - RTEMS_SUCCESSFUL - task restarted successfully
866 866 * - RTEMS_INVALID_ID - task id invalid
867 867 * - RTEMS_INCORRECT_STATE - task never started
868 868 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
869 869 *
870 870 * Science tasks are AVF0, PRC0, WFRM, CWF3, CW2, CWF1
871 871 *
872 872 */
873 873
874 874 rtems_status_code status[10];
875 875 rtems_status_code ret;
876 876
877 877 ret = RTEMS_SUCCESSFUL;
878 878
879 879 status[0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
880 880 if (status[0] != RTEMS_SUCCESSFUL)
881 881 {
882 882 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[0])
883 883 }
884 884
885 885 status[1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
886 886 if (status[1] != RTEMS_SUCCESSFUL)
887 887 {
888 888 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[1])
889 889 }
890 890
891 891 status[2] = rtems_task_restart( Task_id[TASKID_WFRM],1 );
892 892 if (status[2] != RTEMS_SUCCESSFUL)
893 893 {
894 894 PRINTF1("in restart_science_task *** WFRM ERR %d\n", status[2])
895 895 }
896 896
897 897 status[3] = rtems_task_restart( Task_id[TASKID_CWF3],1 );
898 898 if (status[3] != RTEMS_SUCCESSFUL)
899 899 {
900 900 PRINTF1("in restart_science_task *** CWF3 ERR %d\n", status[3])
901 901 }
902 902
903 903 status[4] = rtems_task_restart( Task_id[TASKID_CWF2],1 );
904 904 if (status[4] != RTEMS_SUCCESSFUL)
905 905 {
906 906 PRINTF1("in restart_science_task *** CWF2 ERR %d\n", status[4])
907 907 }
908 908
909 909 status[5] = rtems_task_restart( Task_id[TASKID_CWF1],1 );
910 910 if (status[5] != RTEMS_SUCCESSFUL)
911 911 {
912 912 PRINTF1("in restart_science_task *** CWF1 ERR %d\n", status[5])
913 913 }
914 914
915 915 status[6] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
916 916 if (status[6] != RTEMS_SUCCESSFUL)
917 917 {
918 918 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[6])
919 919 }
920 920
921 921 status[7] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
922 922 if (status[7] != RTEMS_SUCCESSFUL)
923 923 {
924 924 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[7])
925 925 }
926 926
927 927 status[8] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
928 928 if (status[8] != RTEMS_SUCCESSFUL)
929 929 {
930 930 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[8])
931 931 }
932 932
933 933 status[9] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
934 934 if (status[9] != RTEMS_SUCCESSFUL)
935 935 {
936 936 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[9])
937 937 }
938 938
939 939 if ( (status[0] != RTEMS_SUCCESSFUL) || (status[1] != RTEMS_SUCCESSFUL) ||
940 940 (status[2] != RTEMS_SUCCESSFUL) || (status[3] != RTEMS_SUCCESSFUL) ||
941 941 (status[4] != RTEMS_SUCCESSFUL) || (status[5] != RTEMS_SUCCESSFUL) ||
942 942 (status[6] != RTEMS_SUCCESSFUL) || (status[7] != RTEMS_SUCCESSFUL) ||
943 943 (status[8] != RTEMS_SUCCESSFUL) || (status[9] != RTEMS_SUCCESSFUL) )
944 944 {
945 945 ret = RTEMS_UNSATISFIED;
946 946 }
947 947
948 948 return ret;
949 949 }
950 950
951 951 int restart_asm_tasks( unsigned char lfrRequestedMode )
952 952 {
953 953 /** This function is used to restart average spectral matrices tasks.
954 954 *
955 955 * @return RTEMS directive status codes:
956 956 * - RTEMS_SUCCESSFUL - task restarted successfully
957 957 * - RTEMS_INVALID_ID - task id invalid
958 958 * - RTEMS_INCORRECT_STATE - task never started
959 959 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
960 960 *
961 961 * ASM tasks are AVF0, PRC0, AVF1, PRC1, AVF2 and PRC2
962 962 *
963 963 */
964 964
965 965 rtems_status_code status[6];
966 966 rtems_status_code ret;
967 967
968 968 ret = RTEMS_SUCCESSFUL;
969 969
970 970 status[0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
971 971 if (status[0] != RTEMS_SUCCESSFUL)
972 972 {
973 973 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[0])
974 974 }
975 975
976 976 status[1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
977 977 if (status[1] != RTEMS_SUCCESSFUL)
978 978 {
979 979 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[1])
980 980 }
981 981
982 982 status[2] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
983 983 if (status[2] != RTEMS_SUCCESSFUL)
984 984 {
985 985 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[2])
986 986 }
987 987
988 988 status[3] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
989 989 if (status[3] != RTEMS_SUCCESSFUL)
990 990 {
991 991 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[3])
992 992 }
993 993
994 994 status[4] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
995 995 if (status[4] != RTEMS_SUCCESSFUL)
996 996 {
997 997 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[4])
998 998 }
999 999
1000 1000 status[5] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
1001 1001 if (status[5] != RTEMS_SUCCESSFUL)
1002 1002 {
1003 1003 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[5])
1004 1004 }
1005 1005
1006 1006 if ( (status[0] != RTEMS_SUCCESSFUL) || (status[1] != RTEMS_SUCCESSFUL) ||
1007 1007 (status[2] != RTEMS_SUCCESSFUL) || (status[3] != RTEMS_SUCCESSFUL) ||
1008 1008 (status[4] != RTEMS_SUCCESSFUL) || (status[5] != RTEMS_SUCCESSFUL) )
1009 1009 {
1010 1010 ret = RTEMS_UNSATISFIED;
1011 1011 }
1012 1012
1013 1013 return ret;
1014 1014 }
1015 1015
1016 1016 int suspend_science_tasks( void )
1017 1017 {
1018 1018 /** This function suspends the science tasks.
1019 1019 *
1020 1020 * @return RTEMS directive status codes:
1021 1021 * - RTEMS_SUCCESSFUL - task restarted successfully
1022 1022 * - RTEMS_INVALID_ID - task id invalid
1023 1023 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1024 1024 *
1025 1025 */
1026 1026
1027 1027 rtems_status_code status;
1028 1028
1029 1029 PRINTF("in suspend_science_tasks\n")
1030 1030
1031 1031 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1032 1032 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1033 1033 {
1034 1034 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1035 1035 }
1036 1036 else
1037 1037 {
1038 1038 status = RTEMS_SUCCESSFUL;
1039 1039 }
1040 1040 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1041 1041 {
1042 1042 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1043 1043 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1044 1044 {
1045 1045 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1046 1046 }
1047 1047 else
1048 1048 {
1049 1049 status = RTEMS_SUCCESSFUL;
1050 1050 }
1051 1051 }
1052 1052 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1053 1053 {
1054 1054 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1055 1055 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1056 1056 {
1057 1057 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1058 1058 }
1059 1059 else
1060 1060 {
1061 1061 status = RTEMS_SUCCESSFUL;
1062 1062 }
1063 1063 }
1064 1064 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1065 1065 {
1066 1066 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1067 1067 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1068 1068 {
1069 1069 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1070 1070 }
1071 1071 else
1072 1072 {
1073 1073 status = RTEMS_SUCCESSFUL;
1074 1074 }
1075 1075 }
1076 1076 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1077 1077 {
1078 1078 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1079 1079 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1080 1080 {
1081 1081 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1082 1082 }
1083 1083 else
1084 1084 {
1085 1085 status = RTEMS_SUCCESSFUL;
1086 1086 }
1087 1087 }
1088 1088 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1089 1089 {
1090 1090 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1091 1091 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1092 1092 {
1093 1093 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1094 1094 }
1095 1095 else
1096 1096 {
1097 1097 status = RTEMS_SUCCESSFUL;
1098 1098 }
1099 1099 }
1100 1100 if (status == RTEMS_SUCCESSFUL) // suspend WFRM
1101 1101 {
1102 1102 status = rtems_task_suspend( Task_id[TASKID_WFRM] );
1103 1103 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1104 1104 {
1105 1105 PRINTF1("in suspend_science_task *** WFRM ERR %d\n", status)
1106 1106 }
1107 1107 else
1108 1108 {
1109 1109 status = RTEMS_SUCCESSFUL;
1110 1110 }
1111 1111 }
1112 1112 if (status == RTEMS_SUCCESSFUL) // suspend CWF3
1113 1113 {
1114 1114 status = rtems_task_suspend( Task_id[TASKID_CWF3] );
1115 1115 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1116 1116 {
1117 1117 PRINTF1("in suspend_science_task *** CWF3 ERR %d\n", status)
1118 1118 }
1119 1119 else
1120 1120 {
1121 1121 status = RTEMS_SUCCESSFUL;
1122 1122 }
1123 1123 }
1124 1124 if (status == RTEMS_SUCCESSFUL) // suspend CWF2
1125 1125 {
1126 1126 status = rtems_task_suspend( Task_id[TASKID_CWF2] );
1127 1127 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1128 1128 {
1129 1129 PRINTF1("in suspend_science_task *** CWF2 ERR %d\n", status)
1130 1130 }
1131 1131 else
1132 1132 {
1133 1133 status = RTEMS_SUCCESSFUL;
1134 1134 }
1135 1135 }
1136 1136 if (status == RTEMS_SUCCESSFUL) // suspend CWF1
1137 1137 {
1138 1138 status = rtems_task_suspend( Task_id[TASKID_CWF1] );
1139 1139 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1140 1140 {
1141 1141 PRINTF1("in suspend_science_task *** CWF1 ERR %d\n", status)
1142 1142 }
1143 1143 else
1144 1144 {
1145 1145 status = RTEMS_SUCCESSFUL;
1146 1146 }
1147 1147 }
1148 1148
1149 1149 return status;
1150 1150 }
1151 1151
1152 1152 int suspend_asm_tasks( void )
1153 1153 {
1154 1154 /** This function suspends the science tasks.
1155 1155 *
1156 1156 * @return RTEMS directive status codes:
1157 1157 * - RTEMS_SUCCESSFUL - task restarted successfully
1158 1158 * - RTEMS_INVALID_ID - task id invalid
1159 1159 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1160 1160 *
1161 1161 */
1162 1162
1163 1163 rtems_status_code status;
1164 1164
1165 1165 PRINTF("in suspend_science_tasks\n")
1166 1166
1167 1167 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1168 1168 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1169 1169 {
1170 1170 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1171 1171 }
1172 1172 else
1173 1173 {
1174 1174 status = RTEMS_SUCCESSFUL;
1175 1175 }
1176 1176
1177 1177 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1178 1178 {
1179 1179 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1180 1180 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1181 1181 {
1182 1182 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1183 1183 }
1184 1184 else
1185 1185 {
1186 1186 status = RTEMS_SUCCESSFUL;
1187 1187 }
1188 1188 }
1189 1189
1190 1190 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1191 1191 {
1192 1192 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1193 1193 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1194 1194 {
1195 1195 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1196 1196 }
1197 1197 else
1198 1198 {
1199 1199 status = RTEMS_SUCCESSFUL;
1200 1200 }
1201 1201 }
1202 1202
1203 1203 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1204 1204 {
1205 1205 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1206 1206 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1207 1207 {
1208 1208 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1209 1209 }
1210 1210 else
1211 1211 {
1212 1212 status = RTEMS_SUCCESSFUL;
1213 1213 }
1214 1214 }
1215 1215
1216 1216 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1217 1217 {
1218 1218 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1219 1219 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1220 1220 {
1221 1221 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1222 1222 }
1223 1223 else
1224 1224 {
1225 1225 status = RTEMS_SUCCESSFUL;
1226 1226 }
1227 1227 }
1228 1228
1229 1229 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1230 1230 {
1231 1231 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1232 1232 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1233 1233 {
1234 1234 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1235 1235 }
1236 1236 else
1237 1237 {
1238 1238 status = RTEMS_SUCCESSFUL;
1239 1239 }
1240 1240 }
1241 1241
1242 1242 return status;
1243 1243 }
1244 1244
1245 1245 void launch_waveform_picker( unsigned char mode, unsigned int transitionCoarseTime )
1246 1246 {
1247 1247 WFP_reset_current_ring_nodes();
1248 1248
1249 1249 reset_waveform_picker_regs();
1250 1250
1251 1251 set_wfp_burst_enable_register( mode );
1252 1252
1253 1253 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER );
1254 1254 LEON_Unmask_interrupt( IRQ_WAVEFORM_PICKER );
1255 1255
1256 1256 if (transitionCoarseTime == 0)
1257 1257 {
1258 waveform_picker_regs->start_date = time_management_regs->coarse_time;
1258 // instant transition means transition on the next valid date
1259 // this is mandatory to have a good snapshot period a a good correction of the snapshot period
1260 waveform_picker_regs->start_date = time_management_regs->coarse_time + 1;
1259 1261 }
1260 1262 else
1261 1263 {
1262 1264 waveform_picker_regs->start_date = transitionCoarseTime;
1263 1265 }
1264 1266
1265 1267 }
1266 1268
1267 1269 void launch_spectral_matrix( void )
1268 1270 {
1269 1271 SM_reset_current_ring_nodes();
1270 1272
1271 1273 reset_spectral_matrix_regs();
1272 1274
1273 1275 reset_nb_sm();
1274 1276
1275 1277 set_sm_irq_onNewMatrix( 1 );
1276 1278
1277 1279 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX );
1278 1280 LEON_Unmask_interrupt( IRQ_SPECTRAL_MATRIX );
1279 1281
1280 1282 }
1281 1283
1282 1284 void set_sm_irq_onNewMatrix( unsigned char value )
1283 1285 {
1284 1286 if (value == 1)
1285 1287 {
1286 1288 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x01;
1287 1289 }
1288 1290 else
1289 1291 {
1290 1292 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffe; // 1110
1291 1293 }
1292 1294 }
1293 1295
1294 1296 void set_sm_irq_onError( unsigned char value )
1295 1297 {
1296 1298 if (value == 1)
1297 1299 {
1298 1300 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x02;
1299 1301 }
1300 1302 else
1301 1303 {
1302 1304 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffd; // 1101
1303 1305 }
1304 1306 }
1305 1307
1306 1308 //*****************************
1307 1309 // CONFIGURE CALIBRATION SIGNAL
1308 1310 void setCalibrationPrescaler( unsigned int prescaler )
1309 1311 {
1310 1312 // prescaling of the master clock (25 MHz)
1311 1313 // master clock is divided by 2^prescaler
1312 1314 time_management_regs->calPrescaler = prescaler;
1313 1315 }
1314 1316
1315 1317 void setCalibrationDivisor( unsigned int divisionFactor )
1316 1318 {
1317 1319 // division of the prescaled clock by the division factor
1318 1320 time_management_regs->calDivisor = divisionFactor;
1319 1321 }
1320 1322
1321 1323 void setCalibrationData( void ){
1322 1324 unsigned int k;
1323 1325 unsigned short data;
1324 1326 float val;
1325 1327 float f0;
1326 1328 float f1;
1327 1329 float fs;
1328 1330 float Ts;
1329 1331 float scaleFactor;
1330 1332
1331 1333 f0 = 625;
1332 1334 f1 = 10000;
1333 1335 fs = 160256.410;
1334 1336 Ts = 1. / fs;
1335 1337 scaleFactor = 0.250 / 0.000654; // 191, 500 mVpp, 2 sinus waves => 500 mVpp each, amplitude = 250 mV
1336 1338
1337 1339 time_management_regs->calDataPtr = 0x00;
1338 1340
1339 1341 // build the signal for the SCM calibration
1340 1342 for (k=0; k<256; k++)
1341 1343 {
1342 1344 val = sin( 2 * pi * f0 * k * Ts )
1343 1345 + sin( 2 * pi * f1 * k * Ts );
1344 1346 data = (unsigned short) ((val * scaleFactor) + 2048);
1345 1347 time_management_regs->calData = data & 0xfff;
1346 1348 }
1347 1349 }
1348 1350
1349 1351 void setCalibrationDataInterleaved( void ){
1350 1352 unsigned int k;
1351 1353 float val;
1352 1354 float f0;
1353 1355 float f1;
1354 1356 float fs;
1355 1357 float Ts;
1356 1358 unsigned short data[384];
1357 1359 unsigned char *dataPtr;
1358 1360
1359 1361 f0 = 625;
1360 1362 f1 = 10000;
1361 1363 fs = 240384.615;
1362 1364 Ts = 1. / fs;
1363 1365
1364 1366 time_management_regs->calDataPtr = 0x00;
1365 1367
1366 1368 // build the signal for the SCM calibration
1367 1369 for (k=0; k<384; k++)
1368 1370 {
1369 1371 val = sin( 2 * pi * f0 * k * Ts )
1370 1372 + sin( 2 * pi * f1 * k * Ts );
1371 1373 data[k] = (unsigned short) (val * 512 + 2048);
1372 1374 }
1373 1375
1374 1376 // write the signal in interleaved mode
1375 1377 for (k=0; k<128; k++)
1376 1378 {
1377 1379 dataPtr = (unsigned char*) &data[k*3 + 2];
1378 1380 time_management_regs->calData = (data[k*3] & 0xfff)
1379 1381 + ( (dataPtr[0] & 0x3f) << 12);
1380 1382 time_management_regs->calData = (data[k*3 + 1] & 0xfff)
1381 1383 + ( (dataPtr[1] & 0x3f) << 12);
1382 1384 }
1383 1385 }
1384 1386
1385 1387 void setCalibrationReload( bool state)
1386 1388 {
1387 1389 if (state == true)
1388 1390 {
1389 1391 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000010; // [0001 0000]
1390 1392 }
1391 1393 else
1392 1394 {
1393 1395 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffef; // [1110 1111]
1394 1396 }
1395 1397 }
1396 1398
1397 1399 void setCalibrationEnable( bool state )
1398 1400 {
1399 1401 // this bit drives the multiplexer
1400 1402 if (state == true)
1401 1403 {
1402 1404 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000040; // [0100 0000]
1403 1405 }
1404 1406 else
1405 1407 {
1406 1408 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffbf; // [1011 1111]
1407 1409 }
1408 1410 }
1409 1411
1410 1412 void setCalibrationInterleaved( bool state )
1411 1413 {
1412 1414 // this bit drives the multiplexer
1413 1415 if (state == true)
1414 1416 {
1415 1417 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000020; // [0010 0000]
1416 1418 }
1417 1419 else
1418 1420 {
1419 1421 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffdf; // [1101 1111]
1420 1422 }
1421 1423 }
1422 1424
1423 1425 void setCalibration( bool state )
1424 1426 {
1425 1427 if (state == true)
1426 1428 {
1427 1429 setCalibrationEnable( true );
1428 1430 setCalibrationReload( false );
1429 1431 set_hk_lfr_calib_enable( true );
1430 1432 }
1431 1433 else
1432 1434 {
1433 1435 setCalibrationEnable( false );
1434 1436 setCalibrationReload( true );
1435 1437 set_hk_lfr_calib_enable( false );
1436 1438 }
1437 1439 }
1438 1440
1439 1441 void configureCalibration( bool interleaved )
1440 1442 {
1441 1443 setCalibration( false );
1442 1444 if ( interleaved == true )
1443 1445 {
1444 1446 setCalibrationInterleaved( true );
1445 1447 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1446 1448 setCalibrationDivisor( 26 ); // => 240 384
1447 1449 setCalibrationDataInterleaved();
1448 1450 }
1449 1451 else
1450 1452 {
1451 1453 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1452 1454 setCalibrationDivisor( 38 ); // => 160 256 (39 - 1)
1453 1455 setCalibrationData();
1454 1456 }
1455 1457 }
1456 1458
1457 1459 //****************
1458 1460 // CLOSING ACTIONS
1459 1461 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC, unsigned char * time )
1460 1462 {
1461 1463 /** This function is used to update the HK packets statistics after a successful TC execution.
1462 1464 *
1463 1465 * @param TC points to the TC being processed
1464 1466 * @param time is the time used to date the TC execution
1465 1467 *
1466 1468 */
1467 1469
1468 1470 unsigned int val;
1469 1471
1470 1472 housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
1471 1473 housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
1472 1474 housekeeping_packet.hk_lfr_last_exe_tc_type[0] = 0x00;
1473 1475 housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
1474 1476 housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = 0x00;
1475 1477 housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
1476 1478 housekeeping_packet.hk_lfr_last_exe_tc_time[0] = time[0];
1477 1479 housekeeping_packet.hk_lfr_last_exe_tc_time[1] = time[1];
1478 1480 housekeeping_packet.hk_lfr_last_exe_tc_time[2] = time[2];
1479 1481 housekeeping_packet.hk_lfr_last_exe_tc_time[3] = time[3];
1480 1482 housekeeping_packet.hk_lfr_last_exe_tc_time[4] = time[4];
1481 1483 housekeeping_packet.hk_lfr_last_exe_tc_time[5] = time[5];
1482 1484
1483 1485 val = housekeeping_packet.hk_lfr_exe_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
1484 1486 val++;
1485 1487 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> 8);
1486 1488 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
1487 1489 }
1488 1490
1489 1491 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC, unsigned char * time )
1490 1492 {
1491 1493 /** This function is used to update the HK packets statistics after a TC rejection.
1492 1494 *
1493 1495 * @param TC points to the TC being processed
1494 1496 * @param time is the time used to date the TC rejection
1495 1497 *
1496 1498 */
1497 1499
1498 1500 unsigned int val;
1499 1501
1500 1502 housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
1501 1503 housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
1502 1504 housekeeping_packet.hk_lfr_last_rej_tc_type[0] = 0x00;
1503 1505 housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
1504 1506 housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = 0x00;
1505 1507 housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
1506 1508 housekeeping_packet.hk_lfr_last_rej_tc_time[0] = time[0];
1507 1509 housekeeping_packet.hk_lfr_last_rej_tc_time[1] = time[1];
1508 1510 housekeeping_packet.hk_lfr_last_rej_tc_time[2] = time[2];
1509 1511 housekeeping_packet.hk_lfr_last_rej_tc_time[3] = time[3];
1510 1512 housekeeping_packet.hk_lfr_last_rej_tc_time[4] = time[4];
1511 1513 housekeeping_packet.hk_lfr_last_rej_tc_time[5] = time[5];
1512 1514
1513 1515 val = housekeeping_packet.hk_lfr_rej_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
1514 1516 val++;
1515 1517 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> 8);
1516 1518 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
1517 1519 }
1518 1520
1519 1521 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id )
1520 1522 {
1521 1523 /** This function is the last step of the TC execution workflow.
1522 1524 *
1523 1525 * @param TC points to the TC being processed
1524 1526 * @param result is the result of the TC execution (LFR_SUCCESSFUL / LFR_DEFAULT)
1525 1527 * @param queue_id is the id of the RTEMS message queue used to send TM packets
1526 1528 * @param time is the time used to date the TC execution
1527 1529 *
1528 1530 */
1529 1531
1530 1532 unsigned char requestedMode;
1531 1533
1532 1534 if (result == LFR_SUCCESSFUL)
1533 1535 {
1534 1536 if ( !( (TC->serviceType==TC_TYPE_TIME) & (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
1535 1537 &
1536 1538 !( (TC->serviceType==TC_TYPE_GEN) & (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
1537 1539 )
1538 1540 {
1539 1541 send_tm_lfr_tc_exe_success( TC, queue_id );
1540 1542 }
1541 1543 if ( (TC->serviceType == TC_TYPE_GEN) & (TC->serviceSubType == TC_SUBTYPE_ENTER) )
1542 1544 {
1543 1545 //**********************************
1544 1546 // UPDATE THE LFRMODE LOCAL VARIABLE
1545 1547 requestedMode = TC->dataAndCRC[1];
1546 1548 housekeeping_packet.lfr_status_word[0] = (unsigned char) ((requestedMode << 4) + 0x0d);
1547 1549 updateLFRCurrentMode();
1548 1550 }
1549 1551 }
1550 1552 else if (result == LFR_EXE_ERROR)
1551 1553 {
1552 1554 send_tm_lfr_tc_exe_error( TC, queue_id );
1553 1555 }
1554 1556 }
1555 1557
1556 1558 //***************************
1557 1559 // Interrupt Service Routines
1558 1560 rtems_isr commutation_isr1( rtems_vector_number vector )
1559 1561 {
1560 1562 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1561 1563 PRINTF("In commutation_isr1 *** Error sending event to DUMB\n")
1562 1564 }
1563 1565 }
1564 1566
1565 1567 rtems_isr commutation_isr2( rtems_vector_number vector )
1566 1568 {
1567 1569 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1568 1570 PRINTF("In commutation_isr2 *** Error sending event to DUMB\n")
1569 1571 }
1570 1572 }
1571 1573
1572 1574 //****************
1573 1575 // OTHER FUNCTIONS
1574 1576 void updateLFRCurrentMode()
1575 1577 {
1576 1578 /** This function updates the value of the global variable lfrCurrentMode.
1577 1579 *
1578 1580 * lfrCurrentMode is a parameter used by several functions to know in which mode LFR is running.
1579 1581 *
1580 1582 */
1581 1583 // update the local value of lfrCurrentMode with the value contained in the housekeeping_packet structure
1582 1584 lfrCurrentMode = (housekeeping_packet.lfr_status_word[0] & 0xf0) >> 4;
1583 1585 }
1584 1586
1585 1587 void set_lfr_soft_reset( unsigned char value )
1586 1588 {
1587 1589 if (value == 1)
1588 1590 {
1589 1591 time_management_regs->ctrl = time_management_regs->ctrl | 0x00000004; // [0100]
1590 1592 }
1591 1593 else
1592 1594 {
1593 1595 time_management_regs->ctrl = time_management_regs->ctrl & 0xfffffffb; // [1011]
1594 1596 }
1595 1597 }
1596 1598
1597 1599 void reset_lfr( void )
1598 1600 {
1599 1601 set_lfr_soft_reset( 1 );
1600 1602
1601 1603 set_lfr_soft_reset( 0 );
1602 1604
1603 1605 set_hk_lfr_sc_potential_flag( true );
1604 1606 }
@@ -1,1208 +1,1196
1 1 /** Functions and tasks related to waveform packet generation.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * A group of functions to handle waveforms, in snapshot or continuous format.\n
7 7 *
8 8 */
9 9
10 10 #include "wf_handler.h"
11 11
12 12 //***************
13 13 // waveform rings
14 14 // F0
15 15 ring_node waveform_ring_f0[NB_RING_NODES_F0];
16 16 ring_node *current_ring_node_f0;
17 17 ring_node *ring_node_to_send_swf_f0;
18 18 // F1
19 19 ring_node waveform_ring_f1[NB_RING_NODES_F1];
20 20 ring_node *current_ring_node_f1;
21 21 ring_node *ring_node_to_send_swf_f1;
22 22 ring_node *ring_node_to_send_cwf_f1;
23 23 // F2
24 24 ring_node waveform_ring_f2[NB_RING_NODES_F2];
25 25 ring_node *current_ring_node_f2;
26 26 ring_node *ring_node_to_send_swf_f2;
27 27 ring_node *ring_node_to_send_cwf_f2;
28 28 // F3
29 29 ring_node waveform_ring_f3[NB_RING_NODES_F3];
30 30 ring_node *current_ring_node_f3;
31 31 ring_node *ring_node_to_send_cwf_f3;
32 32 char wf_cont_f3_light[ (NB_SAMPLES_PER_SNAPSHOT) * NB_BYTES_CWF3_LIGHT_BLK ];
33 33
34 34 bool extractSWF1 = false;
35 35 bool extractSWF2 = false;
36 36 bool swf0_ready_flag_f1 = false;
37 37 bool swf0_ready_flag_f2 = false;
38 38 bool swf1_ready = false;
39 39 bool swf2_ready = false;
40 40
41 41 int swf1_extracted[ (NB_SAMPLES_PER_SNAPSHOT * NB_WORDS_SWF_BLK) ];
42 42 int swf2_extracted[ (NB_SAMPLES_PER_SNAPSHOT * NB_WORDS_SWF_BLK) ];
43 43 ring_node ring_node_swf1_extracted;
44 44 ring_node ring_node_swf2_extracted;
45 45
46 46 //*********************
47 47 // Interrupt SubRoutine
48 48
49 49 ring_node * getRingNodeToSendCWF( unsigned char frequencyChannel)
50 50 {
51 51 ring_node *node;
52 52
53 53 node = NULL;
54 54 switch ( frequencyChannel ) {
55 55 case 1:
56 56 node = ring_node_to_send_cwf_f1;
57 57 break;
58 58 case 2:
59 59 node = ring_node_to_send_cwf_f2;
60 60 break;
61 61 case 3:
62 62 node = ring_node_to_send_cwf_f3;
63 63 break;
64 64 default:
65 65 break;
66 66 }
67 67
68 68 return node;
69 69 }
70 70
71 71 ring_node * getRingNodeToSendSWF( unsigned char frequencyChannel)
72 72 {
73 73 ring_node *node;
74 74
75 75 node = NULL;
76 76 switch ( frequencyChannel ) {
77 77 case 0:
78 78 node = ring_node_to_send_swf_f0;
79 79 break;
80 80 case 1:
81 81 node = ring_node_to_send_swf_f1;
82 82 break;
83 83 case 2:
84 84 node = ring_node_to_send_swf_f2;
85 85 break;
86 86 default:
87 87 break;
88 88 }
89 89
90 90 return node;
91 91 }
92 92
93 93 void reset_extractSWF( void )
94 94 {
95 95 extractSWF1 = false;
96 96 extractSWF2 = false;
97 97 swf0_ready_flag_f1 = false;
98 98 swf0_ready_flag_f2 = false;
99 99 swf1_ready = false;
100 100 swf2_ready = false;
101 101 }
102 102
103 103 inline void waveforms_isr_f3( void )
104 104 {
105 105 rtems_status_code spare_status;
106 106
107 107 if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_BURST) // in BURST the data are used to place v, e1 and e2 in the HK packet
108 108 || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) )
109 109 { // in modes other than STANDBY and BURST, send the CWF_F3 data
110 110 //***
111 111 // F3
112 112 if ( (waveform_picker_regs->status & 0xc0) != 0x00 ) { // [1100 0000] check the f3 full bits
113 113 ring_node_to_send_cwf_f3 = current_ring_node_f3->previous;
114 114 current_ring_node_f3 = current_ring_node_f3->next;
115 115 if ((waveform_picker_regs->status & 0x40) == 0x40){ // [0100 0000] f3 buffer 0 is full
116 116 ring_node_to_send_cwf_f3->coarseTime = waveform_picker_regs->f3_0_coarse_time;
117 117 ring_node_to_send_cwf_f3->fineTime = waveform_picker_regs->f3_0_fine_time;
118 118 waveform_picker_regs->addr_data_f3_0 = current_ring_node_f3->buffer_address;
119 119 waveform_picker_regs->status = waveform_picker_regs->status & 0x00008840; // [1000 1000 0100 0000]
120 120 }
121 121 else if ((waveform_picker_regs->status & 0x80) == 0x80){ // [1000 0000] f3 buffer 1 is full
122 122 ring_node_to_send_cwf_f3->coarseTime = waveform_picker_regs->f3_1_coarse_time;
123 123 ring_node_to_send_cwf_f3->fineTime = waveform_picker_regs->f3_1_fine_time;
124 124 waveform_picker_regs->addr_data_f3_1 = current_ring_node_f3->buffer_address;
125 125 waveform_picker_regs->status = waveform_picker_regs->status & 0x00008880; // [1000 1000 1000 0000]
126 126 }
127 127 if (rtems_event_send( Task_id[TASKID_CWF3], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
128 128 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
129 129 }
130 130 }
131 131 }
132 132 }
133 133
134 134 inline void waveforms_isr_burst( void )
135 135 {
136 136 unsigned char status;
137 137 rtems_status_code spare_status;
138 138
139 139 status = (waveform_picker_regs->status & 0x30) >> 4; // [0011 0000] get the status bits for f2
140 140
141 141
142 142 switch(status)
143 143 {
144 144 case 1:
145 145 ring_node_to_send_cwf_f2 = current_ring_node_f2->previous;
146 146 ring_node_to_send_cwf_f2->sid = SID_BURST_CWF_F2;
147 147 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_0_coarse_time;
148 148 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_0_fine_time;
149 149 current_ring_node_f2 = current_ring_node_f2->next;
150 150 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->buffer_address;
151 151 if (rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_BURST ) != RTEMS_SUCCESSFUL) {
152 152 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
153 153 }
154 154 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004410; // [0100 0100 0001 0000]
155 155 break;
156 156 case 2:
157 157 ring_node_to_send_cwf_f2 = current_ring_node_f2->previous;
158 158 ring_node_to_send_cwf_f2->sid = SID_BURST_CWF_F2;
159 159 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_1_coarse_time;
160 160 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_1_fine_time;
161 161 current_ring_node_f2 = current_ring_node_f2->next;
162 162 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address;
163 163 if (rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_BURST ) != RTEMS_SUCCESSFUL) {
164 164 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
165 165 }
166 166 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004420; // [0100 0100 0010 0000]
167 167 break;
168 168 default:
169 169 break;
170 170 }
171 171 }
172 172
173 173 inline void waveform_isr_normal_sbm1_sbm2( void )
174 174 {
175 175 rtems_status_code status;
176 176
177 177 //***
178 178 // F0
179 179 if ( (waveform_picker_regs->status & 0x03) != 0x00 ) // [0000 0011] check the f0 full bits
180 180 {
181 181 swf0_ready_flag_f1 = true;
182 182 swf0_ready_flag_f2 = true;
183 183 ring_node_to_send_swf_f0 = current_ring_node_f0->previous;
184 184 current_ring_node_f0 = current_ring_node_f0->next;
185 185 if ( (waveform_picker_regs->status & 0x01) == 0x01)
186 186 {
187 187
188 188 ring_node_to_send_swf_f0->coarseTime = waveform_picker_regs->f0_0_coarse_time;
189 189 ring_node_to_send_swf_f0->fineTime = waveform_picker_regs->f0_0_fine_time;
190 190 waveform_picker_regs->addr_data_f0_0 = current_ring_node_f0->buffer_address;
191 191 waveform_picker_regs->status = waveform_picker_regs->status & 0x00001101; // [0001 0001 0000 0001]
192 192 }
193 193 else if ( (waveform_picker_regs->status & 0x02) == 0x02)
194 194 {
195 195 ring_node_to_send_swf_f0->coarseTime = waveform_picker_regs->f0_1_coarse_time;
196 196 ring_node_to_send_swf_f0->fineTime = waveform_picker_regs->f0_1_fine_time;
197 197 waveform_picker_regs->addr_data_f0_1 = current_ring_node_f0->buffer_address;
198 198 waveform_picker_regs->status = waveform_picker_regs->status & 0x00001102; // [0001 0001 0000 0010]
199 199 }
200 200 }
201 201
202 202 //***
203 203 // F1
204 204 if ( (waveform_picker_regs->status & 0x0c) != 0x00 ) { // [0000 1100] check the f1 full bits
205 205 // (1) change the receiving buffer for the waveform picker
206 206 ring_node_to_send_cwf_f1 = current_ring_node_f1->previous;
207 207 current_ring_node_f1 = current_ring_node_f1->next;
208 208 if ( (waveform_picker_regs->status & 0x04) == 0x04)
209 209 {
210 210 ring_node_to_send_cwf_f1->coarseTime = waveform_picker_regs->f1_0_coarse_time;
211 211 ring_node_to_send_cwf_f1->fineTime = waveform_picker_regs->f1_0_fine_time;
212 212 waveform_picker_regs->addr_data_f1_0 = current_ring_node_f1->buffer_address;
213 213 waveform_picker_regs->status = waveform_picker_regs->status & 0x00002204; // [0010 0010 0000 0100] f1 bits = 0
214 214 }
215 215 else if ( (waveform_picker_regs->status & 0x08) == 0x08)
216 216 {
217 217 ring_node_to_send_cwf_f1->coarseTime = waveform_picker_regs->f1_1_coarse_time;
218 218 ring_node_to_send_cwf_f1->fineTime = waveform_picker_regs->f1_1_fine_time;
219 219 waveform_picker_regs->addr_data_f1_1 = current_ring_node_f1->buffer_address;
220 220 waveform_picker_regs->status = waveform_picker_regs->status & 0x00002208; // [0010 0010 0000 1000] f1 bits = 0
221 221 }
222 222 // (2) send an event for the the CWF1 task for transmission (and snapshot extraction if needed)
223 223 status = rtems_event_send( Task_id[TASKID_CWF1], RTEMS_EVENT_MODE_NORM_S1_S2 );
224 224 }
225 225
226 226 //***
227 227 // F2
228 228 if ( (waveform_picker_regs->status & 0x30) != 0x00 ) { // [0011 0000] check the f2 full bit
229 229 // (1) change the receiving buffer for the waveform picker
230 230 ring_node_to_send_cwf_f2 = current_ring_node_f2->previous;
231 231 ring_node_to_send_cwf_f2->sid = SID_SBM2_CWF_F2;
232 232 current_ring_node_f2 = current_ring_node_f2->next;
233 233 if ( (waveform_picker_regs->status & 0x10) == 0x10)
234 234 {
235 235 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_0_coarse_time;
236 236 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_0_fine_time;
237 237 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->buffer_address;
238 238 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004410; // [0100 0100 0001 0000]
239 239 }
240 240 else if ( (waveform_picker_regs->status & 0x20) == 0x20)
241 241 {
242 242 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_1_coarse_time;
243 243 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_1_fine_time;
244 244 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address;
245 245 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004420; // [0100 0100 0010 0000]
246 246 }
247 247 // (2) send an event for the waveforms transmission
248 248 status = rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_NORM_S1_S2 );
249 249 }
250 250 }
251 251
252 252 rtems_isr waveforms_isr( rtems_vector_number vector )
253 253 {
254 254 /** This is the interrupt sub routine called by the waveform picker core.
255 255 *
256 256 * This ISR launch different actions depending mainly on two pieces of information:
257 257 * 1. the values read in the registers of the waveform picker.
258 258 * 2. the current LFR mode.
259 259 *
260 260 */
261 261
262 262 // STATUS
263 263 // new error error buffer full
264 264 // 15 14 13 12 11 10 9 8
265 265 // f3 f2 f1 f0 f3 f2 f1 f0
266 266 //
267 267 // ready buffer
268 268 // 7 6 5 4 3 2 1 0
269 269 // f3_1 f3_0 f2_1 f2_0 f1_1 f1_0 f0_1 f0_0
270 270
271 271 rtems_status_code spare_status;
272 272
273 273 waveforms_isr_f3();
274 274
275 275 if ( (waveform_picker_regs->status & 0xff00) != 0x00) // [1111 1111 0000 0000] check the error bits
276 276 {
277 277 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_10 );
278 278 }
279 279
280 280 switch(lfrCurrentMode)
281 281 {
282 282 //********
283 283 // STANDBY
284 284 case LFR_MODE_STANDBY:
285 285 break;
286 286 //**************************
287 287 // LFR NORMAL, SBM1 and SBM2
288 288 case LFR_MODE_NORMAL:
289 289 case LFR_MODE_SBM1:
290 290 case LFR_MODE_SBM2:
291 291 waveform_isr_normal_sbm1_sbm2();
292 292 break;
293 293 //******
294 294 // BURST
295 295 case LFR_MODE_BURST:
296 296 waveforms_isr_burst();
297 297 break;
298 298 //********
299 299 // DEFAULT
300 300 default:
301 301 break;
302 302 }
303 303 }
304 304
305 305 //************
306 306 // RTEMS TASKS
307 307
308 308 rtems_task wfrm_task(rtems_task_argument argument) //used with the waveform picker VHDL IP
309 309 {
310 310 /** This RTEMS task is dedicated to the transmission of snapshots of the NORMAL mode.
311 311 *
312 312 * @param unused is the starting argument of the RTEMS task
313 313 *
314 314 * The following data packets are sent by this task:
315 315 * - TM_LFR_SCIENCE_NORMAL_SWF_F0
316 316 * - TM_LFR_SCIENCE_NORMAL_SWF_F1
317 317 * - TM_LFR_SCIENCE_NORMAL_SWF_F2
318 318 *
319 319 */
320 320
321 321 rtems_event_set event_out;
322 322 rtems_id queue_id;
323 323 rtems_status_code status;
324 bool resynchronisationEngaged;
325 324 ring_node *ring_node_swf1_extracted_ptr;
326 325 ring_node *ring_node_swf2_extracted_ptr;
327 326
328 327 ring_node_swf1_extracted_ptr = (ring_node *) &ring_node_swf1_extracted;
329 328 ring_node_swf2_extracted_ptr = (ring_node *) &ring_node_swf2_extracted;
330 329
331 resynchronisationEngaged = false;
332
333 330 status = get_message_queue_id_send( &queue_id );
334 331 if (status != RTEMS_SUCCESSFUL)
335 332 {
336 333 PRINTF1("in WFRM *** ERR get_message_queue_id_send %d\n", status);
337 334 }
338 335
339 336 BOOT_PRINTF("in WFRM ***\n");
340 337
341 338 while(1){
342 339 // wait for an RTEMS_EVENT
343 340 rtems_event_receive(RTEMS_EVENT_MODE_NORMAL,
344 341 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
345 if(resynchronisationEngaged == false)
346 { // engage resynchronisation
347 snapshot_resynchronization( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
348 resynchronisationEngaged = true;
349 }
350 else
351 { // reset delta_snapshot to the nominal value
352 PRINTF("no resynchronisation, reset delta_snapshot to the nominal value\n");
353 set_wfp_delta_snapshot();
354 resynchronisationEngaged = false;
355 }
356 //
342
343 snapshot_resynchronization( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
344
357 345 if (event_out == RTEMS_EVENT_MODE_NORMAL)
358 346 {
359 347 DEBUG_PRINTF("WFRM received RTEMS_EVENT_MODE_SBM2\n");
360 348 ring_node_to_send_swf_f0->sid = SID_NORM_SWF_F0;
361 349 ring_node_swf1_extracted_ptr->sid = SID_NORM_SWF_F1;
362 350 ring_node_swf2_extracted_ptr->sid = SID_NORM_SWF_F2;
363 351 status = rtems_message_queue_send( queue_id, &ring_node_to_send_swf_f0, sizeof( ring_node* ) );
364 352 status = rtems_message_queue_send( queue_id, &ring_node_swf1_extracted_ptr, sizeof( ring_node* ) );
365 353 status = rtems_message_queue_send( queue_id, &ring_node_swf2_extracted_ptr, sizeof( ring_node* ) );
366 354 }
367 355 }
368 356 }
369 357
370 358 rtems_task cwf3_task(rtems_task_argument argument) //used with the waveform picker VHDL IP
371 359 {
372 360 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f3.
373 361 *
374 362 * @param unused is the starting argument of the RTEMS task
375 363 *
376 364 * The following data packet is sent by this task:
377 365 * - TM_LFR_SCIENCE_NORMAL_CWF_F3
378 366 *
379 367 */
380 368
381 369 rtems_event_set event_out;
382 370 rtems_id queue_id;
383 371 rtems_status_code status;
384 372 ring_node ring_node_cwf3_light;
385 373 ring_node *ring_node_to_send_cwf;
386 374
387 375 status = get_message_queue_id_send( &queue_id );
388 376 if (status != RTEMS_SUCCESSFUL)
389 377 {
390 378 PRINTF1("in CWF3 *** ERR get_message_queue_id_send %d\n", status)
391 379 }
392 380
393 381 ring_node_to_send_cwf_f3->sid = SID_NORM_CWF_LONG_F3;
394 382
395 383 // init the ring_node_cwf3_light structure
396 384 ring_node_cwf3_light.buffer_address = (int) wf_cont_f3_light;
397 385 ring_node_cwf3_light.coarseTime = 0x00;
398 386 ring_node_cwf3_light.fineTime = 0x00;
399 387 ring_node_cwf3_light.next = NULL;
400 388 ring_node_cwf3_light.previous = NULL;
401 389 ring_node_cwf3_light.sid = SID_NORM_CWF_F3;
402 390 ring_node_cwf3_light.status = 0x00;
403 391
404 392 BOOT_PRINTF("in CWF3 ***\n")
405 393
406 394 while(1){
407 395 // wait for an RTEMS_EVENT
408 396 rtems_event_receive( RTEMS_EVENT_0,
409 397 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
410 398 if ( (lfrCurrentMode == LFR_MODE_NORMAL)
411 399 || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode==LFR_MODE_SBM2) )
412 400 {
413 401 ring_node_to_send_cwf = getRingNodeToSendCWF( 3 );
414 402 if ( (parameter_dump_packet.sy_lfr_n_cwf_long_f3 & 0x01) == 0x01)
415 403 {
416 404 PRINTF("send CWF_LONG_F3\n")
417 405 ring_node_to_send_cwf_f3->sid = SID_NORM_CWF_LONG_F3;
418 406 status = rtems_message_queue_send( queue_id, &ring_node_to_send_cwf, sizeof( ring_node* ) );
419 407 }
420 408 else
421 409 {
422 410 PRINTF("send CWF_F3 (light)\n")
423 411 send_waveform_CWF3_light( ring_node_to_send_cwf, &ring_node_cwf3_light, queue_id );
424 412 }
425 413
426 414 }
427 415 else
428 416 {
429 417 PRINTF1("in CWF3 *** lfrCurrentMode is %d, no data will be sent\n", lfrCurrentMode)
430 418 }
431 419 }
432 420 }
433 421
434 422 rtems_task cwf2_task(rtems_task_argument argument) // ONLY USED IN BURST AND SBM2
435 423 {
436 424 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f2.
437 425 *
438 426 * @param unused is the starting argument of the RTEMS task
439 427 *
440 428 * The following data packet is sent by this function:
441 429 * - TM_LFR_SCIENCE_BURST_CWF_F2
442 430 * - TM_LFR_SCIENCE_SBM2_CWF_F2
443 431 *
444 432 */
445 433
446 434 rtems_event_set event_out;
447 435 rtems_id queue_id;
448 436 rtems_status_code status;
449 437 ring_node *ring_node_to_send;
450 438 unsigned long long int acquisitionTimeF0_asLong;
451 439
452 440 acquisitionTimeF0_asLong = 0x00;
453 441
454 442 status = get_message_queue_id_send( &queue_id );
455 443 if (status != RTEMS_SUCCESSFUL)
456 444 {
457 445 PRINTF1("in CWF2 *** ERR get_message_queue_id_send %d\n", status)
458 446 }
459 447
460 448 BOOT_PRINTF("in CWF2 ***\n")
461 449
462 450 while(1){
463 451 // wait for an RTEMS_EVENT
464 452 rtems_event_receive( RTEMS_EVENT_MODE_NORM_S1_S2 | RTEMS_EVENT_MODE_BURST,
465 453 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
466 454 ring_node_to_send = getRingNodeToSendCWF( 2 );
467 455 if (event_out == RTEMS_EVENT_MODE_BURST)
468 456 {
469 457 status = rtems_message_queue_send( queue_id, &ring_node_to_send, sizeof( ring_node* ) );
470 458 }
471 459 else if (event_out == RTEMS_EVENT_MODE_NORM_S1_S2)
472 460 {
473 461 if ( lfrCurrentMode == LFR_MODE_SBM2 )
474 462 {
475 463 status = rtems_message_queue_send( queue_id, &ring_node_to_send, sizeof( ring_node* ) );
476 464 }
477 465 // launch snapshot extraction if needed
478 466 if (extractSWF2 == true)
479 467 {
480 468 ring_node_to_send_swf_f2 = ring_node_to_send_cwf_f2;
481 469 // extract the snapshot
482 470 build_snapshot_from_ring( ring_node_to_send_swf_f2, 2, acquisitionTimeF0_asLong,
483 471 &ring_node_swf2_extracted, swf2_extracted );
484 472 // send the snapshot when built
485 473 status = rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_SBM2 );
486 474 extractSWF2 = false;
487 475 swf2_ready = true;
488 476 }
489 477 if (swf0_ready_flag_f2 == true)
490 478 {
491 479 extractSWF2 = true;
492 480 // record the acquition time of the f0 snapshot to use to build the snapshot at f2
493 481 acquisitionTimeF0_asLong = get_acquisition_time( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
494 482 swf0_ready_flag_f2 = false;
495 483 }
496 484 }
497 485 }
498 486 }
499 487
500 488 rtems_task cwf1_task(rtems_task_argument argument) // ONLY USED IN SBM1
501 489 {
502 490 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f1.
503 491 *
504 492 * @param unused is the starting argument of the RTEMS task
505 493 *
506 494 * The following data packet is sent by this function:
507 495 * - TM_LFR_SCIENCE_SBM1_CWF_F1
508 496 *
509 497 */
510 498
511 499 rtems_event_set event_out;
512 500 rtems_id queue_id;
513 501 rtems_status_code status;
514 502
515 503 ring_node *ring_node_to_send_cwf;
516 504
517 505 status = get_message_queue_id_send( &queue_id );
518 506 if (status != RTEMS_SUCCESSFUL)
519 507 {
520 508 PRINTF1("in CWF1 *** ERR get_message_queue_id_send %d\n", status)
521 509 }
522 510
523 BOOT_PRINTF("in CWF1 ***\n")
511 BOOT_PRINTF("in CWF1 ***\n");
524 512
525 while(1){
513 while(1){
526 514 // wait for an RTEMS_EVENT
527 515 rtems_event_receive( RTEMS_EVENT_MODE_NORM_S1_S2,
528 516 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
529 517 ring_node_to_send_cwf = getRingNodeToSendCWF( 1 );
530 518 ring_node_to_send_cwf_f1->sid = SID_SBM1_CWF_F1;
531 519 if (lfrCurrentMode == LFR_MODE_SBM1)
532 520 {
533 521 status = rtems_message_queue_send( queue_id, &ring_node_to_send_cwf, sizeof( ring_node* ) );
534 522 if (status != 0)
535 523 {
536 524 PRINTF("cwf sending failed\n")
537 525 }
538 526 }
539 527 // launch snapshot extraction if needed
540 528 if (extractSWF1 == true)
541 529 {
542 530 ring_node_to_send_swf_f1 = ring_node_to_send_cwf;
543 531 // launch the snapshot extraction
544 532 status = rtems_event_send( Task_id[TASKID_SWBD], RTEMS_EVENT_MODE_NORM_S1_S2 );
545 533 extractSWF1 = false;
546 534 }
547 535 if (swf0_ready_flag_f1 == true)
548 536 {
549 537 extractSWF1 = true;
550 538 swf0_ready_flag_f1 = false; // this step shall be executed only one time
551 539 }
552 540 if ((swf1_ready == true) && (swf2_ready == true)) // swf_f1 is ready after the extraction
553 541 {
554 542 status = rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_NORMAL );
555 543 swf1_ready = false;
556 544 swf2_ready = false;
557 545 }
558 546 }
559 547 }
560 548
561 549 rtems_task swbd_task(rtems_task_argument argument)
562 550 {
563 551 /** This RTEMS task is dedicated to the building of snapshots from different continuous waveforms buffers.
564 552 *
565 553 * @param unused is the starting argument of the RTEMS task
566 554 *
567 555 */
568 556
569 557 rtems_event_set event_out;
570 558 unsigned long long int acquisitionTimeF0_asLong;
571 559
572 560 acquisitionTimeF0_asLong = 0x00;
573 561
574 562 BOOT_PRINTF("in SWBD ***\n")
575 563
576 564 while(1){
577 565 // wait for an RTEMS_EVENT
578 566 rtems_event_receive( RTEMS_EVENT_MODE_NORM_S1_S2,
579 567 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
580 568 if (event_out == RTEMS_EVENT_MODE_NORM_S1_S2)
581 569 {
582 570 acquisitionTimeF0_asLong = get_acquisition_time( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
583 571 build_snapshot_from_ring( ring_node_to_send_swf_f1, 1, acquisitionTimeF0_asLong,
584 572 &ring_node_swf1_extracted, swf1_extracted );
585 573 swf1_ready = true; // the snapshot has been extracted and is ready to be sent
586 574 }
587 575 else
588 576 {
589 577 PRINTF1("in SWBD *** unexpected rtems event received %x\n", (int) event_out)
590 578 }
591 579 }
592 580 }
593 581
594 582 //******************
595 583 // general functions
596 584
597 585 void WFP_init_rings( void )
598 586 {
599 587 // F0 RING
600 588 init_ring( waveform_ring_f0, NB_RING_NODES_F0, wf_buffer_f0, WFRM_BUFFER );
601 589 // F1 RING
602 590 init_ring( waveform_ring_f1, NB_RING_NODES_F1, wf_buffer_f1, WFRM_BUFFER );
603 591 // F2 RING
604 592 init_ring( waveform_ring_f2, NB_RING_NODES_F2, wf_buffer_f2, WFRM_BUFFER );
605 593 // F3 RING
606 594 init_ring( waveform_ring_f3, NB_RING_NODES_F3, wf_buffer_f3, WFRM_BUFFER );
607 595
608 596 ring_node_swf1_extracted.buffer_address = (int) swf1_extracted;
609 597 ring_node_swf2_extracted.buffer_address = (int) swf2_extracted;
610 598
611 599 DEBUG_PRINTF1("waveform_ring_f0 @%x\n", (unsigned int) waveform_ring_f0)
612 600 DEBUG_PRINTF1("waveform_ring_f1 @%x\n", (unsigned int) waveform_ring_f1)
613 601 DEBUG_PRINTF1("waveform_ring_f2 @%x\n", (unsigned int) waveform_ring_f2)
614 602 DEBUG_PRINTF1("waveform_ring_f3 @%x\n", (unsigned int) waveform_ring_f3)
615 603 DEBUG_PRINTF1("wf_buffer_f0 @%x\n", (unsigned int) wf_buffer_f0)
616 604 DEBUG_PRINTF1("wf_buffer_f1 @%x\n", (unsigned int) wf_buffer_f1)
617 605 DEBUG_PRINTF1("wf_buffer_f2 @%x\n", (unsigned int) wf_buffer_f2)
618 606 DEBUG_PRINTF1("wf_buffer_f3 @%x\n", (unsigned int) wf_buffer_f3)
619 607
620 608 }
621 609
622 610 void WFP_reset_current_ring_nodes( void )
623 611 {
624 612 current_ring_node_f0 = waveform_ring_f0[0].next;
625 613 current_ring_node_f1 = waveform_ring_f1[0].next;
626 614 current_ring_node_f2 = waveform_ring_f2[0].next;
627 615 current_ring_node_f3 = waveform_ring_f3[0].next;
628 616
629 617 ring_node_to_send_swf_f0 = waveform_ring_f0;
630 618 ring_node_to_send_swf_f1 = waveform_ring_f1;
631 619 ring_node_to_send_swf_f2 = waveform_ring_f2;
632 620
633 621 ring_node_to_send_cwf_f1 = waveform_ring_f1;
634 622 ring_node_to_send_cwf_f2 = waveform_ring_f2;
635 623 ring_node_to_send_cwf_f3 = waveform_ring_f3;
636 624 }
637 625
638 626 int send_waveform_CWF3_light( ring_node *ring_node_to_send, ring_node *ring_node_cwf3_light, rtems_id queue_id )
639 627 {
640 628 /** This function sends CWF_F3 CCSDS packets without the b1, b2 and b3 data.
641 629 *
642 630 * @param waveform points to the buffer containing the data that will be send.
643 631 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
644 632 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
645 633 * contain information to setup the transmission of the data packets.
646 634 *
647 635 * By default, CWF_F3 packet are send without the b1, b2 and b3 data. This function rebuilds a data buffer
648 636 * from the incoming data and sends it in 7 packets, 6 containing 340 blocks and 1 one containing 8 blocks.
649 637 *
650 638 */
651 639
652 640 unsigned int i;
653 641 int ret;
654 642 rtems_status_code status;
655 643
656 644 char *sample;
657 645 int *dataPtr;
658 646
659 647 ret = LFR_DEFAULT;
660 648
661 649 dataPtr = (int*) ring_node_to_send->buffer_address;
662 650
663 651 ring_node_cwf3_light->coarseTime = ring_node_to_send->coarseTime;
664 652 ring_node_cwf3_light->fineTime = ring_node_to_send->fineTime;
665 653
666 654 //**********************
667 655 // BUILD CWF3_light DATA
668 656 for ( i=0; i< NB_SAMPLES_PER_SNAPSHOT; i++)
669 657 {
670 658 sample = (char*) &dataPtr[ (i * NB_WORDS_SWF_BLK) ];
671 659 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) ] = sample[ 0 ];
672 660 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 1 ] = sample[ 1 ];
673 661 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 2 ] = sample[ 2 ];
674 662 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 3 ] = sample[ 3 ];
675 663 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 4 ] = sample[ 4 ];
676 664 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 5 ] = sample[ 5 ];
677 665 }
678 666
679 667 // SEND PACKET
680 668 status = rtems_message_queue_send( queue_id, &ring_node_cwf3_light, sizeof( ring_node* ) );
681 669 if (status != RTEMS_SUCCESSFUL) {
682 670 ret = LFR_DEFAULT;
683 671 }
684 672
685 673 return ret;
686 674 }
687 675
688 676 void compute_acquisition_time( unsigned int coarseTime, unsigned int fineTime,
689 677 unsigned int sid, unsigned char pa_lfr_pkt_nr, unsigned char * acquisitionTime )
690 678 {
691 679 unsigned long long int acquisitionTimeAsLong;
692 680 unsigned char localAcquisitionTime[6];
693 681 double deltaT;
694 682
695 683 deltaT = 0.;
696 684
697 685 localAcquisitionTime[0] = (unsigned char) ( coarseTime >> 24 );
698 686 localAcquisitionTime[1] = (unsigned char) ( coarseTime >> 16 );
699 687 localAcquisitionTime[2] = (unsigned char) ( coarseTime >> 8 );
700 688 localAcquisitionTime[3] = (unsigned char) ( coarseTime );
701 689 localAcquisitionTime[4] = (unsigned char) ( fineTime >> 8 );
702 690 localAcquisitionTime[5] = (unsigned char) ( fineTime );
703 691
704 692 acquisitionTimeAsLong = ( (unsigned long long int) localAcquisitionTime[0] << 40 )
705 693 + ( (unsigned long long int) localAcquisitionTime[1] << 32 )
706 694 + ( (unsigned long long int) localAcquisitionTime[2] << 24 )
707 695 + ( (unsigned long long int) localAcquisitionTime[3] << 16 )
708 696 + ( (unsigned long long int) localAcquisitionTime[4] << 8 )
709 697 + ( (unsigned long long int) localAcquisitionTime[5] );
710 698
711 699 switch( sid )
712 700 {
713 701 case SID_NORM_SWF_F0:
714 702 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 24576. ;
715 703 break;
716 704
717 705 case SID_NORM_SWF_F1:
718 706 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 4096. ;
719 707 break;
720 708
721 709 case SID_NORM_SWF_F2:
722 710 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 256. ;
723 711 break;
724 712
725 713 case SID_SBM1_CWF_F1:
726 714 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 4096. ;
727 715 break;
728 716
729 717 case SID_SBM2_CWF_F2:
730 718 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 256. ;
731 719 break;
732 720
733 721 case SID_BURST_CWF_F2:
734 722 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 256. ;
735 723 break;
736 724
737 725 case SID_NORM_CWF_F3:
738 726 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF_SHORT_F3 * 65536. / 16. ;
739 727 break;
740 728
741 729 case SID_NORM_CWF_LONG_F3:
742 730 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 16. ;
743 731 break;
744 732
745 733 default:
746 734 PRINTF1("in compute_acquisition_time *** ERR unexpected sid %d\n", sid)
747 735 deltaT = 0.;
748 736 break;
749 737 }
750 738
751 739 acquisitionTimeAsLong = acquisitionTimeAsLong + (unsigned long long int) deltaT;
752 740 //
753 741 acquisitionTime[0] = (unsigned char) (acquisitionTimeAsLong >> 40);
754 742 acquisitionTime[1] = (unsigned char) (acquisitionTimeAsLong >> 32);
755 743 acquisitionTime[2] = (unsigned char) (acquisitionTimeAsLong >> 24);
756 744 acquisitionTime[3] = (unsigned char) (acquisitionTimeAsLong >> 16);
757 745 acquisitionTime[4] = (unsigned char) (acquisitionTimeAsLong >> 8 );
758 746 acquisitionTime[5] = (unsigned char) (acquisitionTimeAsLong );
759 747
760 748 }
761 749
762 750 void build_snapshot_from_ring( ring_node *ring_node_to_send,
763 751 unsigned char frequencyChannel,
764 752 unsigned long long int acquisitionTimeF0_asLong,
765 753 ring_node *ring_node_swf_extracted,
766 754 int *swf_extracted)
767 755 {
768 756 unsigned int i;
769 757 unsigned long long int centerTime_asLong;
770 758 unsigned long long int acquisitionTime_asLong;
771 759 unsigned long long int bufferAcquisitionTime_asLong;
772 760 unsigned char *ptr1;
773 761 unsigned char *ptr2;
774 762 unsigned char *timeCharPtr;
775 763 unsigned char nb_ring_nodes;
776 764 unsigned long long int frequency_asLong;
777 765 unsigned long long int nbTicksPerSample_asLong;
778 766 unsigned long long int nbSamplesPart1_asLong;
779 767 unsigned long long int sampleOffset_asLong;
780 768
781 769 unsigned int deltaT_F0;
782 770 unsigned int deltaT_F1;
783 771 unsigned long long int deltaT_F2;
784 772
785 773 deltaT_F0 = 2731; // (2048. / 24576. / 2.) * 65536. = 2730.667;
786 774 deltaT_F1 = 16384; // (2048. / 4096. / 2.) * 65536. = 16384;
787 775 deltaT_F2 = 262144; // (2048. / 256. / 2.) * 65536. = 262144;
788 776 sampleOffset_asLong = 0x00;
789 777
790 778 // (1) get the f0 acquisition time => the value is passed in argument
791 779
792 780 // (2) compute the central reference time
793 781 centerTime_asLong = acquisitionTimeF0_asLong + deltaT_F0;
794 782
795 783 // (3) compute the acquisition time of the current snapshot
796 784 switch(frequencyChannel)
797 785 {
798 786 case 1: // 1 is for F1 = 4096 Hz
799 787 acquisitionTime_asLong = centerTime_asLong - deltaT_F1;
800 788 nb_ring_nodes = NB_RING_NODES_F1;
801 789 frequency_asLong = 4096;
802 790 nbTicksPerSample_asLong = 16; // 65536 / 4096;
803 791 break;
804 792 case 2: // 2 is for F2 = 256 Hz
805 793 acquisitionTime_asLong = centerTime_asLong - deltaT_F2;
806 794 nb_ring_nodes = NB_RING_NODES_F2;
807 795 frequency_asLong = 256;
808 796 nbTicksPerSample_asLong = 256; // 65536 / 256;
809 797 break;
810 798 default:
811 799 acquisitionTime_asLong = centerTime_asLong;
812 800 frequency_asLong = 256;
813 801 nbTicksPerSample_asLong = 256;
814 802 break;
815 803 }
816 804
817 805 //****************************************************************************
818 806 // (4) search the ring_node with the acquisition time <= acquisitionTime_asLong
819 807 for (i=0; i<nb_ring_nodes; i++)
820 808 {
821 809 //PRINTF1("%d ... ", i);
822 810 bufferAcquisitionTime_asLong = get_acquisition_time( (unsigned char *) &ring_node_to_send->coarseTime );
823 811 if (bufferAcquisitionTime_asLong <= acquisitionTime_asLong)
824 812 {
825 813 //PRINTF1("buffer found with acquisition time = %llx\n", bufferAcquisitionTime_asLong);
826 814 break;
827 815 }
828 816 ring_node_to_send = ring_node_to_send->previous;
829 817 }
830 818
831 819 // (5) compute the number of samples to take in the current buffer
832 820 sampleOffset_asLong = ((acquisitionTime_asLong - bufferAcquisitionTime_asLong) * frequency_asLong ) >> 16;
833 821 nbSamplesPart1_asLong = NB_SAMPLES_PER_SNAPSHOT - sampleOffset_asLong;
834 822 //PRINTF2("sampleOffset_asLong = %lld, nbSamplesPart1_asLong = %lld\n", sampleOffset_asLong, nbSamplesPart1_asLong);
835 823
836 824 // (6) compute the final acquisition time
837 825 acquisitionTime_asLong = bufferAcquisitionTime_asLong +
838 826 sampleOffset_asLong * nbTicksPerSample_asLong;
839 827
840 828 // (7) copy the acquisition time at the beginning of the extrated snapshot
841 829 ptr1 = (unsigned char*) &acquisitionTime_asLong;
842 830 // fine time
843 831 ptr2 = (unsigned char*) &ring_node_swf_extracted->fineTime;
844 832 ptr2[2] = ptr1[ 4 + 2 ];
845 833 ptr2[3] = ptr1[ 5 + 2 ];
846 834 // coarse time
847 835 ptr2 = (unsigned char*) &ring_node_swf_extracted->coarseTime;
848 836 ptr2[0] = ptr1[ 0 + 2 ];
849 837 ptr2[1] = ptr1[ 1 + 2 ];
850 838 ptr2[2] = ptr1[ 2 + 2 ];
851 839 ptr2[3] = ptr1[ 3 + 2 ];
852 840
853 841 // re set the synchronization bit
854 842 timeCharPtr = (unsigned char*) &ring_node_to_send->coarseTime;
855 843 ptr2[0] = ptr2[0] | (timeCharPtr[0] & 0x80); // [1000 0000]
856 844
857 845 if ( (nbSamplesPart1_asLong >= NB_SAMPLES_PER_SNAPSHOT) | (nbSamplesPart1_asLong < 0) )
858 846 {
859 847 nbSamplesPart1_asLong = 0;
860 848 }
861 849 // copy the part 1 of the snapshot in the extracted buffer
862 850 for ( i = 0; i < (nbSamplesPart1_asLong * NB_WORDS_SWF_BLK); i++ )
863 851 {
864 852 swf_extracted[i] =
865 853 ((int*) ring_node_to_send->buffer_address)[ i + (sampleOffset_asLong * NB_WORDS_SWF_BLK) ];
866 854 }
867 855 // copy the part 2 of the snapshot in the extracted buffer
868 856 ring_node_to_send = ring_node_to_send->next;
869 857 for ( i = (nbSamplesPart1_asLong * NB_WORDS_SWF_BLK); i < (NB_SAMPLES_PER_SNAPSHOT * NB_WORDS_SWF_BLK); i++ )
870 858 {
871 859 swf_extracted[i] =
872 860 ((int*) ring_node_to_send->buffer_address)[ (i-(nbSamplesPart1_asLong * NB_WORDS_SWF_BLK)) ];
873 861 }
874 862 }
875 863
876 864 void snapshot_resynchronization( unsigned char *timePtr )
877 865 {
878 866 unsigned long long int acquisitionTime;
879 867 unsigned long long int centerTime;
880 868 unsigned long long int previousTick;
881 869 unsigned long long int nextTick;
882 870 unsigned long long int deltaPreviousTick;
883 871 unsigned long long int deltaNextTick;
884 872 unsigned int deltaTickInF2;
885 873 double deltaPrevious_ms;
886 874 double deltaNext_ms;
887 875
888 876 // get acquisition time in fine time ticks
889 877 acquisitionTime = get_acquisition_time( timePtr );
890 878
891 879 // compute center time
892 880 centerTime = acquisitionTime + 2731; // (2048. / 24576. / 2.) * 65536. = 2730.667;
893 881 previousTick = centerTime - (centerTime & 0xffff);
894 882 nextTick = previousTick + 65536;
895 883
896 884 deltaPreviousTick = centerTime - previousTick;
897 885 deltaNextTick = nextTick - centerTime;
898 886
899 887 deltaPrevious_ms = ((double) deltaPreviousTick) / 65536. * 1000.;
900 888 deltaNext_ms = ((double) deltaNextTick) / 65536. * 1000.;
901 889
902 890 PRINTF2("delta previous = %f ms, delta next = %f ms\n", deltaPrevious_ms, deltaNext_ms);
903 891 PRINTF2("delta previous = %llu fine time ticks, delta next = %llu fine time ticks\n", deltaPreviousTick, deltaNextTick);
904 892
905 893 // which tick is the closest
906 894 if (deltaPreviousTick > deltaNextTick)
907 895 {
908 // deltaNext is in [ms]
909 deltaTickInF2 = floor( (deltaNext_ms * 256. / 1000.) );
896 // the snapshot center is just before the second => increase delta_snapshot
897 deltaTickInF2 = ceil( (deltaNext_ms * 256. / 1000.) );
910 898 waveform_picker_regs->delta_snapshot = waveform_picker_regs->delta_snapshot + 1 * deltaTickInF2;
911 899 PRINTF2("correction of = + %u, delta_snapshot = %d\n", deltaTickInF2, waveform_picker_regs->delta_snapshot);
912 900 }
913 901 else
914 902 {
915 // deltaPrevious is in [ms]
916 deltaTickInF2 = floor( (deltaPrevious_ms * 256. / 1000.) );
903 // the snapshot center is just after the second => decrease delat_snapshot
904 deltaTickInF2 = ceil( (deltaPrevious_ms * 256. / 1000.) );
917 905 waveform_picker_regs->delta_snapshot = waveform_picker_regs->delta_snapshot - 1 * deltaTickInF2;
918 906 PRINTF2("correction of = - %u, delta_snapshot = %d\n", deltaTickInF2, waveform_picker_regs->delta_snapshot);
919 907 }
920 908 }
921 909
922 910 //**************
923 911 // wfp registers
924 912 void reset_wfp_burst_enable( void )
925 913 {
926 914 /** This function resets the waveform picker burst_enable register.
927 915 *
928 916 * The burst bits [f2 f1 f0] and the enable bits [f3 f2 f1 f0] are set to 0.
929 917 *
930 918 */
931 919
932 920 // [1000 000] burst f2, f1, f0 enable f3, f2, f1, f0
933 921 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable & 0x80;
934 922 }
935 923
936 924 void reset_wfp_status( void )
937 925 {
938 926 /** This function resets the waveform picker status register.
939 927 *
940 928 * All status bits are set to 0 [new_err full_err full].
941 929 *
942 930 */
943 931
944 932 waveform_picker_regs->status = 0xffff;
945 933 }
946 934
947 935 void reset_wfp_buffer_addresses( void )
948 936 {
949 937 // F0
950 938 waveform_picker_regs->addr_data_f0_0 = current_ring_node_f0->previous->buffer_address; // 0x08
951 939 waveform_picker_regs->addr_data_f0_1 = current_ring_node_f0->buffer_address; // 0x0c
952 940 // F1
953 941 waveform_picker_regs->addr_data_f1_0 = current_ring_node_f1->previous->buffer_address; // 0x10
954 942 waveform_picker_regs->addr_data_f1_1 = current_ring_node_f1->buffer_address; // 0x14
955 943 // F2
956 944 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->previous->buffer_address; // 0x18
957 945 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address; // 0x1c
958 946 // F3
959 947 waveform_picker_regs->addr_data_f3_0 = current_ring_node_f3->previous->buffer_address; // 0x20
960 948 waveform_picker_regs->addr_data_f3_1 = current_ring_node_f3->buffer_address; // 0x24
961 949 }
962 950
963 951 void reset_waveform_picker_regs( void )
964 952 {
965 953 /** This function resets the waveform picker module registers.
966 954 *
967 955 * The registers affected by this function are located at the following offset addresses:
968 956 * - 0x00 data_shaping
969 957 * - 0x04 run_burst_enable
970 958 * - 0x08 addr_data_f0
971 959 * - 0x0C addr_data_f1
972 960 * - 0x10 addr_data_f2
973 961 * - 0x14 addr_data_f3
974 962 * - 0x18 status
975 963 * - 0x1C delta_snapshot
976 964 * - 0x20 delta_f0
977 965 * - 0x24 delta_f0_2
978 966 * - 0x28 delta_f1
979 967 * - 0x2c delta_f2
980 968 * - 0x30 nb_data_by_buffer
981 969 * - 0x34 nb_snapshot_param
982 970 * - 0x38 start_date
983 971 * - 0x3c nb_word_in_buffer
984 972 *
985 973 */
986 974
987 975 set_wfp_data_shaping(); // 0x00 *** R1 R0 SP1 SP0 BW
988 976
989 977 reset_wfp_burst_enable(); // 0x04 *** [run *** burst f2, f1, f0 *** enable f3, f2, f1, f0 ]
990 978
991 979 reset_wfp_buffer_addresses();
992 980
993 981 reset_wfp_status(); // 0x18
994 982
995 983 set_wfp_delta_snapshot(); // 0x1c *** 300 s => 0x12bff
996 984
997 985 set_wfp_delta_f0_f0_2(); // 0x20, 0x24
998 986
999 987 set_wfp_delta_f1(); // 0x28
1000 988
1001 989 set_wfp_delta_f2(); // 0x2c
1002 990
1003 991 DEBUG_PRINTF1("delta_snapshot %x\n", waveform_picker_regs->delta_snapshot)
1004 992 DEBUG_PRINTF1("delta_f0 %x\n", waveform_picker_regs->delta_f0)
1005 993 DEBUG_PRINTF1("delta_f0_2 %x\n", waveform_picker_regs->delta_f0_2)
1006 994 DEBUG_PRINTF1("delta_f1 %x\n", waveform_picker_regs->delta_f1)
1007 995 DEBUG_PRINTF1("delta_f2 %x\n", waveform_picker_regs->delta_f2)
1008 996 // 2688 = 8 * 336
1009 997 waveform_picker_regs->nb_data_by_buffer = 0xa7f; // 0x30 *** 2688 - 1 => nb samples -1
1010 998 waveform_picker_regs->snapshot_param = 0xa80; // 0x34 *** 2688 => nb samples
1011 999 waveform_picker_regs->start_date = 0x7fffffff; // 0x38
1012 1000 //
1013 1001 // coarse time and fine time registers are not initialized, they are volatile
1014 1002 //
1015 1003 waveform_picker_regs->buffer_length = 0x1f8;// buffer length in burst = 3 * 2688 / 16 = 504 = 0x1f8
1016 1004 }
1017 1005
1018 1006 void set_wfp_data_shaping( void )
1019 1007 {
1020 1008 /** This function sets the data_shaping register of the waveform picker module.
1021 1009 *
1022 1010 * The value is read from one field of the parameter_dump_packet structure:\n
1023 1011 * bw_sp0_sp1_r0_r1
1024 1012 *
1025 1013 */
1026 1014
1027 1015 unsigned char data_shaping;
1028 1016
1029 1017 // get the parameters for the data shaping [BW SP0 SP1 R0 R1] in sy_lfr_common1 and configure the register
1030 1018 // waveform picker : [R1 R0 SP1 SP0 BW]
1031 1019
1032 1020 data_shaping = parameter_dump_packet.sy_lfr_common_parameters;
1033 1021
1034 1022 waveform_picker_regs->data_shaping =
1035 1023 ( (data_shaping & 0x20) >> 5 ) // BW
1036 1024 + ( (data_shaping & 0x10) >> 3 ) // SP0
1037 1025 + ( (data_shaping & 0x08) >> 1 ) // SP1
1038 1026 + ( (data_shaping & 0x04) << 1 ) // R0
1039 1027 + ( (data_shaping & 0x02) << 3 ) // R1
1040 1028 + ( (data_shaping & 0x01) << 5 ); // R2
1041 1029 }
1042 1030
1043 1031 void set_wfp_burst_enable_register( unsigned char mode )
1044 1032 {
1045 1033 /** This function sets the waveform picker burst_enable register depending on the mode.
1046 1034 *
1047 1035 * @param mode is the LFR mode to launch.
1048 1036 *
1049 1037 * The burst bits shall be before the enable bits.
1050 1038 *
1051 1039 */
1052 1040
1053 1041 // [0000 0000] burst f2, f1, f0 enable f3 f2 f1 f0
1054 1042 // the burst bits shall be set first, before the enable bits
1055 1043 switch(mode) {
1056 1044 case LFR_MODE_NORMAL:
1057 1045 case LFR_MODE_SBM1:
1058 1046 case LFR_MODE_SBM2:
1059 1047 waveform_picker_regs->run_burst_enable = 0x60; // [0110 0000] enable f2 and f1 burst
1060 1048 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x0f; // [1111] enable f3 f2 f1 f0
1061 1049 break;
1062 1050 case LFR_MODE_BURST:
1063 1051 waveform_picker_regs->run_burst_enable = 0x40; // [0100 0000] f2 burst enabled
1064 1052 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x0c; // [1100] enable f3 and f2
1065 1053 break;
1066 1054 default:
1067 1055 waveform_picker_regs->run_burst_enable = 0x00; // [0000 0000] no burst enabled, no waveform enabled
1068 1056 break;
1069 1057 }
1070 1058 }
1071 1059
1072 1060 void set_wfp_delta_snapshot( void )
1073 1061 {
1074 1062 /** This function sets the delta_snapshot register of the waveform picker module.
1075 1063 *
1076 1064 * The value is read from two (unsigned char) of the parameter_dump_packet structure:
1077 1065 * - sy_lfr_n_swf_p[0]
1078 1066 * - sy_lfr_n_swf_p[1]
1079 1067 *
1080 1068 */
1081 1069
1082 1070 unsigned int delta_snapshot;
1083 1071 unsigned int delta_snapshot_in_T2;
1084 1072
1085 1073 delta_snapshot = parameter_dump_packet.sy_lfr_n_swf_p[0]*256
1086 1074 + parameter_dump_packet.sy_lfr_n_swf_p[1];
1087 1075
1088 1076 delta_snapshot_in_T2 = delta_snapshot * 256;
1089 1077 waveform_picker_regs->delta_snapshot = delta_snapshot_in_T2 - 1; // max 4 bytes
1090 1078 }
1091 1079
1092 1080 void set_wfp_delta_f0_f0_2( void )
1093 1081 {
1094 1082 unsigned int delta_snapshot;
1095 1083 unsigned int nb_samples_per_snapshot;
1096 1084 float delta_f0_in_float;
1097 1085
1098 1086 delta_snapshot = waveform_picker_regs->delta_snapshot;
1099 1087 nb_samples_per_snapshot = parameter_dump_packet.sy_lfr_n_swf_l[0] * 256 + parameter_dump_packet.sy_lfr_n_swf_l[1];
1100 1088 delta_f0_in_float =nb_samples_per_snapshot / 2. * ( 1. / 256. - 1. / 24576.) * 256.;
1101 1089
1102 1090 waveform_picker_regs->delta_f0 = delta_snapshot - floor( delta_f0_in_float );
1103 1091 waveform_picker_regs->delta_f0_2 = 0x30; // 48 = 11 0000, max 7 bits
1104 1092 }
1105 1093
1106 1094 void set_wfp_delta_f1( void )
1107 1095 {
1108 1096 unsigned int delta_snapshot;
1109 1097 unsigned int nb_samples_per_snapshot;
1110 1098 float delta_f1_in_float;
1111 1099
1112 1100 delta_snapshot = waveform_picker_regs->delta_snapshot;
1113 1101 nb_samples_per_snapshot = parameter_dump_packet.sy_lfr_n_swf_l[0] * 256 + parameter_dump_packet.sy_lfr_n_swf_l[1];
1114 1102 delta_f1_in_float = nb_samples_per_snapshot / 2. * ( 1. / 256. - 1. / 4096.) * 256.;
1115 1103
1116 1104 waveform_picker_regs->delta_f1 = delta_snapshot - floor( delta_f1_in_float );
1117 1105 }
1118 1106
1119 1107 void set_wfp_delta_f2()
1120 1108 {
1121 1109 unsigned int delta_snapshot;
1122 1110 unsigned int nb_samples_per_snapshot;
1123 1111
1124 1112 delta_snapshot = waveform_picker_regs->delta_snapshot;
1125 1113 nb_samples_per_snapshot = parameter_dump_packet.sy_lfr_n_swf_l[0] * 256 + parameter_dump_packet.sy_lfr_n_swf_l[1];
1126 1114
1127 1115 waveform_picker_regs->delta_f2 = delta_snapshot - nb_samples_per_snapshot / 2;
1128 1116 }
1129 1117
1130 1118 //*****************
1131 1119 // local parameters
1132 1120
1133 1121 void increment_seq_counter_source_id( unsigned char *packet_sequence_control, unsigned int sid )
1134 1122 {
1135 1123 /** This function increments the parameter "sequence_cnt" depending on the sid passed in argument.
1136 1124 *
1137 1125 * @param packet_sequence_control is a pointer toward the parameter sequence_cnt to update.
1138 1126 * @param sid is the source identifier of the packet being updated.
1139 1127 *
1140 1128 * REQ-LFR-SRS-5240 / SSS-CP-FS-590
1141 1129 * The sequence counters shall wrap around from 2^14 to zero.
1142 1130 * The sequence counter shall start at zero at startup.
1143 1131 *
1144 1132 * REQ-LFR-SRS-5239 / SSS-CP-FS-580
1145 1133 * All TM_LFR_SCIENCE_ packets are sent to ground, i.e. destination id = 0
1146 1134 *
1147 1135 */
1148 1136
1149 1137 unsigned short *sequence_cnt;
1150 1138 unsigned short segmentation_grouping_flag;
1151 1139 unsigned short new_packet_sequence_control;
1152 1140 rtems_mode initial_mode_set;
1153 1141 rtems_mode current_mode_set;
1154 1142 rtems_status_code status;
1155 1143
1156 1144 //******************************************
1157 1145 // CHANGE THE MODE OF THE CALLING RTEMS TASK
1158 1146 status = rtems_task_mode( RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &initial_mode_set );
1159 1147
1160 1148 if ( (sid == SID_NORM_SWF_F0) || (sid == SID_NORM_SWF_F1) || (sid == SID_NORM_SWF_F2)
1161 1149 || (sid == SID_NORM_CWF_F3) || (sid == SID_NORM_CWF_LONG_F3)
1162 1150 || (sid == SID_BURST_CWF_F2)
1163 1151 || (sid == SID_NORM_ASM_F0) || (sid == SID_NORM_ASM_F1) || (sid == SID_NORM_ASM_F2)
1164 1152 || (sid == SID_NORM_BP1_F0) || (sid == SID_NORM_BP1_F1) || (sid == SID_NORM_BP1_F2)
1165 1153 || (sid == SID_NORM_BP2_F0) || (sid == SID_NORM_BP2_F1) || (sid == SID_NORM_BP2_F2)
1166 1154 || (sid == SID_BURST_BP1_F0) || (sid == SID_BURST_BP2_F0)
1167 1155 || (sid == SID_BURST_BP1_F1) || (sid == SID_BURST_BP2_F1) )
1168 1156 {
1169 1157 sequence_cnt = (unsigned short *) &sequenceCounters_SCIENCE_NORMAL_BURST;
1170 1158 }
1171 1159 else if ( (sid ==SID_SBM1_CWF_F1) || (sid ==SID_SBM2_CWF_F2)
1172 1160 || (sid == SID_SBM1_BP1_F0) || (sid == SID_SBM1_BP2_F0)
1173 1161 || (sid == SID_SBM2_BP1_F0) || (sid == SID_SBM2_BP2_F0)
1174 1162 || (sid == SID_SBM2_BP1_F1) || (sid == SID_SBM2_BP2_F1) )
1175 1163 {
1176 1164 sequence_cnt = (unsigned short *) &sequenceCounters_SCIENCE_SBM1_SBM2;
1177 1165 }
1178 1166 else
1179 1167 {
1180 1168 sequence_cnt = (unsigned short *) NULL;
1181 1169 PRINTF1("in increment_seq_counter_source_id *** ERR apid_destid %d not known\n", sid)
1182 1170 }
1183 1171
1184 1172 if (sequence_cnt != NULL)
1185 1173 {
1186 1174 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << 8;
1187 1175 *sequence_cnt = (*sequence_cnt) & 0x3fff;
1188 1176
1189 1177 new_packet_sequence_control = segmentation_grouping_flag | (*sequence_cnt) ;
1190 1178
1191 1179 packet_sequence_control[0] = (unsigned char) (new_packet_sequence_control >> 8);
1192 1180 packet_sequence_control[1] = (unsigned char) (new_packet_sequence_control );
1193 1181
1194 1182 // increment the sequence counter
1195 1183 if ( *sequence_cnt < SEQ_CNT_MAX)
1196 1184 {
1197 1185 *sequence_cnt = *sequence_cnt + 1;
1198 1186 }
1199 1187 else
1200 1188 {
1201 1189 *sequence_cnt = 0;
1202 1190 }
1203 1191 }
1204 1192
1205 1193 //*************************************
1206 1194 // RESTORE THE MODE OF THE CALLING TASK
1207 1195 status = rtems_task_mode( initial_mode_set, RTEMS_PREEMPT_MASK, &current_mode_set );
1208 1196 }
General Comments 0
You need to be logged in to leave comments. Login now