##// END OF EJS Templates
Few cosmetic changes and lowered optim to -O2...
jeandet -
r400:9d5e16586c2c 3.2.0.22 R3++ draft
parent child
Show More
@@ -1,14 +1,14
1 cmake_minimum_required (VERSION 2.6)
1 cmake_minimum_required (VERSION 3.6)
2 2 project (LFR_FSW)
3 3
4 4 if(NOT CMAKE_BUILD_TYPE)
5 5 set(CMAKE_BUILD_TYPE "Release" CACHE STRING
6 6 "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
7 7 endif(NOT CMAKE_BUILD_TYPE)
8 8
9 9 set(LFR_BP_SRC ${CMAKE_CURRENT_SOURCE_DIR}/LFR_basic-parameters/basic_parameters.c)
10 10
11 11 SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/sparc")
12 12
13 13 add_subdirectory(libgcov)
14 14 add_subdirectory(src)
@@ -1,17 +1,20
1 1 cmake_minimum_required(VERSION 3.6)
2 2 project(libgcov C)
3 3 include(sparc-rtems)
4 4 include(cppcheck)
5 5
6 6 set(LIB_GCOV_SOURCES
7 7 gcov-io.c
8 8 gcov-io.h
9 9 gcov-iov.h
10 10 libgcov.c
11 11 )
12
12 if(Coverage)
13 # add_definitions(-DGCOV_USE_EXIT)
14 add_definitions(-DGCOV_ENABLED)
15 endif()
13 16 add_library(gcov STATIC ${LIB_GCOV_SOURCES})
14 17
15 18 add_custom_target(gcovr
16 19 COMMAND gcovr --exclude='.*gcov.*' --gcov-executable=${rtems_dir}/bin/sparc-rtems-gcov --object-directory ${CMAKE_BINARY_DIR} -r ${CMAKE_SOURCE_DIR} --html --html-details -o ${CMAKE_CURRENT_BINARY_DIR}/gcov.html && xdg-open ${CMAKE_CURRENT_BINARY_DIR}/gcov.html
17 20 )
@@ -1,488 +1,490
1 1 /* Test for GCC >= 3.4.4 && <= 4.4.6 */
2 2 //#if ( ( __GNUC__ > 3 ) || \
3 3 // ( __GNUC__ == 3 && __GNUC_MINOR__ > 4 )|| \
4 4 // ( __GNUC__ == 3 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ >= 4 ) ) && \
5 5 // ( ( __GNUC__ < 4 ) || \
6 6 // ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 )|| \
7 7 // ( __GNUC__ == 4 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ <= 6 ) )
8 8 /*
9 9 * =====================================================================================
10 10 *
11 11 * Filename: gcov-io.c
12 12 *
13 13 * Description: This is the I/O file for embedded systems
14 14 *
15 15 * Version: 1.0
16 16 * Created: 03/04/08 09:51:59
17 17 * Revision: none
18 18 * Compiler: gcc
19 19 *
20 20 * Author: Aitor Viana Sanchez (avs), aitor.viana.sanchez@esa.int
21 21 * Company: European Space Agency (ESA-ESTEC)
22 22 *
23 23 * =====================================================================================
24 24 */
25 25
26 26 /* File format for coverage information
27 27 Copyright (C) 1996, 1997, 1998, 2000, 2002,
28 28 2003 Free Software Foundation, Inc.
29 29 Contributed by Bob Manson <manson@cygnus.com>.
30 30 Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
31 31
32 32 This file is part of GCC.
33 33
34 34 GCC is free software; you can redistribute it and/or modify it under
35 35 the terms of the GNU General Public License as published by the Free
36 36 Software Foundation; either version 2, or (at your option) any later
37 37 version.
38 38
39 39 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
40 40 WARRANTY; without even the implied warranty of MERCHANTABILITY or
41 41 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
42 42 for more details.
43 43
44 44 You should have received a copy of the GNU General Public License
45 45 along with GCC; see the file COPYING. If not, write to the Free
46 46 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
47 47 02111-1307, USA. */
48 48
49 49 #include <stdio.h>
50 50 #include <stdlib.h> /* for atexit() */
51 51 #include <string.h>
52 52 #include "gcov-io.h"
53 53
54 54 /* Routines declared in gcov-io.h. This file should be #included by
55 55 another source file, after having #included gcov-io.h. */
56 56
57 57
58 58 /* This function shall be defined somewhere else */
59 59 //int send_data(unsigned char * buffer, unsigned int size);
60 60
61 61 /*-----------------------------------------------------------------------------
62 62 * PRIVATE INTERFACE
63 63 *-----------------------------------------------------------------------------*/
64 64
65 65 static void gcov_write_block (unsigned);
66 66 static gcov_unsigned_t *gcov_write_words (unsigned);
67 67 GCOV_LINKAGE int gcov_send (void);
68 68 GCOV_LINKAGE int gcov_close(void);
69 69
70 70 extern struct gcov_info * gcov_list;
71 71 extern gcov_unsigned_t gcov_crc32;
72 72
73 73 int dev_id = 0;
74 74
75 75 /*
76 76 * === FUNCTION ======================================================================
77 77 * Name: from_file
78 78 * Description: This function just return the given parameter
79 79 * =====================================================================================
80 80 */
81 81 static inline gcov_unsigned_t from_file (gcov_unsigned_t value)
82 82 {
83 83 return value;
84 84 }
85 85
86 86 /*
87 87 * === FUNCTION ======================================================================
88 88 * Name: gcov_version
89 89 * Description: This function returns TRUE (1) if the gcov version is the
90 90 * version expected. The function returns FALSE (0) in any other case.
91 91 * =====================================================================================
92 92 */
93 93 static int gcov_version (struct gcov_info *ptr, gcov_unsigned_t version)
94 94 {
95 95 if (version != GCOV_VERSION)
96 96 {
97 97 char v[4], e[4];
98 98
99 99 GCOV_UNSIGNED2STRING (v, version);
100 100 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
101 101
102 102 printf ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
103 103 ptr->filename, e, v);
104 104
105 105 return 0;
106 106 }
107 107 return 1;
108 108 }
109 109
110 110
111 111 /*-----------------------------------------------------------------------------
112 112 * PUBLIC INTERFACE
113 113 *-----------------------------------------------------------------------------*/
114 114
115 115 /* Dump the coverage counts. We merge with existing counts when
116 116 possible, to avoid growing the .da files ad infinitum. We use this
117 117 program's checksum to make sure we only accumulate whole program
118 118 statistics to the correct summary. An object file might be embedded
119 119 in two separate programs, and we must keep the two program
120 120 summaries separate. */
121 121
122 122 /*
123 123 * === FUNCTION ======================================================================
124 124 * Name: gcov_exit
125 125 * Description: This function dumps the coverage couns. The merging with
126 126 * existing counts is not done in embedded systems.
127 127 * =====================================================================================
128 128 */
129 129 void gcov_exit (void)
130 130 {
131 131 struct gcov_info *gi_ptr;
132 132 struct gcov_summary this_program;
133 133 struct gcov_summary all;
134 134 struct gcov_ctr_summary *cs_ptr;
135 135 const struct gcov_ctr_info *ci_ptr;
136 136 unsigned t_ix;
137 137 gcov_unsigned_t c_num;
138 138 unsigned long coreId = 0;
139 139
140 140 /* retrieve the id of the CPU the program is running on */
141 141 #ifdef LEON3
142 142 __asm__ __volatile__("rd %%asr17,%0\n\t"
143 143 "srl %0,28,%0" :
144 144 "=&r" (coreId) : );
145 145 #endif
146 146
147 147 printf("_GCOVEXIT_BEGIN_,core%d\n", coreId); /* see also _GCOVEXIT_END_ */
148 148
149 149 if(gcov_list == (void*)0x0)
150 150 printf("%s: gcov_list == NULL\n", __func__);
151 151
152 152 memset (&all, 0, sizeof (all));
153 153 /* Find the totals for this execution. */
154 154 memset (&this_program, 0, sizeof (this_program));
155 155 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
156 156 {
157 157
158 158 ci_ptr = gi_ptr->counts;
159 159 for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
160 160 {
161 161 if (!((1 << t_ix) & gi_ptr->ctr_mask))
162 162 continue;
163 163
164 164 cs_ptr = &this_program.ctrs[t_ix];
165 165 cs_ptr->num += ci_ptr->num;
166 166 for (c_num = 0; c_num < ci_ptr->num; c_num++)
167 167 {
168 168 cs_ptr->sum_all += ci_ptr->values[c_num];
169 169 if (cs_ptr->run_max < ci_ptr->values[c_num])
170 170 cs_ptr->run_max = ci_ptr->values[c_num];
171 171 }
172 172 ci_ptr++;
173 173 }
174 174 }
175 175 /* Now merge each file. */
176 176 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
177 177 {
178 178
179 179 struct gcov_summary program;
180 180 gcov_type *values[GCOV_COUNTERS];
181 181 const struct gcov_fn_info *fi_ptr;
182 182 unsigned fi_stride;
183 183 unsigned c_ix, f_ix, n_counts;
184 184
185 185 c_ix = 0;
186 186 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
187 187 if ((1 << t_ix) & gi_ptr->ctr_mask)
188 188 {
189 189 values[c_ix] = gi_ptr->counts[c_ix].values;
190 190 c_ix++;
191 191 }
192 192
193 193 /* Calculate the function_info stride. This depends on the
194 194 number of counter types being measured. */
195 195 fi_stride = sizeof (struct gcov_fn_info) + c_ix * sizeof (unsigned);
196 196 if (__alignof__ (struct gcov_fn_info) > sizeof (unsigned))
197 197 {
198 198 fi_stride += __alignof__ (struct gcov_fn_info) - 1;
199 199 fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1);
200 200 }
201 201
202 202 if (!gcov_open (gi_ptr->filename))
203 203 {
204 204 printf ("profiling:%s:Cannot open\n", gi_ptr->filename);
205 205 continue;
206 206 }
207 207
208 208 program.checksum = gcov_crc32;
209 209
210 210 /* Write out the data. */
211 211 gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
212 212 gcov_write_unsigned (gi_ptr->stamp);
213 213
214 214 /* Write execution counts for each function. */
215 215 for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
216 216 {
217 217 fi_ptr = (const struct gcov_fn_info *)
218 218 ((const char *) gi_ptr->functions + f_ix * fi_stride);
219 219
220 220 /* Announce function. */
221 221 gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
222 222 gcov_write_unsigned (fi_ptr->ident);
223 223 gcov_write_unsigned (fi_ptr->checksum);
224 224
225 225 c_ix = 0;
226 226 for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
227 227 {
228 228 gcov_type *c_ptr;
229 229
230 230 if (!((1 << t_ix) & gi_ptr->ctr_mask))
231 231 continue;
232 232
233 233 n_counts = fi_ptr->n_ctrs[c_ix];
234 234
235 235 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
236 236 GCOV_TAG_COUNTER_LENGTH (n_counts));
237 237 c_ptr = values[c_ix];
238 238 while (n_counts--)
239 239 gcov_write_counter (*c_ptr++);
240 240
241 241 values[c_ix] = c_ptr;
242 242 c_ix++;
243 243 }
244 244 }
245 245
246 246 gcov_send();
247 247 gcov_close();
248 248
249 249 }
250 250
251 251 printf("_GCOVEXIT_END_,core%d\n", coreId);
252 252 }
253 253
254 254
255 255 /* Called before fork or exec - write out profile information gathered so
256 256 far and reset it to zero. This avoids duplication or loss of the
257 257 profile information gathered so far. */
258 258
259 259 void
260 260 __gcov_flush (void)
261 261 {
262 262 const struct gcov_info *gi_ptr;
263 263
264 264 gcov_exit ();
265 265 for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
266 266 {
267 267 unsigned t_ix;
268 268 const struct gcov_ctr_info *ci_ptr;
269 269
270 270 for (t_ix = 0, ci_ptr = gi_ptr->counts; t_ix != GCOV_COUNTERS; t_ix++)
271 271 if ((1 << t_ix) & gi_ptr->ctr_mask)
272 272 {
273 273 memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
274 274 ci_ptr++;
275 275 }
276 276 }
277 277 }
278 278
279 279
280 280
281 281 /* Open a gcov file. NAME is the name of the file to open and MODE
282 282 indicates whether a new file should be created, or an existing file
283 283 opened for modification. If MODE is >= 0 an existing file will be
284 284 opened, if possible, and if MODE is <= 0, a new file will be
285 285 created. Use MODE=0 to attempt to reopen an existing file and then
286 286 fall back on creating a new one. Return zero on failure, >0 on
287 287 opening an existing file and <0 on creating a new one. */
288 288 GCOV_LINKAGE int gcov_open(const char *name)
289 289 {
290 290 // gcov_var.start is cleared in the gcov_close function.
291 291 // If this variable is not cleared...ERROR
292 292 if( gcov_var.start != 0 )
293 293 return 0;
294 294
295 295 // Clear everything
296 296 gcov_var.start = 0;
297 297 gcov_var.offset = gcov_var.length = 0;
298 298 gcov_var.overread = -1u;
299 299 gcov_var.error = 0;
300 300
301 301
302 302 // copy the filename in the gcov_var structure
303 303 strcpy(gcov_var.filename, name);
304 304
305 305
306 306 // return 1 means everything is OK
307 307 return 1;
308 308 }
309 309
310 310 /* Close the current gcov file. Flushes data to disk. Returns nonzero
311 311 on failure or error flag set. */
312 312
313 313 GCOV_LINKAGE int gcov_send (void)
314 314 {
315 315 /*printf("%s: file %s\n", __func__, gcov_var.filename);*/
316 316 if (gcov_var.offset)
317 317 gcov_write_block (gcov_var.offset);
318 318
319 319 gcov_var.length = 0;
320 320 return gcov_var.error;
321 321 }
322 322
323 323 GCOV_LINKAGE int gcov_close(void)
324 324 {
325 325 memset(gcov_var.filename, 0, strlen(gcov_var.filename));
326 326
327 327 // Clear the start variable because will be tested in the gcov_open
328 328 // function
329 329 gcov_var.start = 0;
330 330
331 331 // Return the error, not sure whether the error is modifed.
332 332 return gcov_var.error;
333 333 }
334 334
335 335
336 336 static void gcov_write_block (unsigned size) {
337 337 unsigned char *buffer = (unsigned char*) gcov_var.buffer;
338 338 unsigned int i;
339 339
340 340 printf("_GCOV_,%s,", gcov_var.filename);
341 341 /* to speed up the printing process, we display bytes 4 by 4 */
342 342 for(i = 0; i < size; i++) {
343 343 printf("%02X%02X%02X%02X", (unsigned int)(buffer[0]),
344 344 (unsigned int)(buffer[1]),
345 345 (unsigned int)(buffer[2]),
346 346 (unsigned int)(buffer[3]));
347 347
348 348 buffer += sizeof(gcov_unsigned_t);
349 349 }
350 350 printf("\n");
351 351
352 352 gcov_var.start += size;
353 353 gcov_var.offset -= size;
354 354 }
355 355
356 356 /* Allocate space to write BYTES bytes to the gcov file. Return a
357 357 pointer to those bytes, or NULL on failure. */
358 358
359 359 static gcov_unsigned_t *gcov_write_words (unsigned words) {
360 360 gcov_unsigned_t *result;
361 361
362 362 GCOV_CHECK_WRITING ();
363 363 if (gcov_var.offset >= GCOV_BLOCK_SIZE)
364 364 {
365 365 gcov_write_block (GCOV_BLOCK_SIZE);
366 366 if (gcov_var.offset)
367 367 {
368 368 GCOV_CHECK (gcov_var.offset == 1);
369 369 memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4);
370 370 }
371 371 }
372 372 result = &gcov_var.buffer[gcov_var.offset];
373 373 gcov_var.offset += words;
374 374
375 375 return result;
376 376 }
377 377
378 378 /* Write unsigned VALUE to coverage file. Sets error flag
379 379 appropriately. */
380 380
381 381 GCOV_LINKAGE void
382 382 gcov_write_unsigned (gcov_unsigned_t value)
383 383 {
384 384 gcov_unsigned_t *buffer = gcov_write_words (1);
385 385
386 386 buffer[0] = value;
387 387 }
388 388
389 389 /* Write counter VALUE to coverage file. Sets error flag
390 390 appropriately. */
391 391
392 392 GCOV_LINKAGE void
393 393 gcov_write_counter (gcov_type value)
394 394 {
395 395 gcov_unsigned_t *buffer = gcov_write_words (2);
396 396
397 397 buffer[0] = (gcov_unsigned_t) value;
398 398 if (sizeof (value) > sizeof (gcov_unsigned_t))
399 399 buffer[1] = (gcov_unsigned_t) (value >> 32);
400 400 else
401 401 buffer[1] = 0;
402 402
403 403 }
404 404
405 405 /* Write a tag TAG and length LENGTH. */
406 406
407 407 GCOV_LINKAGE void
408 408 gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length)
409 409 {
410 410 gcov_unsigned_t *buffer = gcov_write_words (2);
411 411
412 412 buffer[0] = tag;
413 413 buffer[1] = length;
414 414 }
415 415
416 416 /* Write a summary structure to the gcov file. Return nonzero on
417 417 overflow. */
418 418
419 419 GCOV_LINKAGE void
420 420 gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary)
421 421 {
422 422 unsigned ix;
423 423 const struct gcov_ctr_summary *csum;
424 424
425 425 gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH);
426 426 gcov_write_unsigned (summary->checksum);
427 427 for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
428 428 {
429 429 gcov_write_unsigned (csum->num);
430 430 gcov_write_unsigned (csum->runs);
431 431 gcov_write_counter (csum->sum_all);
432 432 gcov_write_counter (csum->run_max);
433 433 gcov_write_counter (csum->sum_max);
434 434 }
435 435 }
436 436
437 437 GCOV_LINKAGE gcov_type
438 438 gcov_read_counter (void)
439 439 {
440 440 return 0;
441 441 }
442 442
443 443 /* Add a new object file onto the bb chain. Invoked automatically
444 444 when running an object file's global ctors. */
445 445
446 446 void
447 447 __gcov_init (struct gcov_info *info)
448 448 {
449 449 if (!info->version)
450 450 return;
451 451 if (gcov_version (info, info->version))
452 452 {
453 453 const char *ptr = info->filename;
454 454 gcov_unsigned_t crc32 = gcov_crc32;
455 455
456 456 /* Added by LESIA*/
457 457 printf("Covered file: %s\n", info->filename);
458 458 /* End of Added by LESIA*/
459 459
460 460 do
461 461 {
462 462 unsigned ix;
463 463 gcov_unsigned_t value = *ptr << 24;
464 464
465 465 for (ix = 8; ix--; value <<= 1)
466 466 {
467 467 gcov_unsigned_t feedback;
468 468
469 469 feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
470 470 crc32 <<= 1;
471 471 crc32 ^= feedback;
472 472 }
473 473 }
474 474 while (*ptr++);
475 475
476 476 gcov_crc32 = crc32;
477 477
478 #ifdef GCOV_USE_EXIT
478 479 if (!gcov_list)
479 480 atexit (gcov_exit);
481 #endif
480 482
481 483 info->next = gcov_list;
482 484 gcov_list = info;
483 485 }
484 486 else
485 487 printf("%s: Version mismatch\n", "WARNING");
486 488 info->version = 0;
487 489 }
488 490 //#endif /* __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ */
@@ -1,39 +1,39
1 1 set(rtems_dir /opt/rtems-4.10/)
2 2
3 3 set(CMAKE_SYSTEM_NAME rtems)
4 4 set(CMAKE_C_COMPILER ${rtems_dir}/bin/sparc-rtems-gcc)
5 5 set(CMAKE_CXX_COMPILER ${rtems_dir}/bin/sparc-rtems-g++)
6 6 set(CMAKE_LINKER ${rtems_dir}/bin/sparc-rtems-g++)
7 7 SET(CMAKE_EXE_LINKER_FLAGS "-static")
8 8 option(fix-b2bst "Activate -mfix-b2bst switch to mitigate \"LEON3FT Stale Cache Entry After Store with Data Tag Parity Error\" errata, GRLIB-TN-0009" ON)
9 9
10 10 option(Coverage "Enables code coverage" OFF)
11 11
12 12
13 set(CMAKE_C_FLAGS_RELEASE "-O3")
14 set(CMAKE_C_FLAGS_DEBUG "-O3 -fno-inline")
13 set(CMAKE_C_FLAGS_RELEASE "-O2")
14 set(CMAKE_C_FLAGS_DEBUG "-O2 -g -fno-inline")
15 15
16 16
17 17 if(fix-b2bst)
18 18 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mfix-b2bst")
19 19 set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -mfix-b2bst")
20 20 endif()
21 21
22 22
23 23 set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_LINKER> <FLAGS> -Xlinker -Map=<TARGET>.map <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
24 24
25 25 include_directories("${rtems_dir}/sparc-rtems/leon3/lib/include")
26 26
27 27 function (check_b2bst target bin)
28 28 add_custom_command(TARGET ${target}
29 29 POST_BUILD
30 30 COMMAND ${rtems_dir}/bin/sparc-rtems-objdump -d ${bin}/${target} | ${CMAKE_SOURCE_DIR}/sparc/leon3ft-b2bst-scan.tcl
31 31 )
32 32 endfunction()
33 33
34 34 function (build_srec target bin rev)
35 35 add_custom_command(TARGET ${target}
36 36 POST_BUILD
37 37 COMMAND ${rtems_dir}/bin/sparc-rtems-objcopy -j .data -F srec ${bin}/${target} RpwLfrApp_XXXX_data_rev-${rev}.srec && ${rtems_dir}/bin/sparc-rtems-objcopy -j .text -F srec ${bin}/${target} RpwLfrApp_XXXX_text_rev-${rev}.srec
38 38 )
39 39 endfunction()
@@ -1,130 +1,130
1 cmake_minimum_required (VERSION 2.6)
1 cmake_minimum_required (VERSION 3.6)
2 2 project (fsw)
3 3
4 4 include(sparc-rtems)
5 5 include(cppcheck)
6 6
7 7 include_directories("../header"
8 8 "../header/lfr_common_headers"
9 9 "../header/processing"
10 10 "../LFR_basic-parameters"
11 11 "../src")
12 12
13 13 set(SOURCES wf_handler.c
14 14 tc_handler.c
15 15 fsw_misc.c
16 16 fsw_init.c
17 17 fsw_globals.c
18 18 fsw_spacewire.c
19 19 tc_load_dump_parameters.c
20 20 tm_lfr_tc_exe.c
21 21 tc_acceptance.c
22 22 processing/fsw_processing.c
23 23 processing/avf0_prc0.c
24 24 processing/avf1_prc1.c
25 25 processing/avf2_prc2.c
26 26 lfr_cpu_usage_report.c
27 27 ${LFR_BP_SRC}
28 28 ../header/wf_handler.h
29 29 ../header/tc_handler.h
30 30 ../header/grlib_regs.h
31 31 ../header/fsw_misc.h
32 32 ../header/fsw_init.h
33 33 ../header/fsw_spacewire.h
34 34 ../header/tc_load_dump_parameters.h
35 35 ../header/tm_lfr_tc_exe.h
36 36 ../header/tc_acceptance.h
37 37 ../header/processing/fsw_processing.h
38 38 ../header/processing/avf0_prc0.h
39 39 ../header/processing/avf1_prc1.h
40 40 ../header/processing/avf2_prc2.h
41 41 ../header/fsw_params_wf_handler.h
42 42 ../header/lfr_cpu_usage_report.h
43 43 ../header/lfr_common_headers/ccsds_types.h
44 44 ../header/lfr_common_headers/fsw_params.h
45 45 ../header/lfr_common_headers/fsw_params_nb_bytes.h
46 46 ../header/lfr_common_headers/fsw_params_processing.h
47 47 ../header/lfr_common_headers/tm_byte_positions.h
48 48 ../LFR_basic-parameters/basic_parameters.h
49 49 ../LFR_basic-parameters/basic_parameters_params.h
50 50 ../header/GscMemoryLPP.hpp
51 51 )
52 52
53 53
54 54 option(FSW_verbose "Enable verbose LFR" OFF)
55 55 option(FSW_boot_messages "Enable LFR boot messages" OFF)
56 56 option(FSW_debug_messages "Enable LFR debug messages" OFF)
57 57 option(FSW_cpu_usage_report "Enable LFR cpu usage report" OFF)
58 58 option(FSW_stack_report "Enable LFR stack report" OFF)
59 59 option(FSW_vhdl_dev "?" OFF)
60 60 option(FSW_lpp_dpu_destid "Set to debug at LPP" OFF)
61 61 option(FSW_debug_watchdog "Enable debug watchdog" OFF)
62 62 option(FSW_debug_tch "?" OFF)
63 63 option(FSW_Instrument_Scrubbing "Enable scrubbing counter" OFF)
64 64
65 65 set(SW_VERSION_N1 "3" CACHE STRING "Choose N1 FSW Version." FORCE)
66 66 set(SW_VERSION_N2 "2" CACHE STRING "Choose N2 FSW Version." FORCE)
67 67 set(SW_VERSION_N3 "0" CACHE STRING "Choose N3 FSW Version." FORCE)
68 set(SW_VERSION_N4 "21" CACHE STRING "Choose N4 FSW Version." FORCE)
68 set(SW_VERSION_N4 "22" CACHE STRING "Choose N4 FSW Version." FORCE)
69 69
70 70 if(FSW_verbose)
71 71 add_definitions(-DPRINT_MESSAGES_ON_CONSOLE)
72 72 endif()
73 73 if(FSW_boot_messages)
74 74 add_definitions(-DBOOT_MESSAGES)
75 75 endif()
76 76 if(FSW_debug_messages)
77 77 add_definitions(-DDEBUG_MESSAGES)
78 78 endif()
79 79 if(FSW_cpu_usage_report)
80 80 add_definitions(-DPRINT_TASK_STATISTICS)
81 81 endif()
82 82 if(FSW_stack_report)
83 83 add_definitions(-DPRINT_STACK_REPORT)
84 84 endif()
85 85 if(FSW_vhdl_dev)
86 86 add_definitions(-DVHDL_DEV)
87 87 endif()
88 88 if(FSW_lpp_dpu_destid)
89 89 add_definitions(-DLPP_DPU_DESTID)
90 90 endif()
91 91 if(FSW_debug_watchdog)
92 92 add_definitions(-DDEBUG_WATCHDOG)
93 93 endif()
94 94 if(FSW_debug_tch)
95 95 add_definitions(-DDEBUG_TCH)
96 96 endif()
97 97
98 98
99 99
100 100 add_definitions(-DMSB_FIRST_TCH)
101 101
102 102 add_definitions(-DSWVERSION=-1-0)
103 103 add_definitions(-DSW_VERSION_N1=${SW_VERSION_N1})
104 104 add_definitions(-DSW_VERSION_N2=${SW_VERSION_N2})
105 105 add_definitions(-DSW_VERSION_N3=${SW_VERSION_N3})
106 106 add_definitions(-DSW_VERSION_N4=${SW_VERSION_N4})
107 107
108 108 add_executable(fsw ${SOURCES})
109 109
110 110 if(FSW_Instrument_Scrubbing)
111 111 add_definitions(-DENABLE_SCRUBBING_COUNTER)
112 112 endif()
113 113
114 114 if(Coverage)
115 115 target_link_libraries(fsw gcov)
116 116 SET_TARGET_PROPERTIES(fsw PROPERTIES COMPILE_FLAGS "-fprofile-arcs -ftest-coverage")
117 117 endif()
118 118
119 119
120 120 if(fix-b2bst)
121 121 check_b2bst(fsw ${CMAKE_CURRENT_BINARY_DIR})
122 122 endif()
123 123
124 124 if(NOT FSW_lpp_dpu_destid)
125 125 build_srec(fsw ${CMAKE_CURRENT_BINARY_DIR} "${SW_VERSION_N1}-${SW_VERSION_N2}-${SW_VERSION_N3}-${SW_VERSION_N4}")
126 126 endif()
127 127
128 128
129 add_test_cppcheck(fsw STYLE UNUSED_FUNCTIONS POSSIBLE_ERROR MISSING_INCLUDE)
129 #add_test_cppcheck(fsw STYLE UNUSED_FUNCTIONS POSSIBLE_ERROR MISSING_INCLUDE)
130 130
@@ -1,1696 +1,1702
1 1 /*------------------------------------------------------------------------------
2 2 -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW),
3 3 -- This file is a part of the LFR FSW
4 4 -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS
5 5 --
6 6 -- This program is free software; you can redistribute it and/or modify
7 7 -- it under the terms of the GNU General Public License as published by
8 8 -- the Free Software Foundation; either version 2 of the License, or
9 9 -- (at your option) any later version.
10 10 --
11 11 -- This program is distributed in the hope that it will be useful,
12 12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 -- GNU General Public License for more details.
15 15 --
16 16 -- You should have received a copy of the GNU General Public License
17 17 -- along with this program; if not, write to the Free Software
18 18 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19 -------------------------------------------------------------------------------*/
20 20 /*-- Author : Paul Leroy
21 21 -- Contact : Alexis Jeandet
22 22 -- Mail : alexis.jeandet@lpp.polytechnique.fr
23 23 ----------------------------------------------------------------------------*/
24 24 /** Functions and tasks related to TeleCommand handling.
25 25 *
26 26 * @file
27 27 * @author P. LEROY
28 28 *
29 29 * A group of functions to handle TeleCommands:\n
30 30 * action launching\n
31 31 * TC parsing\n
32 32 * ...
33 33 *
34 34 */
35 35
36 36 #include "tc_handler.h"
37 37 #include "math.h"
38 38
39 39 //***********
40 40 // RTEMS TASK
41 41
42 42 rtems_task actn_task( rtems_task_argument unused )
43 43 {
44 44 /** This RTEMS task is responsible for launching actions upton the reception of valid TeleCommands.
45 45 *
46 46 * @param unused is the starting argument of the RTEMS task
47 47 *
48 48 * The ACTN task waits for data coming from an RTEMS msesage queue. When data arrives, it launches specific actions depending
49 49 * on the incoming TeleCommand.
50 50 *
51 51 */
52 52
53 53 int result;
54 54 rtems_status_code status; // RTEMS status code
55 55 ccsdsTelecommandPacket_t __attribute__((aligned(4))) TC; // TC sent to the ACTN task
56 56 size_t size; // size of the incoming TC packet
57 57 unsigned char subtype; // subtype of the current TC packet
58 58 unsigned char time[BYTES_PER_TIME];
59 59 rtems_id queue_rcv_id;
60 60 rtems_id queue_snd_id;
61 61
62 62 memset(&TC, 0, sizeof(ccsdsTelecommandPacket_t));
63 63 size = 0;
64 64 queue_rcv_id = RTEMS_ID_NONE;
65 65 queue_snd_id = RTEMS_ID_NONE;
66 66
67 67 status = get_message_queue_id_recv( &queue_rcv_id );
68 68 if (status != RTEMS_SUCCESSFUL)
69 69 {
70 70 PRINTF1("in ACTN *** ERR get_message_queue_id_recv %d\n", status)
71 71 }
72 72
73 73 status = get_message_queue_id_send( &queue_snd_id );
74 74 if (status != RTEMS_SUCCESSFUL)
75 75 {
76 76 PRINTF1("in ACTN *** ERR get_message_queue_id_send %d\n", status)
77 77 }
78 78
79 79 result = LFR_SUCCESSFUL;
80 80 subtype = 0; // subtype of the current TC packet
81 81
82 82 BOOT_PRINTF("in ACTN *** \n");
83 83
84 84 while(1)
85 85 {
86 86 status = rtems_message_queue_receive( queue_rcv_id, (char*) &TC, &size,
87 87 RTEMS_WAIT, RTEMS_NO_TIMEOUT);
88 88 getTime( time ); // set time to the current time
89 89 if (status!=RTEMS_SUCCESSFUL)
90 90 {
91 91 PRINTF1("ERR *** in task ACTN *** error receiving a message, code %d \n", status)
92 92 }
93 93 else
94 94 {
95 95 subtype = TC.serviceSubType;
96 96 switch(subtype)
97 97 {
98 98 case TC_SUBTYPE_RESET:
99 99 result = action_reset( &TC, queue_snd_id, time );
100 100 close_action( &TC, result, queue_snd_id );
101 101 break;
102 102 case TC_SUBTYPE_LOAD_COMM:
103 103 result = action_load_common_par( &TC );
104 104 close_action( &TC, result, queue_snd_id );
105 105 break;
106 106 case TC_SUBTYPE_LOAD_NORM:
107 107 result = action_load_normal_par( &TC, queue_snd_id, time );
108 108 close_action( &TC, result, queue_snd_id );
109 109 break;
110 110 case TC_SUBTYPE_LOAD_BURST:
111 111 result = action_load_burst_par( &TC, queue_snd_id, time );
112 112 close_action( &TC, result, queue_snd_id );
113 113 break;
114 114 case TC_SUBTYPE_LOAD_SBM1:
115 115 result = action_load_sbm1_par( &TC, queue_snd_id, time );
116 116 close_action( &TC, result, queue_snd_id );
117 117 break;
118 118 case TC_SUBTYPE_LOAD_SBM2:
119 119 result = action_load_sbm2_par( &TC, queue_snd_id, time );
120 120 close_action( &TC, result, queue_snd_id );
121 121 break;
122 122 case TC_SUBTYPE_DUMP:
123 123 result = action_dump_par( &TC, queue_snd_id );
124 124 close_action( &TC, result, queue_snd_id );
125 125 break;
126 126 case TC_SUBTYPE_ENTER:
127 127 result = action_enter_mode( &TC, queue_snd_id );
128 128 close_action( &TC, result, queue_snd_id );
129 129 break;
130 130 case TC_SUBTYPE_UPDT_INFO:
131 131 result = action_update_info( &TC, queue_snd_id );
132 132 close_action( &TC, result, queue_snd_id );
133 133 break;
134 134 case TC_SUBTYPE_EN_CAL:
135 135 result = action_enable_calibration( &TC, queue_snd_id, time );
136 136 close_action( &TC, result, queue_snd_id );
137 137 break;
138 138 case TC_SUBTYPE_DIS_CAL:
139 139 result = action_disable_calibration( &TC, queue_snd_id, time );
140 140 close_action( &TC, result, queue_snd_id );
141 141 break;
142 142 case TC_SUBTYPE_LOAD_K:
143 143 result = action_load_kcoefficients( &TC, queue_snd_id, time );
144 144 close_action( &TC, result, queue_snd_id );
145 145 break;
146 146 case TC_SUBTYPE_DUMP_K:
147 147 result = action_dump_kcoefficients( &TC, queue_snd_id, time );
148 148 close_action( &TC, result, queue_snd_id );
149 149 break;
150 150 case TC_SUBTYPE_LOAD_FBINS:
151 151 result = action_load_fbins_mask( &TC, queue_snd_id, time );
152 152 close_action( &TC, result, queue_snd_id );
153 153 break;
154 154 case TC_SUBTYPE_LOAD_FILTER_PAR:
155 155 result = action_load_filter_par( &TC, queue_snd_id, time );
156 156 close_action( &TC, result, queue_snd_id );
157 157 break;
158 158 case TC_SUBTYPE_UPDT_TIME:
159 159 result = action_update_time( &TC );
160 160 close_action( &TC, result, queue_snd_id );
161 161 break;
162 162 default:
163 163 break;
164 164 }
165 165 }
166 166 }
167 167 }
168 168
169 169 //***********
170 170 // TC ACTIONS
171 171
172 172 int action_reset(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
173 173 {
174 174 /** This function executes specific actions when a TC_LFR_RESET TeleCommand has been received.
175 175 *
176 176 * @param TC points to the TeleCommand packet that is being processed
177 177 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
178 178 *
179 179 */
180 180
181 181 PRINTF("this is the end!!!\n");
182 #ifdef GCOV_ENABLED
183 #ifndef GCOV_USE_EXIT
184 extern void gcov_exit (void);
185 gcov_exit();
186 #endif
187 #endif
182 188 exit(0);
183 189
184 190 send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time );
185 191
186 192 return LFR_DEFAULT;
187 193 }
188 194
189 195 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
190 196 {
191 197 /** This function executes specific actions when a TC_LFR_ENTER_MODE TeleCommand has been received.
192 198 *
193 199 * @param TC points to the TeleCommand packet that is being processed
194 200 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
195 201 *
196 202 */
197 203
198 204 rtems_status_code status;
199 205 unsigned char requestedMode;
200 206 unsigned int transitionCoarseTime;
201 207 unsigned char * bytePosPtr;
202 208
203 209 bytePosPtr = (unsigned char *) &TC->packetID;
204 210 requestedMode = bytePosPtr[ BYTE_POS_CP_MODE_LFR_SET ];
205 211 copyInt32ByChar( (char*) &transitionCoarseTime, &bytePosPtr[ BYTE_POS_CP_LFR_ENTER_MODE_TIME ] );
206 212 transitionCoarseTime = transitionCoarseTime & COARSE_TIME_MASK;
207 213 status = check_mode_value( requestedMode );
208 214
209 215 if ( status != LFR_SUCCESSFUL ) // the mode value is inconsistent
210 216 {
211 217 send_tm_lfr_tc_exe_inconsistent( TC, queue_id, BYTE_POS_CP_MODE_LFR_SET, requestedMode );
212 218 }
213 219
214 220 else // the mode value is valid, check the transition
215 221 {
216 222 status = check_mode_transition(requestedMode);
217 223 if (status != LFR_SUCCESSFUL)
218 224 {
219 225 PRINTF("ERR *** in action_enter_mode *** check_mode_transition\n")
220 226 send_tm_lfr_tc_exe_not_executable( TC, queue_id );
221 227 }
222 228 }
223 229
224 230 if ( status == LFR_SUCCESSFUL ) // the transition is valid, check the date
225 231 {
226 232 status = check_transition_date( transitionCoarseTime );
227 233 if (status != LFR_SUCCESSFUL)
228 234 {
229 235 PRINTF("ERR *** in action_enter_mode *** check_transition_date\n");
230 236 send_tm_lfr_tc_exe_not_executable(TC, queue_id );
231 237 }
232 238 }
233 239
234 240 if ( status == LFR_SUCCESSFUL ) // the date is valid, enter the mode
235 241 {
236 242 PRINTF1("OK *** in action_enter_mode *** enter mode %d\n", requestedMode);
237 243
238 244 switch(requestedMode)
239 245 {
240 246 case LFR_MODE_STANDBY:
241 247 status = enter_mode_standby();
242 248 break;
243 249 case LFR_MODE_NORMAL:
244 250 status = enter_mode_normal( transitionCoarseTime );
245 251 break;
246 252 case LFR_MODE_BURST:
247 253 status = enter_mode_burst( transitionCoarseTime );
248 254 break;
249 255 case LFR_MODE_SBM1:
250 256 status = enter_mode_sbm1( transitionCoarseTime );
251 257 break;
252 258 case LFR_MODE_SBM2:
253 259 status = enter_mode_sbm2( transitionCoarseTime );
254 260 break;
255 261 default:
256 262 break;
257 263 }
258 264
259 265 if (status != RTEMS_SUCCESSFUL)
260 266 {
261 267 status = LFR_EXE_ERROR;
262 268 }
263 269 }
264 270
265 271 return status;
266 272 }
267 273
268 274 int action_update_info(ccsdsTelecommandPacket_t *TC, rtems_id queue_id)
269 275 {
270 276 /** This function executes specific actions when a TC_LFR_UPDATE_INFO TeleCommand has been received.
271 277 *
272 278 * @param TC points to the TeleCommand packet that is being processed
273 279 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
274 280 *
275 281 * @return LFR directive status code:
276 282 * - LFR_DEFAULT
277 283 * - LFR_SUCCESSFUL
278 284 *
279 285 */
280 286
281 287 unsigned int val;
282 288 unsigned int status;
283 289 unsigned char mode;
284 290 unsigned char * bytePosPtr;
285 291 int pos;
286 292 float value;
287 293
288 294 pos = INIT_CHAR;
289 295 value = INIT_FLOAT;
290 296
291 297 status = LFR_DEFAULT;
292 298
293 299 bytePosPtr = (unsigned char *) &TC->packetID;
294 300
295 301 // check LFR mode
296 302 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET5 ] & BITS_LFR_MODE) >> SHIFT_LFR_MODE;
297 303 status = check_update_info_hk_lfr_mode( mode );
298 304 if (status == LFR_SUCCESSFUL) // check TDS mode
299 305 {
300 306 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & BITS_TDS_MODE) >> SHIFT_TDS_MODE;
301 307 status = check_update_info_hk_tds_mode( mode );
302 308 }
303 309 if (status == LFR_SUCCESSFUL) // check THR mode
304 310 {
305 311 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & BITS_THR_MODE);
306 312 status = check_update_info_hk_thr_mode( mode );
307 313 }
308 314 if (status == LFR_SUCCESSFUL) // check reaction wheels frequencies
309 315 {
310 316 status = check_all_sy_lfr_rw_f(TC, &pos, &value);
311 317 }
312 318
313 319 // if the parameters checking succeeds, udpate all parameters
314 320 if (status == LFR_SUCCESSFUL)
315 321 {
316 322 // pa_bia_status_info
317 323 // => pa_bia_mode_mux_set 3 bits
318 324 // => pa_bia_mode_hv_enabled 1 bit
319 325 // => pa_bia_mode_bias1_enabled 1 bit
320 326 // => pa_bia_mode_bias2_enabled 1 bit
321 327 // => pa_bia_mode_bias3_enabled 1 bit
322 328 // => pa_bia_on_off (cp_dpu_bias_on_off)
323 329 pa_bia_status_info = bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET2 ] & BITS_BIA; // [1111 1110]
324 330 pa_bia_status_info = pa_bia_status_info
325 331 | (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET1 ] & 1);
326 332
327 333 // REACTION_WHEELS_FREQUENCY, copy the incoming parameters in the local variable (to be copied in HK packets)
328 334 getReactionWheelsFrequencies( TC );
329 335 set_hk_lfr_sc_rw_f_flags();
330 336 build_sy_lfr_rw_masks();
331 337
332 338 // once the masks are built, they have to be merged with the fbins_mask
333 339 merge_fbins_masks();
334 340
335 341 // increase the TC_LFR_UPDATE_INFO counter
336 342 if (status == LFR_SUCCESSFUL) // if the parameter check is successful
337 343 {
338 344 val = (housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * CONST_256)
339 345 + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
340 346 val++;
341 347 housekeeping_packet.hk_lfr_update_info_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
342 348 housekeeping_packet.hk_lfr_update_info_tc_cnt[1] = (unsigned char) (val);
343 349 }
344 350 }
345 351
346 352 return status;
347 353 }
348 354
349 355 int action_enable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
350 356 {
351 357 /** This function executes specific actions when a TC_LFR_ENABLE_CALIBRATION TeleCommand has been received.
352 358 *
353 359 * @param TC points to the TeleCommand packet that is being processed
354 360 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
355 361 *
356 362 */
357 363
358 364 int result;
359 365
360 366 result = LFR_DEFAULT;
361 367
362 368 setCalibration( true );
363 369
364 370 result = LFR_SUCCESSFUL;
365 371
366 372 return result;
367 373 }
368 374
369 375 int action_disable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
370 376 {
371 377 /** This function executes specific actions when a TC_LFR_DISABLE_CALIBRATION TeleCommand has been received.
372 378 *
373 379 * @param TC points to the TeleCommand packet that is being processed
374 380 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
375 381 *
376 382 */
377 383
378 384 int result;
379 385
380 386 result = LFR_DEFAULT;
381 387
382 388 setCalibration( false );
383 389
384 390 result = LFR_SUCCESSFUL;
385 391
386 392 return result;
387 393 }
388 394
389 395 int action_update_time(ccsdsTelecommandPacket_t *TC)
390 396 {
391 397 /** This function executes specific actions when a TC_LFR_UPDATE_TIME TeleCommand has been received.
392 398 *
393 399 * @param TC points to the TeleCommand packet that is being processed
394 400 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
395 401 *
396 402 * @return LFR_SUCCESSFUL
397 403 *
398 404 */
399 405
400 406 unsigned int val;
401 407
402 408 time_management_regs->coarse_time_load = (TC->dataAndCRC[BYTE_0] << SHIFT_3_BYTES)
403 409 + (TC->dataAndCRC[BYTE_1] << SHIFT_2_BYTES)
404 410 + (TC->dataAndCRC[BYTE_2] << SHIFT_1_BYTE)
405 411 + TC->dataAndCRC[BYTE_3];
406 412
407 413 val = (housekeeping_packet.hk_lfr_update_time_tc_cnt[0] * CONST_256)
408 414 + housekeeping_packet.hk_lfr_update_time_tc_cnt[1];
409 415 val++;
410 416 housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
411 417 housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char) (val);
412 418
413 419 oneTcLfrUpdateTimeReceived = 1;
414 420
415 421 return LFR_SUCCESSFUL;
416 422 }
417 423
418 424 //*******************
419 425 // ENTERING THE MODES
420 426 int check_mode_value( unsigned char requestedMode )
421 427 {
422 428 int status;
423 429
424 430 status = LFR_DEFAULT;
425 431
426 432 if ( (requestedMode != LFR_MODE_STANDBY)
427 433 && (requestedMode != LFR_MODE_NORMAL) && (requestedMode != LFR_MODE_BURST)
428 434 && (requestedMode != LFR_MODE_SBM1) && (requestedMode != LFR_MODE_SBM2) )
429 435 {
430 436 status = LFR_DEFAULT;
431 437 }
432 438 else
433 439 {
434 440 status = LFR_SUCCESSFUL;
435 441 }
436 442
437 443 return status;
438 444 }
439 445
440 446 int check_mode_transition( unsigned char requestedMode )
441 447 {
442 448 /** This function checks the validity of the transition requested by the TC_LFR_ENTER_MODE.
443 449 *
444 450 * @param requestedMode is the mode requested by the TC_LFR_ENTER_MODE
445 451 *
446 452 * @return LFR directive status codes:
447 453 * - LFR_SUCCESSFUL - the transition is authorized
448 454 * - LFR_DEFAULT - the transition is not authorized
449 455 *
450 456 */
451 457
452 458 int status;
453 459
454 460 switch (requestedMode)
455 461 {
456 462 case LFR_MODE_STANDBY:
457 463 if ( lfrCurrentMode == LFR_MODE_STANDBY ) {
458 464 status = LFR_DEFAULT;
459 465 }
460 466 else
461 467 {
462 468 status = LFR_SUCCESSFUL;
463 469 }
464 470 break;
465 471 case LFR_MODE_NORMAL:
466 472 if ( lfrCurrentMode == LFR_MODE_NORMAL ) {
467 473 status = LFR_DEFAULT;
468 474 }
469 475 else {
470 476 status = LFR_SUCCESSFUL;
471 477 }
472 478 break;
473 479 case LFR_MODE_BURST:
474 480 if ( lfrCurrentMode == LFR_MODE_BURST ) {
475 481 status = LFR_DEFAULT;
476 482 }
477 483 else {
478 484 status = LFR_SUCCESSFUL;
479 485 }
480 486 break;
481 487 case LFR_MODE_SBM1:
482 488 if ( lfrCurrentMode == LFR_MODE_SBM1 ) {
483 489 status = LFR_DEFAULT;
484 490 }
485 491 else {
486 492 status = LFR_SUCCESSFUL;
487 493 }
488 494 break;
489 495 case LFR_MODE_SBM2:
490 496 if ( lfrCurrentMode == LFR_MODE_SBM2 ) {
491 497 status = LFR_DEFAULT;
492 498 }
493 499 else {
494 500 status = LFR_SUCCESSFUL;
495 501 }
496 502 break;
497 503 default:
498 504 status = LFR_DEFAULT;
499 505 break;
500 506 }
501 507
502 508 return status;
503 509 }
504 510
505 511 void update_last_valid_transition_date( unsigned int transitionCoarseTime )
506 512 {
507 513 if (transitionCoarseTime == 0)
508 514 {
509 515 lastValidEnterModeTime = time_management_regs->coarse_time + 1;
510 516 PRINTF1("lastValidEnterModeTime = 0x%x (transitionCoarseTime = 0 => coarse_time+1)\n", lastValidEnterModeTime);
511 517 }
512 518 else
513 519 {
514 520 lastValidEnterModeTime = transitionCoarseTime;
515 521 PRINTF1("lastValidEnterModeTime = 0x%x\n", transitionCoarseTime);
516 522 }
517 523 }
518 524
519 525 int check_transition_date( unsigned int transitionCoarseTime )
520 526 {
521 527 int status;
522 528 unsigned int localCoarseTime;
523 529 unsigned int deltaCoarseTime;
524 530
525 531 status = LFR_SUCCESSFUL;
526 532
527 533 if (transitionCoarseTime == 0) // transition time = 0 means an instant transition
528 534 {
529 535 status = LFR_SUCCESSFUL;
530 536 }
531 537 else
532 538 {
533 539 localCoarseTime = time_management_regs->coarse_time & COARSE_TIME_MASK;
534 540
535 541 PRINTF2("localTime = %x, transitionTime = %x\n", localCoarseTime, transitionCoarseTime);
536 542
537 543 if ( transitionCoarseTime <= localCoarseTime ) // SSS-CP-EQS-322
538 544 {
539 545 status = LFR_DEFAULT;
540 546 PRINTF("ERR *** in check_transition_date *** transitionCoarseTime <= localCoarseTime\n");
541 547 }
542 548
543 549 if (status == LFR_SUCCESSFUL)
544 550 {
545 551 deltaCoarseTime = transitionCoarseTime - localCoarseTime;
546 552 if ( deltaCoarseTime > MAX_DELTA_COARSE_TIME ) // SSS-CP-EQS-323
547 553 {
548 554 status = LFR_DEFAULT;
549 555 PRINTF1("ERR *** in check_transition_date *** deltaCoarseTime = %x\n", deltaCoarseTime)
550 556 }
551 557 }
552 558 }
553 559
554 560 return status;
555 561 }
556 562
557 563 int restart_asm_activities( unsigned char lfrRequestedMode )
558 564 {
559 565 rtems_status_code status;
560 566
561 567 status = stop_spectral_matrices();
562 568
563 569 thisIsAnASMRestart = 1;
564 570
565 571 status = restart_asm_tasks( lfrRequestedMode );
566 572
567 573 launch_spectral_matrix();
568 574
569 575 return status;
570 576 }
571 577
572 578 int stop_spectral_matrices( void )
573 579 {
574 580 /** This function stops and restarts the current mode average spectral matrices activities.
575 581 *
576 582 * @return RTEMS directive status codes:
577 583 * - RTEMS_SUCCESSFUL - task restarted successfully
578 584 * - RTEMS_INVALID_ID - task id invalid
579 585 * - RTEMS_ALREADY_SUSPENDED - task already suspended
580 586 *
581 587 */
582 588
583 589 rtems_status_code status;
584 590
585 591 status = RTEMS_SUCCESSFUL;
586 592
587 593 // (1) mask interruptions
588 594 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // mask spectral matrix interrupt
589 595
590 596 // (2) reset spectral matrices registers
591 597 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
592 598 reset_sm_status();
593 599
594 600 // (3) clear interruptions
595 601 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
596 602
597 603 // suspend several tasks
598 604 if (lfrCurrentMode != LFR_MODE_STANDBY) {
599 605 status = suspend_asm_tasks();
600 606 }
601 607
602 608 if (status != RTEMS_SUCCESSFUL)
603 609 {
604 610 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
605 611 }
606 612
607 613 return status;
608 614 }
609 615
610 616 int stop_current_mode( void )
611 617 {
612 618 /** This function stops the current mode by masking interrupt lines and suspending science tasks.
613 619 *
614 620 * @return RTEMS directive status codes:
615 621 * - RTEMS_SUCCESSFUL - task restarted successfully
616 622 * - RTEMS_INVALID_ID - task id invalid
617 623 * - RTEMS_ALREADY_SUSPENDED - task already suspended
618 624 *
619 625 */
620 626
621 627 rtems_status_code status;
622 628
623 629 status = RTEMS_SUCCESSFUL;
624 630
625 631 // (1) mask interruptions
626 632 LEON_Mask_interrupt( IRQ_WAVEFORM_PICKER ); // mask waveform picker interrupt
627 633 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
628 634
629 635 // (2) reset waveform picker registers
630 636 reset_wfp_burst_enable(); // reset burst and enable bits
631 637 reset_wfp_status(); // reset all the status bits
632 638
633 639 // (3) reset spectral matrices registers
634 640 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
635 641 reset_sm_status();
636 642
637 643 // reset lfr VHDL module
638 644 reset_lfr();
639 645
640 646 reset_extractSWF(); // reset the extractSWF flag to false
641 647
642 648 // (4) clear interruptions
643 649 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER ); // clear waveform picker interrupt
644 650 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
645 651
646 652 // suspend several tasks
647 653 if (lfrCurrentMode != LFR_MODE_STANDBY) {
648 654 status = suspend_science_tasks();
649 655 }
650 656
651 657 if (status != RTEMS_SUCCESSFUL)
652 658 {
653 659 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
654 660 }
655 661
656 662 return status;
657 663 }
658 664
659 665 int enter_mode_standby( void )
660 666 {
661 667 /** This function is used to put LFR in the STANDBY mode.
662 668 *
663 669 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
664 670 *
665 671 * @return RTEMS directive status codes:
666 672 * - RTEMS_SUCCESSFUL - task restarted successfully
667 673 * - RTEMS_INVALID_ID - task id invalid
668 674 * - RTEMS_INCORRECT_STATE - task never started
669 675 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
670 676 *
671 677 * The STANDBY mode does not depends on a specific transition date, the effect of the TC_LFR_ENTER_MODE
672 678 * is immediate.
673 679 *
674 680 */
675 681
676 682 int status;
677 683
678 684 status = stop_current_mode(); // STOP THE CURRENT MODE
679 685
680 686 #ifdef PRINT_TASK_STATISTICS
681 687 rtems_cpu_usage_report();
682 688 #endif
683 689
684 690 #ifdef PRINT_STACK_REPORT
685 691 PRINTF("stack report selected\n")
686 692 rtems_stack_checker_report_usage();
687 693 #endif
688 694
689 695 return status;
690 696 }
691 697
692 698 int enter_mode_normal( unsigned int transitionCoarseTime )
693 699 {
694 700 /** This function is used to start the NORMAL mode.
695 701 *
696 702 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
697 703 *
698 704 * @return RTEMS directive status codes:
699 705 * - RTEMS_SUCCESSFUL - task restarted successfully
700 706 * - RTEMS_INVALID_ID - task id invalid
701 707 * - RTEMS_INCORRECT_STATE - task never started
702 708 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
703 709 *
704 710 * The way the NORMAL mode is started depends on the LFR current mode. If LFR is in SBM1 or SBM2,
705 711 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected.
706 712 *
707 713 */
708 714
709 715 int status;
710 716
711 717 #ifdef PRINT_TASK_STATISTICS
712 718 rtems_cpu_usage_reset();
713 719 #endif
714 720
715 721 status = RTEMS_UNSATISFIED;
716 722
717 723 switch( lfrCurrentMode )
718 724 {
719 725 case LFR_MODE_STANDBY:
720 726 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart science tasks
721 727 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
722 728 {
723 729 launch_spectral_matrix( );
724 730 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
725 731 }
726 732 break;
727 733 case LFR_MODE_BURST:
728 734 status = stop_current_mode(); // stop the current mode
729 735 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart the science tasks
730 736 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
731 737 {
732 738 launch_spectral_matrix( );
733 739 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
734 740 }
735 741 break;
736 742 case LFR_MODE_SBM1:
737 743 status = restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
738 744 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
739 745 update_last_valid_transition_date( transitionCoarseTime );
740 746 break;
741 747 case LFR_MODE_SBM2:
742 748 status = restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
743 749 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
744 750 update_last_valid_transition_date( transitionCoarseTime );
745 751 break;
746 752 default:
747 753 break;
748 754 }
749 755
750 756 if (status != RTEMS_SUCCESSFUL)
751 757 {
752 758 PRINTF1("ERR *** in enter_mode_normal *** status = %d\n", status)
753 759 status = RTEMS_UNSATISFIED;
754 760 }
755 761
756 762 return status;
757 763 }
758 764
759 765 int enter_mode_burst( unsigned int transitionCoarseTime )
760 766 {
761 767 /** This function is used to start the BURST mode.
762 768 *
763 769 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
764 770 *
765 771 * @return RTEMS directive status codes:
766 772 * - RTEMS_SUCCESSFUL - task restarted successfully
767 773 * - RTEMS_INVALID_ID - task id invalid
768 774 * - RTEMS_INCORRECT_STATE - task never started
769 775 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
770 776 *
771 777 * The way the BURST mode is started does not depend on the LFR current mode.
772 778 *
773 779 */
774 780
775 781
776 782 int status;
777 783
778 784 #ifdef PRINT_TASK_STATISTICS
779 785 rtems_cpu_usage_reset();
780 786 #endif
781 787
782 788 status = stop_current_mode(); // stop the current mode
783 789 status = restart_science_tasks( LFR_MODE_BURST ); // restart the science tasks
784 790 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
785 791 {
786 792 launch_spectral_matrix( );
787 793 launch_waveform_picker( LFR_MODE_BURST, transitionCoarseTime );
788 794 }
789 795
790 796 if (status != RTEMS_SUCCESSFUL)
791 797 {
792 798 PRINTF1("ERR *** in enter_mode_burst *** status = %d\n", status)
793 799 status = RTEMS_UNSATISFIED;
794 800 }
795 801
796 802 return status;
797 803 }
798 804
799 805 int enter_mode_sbm1( unsigned int transitionCoarseTime )
800 806 {
801 807 /** This function is used to start the SBM1 mode.
802 808 *
803 809 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
804 810 *
805 811 * @return RTEMS directive status codes:
806 812 * - RTEMS_SUCCESSFUL - task restarted successfully
807 813 * - RTEMS_INVALID_ID - task id invalid
808 814 * - RTEMS_INCORRECT_STATE - task never started
809 815 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
810 816 *
811 817 * The way the SBM1 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM2,
812 818 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
813 819 * cases, the acquisition is completely restarted.
814 820 *
815 821 */
816 822
817 823 int status;
818 824
819 825 #ifdef PRINT_TASK_STATISTICS
820 826 rtems_cpu_usage_reset();
821 827 #endif
822 828
823 829 status = RTEMS_UNSATISFIED;
824 830
825 831 switch( lfrCurrentMode )
826 832 {
827 833 case LFR_MODE_STANDBY:
828 834 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart science tasks
829 835 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
830 836 {
831 837 launch_spectral_matrix( );
832 838 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
833 839 }
834 840 break;
835 841 case LFR_MODE_NORMAL: // lfrCurrentMode will be updated after the execution of close_action
836 842 status = restart_asm_activities( LFR_MODE_SBM1 );
837 843 status = LFR_SUCCESSFUL;
838 844 update_last_valid_transition_date( transitionCoarseTime );
839 845 break;
840 846 case LFR_MODE_BURST:
841 847 status = stop_current_mode(); // stop the current mode
842 848 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart the science tasks
843 849 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
844 850 {
845 851 launch_spectral_matrix( );
846 852 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
847 853 }
848 854 break;
849 855 case LFR_MODE_SBM2:
850 856 status = restart_asm_activities( LFR_MODE_SBM1 );
851 857 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
852 858 update_last_valid_transition_date( transitionCoarseTime );
853 859 break;
854 860 default:
855 861 break;
856 862 }
857 863
858 864 if (status != RTEMS_SUCCESSFUL)
859 865 {
860 866 PRINTF1("ERR *** in enter_mode_sbm1 *** status = %d\n", status);
861 867 status = RTEMS_UNSATISFIED;
862 868 }
863 869
864 870 return status;
865 871 }
866 872
867 873 int enter_mode_sbm2( unsigned int transitionCoarseTime )
868 874 {
869 875 /** This function is used to start the SBM2 mode.
870 876 *
871 877 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
872 878 *
873 879 * @return RTEMS directive status codes:
874 880 * - RTEMS_SUCCESSFUL - task restarted successfully
875 881 * - RTEMS_INVALID_ID - task id invalid
876 882 * - RTEMS_INCORRECT_STATE - task never started
877 883 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
878 884 *
879 885 * The way the SBM2 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM1,
880 886 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
881 887 * cases, the acquisition is completely restarted.
882 888 *
883 889 */
884 890
885 891 int status;
886 892
887 893 #ifdef PRINT_TASK_STATISTICS
888 894 rtems_cpu_usage_reset();
889 895 #endif
890 896
891 897 status = RTEMS_UNSATISFIED;
892 898
893 899 switch( lfrCurrentMode )
894 900 {
895 901 case LFR_MODE_STANDBY:
896 902 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart science tasks
897 903 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
898 904 {
899 905 launch_spectral_matrix( );
900 906 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
901 907 }
902 908 break;
903 909 case LFR_MODE_NORMAL:
904 910 status = restart_asm_activities( LFR_MODE_SBM2 );
905 911 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
906 912 update_last_valid_transition_date( transitionCoarseTime );
907 913 break;
908 914 case LFR_MODE_BURST:
909 915 status = stop_current_mode(); // stop the current mode
910 916 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart the science tasks
911 917 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
912 918 {
913 919 launch_spectral_matrix( );
914 920 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
915 921 }
916 922 break;
917 923 case LFR_MODE_SBM1:
918 924 status = restart_asm_activities( LFR_MODE_SBM2 );
919 925 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
920 926 update_last_valid_transition_date( transitionCoarseTime );
921 927 break;
922 928 default:
923 929 break;
924 930 }
925 931
926 932 if (status != RTEMS_SUCCESSFUL)
927 933 {
928 934 PRINTF1("ERR *** in enter_mode_sbm2 *** status = %d\n", status)
929 935 status = RTEMS_UNSATISFIED;
930 936 }
931 937
932 938 return status;
933 939 }
934 940
935 941 int restart_science_tasks( unsigned char lfrRequestedMode )
936 942 {
937 943 /** This function is used to restart all science tasks.
938 944 *
939 945 * @return RTEMS directive status codes:
940 946 * - RTEMS_SUCCESSFUL - task restarted successfully
941 947 * - RTEMS_INVALID_ID - task id invalid
942 948 * - RTEMS_INCORRECT_STATE - task never started
943 949 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
944 950 *
945 951 * Science tasks are AVF0, PRC0, WFRM, CWF3, CW2, CWF1
946 952 *
947 953 */
948 954
949 955 rtems_status_code status[NB_SCIENCE_TASKS];
950 956 rtems_status_code ret;
951 957
952 958 ret = RTEMS_SUCCESSFUL;
953 959
954 960 status[STATUS_0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
955 961 if (status[STATUS_0] != RTEMS_SUCCESSFUL)
956 962 {
957 963 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[STATUS_0])
958 964 }
959 965
960 966 status[STATUS_1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
961 967 if (status[STATUS_1] != RTEMS_SUCCESSFUL)
962 968 {
963 969 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[STATUS_1])
964 970 }
965 971
966 972 status[STATUS_2] = rtems_task_restart( Task_id[TASKID_WFRM],1 );
967 973 if (status[STATUS_2] != RTEMS_SUCCESSFUL)
968 974 {
969 975 PRINTF1("in restart_science_task *** WFRM ERR %d\n", status[STATUS_2])
970 976 }
971 977
972 978 status[STATUS_3] = rtems_task_restart( Task_id[TASKID_CWF3],1 );
973 979 if (status[STATUS_3] != RTEMS_SUCCESSFUL)
974 980 {
975 981 PRINTF1("in restart_science_task *** CWF3 ERR %d\n", status[STATUS_3])
976 982 }
977 983
978 984 status[STATUS_4] = rtems_task_restart( Task_id[TASKID_CWF2],1 );
979 985 if (status[STATUS_4] != RTEMS_SUCCESSFUL)
980 986 {
981 987 PRINTF1("in restart_science_task *** CWF2 ERR %d\n", status[STATUS_4])
982 988 }
983 989
984 990 status[STATUS_5] = rtems_task_restart( Task_id[TASKID_CWF1],1 );
985 991 if (status[STATUS_5] != RTEMS_SUCCESSFUL)
986 992 {
987 993 PRINTF1("in restart_science_task *** CWF1 ERR %d\n", status[STATUS_5])
988 994 }
989 995
990 996 status[STATUS_6] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
991 997 if (status[STATUS_6] != RTEMS_SUCCESSFUL)
992 998 {
993 999 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[STATUS_6])
994 1000 }
995 1001
996 1002 status[STATUS_7] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
997 1003 if (status[STATUS_7] != RTEMS_SUCCESSFUL)
998 1004 {
999 1005 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[STATUS_7])
1000 1006 }
1001 1007
1002 1008 status[STATUS_8] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
1003 1009 if (status[STATUS_8] != RTEMS_SUCCESSFUL)
1004 1010 {
1005 1011 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[STATUS_8])
1006 1012 }
1007 1013
1008 1014 status[STATUS_9] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
1009 1015 if (status[STATUS_9] != RTEMS_SUCCESSFUL)
1010 1016 {
1011 1017 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[STATUS_9])
1012 1018 }
1013 1019
1014 1020 if ( (status[STATUS_0] != RTEMS_SUCCESSFUL) || (status[STATUS_1] != RTEMS_SUCCESSFUL) ||
1015 1021 (status[STATUS_2] != RTEMS_SUCCESSFUL) || (status[STATUS_3] != RTEMS_SUCCESSFUL) ||
1016 1022 (status[STATUS_4] != RTEMS_SUCCESSFUL) || (status[STATUS_5] != RTEMS_SUCCESSFUL) ||
1017 1023 (status[STATUS_6] != RTEMS_SUCCESSFUL) || (status[STATUS_7] != RTEMS_SUCCESSFUL) ||
1018 1024 (status[STATUS_8] != RTEMS_SUCCESSFUL) || (status[STATUS_9] != RTEMS_SUCCESSFUL) )
1019 1025 {
1020 1026 ret = RTEMS_UNSATISFIED;
1021 1027 }
1022 1028
1023 1029 return ret;
1024 1030 }
1025 1031
1026 1032 int restart_asm_tasks( unsigned char lfrRequestedMode )
1027 1033 {
1028 1034 /** This function is used to restart average spectral matrices tasks.
1029 1035 *
1030 1036 * @return RTEMS directive status codes:
1031 1037 * - RTEMS_SUCCESSFUL - task restarted successfully
1032 1038 * - RTEMS_INVALID_ID - task id invalid
1033 1039 * - RTEMS_INCORRECT_STATE - task never started
1034 1040 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
1035 1041 *
1036 1042 * ASM tasks are AVF0, PRC0, AVF1, PRC1, AVF2 and PRC2
1037 1043 *
1038 1044 */
1039 1045
1040 1046 rtems_status_code status[NB_ASM_TASKS];
1041 1047 rtems_status_code ret;
1042 1048
1043 1049 ret = RTEMS_SUCCESSFUL;
1044 1050
1045 1051 status[STATUS_0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
1046 1052 if (status[STATUS_0] != RTEMS_SUCCESSFUL)
1047 1053 {
1048 1054 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[STATUS_0])
1049 1055 }
1050 1056
1051 1057 status[STATUS_1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
1052 1058 if (status[STATUS_1] != RTEMS_SUCCESSFUL)
1053 1059 {
1054 1060 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[STATUS_1])
1055 1061 }
1056 1062
1057 1063 status[STATUS_2] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
1058 1064 if (status[STATUS_2] != RTEMS_SUCCESSFUL)
1059 1065 {
1060 1066 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[STATUS_2])
1061 1067 }
1062 1068
1063 1069 status[STATUS_3] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
1064 1070 if (status[STATUS_3] != RTEMS_SUCCESSFUL)
1065 1071 {
1066 1072 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[STATUS_3])
1067 1073 }
1068 1074
1069 1075 status[STATUS_4] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
1070 1076 if (status[STATUS_4] != RTEMS_SUCCESSFUL)
1071 1077 {
1072 1078 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[STATUS_4])
1073 1079 }
1074 1080
1075 1081 status[STATUS_5] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
1076 1082 if (status[STATUS_5] != RTEMS_SUCCESSFUL)
1077 1083 {
1078 1084 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[STATUS_5])
1079 1085 }
1080 1086
1081 1087 if ( (status[STATUS_0] != RTEMS_SUCCESSFUL) || (status[STATUS_1] != RTEMS_SUCCESSFUL) ||
1082 1088 (status[STATUS_2] != RTEMS_SUCCESSFUL) || (status[STATUS_3] != RTEMS_SUCCESSFUL) ||
1083 1089 (status[STATUS_4] != RTEMS_SUCCESSFUL) || (status[STATUS_5] != RTEMS_SUCCESSFUL) )
1084 1090 {
1085 1091 ret = RTEMS_UNSATISFIED;
1086 1092 }
1087 1093
1088 1094 return ret;
1089 1095 }
1090 1096
1091 1097 int suspend_science_tasks( void )
1092 1098 {
1093 1099 /** This function suspends the science tasks.
1094 1100 *
1095 1101 * @return RTEMS directive status codes:
1096 1102 * - RTEMS_SUCCESSFUL - task restarted successfully
1097 1103 * - RTEMS_INVALID_ID - task id invalid
1098 1104 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1099 1105 *
1100 1106 */
1101 1107
1102 1108 rtems_status_code status;
1103 1109
1104 1110 PRINTF("in suspend_science_tasks\n")
1105 1111
1106 1112 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1107 1113 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1108 1114 {
1109 1115 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1110 1116 }
1111 1117 else
1112 1118 {
1113 1119 status = RTEMS_SUCCESSFUL;
1114 1120 }
1115 1121 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1116 1122 {
1117 1123 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1118 1124 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1119 1125 {
1120 1126 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1121 1127 }
1122 1128 else
1123 1129 {
1124 1130 status = RTEMS_SUCCESSFUL;
1125 1131 }
1126 1132 }
1127 1133 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1128 1134 {
1129 1135 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1130 1136 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1131 1137 {
1132 1138 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1133 1139 }
1134 1140 else
1135 1141 {
1136 1142 status = RTEMS_SUCCESSFUL;
1137 1143 }
1138 1144 }
1139 1145 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1140 1146 {
1141 1147 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1142 1148 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1143 1149 {
1144 1150 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1145 1151 }
1146 1152 else
1147 1153 {
1148 1154 status = RTEMS_SUCCESSFUL;
1149 1155 }
1150 1156 }
1151 1157 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1152 1158 {
1153 1159 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1154 1160 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1155 1161 {
1156 1162 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1157 1163 }
1158 1164 else
1159 1165 {
1160 1166 status = RTEMS_SUCCESSFUL;
1161 1167 }
1162 1168 }
1163 1169 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1164 1170 {
1165 1171 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1166 1172 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1167 1173 {
1168 1174 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1169 1175 }
1170 1176 else
1171 1177 {
1172 1178 status = RTEMS_SUCCESSFUL;
1173 1179 }
1174 1180 }
1175 1181 if (status == RTEMS_SUCCESSFUL) // suspend WFRM
1176 1182 {
1177 1183 status = rtems_task_suspend( Task_id[TASKID_WFRM] );
1178 1184 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1179 1185 {
1180 1186 PRINTF1("in suspend_science_task *** WFRM ERR %d\n", status)
1181 1187 }
1182 1188 else
1183 1189 {
1184 1190 status = RTEMS_SUCCESSFUL;
1185 1191 }
1186 1192 }
1187 1193 if (status == RTEMS_SUCCESSFUL) // suspend CWF3
1188 1194 {
1189 1195 status = rtems_task_suspend( Task_id[TASKID_CWF3] );
1190 1196 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1191 1197 {
1192 1198 PRINTF1("in suspend_science_task *** CWF3 ERR %d\n", status)
1193 1199 }
1194 1200 else
1195 1201 {
1196 1202 status = RTEMS_SUCCESSFUL;
1197 1203 }
1198 1204 }
1199 1205 if (status == RTEMS_SUCCESSFUL) // suspend CWF2
1200 1206 {
1201 1207 status = rtems_task_suspend( Task_id[TASKID_CWF2] );
1202 1208 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1203 1209 {
1204 1210 PRINTF1("in suspend_science_task *** CWF2 ERR %d\n", status)
1205 1211 }
1206 1212 else
1207 1213 {
1208 1214 status = RTEMS_SUCCESSFUL;
1209 1215 }
1210 1216 }
1211 1217 if (status == RTEMS_SUCCESSFUL) // suspend CWF1
1212 1218 {
1213 1219 status = rtems_task_suspend( Task_id[TASKID_CWF1] );
1214 1220 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1215 1221 {
1216 1222 PRINTF1("in suspend_science_task *** CWF1 ERR %d\n", status)
1217 1223 }
1218 1224 else
1219 1225 {
1220 1226 status = RTEMS_SUCCESSFUL;
1221 1227 }
1222 1228 }
1223 1229
1224 1230 return status;
1225 1231 }
1226 1232
1227 1233 int suspend_asm_tasks( void )
1228 1234 {
1229 1235 /** This function suspends the science tasks.
1230 1236 *
1231 1237 * @return RTEMS directive status codes:
1232 1238 * - RTEMS_SUCCESSFUL - task restarted successfully
1233 1239 * - RTEMS_INVALID_ID - task id invalid
1234 1240 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1235 1241 *
1236 1242 */
1237 1243
1238 1244 rtems_status_code status;
1239 1245
1240 1246 PRINTF("in suspend_science_tasks\n")
1241 1247
1242 1248 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1243 1249 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1244 1250 {
1245 1251 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1246 1252 }
1247 1253 else
1248 1254 {
1249 1255 status = RTEMS_SUCCESSFUL;
1250 1256 }
1251 1257
1252 1258 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1253 1259 {
1254 1260 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1255 1261 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1256 1262 {
1257 1263 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1258 1264 }
1259 1265 else
1260 1266 {
1261 1267 status = RTEMS_SUCCESSFUL;
1262 1268 }
1263 1269 }
1264 1270
1265 1271 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1266 1272 {
1267 1273 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1268 1274 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1269 1275 {
1270 1276 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1271 1277 }
1272 1278 else
1273 1279 {
1274 1280 status = RTEMS_SUCCESSFUL;
1275 1281 }
1276 1282 }
1277 1283
1278 1284 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1279 1285 {
1280 1286 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1281 1287 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1282 1288 {
1283 1289 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1284 1290 }
1285 1291 else
1286 1292 {
1287 1293 status = RTEMS_SUCCESSFUL;
1288 1294 }
1289 1295 }
1290 1296
1291 1297 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1292 1298 {
1293 1299 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1294 1300 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1295 1301 {
1296 1302 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1297 1303 }
1298 1304 else
1299 1305 {
1300 1306 status = RTEMS_SUCCESSFUL;
1301 1307 }
1302 1308 }
1303 1309
1304 1310 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1305 1311 {
1306 1312 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1307 1313 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1308 1314 {
1309 1315 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1310 1316 }
1311 1317 else
1312 1318 {
1313 1319 status = RTEMS_SUCCESSFUL;
1314 1320 }
1315 1321 }
1316 1322
1317 1323 return status;
1318 1324 }
1319 1325
1320 1326 void launch_waveform_picker( unsigned char mode, unsigned int transitionCoarseTime )
1321 1327 {
1322 1328
1323 1329 WFP_reset_current_ring_nodes();
1324 1330
1325 1331 reset_waveform_picker_regs();
1326 1332
1327 1333 set_wfp_burst_enable_register( mode );
1328 1334
1329 1335 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER );
1330 1336 LEON_Unmask_interrupt( IRQ_WAVEFORM_PICKER );
1331 1337
1332 1338 if (transitionCoarseTime == 0)
1333 1339 {
1334 1340 // instant transition means transition on the next valid date
1335 1341 // this is mandatory to have a good snapshot period and a good correction of the snapshot period
1336 1342 waveform_picker_regs->start_date = time_management_regs->coarse_time + 1;
1337 1343 }
1338 1344 else
1339 1345 {
1340 1346 waveform_picker_regs->start_date = transitionCoarseTime;
1341 1347 }
1342 1348
1343 1349 update_last_valid_transition_date(waveform_picker_regs->start_date);
1344 1350
1345 1351 }
1346 1352
1347 1353 void launch_spectral_matrix( void )
1348 1354 {
1349 1355 SM_reset_current_ring_nodes();
1350 1356
1351 1357 reset_spectral_matrix_regs();
1352 1358
1353 1359 reset_nb_sm();
1354 1360
1355 1361 set_sm_irq_onNewMatrix( 1 );
1356 1362
1357 1363 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX );
1358 1364 LEON_Unmask_interrupt( IRQ_SPECTRAL_MATRIX );
1359 1365
1360 1366 }
1361 1367
1362 1368 void set_sm_irq_onNewMatrix( unsigned char value )
1363 1369 {
1364 1370 if (value == 1)
1365 1371 {
1366 1372 spectral_matrix_regs->config = spectral_matrix_regs->config | BIT_IRQ_ON_NEW_MATRIX;
1367 1373 }
1368 1374 else
1369 1375 {
1370 1376 spectral_matrix_regs->config = spectral_matrix_regs->config & MASK_IRQ_ON_NEW_MATRIX; // 1110
1371 1377 }
1372 1378 }
1373 1379
1374 1380 void set_sm_irq_onError( unsigned char value )
1375 1381 {
1376 1382 if (value == 1)
1377 1383 {
1378 1384 spectral_matrix_regs->config = spectral_matrix_regs->config | BIT_IRQ_ON_ERROR;
1379 1385 }
1380 1386 else
1381 1387 {
1382 1388 spectral_matrix_regs->config = spectral_matrix_regs->config & MASK_IRQ_ON_ERROR; // 1101
1383 1389 }
1384 1390 }
1385 1391
1386 1392 //*****************************
1387 1393 // CONFIGURE CALIBRATION SIGNAL
1388 1394 void setCalibrationPrescaler( unsigned int prescaler )
1389 1395 {
1390 1396 // prescaling of the master clock (25 MHz)
1391 1397 // master clock is divided by 2^prescaler
1392 1398 time_management_regs->calPrescaler = prescaler;
1393 1399 }
1394 1400
1395 1401 void setCalibrationDivisor( unsigned int divisionFactor )
1396 1402 {
1397 1403 // division of the prescaled clock by the division factor
1398 1404 time_management_regs->calDivisor = divisionFactor;
1399 1405 }
1400 1406
1401 1407 void setCalibrationData( void )
1402 1408 {
1403 1409 /** This function is used to store the values used to drive the DAC in order to generate the SCM calibration signal
1404 1410 *
1405 1411 * @param void
1406 1412 *
1407 1413 * @return void
1408 1414 *
1409 1415 */
1410 1416
1411 1417 unsigned int k;
1412 1418 unsigned short data;
1413 1419 float val;
1414 1420 float Ts;
1415 1421
1416 1422 time_management_regs->calDataPtr = INIT_CHAR;
1417 1423
1418 1424 Ts = 1 / CAL_FS;
1419 1425
1420 1426 // build the signal for the SCM calibration
1421 1427 for (k = 0; k < CAL_NB_PTS; k++)
1422 1428 {
1423 1429 val = CAL_A0 * sin( CAL_W0 * k * Ts )
1424 1430 + CAL_A1 * sin( CAL_W1 * k * Ts );
1425 1431 data = (unsigned short) ((val * CAL_SCALE_FACTOR) + CONST_2048);
1426 1432 time_management_regs->calData = data & CAL_DATA_MASK;
1427 1433 }
1428 1434 }
1429 1435
1430 1436 void setCalibrationDataInterleaved( void )
1431 1437 {
1432 1438 /** This function is used to store the values used to drive the DAC in order to generate the SCM calibration signal
1433 1439 *
1434 1440 * @param void
1435 1441 *
1436 1442 * @return void
1437 1443 *
1438 1444 * In interleaved mode, one can store more values than in normal mode.
1439 1445 * The data are stored in bunch of 18 bits, 12 bits from one sample and 6 bits from another sample.
1440 1446 * T store 3 values, one need two write operations.
1441 1447 * s1 [ b11 b10 b9 b8 b7 b6 ] s0 [ b11 b10 b9 b8 b7 b6 b5 b3 b2 b1 b0 ]
1442 1448 * s1 [ b5 b4 b3 b2 b1 b0 ] s2 [ b11 b10 b9 b8 b7 b6 b5 b3 b2 b1 b0 ]
1443 1449 *
1444 1450 */
1445 1451
1446 1452 unsigned int k;
1447 1453 float val;
1448 1454 float Ts;
1449 1455 unsigned short data[CAL_NB_PTS_INTER];
1450 1456 unsigned char *dataPtr;
1451 1457
1452 1458 Ts = 1 / CAL_FS_INTER;
1453 1459
1454 1460 time_management_regs->calDataPtr = INIT_CHAR;
1455 1461
1456 1462 // build the signal for the SCM calibration
1457 1463 for (k=0; k<CAL_NB_PTS_INTER; k++)
1458 1464 {
1459 1465 val = sin( 2 * pi * CAL_F0 * k * Ts )
1460 1466 + sin( 2 * pi * CAL_F1 * k * Ts );
1461 1467 data[k] = (unsigned short) ((val * CONST_512) + CONST_2048);
1462 1468 }
1463 1469
1464 1470 // write the signal in interleaved mode
1465 1471 for (k=0; k < STEPS_FOR_STORAGE_INTER; k++)
1466 1472 {
1467 1473 dataPtr = (unsigned char*) &data[ (k * BYTES_FOR_2_SAMPLES) + 2 ];
1468 1474 time_management_regs->calData = ( data[ k * BYTES_FOR_2_SAMPLES ] & CAL_DATA_MASK )
1469 1475 + ( (dataPtr[0] & CAL_DATA_MASK_INTER) << CAL_DATA_SHIFT_INTER);
1470 1476 time_management_regs->calData = ( data[(k * BYTES_FOR_2_SAMPLES) + 1] & CAL_DATA_MASK )
1471 1477 + ( (dataPtr[1] & CAL_DATA_MASK_INTER) << CAL_DATA_SHIFT_INTER);
1472 1478 }
1473 1479 }
1474 1480
1475 1481 void setCalibrationReload( bool state)
1476 1482 {
1477 1483 if (state == true)
1478 1484 {
1479 1485 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | BIT_CAL_RELOAD; // [0001 0000]
1480 1486 }
1481 1487 else
1482 1488 {
1483 1489 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & MASK_CAL_RELOAD; // [1110 1111]
1484 1490 }
1485 1491 }
1486 1492
1487 1493 void setCalibrationEnable( bool state )
1488 1494 {
1489 1495 // this bit drives the multiplexer
1490 1496 if (state == true)
1491 1497 {
1492 1498 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | BIT_CAL_ENABLE; // [0100 0000]
1493 1499 }
1494 1500 else
1495 1501 {
1496 1502 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & MASK_CAL_ENABLE; // [1011 1111]
1497 1503 }
1498 1504 }
1499 1505
1500 1506 void setCalibrationInterleaved( bool state )
1501 1507 {
1502 1508 // this bit drives the multiplexer
1503 1509 if (state == true)
1504 1510 {
1505 1511 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | BIT_SET_INTERLEAVED; // [0010 0000]
1506 1512 }
1507 1513 else
1508 1514 {
1509 1515 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & MASK_SET_INTERLEAVED; // [1101 1111]
1510 1516 }
1511 1517 }
1512 1518
1513 1519 void setCalibration( bool state )
1514 1520 {
1515 1521 if (state == true)
1516 1522 {
1517 1523 setCalibrationEnable( true );
1518 1524 setCalibrationReload( false );
1519 1525 set_hk_lfr_calib_enable( true );
1520 1526 }
1521 1527 else
1522 1528 {
1523 1529 setCalibrationEnable( false );
1524 1530 setCalibrationReload( true );
1525 1531 set_hk_lfr_calib_enable( false );
1526 1532 }
1527 1533 }
1528 1534
1529 1535 void configureCalibration( bool interleaved )
1530 1536 {
1531 1537 setCalibration( false );
1532 1538 if ( interleaved == true )
1533 1539 {
1534 1540 setCalibrationInterleaved( true );
1535 1541 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1536 1542 setCalibrationDivisor( CAL_F_DIVISOR_INTER ); // => 240 384
1537 1543 setCalibrationDataInterleaved();
1538 1544 }
1539 1545 else
1540 1546 {
1541 1547 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1542 1548 setCalibrationDivisor( CAL_F_DIVISOR ); // => 160 256 (39 - 1)
1543 1549 setCalibrationData();
1544 1550 }
1545 1551 }
1546 1552
1547 1553 //****************
1548 1554 // CLOSING ACTIONS
1549 1555 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC, unsigned char * time )
1550 1556 {
1551 1557 /** This function is used to update the HK packets statistics after a successful TC execution.
1552 1558 *
1553 1559 * @param TC points to the TC being processed
1554 1560 * @param time is the time used to date the TC execution
1555 1561 *
1556 1562 */
1557 1563
1558 1564 unsigned int val;
1559 1565
1560 1566 housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
1561 1567 housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
1562 1568 housekeeping_packet.hk_lfr_last_exe_tc_type[0] = INIT_CHAR;
1563 1569 housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
1564 1570 housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = INIT_CHAR;
1565 1571 housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
1566 1572 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_0] = time[BYTE_0];
1567 1573 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_1] = time[BYTE_1];
1568 1574 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_2] = time[BYTE_2];
1569 1575 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_3] = time[BYTE_3];
1570 1576 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_4] = time[BYTE_4];
1571 1577 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_5] = time[BYTE_5];
1572 1578
1573 1579 val = (housekeeping_packet.hk_lfr_exe_tc_cnt[0] * CONST_256) + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
1574 1580 val++;
1575 1581 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
1576 1582 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
1577 1583 }
1578 1584
1579 1585 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC, unsigned char * time )
1580 1586 {
1581 1587 /** This function is used to update the HK packets statistics after a TC rejection.
1582 1588 *
1583 1589 * @param TC points to the TC being processed
1584 1590 * @param time is the time used to date the TC rejection
1585 1591 *
1586 1592 */
1587 1593
1588 1594 unsigned int val;
1589 1595
1590 1596 housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
1591 1597 housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
1592 1598 housekeeping_packet.hk_lfr_last_rej_tc_type[0] = INIT_CHAR;
1593 1599 housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
1594 1600 housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = INIT_CHAR;
1595 1601 housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
1596 1602 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_0] = time[BYTE_0];
1597 1603 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_1] = time[BYTE_1];
1598 1604 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_2] = time[BYTE_2];
1599 1605 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_3] = time[BYTE_3];
1600 1606 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_4] = time[BYTE_4];
1601 1607 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_5] = time[BYTE_5];
1602 1608
1603 1609 val = (housekeeping_packet.hk_lfr_rej_tc_cnt[0] * CONST_256) + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
1604 1610 val++;
1605 1611 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
1606 1612 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
1607 1613 }
1608 1614
1609 1615 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id )
1610 1616 {
1611 1617 /** This function is the last step of the TC execution workflow.
1612 1618 *
1613 1619 * @param TC points to the TC being processed
1614 1620 * @param result is the result of the TC execution (LFR_SUCCESSFUL / LFR_DEFAULT)
1615 1621 * @param queue_id is the id of the RTEMS message queue used to send TM packets
1616 1622 * @param time is the time used to date the TC execution
1617 1623 *
1618 1624 */
1619 1625
1620 1626 unsigned char requestedMode;
1621 1627
1622 1628 if (result == LFR_SUCCESSFUL)
1623 1629 {
1624 1630 if ( !( (TC->serviceType==TC_TYPE_TIME) & (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
1625 1631 &
1626 1632 !( (TC->serviceType==TC_TYPE_GEN) & (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
1627 1633 )
1628 1634 {
1629 1635 send_tm_lfr_tc_exe_success( TC, queue_id );
1630 1636 }
1631 1637 if ( (TC->serviceType == TC_TYPE_GEN) & (TC->serviceSubType == TC_SUBTYPE_ENTER) )
1632 1638 {
1633 1639 //**********************************
1634 1640 // UPDATE THE LFRMODE LOCAL VARIABLE
1635 1641 requestedMode = TC->dataAndCRC[1];
1636 1642 updateLFRCurrentMode( requestedMode );
1637 1643 }
1638 1644 }
1639 1645 else if (result == LFR_EXE_ERROR)
1640 1646 {
1641 1647 send_tm_lfr_tc_exe_error( TC, queue_id );
1642 1648 }
1643 1649 }
1644 1650
1645 1651 //***************************
1646 1652 // Interrupt Service Routines
1647 1653 rtems_isr commutation_isr1( rtems_vector_number vector )
1648 1654 {
1649 1655 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1650 1656 PRINTF("In commutation_isr1 *** Error sending event to DUMB\n")
1651 1657 }
1652 1658 }
1653 1659
1654 1660 rtems_isr commutation_isr2( rtems_vector_number vector )
1655 1661 {
1656 1662 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1657 1663 PRINTF("In commutation_isr2 *** Error sending event to DUMB\n")
1658 1664 }
1659 1665 }
1660 1666
1661 1667 //****************
1662 1668 // OTHER FUNCTIONS
1663 1669 void updateLFRCurrentMode( unsigned char requestedMode )
1664 1670 {
1665 1671 /** This function updates the value of the global variable lfrCurrentMode.
1666 1672 *
1667 1673 * lfrCurrentMode is a parameter used by several functions to know in which mode LFR is running.
1668 1674 *
1669 1675 */
1670 1676
1671 1677 // update the local value of lfrCurrentMode with the value contained in the housekeeping_packet structure
1672 1678 housekeeping_packet.lfr_status_word[0] = (housekeeping_packet.lfr_status_word[0] & STATUS_WORD_LFR_MODE_MASK)
1673 1679 + (unsigned char) ( requestedMode << STATUS_WORD_LFR_MODE_SHIFT );
1674 1680 lfrCurrentMode = requestedMode;
1675 1681 }
1676 1682
1677 1683 void set_lfr_soft_reset( unsigned char value )
1678 1684 {
1679 1685 if (value == 1)
1680 1686 {
1681 1687 time_management_regs->ctrl = time_management_regs->ctrl | BIT_SOFT_RESET; // [0100]
1682 1688 }
1683 1689 else
1684 1690 {
1685 1691 time_management_regs->ctrl = time_management_regs->ctrl & MASK_SOFT_RESET; // [1011]
1686 1692 }
1687 1693 }
1688 1694
1689 1695 void reset_lfr( void )
1690 1696 {
1691 1697 set_lfr_soft_reset( 1 );
1692 1698
1693 1699 set_lfr_soft_reset( 0 );
1694 1700
1695 1701 set_hk_lfr_sc_potential_flag( true );
1696 1702 }
General Comments 0
You need to be logged in to leave comments. Login now