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