##// END OF EJS Templates
3.2.0.1...
paul -
r346:698df4d9c944 R3++ draft
parent child
Show More
@@ -1,107 +1,107
1 1 cmake_minimum_required (VERSION 2.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" ON)
61 61 option(FSW_debug_watchdog "Enable debug watchdog" OFF)
62 62 option(FSW_debug_tch "?" OFF)
63 63
64 64 set(SW_VERSION_N1 "3" CACHE STRING "Choose N1 FSW Version." FORCE)
65 65 set(SW_VERSION_N2 "2" CACHE STRING "Choose N2 FSW Version." FORCE)
66 66 set(SW_VERSION_N3 "0" CACHE STRING "Choose N3 FSW Version." FORCE)
67 set(SW_VERSION_N4 "0" CACHE STRING "Choose N4 FSW Version." FORCE)
67 set(SW_VERSION_N4 "1" CACHE STRING "Choose N4 FSW Version." FORCE)
68 68
69 69 if(FSW_verbose)
70 70 add_definitions(-DPRINT_MESSAGES_ON_CONSOLE)
71 71 endif()
72 72 if(FSW_boot_messages)
73 73 add_definitions(-DBOOT_MESSAGES)
74 74 endif()
75 75 if(FSW_debug_messages)
76 76 add_definitions(-DDEBUG_MESSAGES)
77 77 endif()
78 78 if(FSW_cpu_usage_report)
79 79 add_definitions(-DPRINT_TASK_STATISTICS)
80 80 endif()
81 81 if(FSW_stack_report)
82 82 add_definitions(-DPRINT_STACK_REPORT)
83 83 endif()
84 84 if(FSW_vhdl_dev)
85 85 add_definitions(-DVHDL_DEV)
86 86 endif()
87 87 if(FSW_lpp_dpu_destid)
88 88 add_definitions(-DLPP_DPU_DESTID)
89 89 endif()
90 90 if(FSW_debug_watchdog)
91 91 add_definitions(-DDEBUG_WATCHDOG)
92 92 endif()
93 93 if(FSW_debug_tch)
94 94 add_definitions(-DDEBUG_TCH)
95 95 endif()
96 96
97 97 add_definitions(-DMSB_FIRST_TCH)
98 98
99 99 add_definitions(-DSWVERSION=-1-0)
100 100 add_definitions(-DSW_VERSION_N1=${SW_VERSION_N1})
101 101 add_definitions(-DSW_VERSION_N2=${SW_VERSION_N2})
102 102 add_definitions(-DSW_VERSION_N3=${SW_VERSION_N3})
103 103 add_definitions(-DSW_VERSION_N4=${SW_VERSION_N4})
104 104
105 105 add_executable(fsw ${SOURCES})
106 106 add_test_cppcheck(fsw STYLE UNUSED_FUNCTIONS POSSIBLE_ERROR MISSING_INCLUDE)
107 107
@@ -1,958 +1,975
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 #define CONFIGURE_MAXIMUM_TASKS 20
29 #define CONFIGURE_MAXIMUM_TASKS 21 // number of tasks concurrently active including INIT
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 #define CONFIGURE_MAXIMUM_PERIODS 5
37 #define CONFIGURE_MAXIMUM_PERIODS 5 // [hous] [load] [avgv]
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
51 51 #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
52 52 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GPTIMER
53 53 #endif
54 54
55 55 #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
56 56 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_APBUART
57 57 #endif
58 58
59 59 #endif
60 60 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GRSPW /* GRSPW Driver */
61 61
62 62 #include <drvmgr/drvmgr_confdefs.h>
63 63 #endif
64 64
65 65 #include "fsw_init.h"
66 66 #include "fsw_config.c"
67 67 #include "GscMemoryLPP.hpp"
68 68
69 69 void initCache()
70 70 {
71 71 // ASI 2 contains a few control registers that have not been assigned as ancillary state registers.
72 72 // These should only be read and written using 32-bit LDA/STA instructions.
73 73 // All cache registers are accessed through load/store operations to the alternate address space (LDA/STA), using ASI = 2.
74 74 // The table below shows the register addresses:
75 75 // 0x00 Cache control register
76 76 // 0x04 Reserved
77 77 // 0x08 Instruction cache configuration register
78 78 // 0x0C Data cache configuration register
79 79
80 80 // Cache Control Register Leon3 / Leon3FT
81 81 // 31..30 29 28 27..24 23 22 21 20..19 18 17 16
82 82 // RFT PS TB DS FD FI FT ST IB
83 83 // 15 14 13..12 11..10 9..8 7..6 5 4 3..2 1..0
84 84 // IP DP ITE IDE DTE DDE DF IF DCS ICS
85 85
86 86 unsigned int cacheControlRegister;
87 87
88 88 CCR_resetCacheControlRegister();
89 89 ASR16_resetRegisterProtectionControlRegister();
90 90
91 91 cacheControlRegister = CCR_getValue();
92 92 PRINTF1("(0) CCR - Cache Control Register = %x\n", cacheControlRegister);
93 93 PRINTF1("(0) ASR16 = %x\n", *asr16Ptr);
94 94
95 95 CCR_enableInstructionCache(); // ICS bits
96 96 CCR_enableDataCache(); // DCS bits
97 97 CCR_enableInstructionBurstFetch(); // IB bit
98 98
99 99 faultTolerantScheme();
100 100
101 101 cacheControlRegister = CCR_getValue();
102 102 PRINTF1("(1) CCR - Cache Control Register = %x\n", cacheControlRegister);
103 103 PRINTF1("(1) ASR16 Register protection control register = %x\n", *asr16Ptr);
104 104
105 105 PRINTF("\n");
106 106 }
107 107
108 108 rtems_task Init( rtems_task_argument ignored )
109 109 {
110 110 /** This is the RTEMS INIT taks, it is the first task launched by the system.
111 111 *
112 112 * @param unused is the starting argument of the RTEMS task
113 113 *
114 114 * The INIT task create and run all other RTEMS tasks.
115 115 *
116 116 */
117 117
118 118 //***********
119 119 // INIT CACHE
120 120
121 121 unsigned char *vhdlVersion;
122 122
123 123 reset_lfr();
124 124
125 125 reset_local_time();
126 126
127 127 rtems_cpu_usage_reset();
128 128
129 129 rtems_status_code status;
130 130 rtems_status_code status_spw;
131 131 rtems_isr_entry old_isr_handler;
132 132
133 133 old_isr_handler = NULL;
134 134
135 135 // UART settings
136 136 enable_apbuart_transmitter();
137 137 set_apbuart_scaler_reload_register(REGS_ADDR_APBUART, APBUART_SCALER_RELOAD_VALUE);
138 138
139 139 DEBUG_PRINTF("\n\n\n\n\nIn INIT *** Now the console is on port COM1\n")
140 140
141 141
142 142 PRINTF("\n\n\n\n\n")
143 143
144 144 initCache();
145 145
146 146 PRINTF("*************************\n")
147 147 PRINTF("** LFR Flight Software **\n")
148 148
149 149 PRINTF1("** %d-", SW_VERSION_N1)
150 150 PRINTF1("%d-" , SW_VERSION_N2)
151 151 PRINTF1("%d-" , SW_VERSION_N3)
152 152 PRINTF1("%d **\n", SW_VERSION_N4)
153 153
154 154 vhdlVersion = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
155 155 PRINTF("** VHDL **\n")
156 156 PRINTF1("** %d-", vhdlVersion[1])
157 157 PRINTF1("%d-" , vhdlVersion[2])
158 158 PRINTF1("%d **\n", vhdlVersion[3])
159 159 PRINTF("*************************\n")
160 160 PRINTF("\n\n")
161 161
162 162 init_parameter_dump();
163 163 init_kcoefficients_dump();
164 164 init_local_mode_parameters();
165 165 init_housekeeping_parameters();
166 166 init_k_coefficients_prc0();
167 167 init_k_coefficients_prc1();
168 168 init_k_coefficients_prc2();
169 169 pa_bia_status_info = INIT_CHAR;
170 170
171 171 // initialize all reaction wheels frequencies to NaN
172 172 rw_f.cp_rpw_sc_rw1_f1 = NAN;
173 173 rw_f.cp_rpw_sc_rw1_f2 = NAN;
174 174 rw_f.cp_rpw_sc_rw1_f3 = NAN;
175 175 rw_f.cp_rpw_sc_rw1_f4 = NAN;
176 176 rw_f.cp_rpw_sc_rw2_f1 = NAN;
177 177 rw_f.cp_rpw_sc_rw2_f2 = NAN;
178 178 rw_f.cp_rpw_sc_rw2_f3 = NAN;
179 179 rw_f.cp_rpw_sc_rw2_f4 = NAN;
180 180 rw_f.cp_rpw_sc_rw3_f1 = NAN;
181 181 rw_f.cp_rpw_sc_rw3_f2 = NAN;
182 182 rw_f.cp_rpw_sc_rw3_f3 = NAN;
183 183 rw_f.cp_rpw_sc_rw3_f4 = NAN;
184 184 rw_f.cp_rpw_sc_rw4_f1 = NAN;
185 185 rw_f.cp_rpw_sc_rw4_f2 = NAN;
186 186 rw_f.cp_rpw_sc_rw4_f3 = NAN;
187 187 rw_f.cp_rpw_sc_rw4_f4 = NAN;
188 188
189 189 cp_rpw_sc_rw1_rw2_f_flags = INIT_CHAR;
190 190 cp_rpw_sc_rw3_rw4_f_flags = INIT_CHAR;
191 191
192 192 // initialize filtering parameters
193 193 filterPar.spare_sy_lfr_pas_filter_enabled = DEFAULT_SY_LFR_PAS_FILTER_ENABLED;
194 194 filterPar.sy_lfr_pas_filter_modulus = DEFAULT_SY_LFR_PAS_FILTER_MODULUS;
195 195 filterPar.sy_lfr_pas_filter_tbad = DEFAULT_SY_LFR_PAS_FILTER_TBAD;
196 196 filterPar.sy_lfr_pas_filter_offset = DEFAULT_SY_LFR_PAS_FILTER_OFFSET;
197 197 filterPar.sy_lfr_pas_filter_shift = DEFAULT_SY_LFR_PAS_FILTER_SHIFT;
198 198 filterPar.sy_lfr_sc_rw_delta_f = DEFAULT_SY_LFR_SC_RW_DELTA_F;
199 199 update_last_valid_transition_date( DEFAULT_LAST_VALID_TRANSITION_DATE );
200 200
201 201 // waveform picker initialization
202 202 WFP_init_rings();
203 203 LEON_Clear_interrupt( IRQ_SPARC_GPTIMER_WATCHDOG ); // initialize the waveform rings
204 204 WFP_reset_current_ring_nodes();
205 205 reset_waveform_picker_regs();
206 206
207 207 // spectral matrices initialization
208 208 SM_init_rings(); // initialize spectral matrices rings
209 209 SM_reset_current_ring_nodes();
210 210 reset_spectral_matrix_regs();
211 211
212 212 // configure calibration
213 213 configureCalibration( false ); // true means interleaved mode, false is for normal mode
214 214
215 215 updateLFRCurrentMode( LFR_MODE_STANDBY );
216 216
217 217 BOOT_PRINTF1("in INIT *** lfrCurrentMode is %d\n", lfrCurrentMode)
218 218
219 219 create_names(); // create all names
220 220
221 221 status = create_timecode_timer(); // create the timer used by timecode_irq_handler
222 222 if (status != RTEMS_SUCCESSFUL)
223 223 {
224 224 PRINTF1("in INIT *** ERR in create_timer_timecode, code %d", status)
225 225 }
226 226
227 227 status = create_message_queues(); // create message queues
228 228 if (status != RTEMS_SUCCESSFUL)
229 229 {
230 230 PRINTF1("in INIT *** ERR in create_message_queues, code %d", status)
231 231 }
232 232
233 233 status = create_all_tasks(); // create all tasks
234 234 if (status != RTEMS_SUCCESSFUL)
235 235 {
236 236 PRINTF1("in INIT *** ERR in create_all_tasks, code %d\n", status)
237 237 }
238 238
239 239 // **************************
240 240 // <SPACEWIRE INITIALIZATION>
241 241 status_spw = spacewire_open_link(); // (1) open the link
242 242 if ( status_spw != RTEMS_SUCCESSFUL )
243 243 {
244 244 PRINTF1("in INIT *** ERR spacewire_open_link code %d\n", status_spw )
245 245 }
246 246
247 247 if ( status_spw == RTEMS_SUCCESSFUL ) // (2) configure the link
248 248 {
249 249 status_spw = spacewire_configure_link( fdSPW );
250 250 if ( status_spw != RTEMS_SUCCESSFUL )
251 251 {
252 252 PRINTF1("in INIT *** ERR spacewire_configure_link code %d\n", status_spw )
253 253 }
254 254 }
255 255
256 256 if ( status_spw == RTEMS_SUCCESSFUL) // (3) start the link
257 257 {
258 258 status_spw = spacewire_start_link( fdSPW );
259 259 if ( status_spw != RTEMS_SUCCESSFUL )
260 260 {
261 261 PRINTF1("in INIT *** ERR spacewire_start_link code %d\n", status_spw )
262 262 }
263 263 }
264 264 // </SPACEWIRE INITIALIZATION>
265 265 // ***************************
266 266
267 267 status = start_all_tasks(); // start all tasks
268 268 if (status != RTEMS_SUCCESSFUL)
269 269 {
270 270 PRINTF1("in INIT *** ERR in start_all_tasks, code %d", status)
271 271 }
272 272
273 273 // start RECV and SEND *AFTER* SpaceWire Initialization, due to the timeout of the start call during the initialization
274 274 status = start_recv_send_tasks();
275 275 if ( status != RTEMS_SUCCESSFUL )
276 276 {
277 277 PRINTF1("in INIT *** ERR start_recv_send_tasks code %d\n", status )
278 278 }
279 279
280 280 // suspend science tasks, they will be restarted later depending on the mode
281 281 status = suspend_science_tasks(); // suspend science tasks (not done in stop_current_mode if current mode = STANDBY)
282 282 if (status != RTEMS_SUCCESSFUL)
283 283 {
284 284 PRINTF1("in INIT *** in suspend_science_tasks *** ERR code: %d\n", status)
285 285 }
286 286
287 287 // configure IRQ handling for the waveform picker unit
288 288 status = rtems_interrupt_catch( waveforms_isr,
289 289 IRQ_SPARC_WAVEFORM_PICKER,
290 290 &old_isr_handler) ;
291 291 // configure IRQ handling for the spectral matrices unit
292 292 status = rtems_interrupt_catch( spectral_matrices_isr,
293 293 IRQ_SPARC_SPECTRAL_MATRIX,
294 294 &old_isr_handler) ;
295 295
296 296 // if the spacewire link is not up then send an event to the SPIQ task for link recovery
297 297 if ( status_spw != RTEMS_SUCCESSFUL )
298 298 {
299 299 status = rtems_event_send( Task_id[TASKID_SPIQ], SPW_LINKERR_EVENT );
300 300 if ( status != RTEMS_SUCCESSFUL ) {
301 301 PRINTF1("in INIT *** ERR rtems_event_send to SPIQ code %d\n", status )
302 302 }
303 303 }
304 304
305 305 BOOT_PRINTF("delete INIT\n")
306 306
307 307 set_hk_lfr_sc_potential_flag( true );
308 308
309 309 // start the timer to detect a missing spacewire timecode
310 310 // the timeout is larger because the spw IP needs to receive several valid timecodes before generating a tickout
311 311 // if a tickout is generated, the timer is restarted
312 312 status = rtems_timer_fire_after( timecode_timer_id, TIMECODE_TIMER_TIMEOUT_INIT, timecode_timer_routine, NULL );
313 313
314 314 grspw_timecode_callback = &timecode_irq_handler;
315 315
316 316 status = rtems_task_delete(RTEMS_SELF);
317 317
318 318 }
319 319
320 320 void init_local_mode_parameters( void )
321 321 {
322 322 /** This function initialize the param_local global variable with default values.
323 323 *
324 324 */
325 325
326 326 unsigned int i;
327 327
328 328 // LOCAL PARAMETERS
329 329
330 330 BOOT_PRINTF1("local_sbm1_nb_cwf_max %d \n", param_local.local_sbm1_nb_cwf_max)
331 331 BOOT_PRINTF1("local_sbm2_nb_cwf_max %d \n", param_local.local_sbm2_nb_cwf_max)
332 332
333 333 // init sequence counters
334 334
335 335 for(i = 0; i<SEQ_CNT_NB_DEST_ID; i++)
336 336 {
337 337 sequenceCounters_TC_EXE[i] = INIT_CHAR;
338 338 sequenceCounters_TM_DUMP[i] = INIT_CHAR;
339 339 }
340 340 sequenceCounters_SCIENCE_NORMAL_BURST = INIT_CHAR;
341 341 sequenceCounters_SCIENCE_SBM1_SBM2 = INIT_CHAR;
342 342 sequenceCounterHK = TM_PACKET_SEQ_CTRL_STANDALONE << TM_PACKET_SEQ_SHIFT;
343 343 }
344 344
345 345 void reset_local_time( void )
346 346 {
347 347 time_management_regs->ctrl = time_management_regs->ctrl | VAL_SOFTWARE_RESET; // [0010] software reset, coarse time = 0x80000000
348 348 }
349 349
350 350 void create_names( void ) // create all names for tasks and queues
351 351 {
352 352 /** This function creates all RTEMS names used in the software for tasks and queues.
353 353 *
354 354 * @return RTEMS directive status codes:
355 355 * - RTEMS_SUCCESSFUL - successful completion
356 356 *
357 357 */
358 358
359 359 // task names
360 Task_name[TASKID_AVGV] = rtems_build_name( 'A', 'V', 'G', 'V' );
360 361 Task_name[TASKID_RECV] = rtems_build_name( 'R', 'E', 'C', 'V' );
361 362 Task_name[TASKID_ACTN] = rtems_build_name( 'A', 'C', 'T', 'N' );
362 363 Task_name[TASKID_SPIQ] = rtems_build_name( 'S', 'P', 'I', 'Q' );
363 364 Task_name[TASKID_LOAD] = rtems_build_name( 'L', 'O', 'A', 'D' );
364 365 Task_name[TASKID_AVF0] = rtems_build_name( 'A', 'V', 'F', '0' );
365 366 Task_name[TASKID_SWBD] = rtems_build_name( 'S', 'W', 'B', 'D' );
366 367 Task_name[TASKID_WFRM] = rtems_build_name( 'W', 'F', 'R', 'M' );
367 368 Task_name[TASKID_DUMB] = rtems_build_name( 'D', 'U', 'M', 'B' );
368 369 Task_name[TASKID_HOUS] = rtems_build_name( 'H', 'O', 'U', 'S' );
369 370 Task_name[TASKID_PRC0] = rtems_build_name( 'P', 'R', 'C', '0' );
370 371 Task_name[TASKID_CWF3] = rtems_build_name( 'C', 'W', 'F', '3' );
371 372 Task_name[TASKID_CWF2] = rtems_build_name( 'C', 'W', 'F', '2' );
372 373 Task_name[TASKID_CWF1] = rtems_build_name( 'C', 'W', 'F', '1' );
373 374 Task_name[TASKID_SEND] = rtems_build_name( 'S', 'E', 'N', 'D' );
374 375 Task_name[TASKID_LINK] = rtems_build_name( 'L', 'I', 'N', 'K' );
375 376 Task_name[TASKID_AVF1] = rtems_build_name( 'A', 'V', 'F', '1' );
376 377 Task_name[TASKID_PRC1] = rtems_build_name( 'P', 'R', 'C', '1' );
377 378 Task_name[TASKID_AVF2] = rtems_build_name( 'A', 'V', 'F', '2' );
378 379 Task_name[TASKID_PRC2] = rtems_build_name( 'P', 'R', 'C', '2' );
379 380
380 381 // rate monotonic period names
381 382 name_hk_rate_monotonic = rtems_build_name( 'H', 'O', 'U', 'S' );
383 name_avgv_rate_monotonic = rtems_build_name( 'A', 'V', 'G', 'V' );
382 384
383 385 misc_name[QUEUE_RECV] = rtems_build_name( 'Q', '_', 'R', 'V' );
384 386 misc_name[QUEUE_SEND] = rtems_build_name( 'Q', '_', 'S', 'D' );
385 387 misc_name[QUEUE_PRC0] = rtems_build_name( 'Q', '_', 'P', '0' );
386 388 misc_name[QUEUE_PRC1] = rtems_build_name( 'Q', '_', 'P', '1' );
387 389 misc_name[QUEUE_PRC2] = rtems_build_name( 'Q', '_', 'P', '2' );
388 390
389 391 timecode_timer_name = rtems_build_name( 'S', 'P', 'T', 'C' );
390 392 }
391 393
392 394 int create_all_tasks( void ) // create all tasks which run in the software
393 395 {
394 396 /** This function creates all RTEMS tasks used in the software.
395 397 *
396 398 * @return RTEMS directive status codes:
397 399 * - RTEMS_SUCCESSFUL - task created successfully
398 400 * - RTEMS_INVALID_ADDRESS - id is NULL
399 401 * - RTEMS_INVALID_NAME - invalid task name
400 402 * - RTEMS_INVALID_PRIORITY - invalid task priority
401 403 * - RTEMS_MP_NOT_CONFIGURED - multiprocessing not configured
402 404 * - RTEMS_TOO_MANY - too many tasks created
403 405 * - RTEMS_UNSATISFIED - not enough memory for stack/FP context
404 406 * - RTEMS_TOO_MANY - too many global objects
405 407 *
406 408 */
407 409
408 410 rtems_status_code status;
409 411
410 412 //**********
411 413 // SPACEWIRE
412 414 // RECV
413 415 status = rtems_task_create(
414 416 Task_name[TASKID_RECV], TASK_PRIORITY_RECV, RTEMS_MINIMUM_STACK_SIZE,
415 417 RTEMS_DEFAULT_MODES,
416 418 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_RECV]
417 419 );
418 420 if (status == RTEMS_SUCCESSFUL) // SEND
419 421 {
420 422 status = rtems_task_create(
421 423 Task_name[TASKID_SEND], TASK_PRIORITY_SEND, RTEMS_MINIMUM_STACK_SIZE * STACK_SIZE_MULT,
422 424 RTEMS_DEFAULT_MODES,
423 425 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SEND]
424 426 );
425 427 }
426 428 if (status == RTEMS_SUCCESSFUL) // LINK
427 429 {
428 430 status = rtems_task_create(
429 431 Task_name[TASKID_LINK], TASK_PRIORITY_LINK, RTEMS_MINIMUM_STACK_SIZE,
430 432 RTEMS_DEFAULT_MODES,
431 433 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_LINK]
432 434 );
433 435 }
434 436 if (status == RTEMS_SUCCESSFUL) // ACTN
435 437 {
436 438 status = rtems_task_create(
437 439 Task_name[TASKID_ACTN], TASK_PRIORITY_ACTN, RTEMS_MINIMUM_STACK_SIZE,
438 440 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
439 441 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_ACTN]
440 442 );
441 443 }
442 444 if (status == RTEMS_SUCCESSFUL) // SPIQ
443 445 {
444 446 status = rtems_task_create(
445 447 Task_name[TASKID_SPIQ], TASK_PRIORITY_SPIQ, RTEMS_MINIMUM_STACK_SIZE,
446 448 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
447 449 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SPIQ]
448 450 );
449 451 }
450 452
451 453 //******************
452 454 // SPECTRAL MATRICES
453 455 if (status == RTEMS_SUCCESSFUL) // AVF0
454 456 {
455 457 status = rtems_task_create(
456 458 Task_name[TASKID_AVF0], TASK_PRIORITY_AVF0, RTEMS_MINIMUM_STACK_SIZE,
457 459 RTEMS_DEFAULT_MODES,
458 460 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF0]
459 461 );
460 462 }
461 463 if (status == RTEMS_SUCCESSFUL) // PRC0
462 464 {
463 465 status = rtems_task_create(
464 466 Task_name[TASKID_PRC0], TASK_PRIORITY_PRC0, RTEMS_MINIMUM_STACK_SIZE * STACK_SIZE_MULT,
465 467 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
466 468 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC0]
467 469 );
468 470 }
469 471 if (status == RTEMS_SUCCESSFUL) // AVF1
470 472 {
471 473 status = rtems_task_create(
472 474 Task_name[TASKID_AVF1], TASK_PRIORITY_AVF1, RTEMS_MINIMUM_STACK_SIZE,
473 475 RTEMS_DEFAULT_MODES,
474 476 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF1]
475 477 );
476 478 }
477 479 if (status == RTEMS_SUCCESSFUL) // PRC1
478 480 {
479 481 status = rtems_task_create(
480 482 Task_name[TASKID_PRC1], TASK_PRIORITY_PRC1, RTEMS_MINIMUM_STACK_SIZE * STACK_SIZE_MULT,
481 483 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
482 484 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC1]
483 485 );
484 486 }
485 487 if (status == RTEMS_SUCCESSFUL) // AVF2
486 488 {
487 489 status = rtems_task_create(
488 490 Task_name[TASKID_AVF2], TASK_PRIORITY_AVF2, RTEMS_MINIMUM_STACK_SIZE,
489 491 RTEMS_DEFAULT_MODES,
490 492 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF2]
491 493 );
492 494 }
493 495 if (status == RTEMS_SUCCESSFUL) // PRC2
494 496 {
495 497 status = rtems_task_create(
496 498 Task_name[TASKID_PRC2], TASK_PRIORITY_PRC2, RTEMS_MINIMUM_STACK_SIZE * STACK_SIZE_MULT,
497 499 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
498 500 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC2]
499 501 );
500 502 }
501 503
502 504 //****************
503 505 // WAVEFORM PICKER
504 506 if (status == RTEMS_SUCCESSFUL) // WFRM
505 507 {
506 508 status = rtems_task_create(
507 509 Task_name[TASKID_WFRM], TASK_PRIORITY_WFRM, RTEMS_MINIMUM_STACK_SIZE,
508 510 RTEMS_DEFAULT_MODES,
509 511 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_WFRM]
510 512 );
511 513 }
512 514 if (status == RTEMS_SUCCESSFUL) // CWF3
513 515 {
514 516 status = rtems_task_create(
515 517 Task_name[TASKID_CWF3], TASK_PRIORITY_CWF3, RTEMS_MINIMUM_STACK_SIZE,
516 518 RTEMS_DEFAULT_MODES,
517 519 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF3]
518 520 );
519 521 }
520 522 if (status == RTEMS_SUCCESSFUL) // CWF2
521 523 {
522 524 status = rtems_task_create(
523 525 Task_name[TASKID_CWF2], TASK_PRIORITY_CWF2, RTEMS_MINIMUM_STACK_SIZE,
524 526 RTEMS_DEFAULT_MODES,
525 527 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF2]
526 528 );
527 529 }
528 530 if (status == RTEMS_SUCCESSFUL) // CWF1
529 531 {
530 532 status = rtems_task_create(
531 533 Task_name[TASKID_CWF1], TASK_PRIORITY_CWF1, RTEMS_MINIMUM_STACK_SIZE,
532 534 RTEMS_DEFAULT_MODES,
533 535 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF1]
534 536 );
535 537 }
536 538 if (status == RTEMS_SUCCESSFUL) // SWBD
537 539 {
538 540 status = rtems_task_create(
539 541 Task_name[TASKID_SWBD], TASK_PRIORITY_SWBD, RTEMS_MINIMUM_STACK_SIZE,
540 542 RTEMS_DEFAULT_MODES,
541 543 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SWBD]
542 544 );
543 545 }
544 546
545 547 //*****
546 548 // MISC
547 549 if (status == RTEMS_SUCCESSFUL) // LOAD
548 550 {
549 551 status = rtems_task_create(
550 552 Task_name[TASKID_LOAD], TASK_PRIORITY_LOAD, RTEMS_MINIMUM_STACK_SIZE,
551 553 RTEMS_DEFAULT_MODES,
552 554 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_LOAD]
553 555 );
554 556 }
555 557 if (status == RTEMS_SUCCESSFUL) // DUMB
556 558 {
557 559 status = rtems_task_create(
558 560 Task_name[TASKID_DUMB], TASK_PRIORITY_DUMB, RTEMS_MINIMUM_STACK_SIZE,
559 561 RTEMS_DEFAULT_MODES,
560 562 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_DUMB]
561 563 );
562 564 }
563 565 if (status == RTEMS_SUCCESSFUL) // HOUS
564 566 {
565 567 status = rtems_task_create(
566 568 Task_name[TASKID_HOUS], TASK_PRIORITY_HOUS, RTEMS_MINIMUM_STACK_SIZE,
567 569 RTEMS_DEFAULT_MODES,
568 570 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_HOUS]
569 571 );
570 572 }
573 if (status == RTEMS_SUCCESSFUL) // AVGV
574 {
575 status = rtems_task_create(
576 Task_name[TASKID_AVGV], TASK_PRIORITY_AVGV, RTEMS_MINIMUM_STACK_SIZE,
577 RTEMS_DEFAULT_MODES,
578 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVGV]
579 );
580 }
571 581
572 582 return status;
573 583 }
574 584
575 585 int start_recv_send_tasks( void )
576 586 {
577 587 rtems_status_code status;
578 588
579 589 status = rtems_task_start( Task_id[TASKID_RECV], recv_task, 1 );
580 590 if (status!=RTEMS_SUCCESSFUL) {
581 591 BOOT_PRINTF("in INIT *** Error starting TASK_RECV\n")
582 592 }
583 593
584 594 if (status == RTEMS_SUCCESSFUL) // SEND
585 595 {
586 596 status = rtems_task_start( Task_id[TASKID_SEND], send_task, 1 );
587 597 if (status!=RTEMS_SUCCESSFUL) {
588 598 BOOT_PRINTF("in INIT *** Error starting TASK_SEND\n")
589 599 }
590 600 }
591 601
592 602 return status;
593 603 }
594 604
595 605 int start_all_tasks( void ) // start all tasks except SEND RECV and HOUS
596 606 {
597 607 /** This function starts all RTEMS tasks used in the software.
598 608 *
599 609 * @return RTEMS directive status codes:
600 610 * - RTEMS_SUCCESSFUL - ask started successfully
601 611 * - RTEMS_INVALID_ADDRESS - invalid task entry point
602 612 * - RTEMS_INVALID_ID - invalid task id
603 613 * - RTEMS_INCORRECT_STATE - task not in the dormant state
604 614 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot start remote task
605 615 *
606 616 */
607 617 // starts all the tasks fot eh flight software
608 618
609 619 rtems_status_code status;
610 620
611 621 //**********
612 622 // SPACEWIRE
613 623 status = rtems_task_start( Task_id[TASKID_SPIQ], spiq_task, 1 );
614 624 if (status!=RTEMS_SUCCESSFUL) {
615 625 BOOT_PRINTF("in INIT *** Error starting TASK_SPIQ\n")
616 626 }
617 627
618 628 if (status == RTEMS_SUCCESSFUL) // LINK
619 629 {
620 630 status = rtems_task_start( Task_id[TASKID_LINK], link_task, 1 );
621 631 if (status!=RTEMS_SUCCESSFUL) {
622 632 BOOT_PRINTF("in INIT *** Error starting TASK_LINK\n")
623 633 }
624 634 }
625 635
626 636 if (status == RTEMS_SUCCESSFUL) // ACTN
627 637 {
628 638 status = rtems_task_start( Task_id[TASKID_ACTN], actn_task, 1 );
629 639 if (status!=RTEMS_SUCCESSFUL) {
630 640 BOOT_PRINTF("in INIT *** Error starting TASK_ACTN\n")
631 641 }
632 642 }
633 643
634 644 //******************
635 645 // SPECTRAL MATRICES
636 646 if (status == RTEMS_SUCCESSFUL) // AVF0
637 647 {
638 648 status = rtems_task_start( Task_id[TASKID_AVF0], avf0_task, LFR_MODE_STANDBY );
639 649 if (status!=RTEMS_SUCCESSFUL) {
640 650 BOOT_PRINTF("in INIT *** Error starting TASK_AVF0\n")
641 651 }
642 652 }
643 653 if (status == RTEMS_SUCCESSFUL) // PRC0
644 654 {
645 655 status = rtems_task_start( Task_id[TASKID_PRC0], prc0_task, LFR_MODE_STANDBY );
646 656 if (status!=RTEMS_SUCCESSFUL) {
647 657 BOOT_PRINTF("in INIT *** Error starting TASK_PRC0\n")
648 658 }
649 659 }
650 660 if (status == RTEMS_SUCCESSFUL) // AVF1
651 661 {
652 662 status = rtems_task_start( Task_id[TASKID_AVF1], avf1_task, LFR_MODE_STANDBY );
653 663 if (status!=RTEMS_SUCCESSFUL) {
654 664 BOOT_PRINTF("in INIT *** Error starting TASK_AVF1\n")
655 665 }
656 666 }
657 667 if (status == RTEMS_SUCCESSFUL) // PRC1
658 668 {
659 669 status = rtems_task_start( Task_id[TASKID_PRC1], prc1_task, LFR_MODE_STANDBY );
660 670 if (status!=RTEMS_SUCCESSFUL) {
661 671 BOOT_PRINTF("in INIT *** Error starting TASK_PRC1\n")
662 672 }
663 673 }
664 674 if (status == RTEMS_SUCCESSFUL) // AVF2
665 675 {
666 676 status = rtems_task_start( Task_id[TASKID_AVF2], avf2_task, 1 );
667 677 if (status!=RTEMS_SUCCESSFUL) {
668 678 BOOT_PRINTF("in INIT *** Error starting TASK_AVF2\n")
669 679 }
670 680 }
671 681 if (status == RTEMS_SUCCESSFUL) // PRC2
672 682 {
673 683 status = rtems_task_start( Task_id[TASKID_PRC2], prc2_task, 1 );
674 684 if (status!=RTEMS_SUCCESSFUL) {
675 685 BOOT_PRINTF("in INIT *** Error starting TASK_PRC2\n")
676 686 }
677 687 }
678 688
679 689 //****************
680 690 // WAVEFORM PICKER
681 691 if (status == RTEMS_SUCCESSFUL) // WFRM
682 692 {
683 693 status = rtems_task_start( Task_id[TASKID_WFRM], wfrm_task, 1 );
684 694 if (status!=RTEMS_SUCCESSFUL) {
685 695 BOOT_PRINTF("in INIT *** Error starting TASK_WFRM\n")
686 696 }
687 697 }
688 698 if (status == RTEMS_SUCCESSFUL) // CWF3
689 699 {
690 700 status = rtems_task_start( Task_id[TASKID_CWF3], cwf3_task, 1 );
691 701 if (status!=RTEMS_SUCCESSFUL) {
692 702 BOOT_PRINTF("in INIT *** Error starting TASK_CWF3\n")
693 703 }
694 704 }
695 705 if (status == RTEMS_SUCCESSFUL) // CWF2
696 706 {
697 707 status = rtems_task_start( Task_id[TASKID_CWF2], cwf2_task, 1 );
698 708 if (status!=RTEMS_SUCCESSFUL) {
699 709 BOOT_PRINTF("in INIT *** Error starting TASK_CWF2\n")
700 710 }
701 711 }
702 712 if (status == RTEMS_SUCCESSFUL) // CWF1
703 713 {
704 714 status = rtems_task_start( Task_id[TASKID_CWF1], cwf1_task, 1 );
705 715 if (status!=RTEMS_SUCCESSFUL) {
706 716 BOOT_PRINTF("in INIT *** Error starting TASK_CWF1\n")
707 717 }
708 718 }
709 719 if (status == RTEMS_SUCCESSFUL) // SWBD
710 720 {
711 721 status = rtems_task_start( Task_id[TASKID_SWBD], swbd_task, 1 );
712 722 if (status!=RTEMS_SUCCESSFUL) {
713 723 BOOT_PRINTF("in INIT *** Error starting TASK_SWBD\n")
714 724 }
715 725 }
716 726
717 727 //*****
718 728 // MISC
719 729 if (status == RTEMS_SUCCESSFUL) // HOUS
720 730 {
721 731 status = rtems_task_start( Task_id[TASKID_HOUS], hous_task, 1 );
722 732 if (status!=RTEMS_SUCCESSFUL) {
723 733 BOOT_PRINTF("in INIT *** Error starting TASK_HOUS\n")
724 734 }
725 735 }
736 if (status == RTEMS_SUCCESSFUL) // AVGV
737 {
738 status = rtems_task_start( Task_id[TASKID_AVGV], avgv_task, 1 );
739 if (status!=RTEMS_SUCCESSFUL) {
740 BOOT_PRINTF("in INIT *** Error starting TASK_AVGV\n")
741 }
742 }
726 743 if (status == RTEMS_SUCCESSFUL) // DUMB
727 744 {
728 745 status = rtems_task_start( Task_id[TASKID_DUMB], dumb_task, 1 );
729 746 if (status!=RTEMS_SUCCESSFUL) {
730 747 BOOT_PRINTF("in INIT *** Error starting TASK_DUMB\n")
731 748 }
732 749 }
733 750 if (status == RTEMS_SUCCESSFUL) // LOAD
734 751 {
735 752 status = rtems_task_start( Task_id[TASKID_LOAD], load_task, 1 );
736 753 if (status!=RTEMS_SUCCESSFUL) {
737 754 BOOT_PRINTF("in INIT *** Error starting TASK_LOAD\n")
738 755 }
739 756 }
740 757
741 758 return status;
742 759 }
743 760
744 761 rtems_status_code create_message_queues( void ) // create the two message queues used in the software
745 762 {
746 763 rtems_status_code status_recv;
747 764 rtems_status_code status_send;
748 765 rtems_status_code status_q_p0;
749 766 rtems_status_code status_q_p1;
750 767 rtems_status_code status_q_p2;
751 768 rtems_status_code ret;
752 769 rtems_id queue_id;
753 770
754 771 ret = RTEMS_SUCCESSFUL;
755 772 queue_id = RTEMS_ID_NONE;
756 773
757 774 //****************************************
758 775 // create the queue for handling valid TCs
759 776 status_recv = rtems_message_queue_create( misc_name[QUEUE_RECV],
760 777 MSG_QUEUE_COUNT_RECV, CCSDS_TC_PKT_MAX_SIZE,
761 778 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
762 779 if ( status_recv != RTEMS_SUCCESSFUL ) {
763 780 PRINTF1("in create_message_queues *** ERR creating QUEU queue, %d\n", status_recv)
764 781 }
765 782
766 783 //************************************************
767 784 // create the queue for handling TM packet sending
768 785 status_send = rtems_message_queue_create( misc_name[QUEUE_SEND],
769 786 MSG_QUEUE_COUNT_SEND, MSG_QUEUE_SIZE_SEND,
770 787 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
771 788 if ( status_send != RTEMS_SUCCESSFUL ) {
772 789 PRINTF1("in create_message_queues *** ERR creating PKTS queue, %d\n", status_send)
773 790 }
774 791
775 792 //*****************************************************************************
776 793 // create the queue for handling averaged spectral matrices for processing @ f0
777 794 status_q_p0 = rtems_message_queue_create( misc_name[QUEUE_PRC0],
778 795 MSG_QUEUE_COUNT_PRC0, MSG_QUEUE_SIZE_PRC0,
779 796 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
780 797 if ( status_q_p0 != RTEMS_SUCCESSFUL ) {
781 798 PRINTF1("in create_message_queues *** ERR creating Q_P0 queue, %d\n", status_q_p0)
782 799 }
783 800
784 801 //*****************************************************************************
785 802 // create the queue for handling averaged spectral matrices for processing @ f1
786 803 status_q_p1 = rtems_message_queue_create( misc_name[QUEUE_PRC1],
787 804 MSG_QUEUE_COUNT_PRC1, MSG_QUEUE_SIZE_PRC1,
788 805 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
789 806 if ( status_q_p1 != RTEMS_SUCCESSFUL ) {
790 807 PRINTF1("in create_message_queues *** ERR creating Q_P1 queue, %d\n", status_q_p1)
791 808 }
792 809
793 810 //*****************************************************************************
794 811 // create the queue for handling averaged spectral matrices for processing @ f2
795 812 status_q_p2 = rtems_message_queue_create( misc_name[QUEUE_PRC2],
796 813 MSG_QUEUE_COUNT_PRC2, MSG_QUEUE_SIZE_PRC2,
797 814 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
798 815 if ( status_q_p2 != RTEMS_SUCCESSFUL ) {
799 816 PRINTF1("in create_message_queues *** ERR creating Q_P2 queue, %d\n", status_q_p2)
800 817 }
801 818
802 819 if ( status_recv != RTEMS_SUCCESSFUL )
803 820 {
804 821 ret = status_recv;
805 822 }
806 823 else if( status_send != RTEMS_SUCCESSFUL )
807 824 {
808 825 ret = status_send;
809 826 }
810 827 else if( status_q_p0 != RTEMS_SUCCESSFUL )
811 828 {
812 829 ret = status_q_p0;
813 830 }
814 831 else if( status_q_p1 != RTEMS_SUCCESSFUL )
815 832 {
816 833 ret = status_q_p1;
817 834 }
818 835 else
819 836 {
820 837 ret = status_q_p2;
821 838 }
822 839
823 840 return ret;
824 841 }
825 842
826 843 rtems_status_code create_timecode_timer( void )
827 844 {
828 845 rtems_status_code status;
829 846
830 847 status = rtems_timer_create( timecode_timer_name, &timecode_timer_id );
831 848
832 849 if ( status != RTEMS_SUCCESSFUL )
833 850 {
834 851 PRINTF1("in create_timer_timecode *** ERR creating SPTC timer, %d\n", status)
835 852 }
836 853 else
837 854 {
838 855 PRINTF("in create_timer_timecode *** OK creating SPTC timer\n")
839 856 }
840 857
841 858 return status;
842 859 }
843 860
844 861 rtems_status_code get_message_queue_id_send( rtems_id *queue_id )
845 862 {
846 863 rtems_status_code status;
847 864 rtems_name queue_name;
848 865
849 866 queue_name = rtems_build_name( 'Q', '_', 'S', 'D' );
850 867
851 868 status = rtems_message_queue_ident( queue_name, 0, queue_id );
852 869
853 870 return status;
854 871 }
855 872
856 873 rtems_status_code get_message_queue_id_recv( rtems_id *queue_id )
857 874 {
858 875 rtems_status_code status;
859 876 rtems_name queue_name;
860 877
861 878 queue_name = rtems_build_name( 'Q', '_', 'R', 'V' );
862 879
863 880 status = rtems_message_queue_ident( queue_name, 0, queue_id );
864 881
865 882 return status;
866 883 }
867 884
868 885 rtems_status_code get_message_queue_id_prc0( rtems_id *queue_id )
869 886 {
870 887 rtems_status_code status;
871 888 rtems_name queue_name;
872 889
873 890 queue_name = rtems_build_name( 'Q', '_', 'P', '0' );
874 891
875 892 status = rtems_message_queue_ident( queue_name, 0, queue_id );
876 893
877 894 return status;
878 895 }
879 896
880 897 rtems_status_code get_message_queue_id_prc1( rtems_id *queue_id )
881 898 {
882 899 rtems_status_code status;
883 900 rtems_name queue_name;
884 901
885 902 queue_name = rtems_build_name( 'Q', '_', 'P', '1' );
886 903
887 904 status = rtems_message_queue_ident( queue_name, 0, queue_id );
888 905
889 906 return status;
890 907 }
891 908
892 909 rtems_status_code get_message_queue_id_prc2( rtems_id *queue_id )
893 910 {
894 911 rtems_status_code status;
895 912 rtems_name queue_name;
896 913
897 914 queue_name = rtems_build_name( 'Q', '_', 'P', '2' );
898 915
899 916 status = rtems_message_queue_ident( queue_name, 0, queue_id );
900 917
901 918 return status;
902 919 }
903 920
904 921 void update_queue_max_count( rtems_id queue_id, unsigned char*fifo_size_max )
905 922 {
906 923 u_int32_t count;
907 924 rtems_status_code status;
908 925
909 926 count = 0;
910 927
911 928 status = rtems_message_queue_get_number_pending( queue_id, &count );
912 929
913 930 count = count + 1;
914 931
915 932 if (status != RTEMS_SUCCESSFUL)
916 933 {
917 934 PRINTF1("in update_queue_max_count *** ERR = %d\n", status)
918 935 }
919 936 else
920 937 {
921 938 if (count > *fifo_size_max)
922 939 {
923 940 *fifo_size_max = count;
924 941 }
925 942 }
926 943 }
927 944
928 945 void init_ring(ring_node ring[], unsigned char nbNodes, volatile int buffer[], unsigned int bufferSize )
929 946 {
930 947 unsigned char i;
931 948
932 949 //***************
933 950 // BUFFER ADDRESS
934 951 for(i=0; i<nbNodes; i++)
935 952 {
936 953 ring[i].coarseTime = INT32_ALL_F;
937 954 ring[i].fineTime = INT32_ALL_F;
938 955 ring[i].sid = INIT_CHAR;
939 956 ring[i].status = INIT_CHAR;
940 957 ring[i].buffer_address = (int) &buffer[ i * bufferSize ];
941 958 }
942 959
943 960 //*****
944 961 // NEXT
945 962 ring[ nbNodes - 1 ].next = (ring_node*) &ring[ 0 ];
946 963 for(i=0; i<nbNodes-1; i++)
947 964 {
948 965 ring[i].next = (ring_node*) &ring[ i + 1 ];
949 966 }
950 967
951 968 //*********
952 969 // PREVIOUS
953 970 ring[ 0 ].previous = (ring_node*) &ring[ nbNodes - 1 ];
954 971 for(i=1; i<nbNodes; i++)
955 972 {
956 973 ring[i].previous = (ring_node*) &ring[ i - 1 ];
957 974 }
958 975 }
@@ -1,1005 +1,1004
1 1 /** General usage functions and RTEMS tasks.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 */
7 7
8 8 #include "fsw_misc.h"
9 9
10 10 int16_t hk_lfr_sc_v_f3_as_int16 = 0;
11 11 int16_t hk_lfr_sc_e1_f3_as_int16 = 0;
12 12 int16_t hk_lfr_sc_e2_f3_as_int16 = 0;
13 13
14 14 void timer_configure(unsigned char timer, unsigned int clock_divider,
15 15 unsigned char interrupt_level, rtems_isr (*timer_isr)() )
16 16 {
17 17 /** This function configures a GPTIMER timer instantiated in the VHDL design.
18 18 *
19 19 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
20 20 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
21 21 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
22 22 * @param interrupt_level is the interrupt level that the timer drives.
23 23 * @param timer_isr is the interrupt subroutine that will be attached to the IRQ driven by the timer.
24 24 *
25 25 * Interrupt levels are described in the SPARC documentation sparcv8.pdf p.76
26 26 *
27 27 */
28 28
29 29 rtems_status_code status;
30 30 rtems_isr_entry old_isr_handler;
31 31
32 32 old_isr_handler = NULL;
33 33
34 34 gptimer_regs->timer[timer].ctrl = INIT_CHAR; // reset the control register
35 35
36 36 status = rtems_interrupt_catch( timer_isr, interrupt_level, &old_isr_handler) ; // see sparcv8.pdf p.76 for interrupt levels
37 37 if (status!=RTEMS_SUCCESSFUL)
38 38 {
39 39 PRINTF("in configure_timer *** ERR rtems_interrupt_catch\n")
40 40 }
41 41
42 42 timer_set_clock_divider( timer, clock_divider);
43 43 }
44 44
45 45 void timer_start(unsigned char timer)
46 46 {
47 47 /** This function starts a GPTIMER timer.
48 48 *
49 49 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
50 50 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
51 51 *
52 52 */
53 53
54 54 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_CLEAR_IRQ;
55 55 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_LD;
56 56 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_EN;
57 57 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_RS;
58 58 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_IE;
59 59 }
60 60
61 61 void timer_stop(unsigned char timer)
62 62 {
63 63 /** This function stops a GPTIMER timer.
64 64 *
65 65 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
66 66 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
67 67 *
68 68 */
69 69
70 70 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & GPTIMER_EN_MASK;
71 71 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & GPTIMER_IE_MASK;
72 72 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_CLEAR_IRQ;
73 73 }
74 74
75 75 void timer_set_clock_divider(unsigned char timer, unsigned int clock_divider)
76 76 {
77 77 /** This function sets the clock divider of a GPTIMER timer.
78 78 *
79 79 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
80 80 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
81 81 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
82 82 *
83 83 */
84 84
85 85 gptimer_regs->timer[timer].reload = clock_divider; // base clock frequency is 1 MHz
86 86 }
87 87
88 88 // WATCHDOG
89 89
90 90 rtems_isr watchdog_isr( rtems_vector_number vector )
91 91 {
92 92 rtems_status_code status_code;
93 93
94 94 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_12 );
95 95
96 96 PRINTF("watchdog_isr *** this is the end, exit(0)\n");
97 97
98 98 exit(0);
99 99 }
100 100
101 101 void watchdog_configure(void)
102 102 {
103 103 /** This function configure the watchdog.
104 104 *
105 105 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
106 106 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
107 107 *
108 108 * The watchdog is a timer provided by the GPTIMER IP core of the GRLIB.
109 109 *
110 110 */
111 111
112 112 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt during configuration
113 113
114 114 timer_configure( TIMER_WATCHDOG, CLKDIV_WATCHDOG, IRQ_SPARC_GPTIMER_WATCHDOG, watchdog_isr );
115 115
116 116 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
117 117 }
118 118
119 119 void watchdog_stop(void)
120 120 {
121 121 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt line
122 122 timer_stop( TIMER_WATCHDOG );
123 123 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
124 124 }
125 125
126 126 void watchdog_reload(void)
127 127 {
128 128 /** This function reloads the watchdog timer counter with the timer reload value.
129 129 *
130 130 * @param void
131 131 *
132 132 * @return void
133 133 *
134 134 */
135 135
136 136 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_LD;
137 137 }
138 138
139 139 void watchdog_start(void)
140 140 {
141 141 /** This function starts the watchdog timer.
142 142 *
143 143 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
144 144 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
145 145 *
146 146 */
147 147
148 148 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG );
149 149
150 150 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_CLEAR_IRQ;
151 151 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_LD;
152 152 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_EN;
153 153 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_IE;
154 154
155 155 LEON_Unmask_interrupt( IRQ_GPTIMER_WATCHDOG );
156 156
157 157 }
158 158
159 159 int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register
160 160 {
161 161 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
162 162
163 163 apbuart_regs->ctrl = APBUART_CTRL_REG_MASK_TE;
164 164
165 165 return 0;
166 166 }
167 167
168 168 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value)
169 169 {
170 170 /** This function sets the scaler reload register of the apbuart module
171 171 *
172 172 * @param regs is the address of the apbuart registers in memory
173 173 * @param value is the value that will be stored in the scaler register
174 174 *
175 175 * The value shall be set by the software to get data on the serial interface.
176 176 *
177 177 */
178 178
179 179 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs;
180 180
181 181 apbuart_regs->scaler = value;
182 182
183 183 BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value)
184 184 }
185 185
186 186 //************
187 187 // RTEMS TASKS
188 188
189 189 rtems_task load_task(rtems_task_argument argument)
190 190 {
191 191 BOOT_PRINTF("in LOAD *** \n")
192 192
193 193 rtems_status_code status;
194 194 unsigned int i;
195 195 unsigned int j;
196 196 rtems_name name_watchdog_rate_monotonic; // name of the watchdog rate monotonic
197 197 rtems_id watchdog_period_id; // id of the watchdog rate monotonic period
198 198
199 199 watchdog_period_id = RTEMS_ID_NONE;
200 200
201 201 name_watchdog_rate_monotonic = rtems_build_name( 'L', 'O', 'A', 'D' );
202 202
203 203 status = rtems_rate_monotonic_create( name_watchdog_rate_monotonic, &watchdog_period_id );
204 204 if( status != RTEMS_SUCCESSFUL ) {
205 205 PRINTF1( "in LOAD *** rtems_rate_monotonic_create failed with status of %d\n", status )
206 206 }
207 207
208 208 i = 0;
209 209 j = 0;
210 210
211 211 watchdog_configure();
212 212
213 213 watchdog_start();
214 214
215 215 set_sy_lfr_watchdog_enabled( true );
216 216
217 217 while(1){
218 218 status = rtems_rate_monotonic_period( watchdog_period_id, WATCHDOG_PERIOD );
219 219 watchdog_reload();
220 220 i = i + 1;
221 221 if ( i == WATCHDOG_LOOP_PRINTF )
222 222 {
223 223 i = 0;
224 224 j = j + 1;
225 225 PRINTF1("%d\n", j)
226 226 }
227 227 #ifdef DEBUG_WATCHDOG
228 228 if (j == WATCHDOG_LOOP_DEBUG )
229 229 {
230 230 status = rtems_task_delete(RTEMS_SELF);
231 231 }
232 232 #endif
233 233 }
234 234 }
235 235
236 236 rtems_task hous_task(rtems_task_argument argument)
237 237 {
238 238 rtems_status_code status;
239 239 rtems_status_code spare_status;
240 240 rtems_id queue_id;
241 241 rtems_rate_monotonic_period_status period_status;
242 242 bool isSynchronized;
243 243
244 244 queue_id = RTEMS_ID_NONE;
245 245 memset(&period_status, 0, sizeof(rtems_rate_monotonic_period_status));
246 246 isSynchronized = false;
247 247
248 248 status = get_message_queue_id_send( &queue_id );
249 249 if (status != RTEMS_SUCCESSFUL)
250 250 {
251 251 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
252 252 }
253 253
254 254 BOOT_PRINTF("in HOUS ***\n");
255 255
256 256 if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
257 257 status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id );
258 258 if( status != RTEMS_SUCCESSFUL ) {
259 259 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status );
260 260 }
261 261 }
262 262
263 263 status = rtems_rate_monotonic_cancel(HK_id);
264 264 if( status != RTEMS_SUCCESSFUL ) {
265 265 PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status );
266 266 }
267 267 else {
268 268 DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n");
269 269 }
270 270
271 271 // startup phase
272 272 status = rtems_rate_monotonic_period( HK_id, SY_LFR_TIME_SYN_TIMEOUT_in_ticks );
273 273 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
274 274 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
275 275 while( (period_status.state != RATE_MONOTONIC_EXPIRED)
276 276 && (isSynchronized == false) ) // after SY_LFR_TIME_SYN_TIMEOUT ms, starts HK anyway
277 277 {
278 278 if ((time_management_regs->coarse_time & VAL_LFR_SYNCHRONIZED) == INT32_ALL_0) // check time synchronization
279 279 {
280 280 isSynchronized = true;
281 281 }
282 282 else
283 283 {
284 284 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
285 285
286 286 status = rtems_task_wake_after( HK_SYNC_WAIT ); // wait HK_SYNCH_WAIT 100 ms = 10 * 10 ms
287 287 }
288 288 }
289 289 status = rtems_rate_monotonic_cancel(HK_id);
290 290 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
291 291
292 292 set_hk_lfr_reset_cause( POWER_ON );
293 293
294 294 while(1){ // launch the rate monotonic task
295 295 status = rtems_rate_monotonic_period( HK_id, HK_PERIOD );
296 296 if ( status != RTEMS_SUCCESSFUL ) {
297 297 PRINTF1( "in HOUS *** ERR period: %d\n", status);
298 298 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 );
299 299 }
300 300 else {
301 301 housekeeping_packet.packetSequenceControl[BYTE_0] = (unsigned char) (sequenceCounterHK >> SHIFT_1_BYTE);
302 302 housekeeping_packet.packetSequenceControl[BYTE_1] = (unsigned char) (sequenceCounterHK );
303 303 increment_seq_counter( &sequenceCounterHK );
304 304
305 305 housekeeping_packet.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
306 306 housekeeping_packet.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
307 307 housekeeping_packet.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
308 308 housekeeping_packet.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
309 309 housekeeping_packet.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
310 310 housekeeping_packet.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
311 311
312 312 spacewire_update_hk_lfr_link_state( &housekeeping_packet.lfr_status_word[0] );
313 313
314 314 spacewire_read_statistics();
315 315
316 316 update_hk_with_grspw_stats();
317 317
318 318 set_hk_lfr_time_not_synchro();
319 319
320 320 housekeeping_packet.hk_lfr_q_sd_fifo_size_max = hk_lfr_q_sd_fifo_size_max;
321 321 housekeeping_packet.hk_lfr_q_rv_fifo_size_max = hk_lfr_q_rv_fifo_size_max;
322 322 housekeeping_packet.hk_lfr_q_p0_fifo_size_max = hk_lfr_q_p0_fifo_size_max;
323 323 housekeeping_packet.hk_lfr_q_p1_fifo_size_max = hk_lfr_q_p1_fifo_size_max;
324 324 housekeeping_packet.hk_lfr_q_p2_fifo_size_max = hk_lfr_q_p2_fifo_size_max;
325 325
326 326 housekeeping_packet.sy_lfr_common_parameters_spare = parameter_dump_packet.sy_lfr_common_parameters_spare;
327 327 housekeeping_packet.sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
328 328 get_temperatures( housekeeping_packet.hk_lfr_temp_scm );
329 329 get_v_e1_e2_f3( housekeeping_packet.hk_lfr_sc_v_f3 );
330 330 get_cpu_load( (unsigned char *) &housekeeping_packet.hk_lfr_cpu_load );
331 331
332 332 hk_lfr_le_me_he_update();
333 333
334 334 housekeeping_packet.hk_lfr_sc_rw1_rw2_f_flags = cp_rpw_sc_rw1_rw2_f_flags;
335 335 housekeeping_packet.hk_lfr_sc_rw3_rw4_f_flags = cp_rpw_sc_rw3_rw4_f_flags;
336 336
337 337 // SEND PACKET
338 338 status = rtems_message_queue_send( queue_id, &housekeeping_packet,
339 339 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
340 340 if (status != RTEMS_SUCCESSFUL) {
341 341 PRINTF1("in HOUS *** ERR send: %d\n", status)
342 342 }
343 343 }
344 344 }
345 345
346 346 PRINTF("in HOUS *** deleting task\n")
347 347
348 348 status = rtems_task_delete( RTEMS_SELF ); // should not return
349 349
350 350 return;
351 351 }
352 352
353 353 rtems_task avgv_task(rtems_task_argument argument)
354 354 {
355 355 #define MOVING_AVERAGE 16
356 356 rtems_status_code status;
357 357 static unsigned int v[MOVING_AVERAGE] = {0};
358 358 static unsigned int e1[MOVING_AVERAGE] = {0};
359 359 static unsigned int e2[MOVING_AVERAGE] = {0};
360 360 float average_v;
361 361 float average_e1;
362 362 float average_e2;
363 363 float newValue_v;
364 364 float newValue_e1;
365 365 float newValue_e2;
366 366 unsigned char k;
367 367 unsigned char indexOfOldValue;
368 368
369 369 BOOT_PRINTF("in AVGV ***\n");
370 370
371 371 if (rtems_rate_monotonic_ident( name_avgv_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
372 372 status = rtems_rate_monotonic_create( name_avgv_rate_monotonic, &AVGV_id );
373 373 if( status != RTEMS_SUCCESSFUL ) {
374 374 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status );
375 375 }
376 376 }
377 377
378 378 status = rtems_rate_monotonic_cancel(AVGV_id);
379 379 if( status != RTEMS_SUCCESSFUL ) {
380 380 PRINTF1( "ERR *** in AVGV *** rtems_rate_monotonic_cancel(AVGV_id) ***code: %d\n", status );
381 381 }
382 382 else {
383 383 DEBUG_PRINTF("OK *** in AVGV *** rtems_rate_monotonic_cancel(AVGV_id)\n");
384 384 }
385 385
386 386 // initialize values
387 387 indexOfOldValue = MOVING_AVERAGE - 1;
388 388 average_v = INIT_FLOAT;
389 389 average_e1 = INIT_FLOAT;
390 390 average_e2 = INIT_FLOAT;
391 391 newValue_v = INIT_FLOAT;
392 392 newValue_e1 = INIT_FLOAT;
393 393 newValue_e2 = INIT_FLOAT;
394 394
395 395 k = INIT_CHAR;
396 396
397 397 while(1)
398 398 { // launch the rate monotonic task
399 399 status = rtems_rate_monotonic_period( AVGV_id, AVGV_PERIOD );
400 400 if ( status != RTEMS_SUCCESSFUL )
401 401 {
402 402 PRINTF1( "in AVGV *** ERR period: %d\n", status);
403 403 }
404 404 else
405 405 {
406 406 // get new values
407 407 newValue_v = waveform_picker_regs->v;
408 408 newValue_e1 = waveform_picker_regs->e1;
409 409 newValue_e2 = waveform_picker_regs->e2;
410 410
411 411 // compute the moving average
412 412 average_v = average_v + newValue_v - v[k];
413 413 average_e1 = average_e1 + newValue_e1 - e1[k];
414 414 average_e2 = average_e2 + newValue_e2 - e2[k];
415 415
416 416 // store new values in buffers
417 417 v[k] = newValue_v;
418 418 e1[k] = newValue_e1;
419 419 e2[k] = newValue_e2;
420 420 }
421 421 if (k == (MOVING_AVERAGE-1))
422 422 {
423 423 k = 0;
424 PRINTF("tick\n");
425 424 }
426 425 else
427 426 {
428 427 k++;
429 428 }
430 429 //update int16 values
431 430 hk_lfr_sc_v_f3_as_int16 = (int16_t) (average_v / ((float) MOVING_AVERAGE) );
432 431 hk_lfr_sc_e1_f3_as_int16 = (int16_t) (average_e1 / ((float) MOVING_AVERAGE) );
433 432 hk_lfr_sc_e2_f3_as_int16 = (int16_t) (average_e2 / ((float) MOVING_AVERAGE) );
434 433 }
435 434
436 435 PRINTF("in AVGV *** deleting task\n");
437 436
438 437 status = rtems_task_delete( RTEMS_SELF ); // should not return
439 438
440 439 return;
441 440 }
442 441
443 442 rtems_task dumb_task( rtems_task_argument unused )
444 443 {
445 444 /** This RTEMS taks is used to print messages without affecting the general behaviour of the software.
446 445 *
447 446 * @param unused is the starting argument of the RTEMS task
448 447 *
449 448 * The DUMB taks waits for RTEMS events and print messages depending on the incoming events.
450 449 *
451 450 */
452 451
453 452 unsigned int i;
454 453 unsigned int intEventOut;
455 454 unsigned int coarse_time = 0;
456 455 unsigned int fine_time = 0;
457 456 rtems_event_set event_out;
458 457
459 458 event_out = EVENT_SETS_NONE_PENDING;
460 459
461 460 BOOT_PRINTF("in DUMB *** \n")
462 461
463 462 while(1){
464 463 rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3
465 464 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7
466 465 | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12 | RTEMS_EVENT_13
467 466 | RTEMS_EVENT_14,
468 467 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT
469 468 intEventOut = (unsigned int) event_out;
470 469 for ( i=0; i<NB_RTEMS_EVENTS; i++)
471 470 {
472 471 if ( ((intEventOut >> i) & 1) != 0)
473 472 {
474 473 coarse_time = time_management_regs->coarse_time;
475 474 fine_time = time_management_regs->fine_time;
476 475 if (i==EVENT_12)
477 476 {
478 477 PRINTF1("%s\n", DUMB_MESSAGE_12)
479 478 }
480 479 if (i==EVENT_13)
481 480 {
482 481 PRINTF1("%s\n", DUMB_MESSAGE_13)
483 482 }
484 483 if (i==EVENT_14)
485 484 {
486 485 PRINTF1("%s\n", DUMB_MESSAGE_1)
487 486 }
488 487 }
489 488 }
490 489 }
491 490 }
492 491
493 492 //*****************************
494 493 // init housekeeping parameters
495 494
496 495 void init_housekeeping_parameters( void )
497 496 {
498 497 /** This function initialize the housekeeping_packet global variable with default values.
499 498 *
500 499 */
501 500
502 501 unsigned int i = 0;
503 502 unsigned char *parameters;
504 503 unsigned char sizeOfHK;
505 504
506 505 sizeOfHK = sizeof( Packet_TM_LFR_HK_t );
507 506
508 507 parameters = (unsigned char*) &housekeeping_packet;
509 508
510 509 for(i = 0; i< sizeOfHK; i++)
511 510 {
512 511 parameters[i] = INIT_CHAR;
513 512 }
514 513
515 514 housekeeping_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
516 515 housekeeping_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
517 516 housekeeping_packet.reserved = DEFAULT_RESERVED;
518 517 housekeeping_packet.userApplication = CCSDS_USER_APP;
519 518 housekeeping_packet.packetID[0] = (unsigned char) (APID_TM_HK >> SHIFT_1_BYTE);
520 519 housekeeping_packet.packetID[1] = (unsigned char) (APID_TM_HK);
521 520 housekeeping_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
522 521 housekeeping_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
523 522 housekeeping_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> SHIFT_1_BYTE);
524 523 housekeeping_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
525 524 housekeeping_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
526 525 housekeeping_packet.serviceType = TM_TYPE_HK;
527 526 housekeeping_packet.serviceSubType = TM_SUBTYPE_HK;
528 527 housekeeping_packet.destinationID = TM_DESTINATION_ID_GROUND;
529 528 housekeeping_packet.sid = SID_HK;
530 529
531 530 // init status word
532 531 housekeeping_packet.lfr_status_word[0] = DEFAULT_STATUS_WORD_BYTE0;
533 532 housekeeping_packet.lfr_status_word[1] = DEFAULT_STATUS_WORD_BYTE1;
534 533 // init software version
535 534 housekeeping_packet.lfr_sw_version[0] = SW_VERSION_N1;
536 535 housekeeping_packet.lfr_sw_version[1] = SW_VERSION_N2;
537 536 housekeeping_packet.lfr_sw_version[BYTE_2] = SW_VERSION_N3;
538 537 housekeeping_packet.lfr_sw_version[BYTE_3] = SW_VERSION_N4;
539 538 // init fpga version
540 539 parameters = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
541 540 housekeeping_packet.lfr_fpga_version[BYTE_0] = parameters[BYTE_1]; // n1
542 541 housekeeping_packet.lfr_fpga_version[BYTE_1] = parameters[BYTE_2]; // n2
543 542 housekeeping_packet.lfr_fpga_version[BYTE_2] = parameters[BYTE_3]; // n3
544 543
545 544 housekeeping_packet.hk_lfr_q_sd_fifo_size = MSG_QUEUE_COUNT_SEND;
546 545 housekeeping_packet.hk_lfr_q_rv_fifo_size = MSG_QUEUE_COUNT_RECV;
547 546 housekeeping_packet.hk_lfr_q_p0_fifo_size = MSG_QUEUE_COUNT_PRC0;
548 547 housekeeping_packet.hk_lfr_q_p1_fifo_size = MSG_QUEUE_COUNT_PRC1;
549 548 housekeeping_packet.hk_lfr_q_p2_fifo_size = MSG_QUEUE_COUNT_PRC2;
550 549 }
551 550
552 551 void increment_seq_counter( unsigned short *packetSequenceControl )
553 552 {
554 553 /** This function increment the sequence counter passes in argument.
555 554 *
556 555 * The increment does not affect the grouping flag. In case of an overflow, the counter is reset to 0.
557 556 *
558 557 */
559 558
560 559 unsigned short segmentation_grouping_flag;
561 560 unsigned short sequence_cnt;
562 561
563 562 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << SHIFT_1_BYTE; // keep bits 7 downto 6
564 563 sequence_cnt = (*packetSequenceControl) & SEQ_CNT_MASK; // [0011 1111 1111 1111]
565 564
566 565 if ( sequence_cnt < SEQ_CNT_MAX)
567 566 {
568 567 sequence_cnt = sequence_cnt + 1;
569 568 }
570 569 else
571 570 {
572 571 sequence_cnt = 0;
573 572 }
574 573
575 574 *packetSequenceControl = segmentation_grouping_flag | sequence_cnt ;
576 575 }
577 576
578 577 void getTime( unsigned char *time)
579 578 {
580 579 /** This function write the current local time in the time buffer passed in argument.
581 580 *
582 581 */
583 582
584 583 time[0] = (unsigned char) (time_management_regs->coarse_time>>SHIFT_3_BYTES);
585 584 time[1] = (unsigned char) (time_management_regs->coarse_time>>SHIFT_2_BYTES);
586 585 time[2] = (unsigned char) (time_management_regs->coarse_time>>SHIFT_1_BYTE);
587 586 time[3] = (unsigned char) (time_management_regs->coarse_time);
588 587 time[4] = (unsigned char) (time_management_regs->fine_time>>SHIFT_1_BYTE);
589 588 time[5] = (unsigned char) (time_management_regs->fine_time);
590 589 }
591 590
592 591 unsigned long long int getTimeAsUnsignedLongLongInt( )
593 592 {
594 593 /** This function write the current local time in the time buffer passed in argument.
595 594 *
596 595 */
597 596 unsigned long long int time;
598 597
599 598 time = ( (unsigned long long int) (time_management_regs->coarse_time & COARSE_TIME_MASK) << SHIFT_2_BYTES )
600 599 + time_management_regs->fine_time;
601 600
602 601 return time;
603 602 }
604 603
605 604 void send_dumb_hk( void )
606 605 {
607 606 Packet_TM_LFR_HK_t dummy_hk_packet;
608 607 unsigned char *parameters;
609 608 unsigned int i;
610 609 rtems_id queue_id;
611 610
612 611 queue_id = RTEMS_ID_NONE;
613 612
614 613 dummy_hk_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
615 614 dummy_hk_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
616 615 dummy_hk_packet.reserved = DEFAULT_RESERVED;
617 616 dummy_hk_packet.userApplication = CCSDS_USER_APP;
618 617 dummy_hk_packet.packetID[0] = (unsigned char) (APID_TM_HK >> SHIFT_1_BYTE);
619 618 dummy_hk_packet.packetID[1] = (unsigned char) (APID_TM_HK);
620 619 dummy_hk_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
621 620 dummy_hk_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
622 621 dummy_hk_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> SHIFT_1_BYTE);
623 622 dummy_hk_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
624 623 dummy_hk_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
625 624 dummy_hk_packet.serviceType = TM_TYPE_HK;
626 625 dummy_hk_packet.serviceSubType = TM_SUBTYPE_HK;
627 626 dummy_hk_packet.destinationID = TM_DESTINATION_ID_GROUND;
628 627 dummy_hk_packet.time[0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
629 628 dummy_hk_packet.time[1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
630 629 dummy_hk_packet.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
631 630 dummy_hk_packet.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
632 631 dummy_hk_packet.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
633 632 dummy_hk_packet.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
634 633 dummy_hk_packet.sid = SID_HK;
635 634
636 635 // init status word
637 636 dummy_hk_packet.lfr_status_word[0] = INT8_ALL_F;
638 637 dummy_hk_packet.lfr_status_word[1] = INT8_ALL_F;
639 638 // init software version
640 639 dummy_hk_packet.lfr_sw_version[0] = SW_VERSION_N1;
641 640 dummy_hk_packet.lfr_sw_version[1] = SW_VERSION_N2;
642 641 dummy_hk_packet.lfr_sw_version[BYTE_2] = SW_VERSION_N3;
643 642 dummy_hk_packet.lfr_sw_version[BYTE_3] = SW_VERSION_N4;
644 643 // init fpga version
645 644 parameters = (unsigned char *) (REGS_ADDR_WAVEFORM_PICKER + APB_OFFSET_VHDL_REV);
646 645 dummy_hk_packet.lfr_fpga_version[BYTE_0] = parameters[BYTE_1]; // n1
647 646 dummy_hk_packet.lfr_fpga_version[BYTE_1] = parameters[BYTE_2]; // n2
648 647 dummy_hk_packet.lfr_fpga_version[BYTE_2] = parameters[BYTE_3]; // n3
649 648
650 649 parameters = (unsigned char *) &dummy_hk_packet.hk_lfr_cpu_load;
651 650
652 651 for (i=0; i<(BYTE_POS_HK_REACTION_WHEELS_FREQUENCY - BYTE_POS_HK_LFR_CPU_LOAD); i++)
653 652 {
654 653 parameters[i] = INT8_ALL_F;
655 654 }
656 655
657 656 get_message_queue_id_send( &queue_id );
658 657
659 658 rtems_message_queue_send( queue_id, &dummy_hk_packet,
660 659 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
661 660 }
662 661
663 662 void get_temperatures( unsigned char *temperatures )
664 663 {
665 664 unsigned char* temp_scm_ptr;
666 665 unsigned char* temp_pcb_ptr;
667 666 unsigned char* temp_fpga_ptr;
668 667
669 668 // SEL1 SEL0
670 669 // 0 0 => PCB
671 670 // 0 1 => FPGA
672 671 // 1 0 => SCM
673 672
674 673 temp_scm_ptr = (unsigned char *) &time_management_regs->temp_scm;
675 674 temp_pcb_ptr = (unsigned char *) &time_management_regs->temp_pcb;
676 675 temp_fpga_ptr = (unsigned char *) &time_management_regs->temp_fpga;
677 676
678 677 temperatures[ BYTE_0 ] = temp_scm_ptr[ BYTE_2 ];
679 678 temperatures[ BYTE_1 ] = temp_scm_ptr[ BYTE_3 ];
680 679 temperatures[ BYTE_2 ] = temp_pcb_ptr[ BYTE_2 ];
681 680 temperatures[ BYTE_3 ] = temp_pcb_ptr[ BYTE_3 ];
682 681 temperatures[ BYTE_4 ] = temp_fpga_ptr[ BYTE_2 ];
683 682 temperatures[ BYTE_5 ] = temp_fpga_ptr[ BYTE_3 ];
684 683 }
685 684
686 685 void get_v_e1_e2_f3( unsigned char *spacecraft_potential )
687 686 {
688 687 unsigned char* v_ptr;
689 688 unsigned char* e1_ptr;
690 689 unsigned char* e2_ptr;
691 690
692 691 v_ptr = (unsigned char *) &hk_lfr_sc_v_f3_as_int16;
693 692 e1_ptr = (unsigned char *) &hk_lfr_sc_e1_f3_as_int16;
694 693 e2_ptr = (unsigned char *) &hk_lfr_sc_e2_f3_as_int16;
695 694
696 695 spacecraft_potential[BYTE_0] = v_ptr[0];
697 696 spacecraft_potential[BYTE_1] = v_ptr[1];
698 697 spacecraft_potential[BYTE_2] = e1_ptr[0];
699 698 spacecraft_potential[BYTE_3] = e1_ptr[1];
700 699 spacecraft_potential[BYTE_4] = e2_ptr[0];
701 700 spacecraft_potential[BYTE_5] = e2_ptr[1];
702 701 }
703 702
704 703 void get_cpu_load( unsigned char *resource_statistics )
705 704 {
706 705 unsigned char cpu_load;
707 706
708 707 cpu_load = lfr_rtems_cpu_usage_report();
709 708
710 709 // HK_LFR_CPU_LOAD
711 710 resource_statistics[0] = cpu_load;
712 711
713 712 // HK_LFR_CPU_LOAD_MAX
714 713 if (cpu_load > resource_statistics[1])
715 714 {
716 715 resource_statistics[1] = cpu_load;
717 716 }
718 717
719 718 // CPU_LOAD_AVE
720 719 resource_statistics[BYTE_2] = 0;
721 720
722 721 #ifndef PRINT_TASK_STATISTICS
723 722 rtems_cpu_usage_reset();
724 723 #endif
725 724
726 725 }
727 726
728 727 void set_hk_lfr_sc_potential_flag( bool state )
729 728 {
730 729 if (state == true)
731 730 {
732 731 housekeeping_packet.lfr_status_word[1] =
733 732 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_SC_POTENTIAL_FLAG_BIT; // [0100 0000]
734 733 }
735 734 else
736 735 {
737 736 housekeeping_packet.lfr_status_word[1] =
738 737 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_SC_POTENTIAL_FLAG_MASK; // [1011 1111]
739 738 }
740 739 }
741 740
742 741 void set_sy_lfr_pas_filter_enabled( bool state )
743 742 {
744 743 if (state == true)
745 744 {
746 745 housekeeping_packet.lfr_status_word[1] =
747 746 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_PAS_FILTER_ENABLED_BIT; // [0010 0000]
748 747 }
749 748 else
750 749 {
751 750 housekeeping_packet.lfr_status_word[1] =
752 751 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_PAS_FILTER_ENABLED_MASK; // [1101 1111]
753 752 }
754 753 }
755 754
756 755 void set_sy_lfr_watchdog_enabled( bool state )
757 756 {
758 757 if (state == true)
759 758 {
760 759 housekeeping_packet.lfr_status_word[1] =
761 760 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_WATCHDOG_BIT; // [0001 0000]
762 761 }
763 762 else
764 763 {
765 764 housekeeping_packet.lfr_status_word[1] =
766 765 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_WATCHDOG_MASK; // [1110 1111]
767 766 }
768 767 }
769 768
770 769 void set_hk_lfr_calib_enable( bool state )
771 770 {
772 771 if (state == true)
773 772 {
774 773 housekeeping_packet.lfr_status_word[1] =
775 774 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_CALIB_BIT; // [0000 1000]
776 775 }
777 776 else
778 777 {
779 778 housekeeping_packet.lfr_status_word[1] =
780 779 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_CALIB_MASK; // [1111 0111]
781 780 }
782 781 }
783 782
784 783 void set_hk_lfr_reset_cause( enum lfr_reset_cause_t lfr_reset_cause )
785 784 {
786 785 housekeeping_packet.lfr_status_word[1] =
787 786 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_RESET_CAUSE_MASK; // [1111 1000]
788 787
789 788 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1]
790 789 | (lfr_reset_cause & STATUS_WORD_RESET_CAUSE_BITS ); // [0000 0111]
791 790
792 791 }
793 792
794 793 void increment_hk_counter( unsigned char newValue, unsigned char oldValue, unsigned int *counter )
795 794 {
796 795 int delta;
797 796
798 797 delta = 0;
799 798
800 799 if (newValue >= oldValue)
801 800 {
802 801 delta = newValue - oldValue;
803 802 }
804 803 else
805 804 {
806 805 delta = (CONST_256 - oldValue) + newValue;
807 806 }
808 807
809 808 *counter = *counter + delta;
810 809 }
811 810
812 811 void hk_lfr_le_update( void )
813 812 {
814 813 static hk_lfr_le_t old_hk_lfr_le = {0};
815 814 hk_lfr_le_t new_hk_lfr_le;
816 815 unsigned int counter;
817 816
818 817 counter = (((unsigned int) housekeeping_packet.hk_lfr_le_cnt[0]) * CONST_256) + housekeeping_packet.hk_lfr_le_cnt[1];
819 818
820 819 // DPU
821 820 new_hk_lfr_le.dpu_spw_parity = housekeeping_packet.hk_lfr_dpu_spw_parity;
822 821 new_hk_lfr_le.dpu_spw_disconnect= housekeeping_packet.hk_lfr_dpu_spw_disconnect;
823 822 new_hk_lfr_le.dpu_spw_escape = housekeeping_packet.hk_lfr_dpu_spw_escape;
824 823 new_hk_lfr_le.dpu_spw_credit = housekeeping_packet.hk_lfr_dpu_spw_credit;
825 824 new_hk_lfr_le.dpu_spw_write_sync= housekeeping_packet.hk_lfr_dpu_spw_write_sync;
826 825 // TIMECODE
827 826 new_hk_lfr_le.timecode_erroneous= housekeeping_packet.hk_lfr_timecode_erroneous;
828 827 new_hk_lfr_le.timecode_missing = housekeeping_packet.hk_lfr_timecode_missing;
829 828 new_hk_lfr_le.timecode_invalid = housekeeping_packet.hk_lfr_timecode_invalid;
830 829 // TIME
831 830 new_hk_lfr_le.time_timecode_it = housekeeping_packet.hk_lfr_time_timecode_it;
832 831 new_hk_lfr_le.time_not_synchro = housekeeping_packet.hk_lfr_time_not_synchro;
833 832 new_hk_lfr_le.time_timecode_ctr = housekeeping_packet.hk_lfr_time_timecode_ctr;
834 833 //AHB
835 834 new_hk_lfr_le.ahb_correctable = housekeeping_packet.hk_lfr_ahb_correctable;
836 835 // housekeeping_packet.hk_lfr_dpu_spw_rx_ahb => not handled by the grspw driver
837 836 // housekeeping_packet.hk_lfr_dpu_spw_tx_ahb => not handled by the grspw driver
838 837
839 838 // update the le counter
840 839 // DPU
841 840 increment_hk_counter( new_hk_lfr_le.dpu_spw_parity, old_hk_lfr_le.dpu_spw_parity, &counter );
842 841 increment_hk_counter( new_hk_lfr_le.dpu_spw_disconnect,old_hk_lfr_le.dpu_spw_disconnect, &counter );
843 842 increment_hk_counter( new_hk_lfr_le.dpu_spw_escape, old_hk_lfr_le.dpu_spw_escape, &counter );
844 843 increment_hk_counter( new_hk_lfr_le.dpu_spw_credit, old_hk_lfr_le.dpu_spw_credit, &counter );
845 844 increment_hk_counter( new_hk_lfr_le.dpu_spw_write_sync,old_hk_lfr_le.dpu_spw_write_sync, &counter );
846 845 // TIMECODE
847 846 increment_hk_counter( new_hk_lfr_le.timecode_erroneous,old_hk_lfr_le.timecode_erroneous, &counter );
848 847 increment_hk_counter( new_hk_lfr_le.timecode_missing, old_hk_lfr_le.timecode_missing, &counter );
849 848 increment_hk_counter( new_hk_lfr_le.timecode_invalid, old_hk_lfr_le.timecode_invalid, &counter );
850 849 // TIME
851 850 increment_hk_counter( new_hk_lfr_le.time_timecode_it, old_hk_lfr_le.time_timecode_it, &counter );
852 851 increment_hk_counter( new_hk_lfr_le.time_not_synchro, old_hk_lfr_le.time_not_synchro, &counter );
853 852 increment_hk_counter( new_hk_lfr_le.time_timecode_ctr, old_hk_lfr_le.time_timecode_ctr, &counter );
854 853 // AHB
855 854 increment_hk_counter( new_hk_lfr_le.ahb_correctable, old_hk_lfr_le.ahb_correctable, &counter );
856 855
857 856 // DPU
858 857 old_hk_lfr_le.dpu_spw_parity = new_hk_lfr_le.dpu_spw_parity;
859 858 old_hk_lfr_le.dpu_spw_disconnect= new_hk_lfr_le.dpu_spw_disconnect;
860 859 old_hk_lfr_le.dpu_spw_escape = new_hk_lfr_le.dpu_spw_escape;
861 860 old_hk_lfr_le.dpu_spw_credit = new_hk_lfr_le.dpu_spw_credit;
862 861 old_hk_lfr_le.dpu_spw_write_sync= new_hk_lfr_le.dpu_spw_write_sync;
863 862 // TIMECODE
864 863 old_hk_lfr_le.timecode_erroneous= new_hk_lfr_le.timecode_erroneous;
865 864 old_hk_lfr_le.timecode_missing = new_hk_lfr_le.timecode_missing;
866 865 old_hk_lfr_le.timecode_invalid = new_hk_lfr_le.timecode_invalid;
867 866 // TIME
868 867 old_hk_lfr_le.time_timecode_it = new_hk_lfr_le.time_timecode_it;
869 868 old_hk_lfr_le.time_not_synchro = new_hk_lfr_le.time_not_synchro;
870 869 old_hk_lfr_le.time_timecode_ctr = new_hk_lfr_le.time_timecode_ctr;
871 870 //AHB
872 871 old_hk_lfr_le.ahb_correctable = new_hk_lfr_le.ahb_correctable;
873 872 // housekeeping_packet.hk_lfr_dpu_spw_rx_ahb => not handled by the grspw driver
874 873 // housekeeping_packet.hk_lfr_dpu_spw_tx_ahb => not handled by the grspw driver
875 874
876 875 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
877 876 // LE
878 877 housekeeping_packet.hk_lfr_le_cnt[0] = (unsigned char) ((counter & BYTE0_MASK) >> SHIFT_1_BYTE);
879 878 housekeeping_packet.hk_lfr_le_cnt[1] = (unsigned char) (counter & BYTE1_MASK);
880 879 }
881 880
882 881 void hk_lfr_me_update( void )
883 882 {
884 883 static hk_lfr_me_t old_hk_lfr_me = {0};
885 884 hk_lfr_me_t new_hk_lfr_me;
886 885 unsigned int counter;
887 886
888 887 counter = (((unsigned int) housekeeping_packet.hk_lfr_me_cnt[0]) * CONST_256) + housekeeping_packet.hk_lfr_me_cnt[1];
889 888
890 889 // get the current values
891 890 new_hk_lfr_me.dpu_spw_early_eop = housekeeping_packet.hk_lfr_dpu_spw_early_eop;
892 891 new_hk_lfr_me.dpu_spw_invalid_addr = housekeeping_packet.hk_lfr_dpu_spw_invalid_addr;
893 892 new_hk_lfr_me.dpu_spw_eep = housekeeping_packet.hk_lfr_dpu_spw_eep;
894 893 new_hk_lfr_me.dpu_spw_rx_too_big = housekeeping_packet.hk_lfr_dpu_spw_rx_too_big;
895 894
896 895 // update the me counter
897 896 increment_hk_counter( new_hk_lfr_me.dpu_spw_early_eop, old_hk_lfr_me.dpu_spw_early_eop, &counter );
898 897 increment_hk_counter( new_hk_lfr_me.dpu_spw_invalid_addr, old_hk_lfr_me.dpu_spw_invalid_addr, &counter );
899 898 increment_hk_counter( new_hk_lfr_me.dpu_spw_eep, old_hk_lfr_me.dpu_spw_eep, &counter );
900 899 increment_hk_counter( new_hk_lfr_me.dpu_spw_rx_too_big, old_hk_lfr_me.dpu_spw_rx_too_big, &counter );
901 900
902 901 // store the counters for the next time
903 902 old_hk_lfr_me.dpu_spw_early_eop = new_hk_lfr_me.dpu_spw_early_eop;
904 903 old_hk_lfr_me.dpu_spw_invalid_addr = new_hk_lfr_me.dpu_spw_invalid_addr;
905 904 old_hk_lfr_me.dpu_spw_eep = new_hk_lfr_me.dpu_spw_eep;
906 905 old_hk_lfr_me.dpu_spw_rx_too_big = new_hk_lfr_me.dpu_spw_rx_too_big;
907 906
908 907 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
909 908 // ME
910 909 housekeeping_packet.hk_lfr_me_cnt[0] = (unsigned char) ((counter & BYTE0_MASK) >> SHIFT_1_BYTE);
911 910 housekeeping_packet.hk_lfr_me_cnt[1] = (unsigned char) (counter & BYTE1_MASK);
912 911 }
913 912
914 913 void hk_lfr_le_me_he_update()
915 914 {
916 915
917 916 unsigned int hk_lfr_he_cnt;
918 917
919 918 hk_lfr_he_cnt = (((unsigned int) housekeeping_packet.hk_lfr_he_cnt[0]) * 256) + housekeeping_packet.hk_lfr_he_cnt[1];
920 919
921 920 //update the low severity error counter
922 921 hk_lfr_le_update( );
923 922
924 923 //update the medium severity error counter
925 924 hk_lfr_me_update();
926 925
927 926 //update the high severity error counter
928 927 hk_lfr_he_cnt = 0;
929 928
930 929 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
931 930 // HE
932 931 housekeeping_packet.hk_lfr_he_cnt[0] = (unsigned char) ((hk_lfr_he_cnt & BYTE0_MASK) >> SHIFT_1_BYTE);
933 932 housekeeping_packet.hk_lfr_he_cnt[1] = (unsigned char) (hk_lfr_he_cnt & BYTE1_MASK);
934 933
935 934 }
936 935
937 936 void set_hk_lfr_time_not_synchro()
938 937 {
939 938 static unsigned char synchroLost = 1;
940 939 int synchronizationBit;
941 940
942 941 // get the synchronization bit
943 942 synchronizationBit =
944 943 (time_management_regs->coarse_time & VAL_LFR_SYNCHRONIZED) >> BIT_SYNCHRONIZATION; // 1000 0000 0000 0000
945 944
946 945 switch (synchronizationBit)
947 946 {
948 947 case 0:
949 948 if (synchroLost == 1)
950 949 {
951 950 synchroLost = 0;
952 951 }
953 952 break;
954 953 case 1:
955 954 if (synchroLost == 0 )
956 955 {
957 956 synchroLost = 1;
958 957 increase_unsigned_char_counter(&housekeeping_packet.hk_lfr_time_not_synchro);
959 958 update_hk_lfr_last_er_fields( RID_LE_LFR_TIME, CODE_NOT_SYNCHRO );
960 959 }
961 960 break;
962 961 default:
963 962 PRINTF1("in hk_lfr_time_not_synchro *** unexpected value for synchronizationBit = %d\n", synchronizationBit);
964 963 break;
965 964 }
966 965
967 966 }
968 967
969 968 void set_hk_lfr_ahb_correctable() // CRITICITY L
970 969 {
971 970 /** This function builds the error counter hk_lfr_ahb_correctable using the statistics provided
972 971 * by the Cache Control Register (ASI 2, offset 0) and in the Register Protection Control Register (ASR16) on the
973 972 * detected errors in the cache, in the integer unit and in the floating point unit.
974 973 *
975 974 * @param void
976 975 *
977 976 * @return void
978 977 *
979 978 * All errors are summed to set the value of the hk_lfr_ahb_correctable counter.
980 979 *
981 980 */
982 981
983 982 unsigned int ahb_correctable;
984 983 unsigned int instructionErrorCounter;
985 984 unsigned int dataErrorCounter;
986 985 unsigned int fprfErrorCounter;
987 986 unsigned int iurfErrorCounter;
988 987
989 988 instructionErrorCounter = 0;
990 989 dataErrorCounter = 0;
991 990 fprfErrorCounter = 0;
992 991 iurfErrorCounter = 0;
993 992
994 993 CCR_getInstructionAndDataErrorCounters( &instructionErrorCounter, &dataErrorCounter);
995 994 ASR16_get_FPRF_IURF_ErrorCounters( &fprfErrorCounter, &iurfErrorCounter);
996 995
997 996 ahb_correctable = instructionErrorCounter
998 997 + dataErrorCounter
999 998 + fprfErrorCounter
1000 999 + iurfErrorCounter
1001 1000 + housekeeping_packet.hk_lfr_ahb_correctable;
1002 1001
1003 1002 housekeeping_packet.hk_lfr_ahb_correctable = (unsigned char) (ahb_correctable & INT8_ALL_F); // [1111 1111]
1004 1003
1005 1004 }
@@ -1,1661 +1,1659
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 __attribute__((aligned(4))) 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[BYTES_PER_TIME];
36 36 rtems_id queue_rcv_id;
37 37 rtems_id queue_snd_id;
38 38
39 39 memset(&TC, 0, sizeof(ccsdsTelecommandPacket_t));
40 40 size = 0;
41 41 queue_rcv_id = RTEMS_ID_NONE;
42 42 queue_snd_id = RTEMS_ID_NONE;
43 43
44 44 status = get_message_queue_id_recv( &queue_rcv_id );
45 45 if (status != RTEMS_SUCCESSFUL)
46 46 {
47 47 PRINTF1("in ACTN *** ERR get_message_queue_id_recv %d\n", status)
48 48 }
49 49
50 50 status = get_message_queue_id_send( &queue_snd_id );
51 51 if (status != RTEMS_SUCCESSFUL)
52 52 {
53 53 PRINTF1("in ACTN *** ERR get_message_queue_id_send %d\n", status)
54 54 }
55 55
56 56 result = LFR_SUCCESSFUL;
57 57 subtype = 0; // subtype of the current TC packet
58 58
59 59 BOOT_PRINTF("in ACTN *** \n");
60 60
61 61 while(1)
62 62 {
63 63 status = rtems_message_queue_receive( queue_rcv_id, (char*) &TC, &size,
64 64 RTEMS_WAIT, RTEMS_NO_TIMEOUT);
65 65 getTime( time ); // set time to the current time
66 66 if (status!=RTEMS_SUCCESSFUL)
67 67 {
68 68 PRINTF1("ERR *** in task ACTN *** error receiving a message, code %d \n", status)
69 69 }
70 70 else
71 71 {
72 72 subtype = TC.serviceSubType;
73 73 switch(subtype)
74 74 {
75 75 case TC_SUBTYPE_RESET:
76 76 result = action_reset( &TC, queue_snd_id, time );
77 77 close_action( &TC, result, queue_snd_id );
78 78 break;
79 79 case TC_SUBTYPE_LOAD_COMM:
80 80 result = action_load_common_par( &TC );
81 81 close_action( &TC, result, queue_snd_id );
82 82 break;
83 83 case TC_SUBTYPE_LOAD_NORM:
84 84 result = action_load_normal_par( &TC, queue_snd_id, time );
85 85 close_action( &TC, result, queue_snd_id );
86 86 break;
87 87 case TC_SUBTYPE_LOAD_BURST:
88 88 result = action_load_burst_par( &TC, queue_snd_id, time );
89 89 close_action( &TC, result, queue_snd_id );
90 90 break;
91 91 case TC_SUBTYPE_LOAD_SBM1:
92 92 result = action_load_sbm1_par( &TC, queue_snd_id, time );
93 93 close_action( &TC, result, queue_snd_id );
94 94 break;
95 95 case TC_SUBTYPE_LOAD_SBM2:
96 96 result = action_load_sbm2_par( &TC, queue_snd_id, time );
97 97 close_action( &TC, result, queue_snd_id );
98 98 break;
99 99 case TC_SUBTYPE_DUMP:
100 100 result = action_dump_par( &TC, queue_snd_id );
101 101 close_action( &TC, result, queue_snd_id );
102 102 break;
103 103 case TC_SUBTYPE_ENTER:
104 104 result = action_enter_mode( &TC, queue_snd_id );
105 105 close_action( &TC, result, queue_snd_id );
106 106 break;
107 107 case TC_SUBTYPE_UPDT_INFO:
108 108 result = action_update_info( &TC, queue_snd_id );
109 109 close_action( &TC, result, queue_snd_id );
110 110 break;
111 111 case TC_SUBTYPE_EN_CAL:
112 112 result = action_enable_calibration( &TC, queue_snd_id, time );
113 113 close_action( &TC, result, queue_snd_id );
114 114 break;
115 115 case TC_SUBTYPE_DIS_CAL:
116 116 result = action_disable_calibration( &TC, queue_snd_id, time );
117 117 close_action( &TC, result, queue_snd_id );
118 118 break;
119 119 case TC_SUBTYPE_LOAD_K:
120 120 result = action_load_kcoefficients( &TC, queue_snd_id, time );
121 121 close_action( &TC, result, queue_snd_id );
122 122 break;
123 123 case TC_SUBTYPE_DUMP_K:
124 124 result = action_dump_kcoefficients( &TC, queue_snd_id, time );
125 125 close_action( &TC, result, queue_snd_id );
126 126 break;
127 127 case TC_SUBTYPE_LOAD_FBINS:
128 128 result = action_load_fbins_mask( &TC, queue_snd_id, time );
129 129 close_action( &TC, result, queue_snd_id );
130 130 break;
131 131 case TC_SUBTYPE_LOAD_FILTER_PAR:
132 132 result = action_load_filter_par( &TC, queue_snd_id, time );
133 133 close_action( &TC, result, queue_snd_id );
134 134 break;
135 135 case TC_SUBTYPE_UPDT_TIME:
136 136 result = action_update_time( &TC );
137 137 close_action( &TC, result, queue_snd_id );
138 138 break;
139 139 default:
140 140 break;
141 141 }
142 142 }
143 143 }
144 144 }
145 145
146 146 //***********
147 147 // TC ACTIONS
148 148
149 149 int action_reset(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
150 150 {
151 151 /** This function executes specific actions when a TC_LFR_RESET TeleCommand has been received.
152 152 *
153 153 * @param TC points to the TeleCommand packet that is being processed
154 154 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
155 155 *
156 156 */
157 157
158 158 PRINTF("this is the end!!!\n");
159 159 exit(0);
160 160
161 161 send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time );
162 162
163 163 return LFR_DEFAULT;
164 164 }
165 165
166 166 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
167 167 {
168 168 /** This function executes specific actions when a TC_LFR_ENTER_MODE TeleCommand has been received.
169 169 *
170 170 * @param TC points to the TeleCommand packet that is being processed
171 171 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
172 172 *
173 173 */
174 174
175 175 rtems_status_code status;
176 176 unsigned char requestedMode;
177 177 unsigned int transitionCoarseTime;
178 178 unsigned char * bytePosPtr;
179 179
180 180 bytePosPtr = (unsigned char *) &TC->packetID;
181 181 requestedMode = bytePosPtr[ BYTE_POS_CP_MODE_LFR_SET ];
182 182 copyInt32ByChar( (char*) &transitionCoarseTime, &bytePosPtr[ BYTE_POS_CP_LFR_ENTER_MODE_TIME ] );
183 183 transitionCoarseTime = transitionCoarseTime & COARSE_TIME_MASK;
184 184 status = check_mode_value( requestedMode );
185 185
186 186 if ( status != LFR_SUCCESSFUL ) // the mode value is inconsistent
187 187 {
188 188 send_tm_lfr_tc_exe_inconsistent( TC, queue_id, BYTE_POS_CP_MODE_LFR_SET, requestedMode );
189 189 }
190 190
191 191 else // the mode value is valid, check the transition
192 192 {
193 193 status = check_mode_transition(requestedMode);
194 194 if (status != LFR_SUCCESSFUL)
195 195 {
196 196 PRINTF("ERR *** in action_enter_mode *** check_mode_transition\n")
197 197 send_tm_lfr_tc_exe_not_executable( TC, queue_id );
198 198 }
199 199 }
200 200
201 201 if ( status == LFR_SUCCESSFUL ) // the transition is valid, check the date
202 202 {
203 203 status = check_transition_date( transitionCoarseTime );
204 204 if (status != LFR_SUCCESSFUL)
205 205 {
206 206 PRINTF("ERR *** in action_enter_mode *** check_transition_date\n");
207 207 send_tm_lfr_tc_exe_not_executable(TC, queue_id );
208 208 }
209 209 }
210 210
211 211 if ( status == LFR_SUCCESSFUL ) // the date is valid, enter the mode
212 212 {
213 213 PRINTF1("OK *** in action_enter_mode *** enter mode %d\n", requestedMode);
214 214
215 215 switch(requestedMode)
216 216 {
217 217 case LFR_MODE_STANDBY:
218 218 status = enter_mode_standby();
219 219 break;
220 220 case LFR_MODE_NORMAL:
221 221 status = enter_mode_normal( transitionCoarseTime );
222 222 break;
223 223 case LFR_MODE_BURST:
224 224 status = enter_mode_burst( transitionCoarseTime );
225 225 break;
226 226 case LFR_MODE_SBM1:
227 227 status = enter_mode_sbm1( transitionCoarseTime );
228 228 break;
229 229 case LFR_MODE_SBM2:
230 230 status = enter_mode_sbm2( transitionCoarseTime );
231 231 break;
232 232 default:
233 233 break;
234 234 }
235 235
236 236 if (status != RTEMS_SUCCESSFUL)
237 237 {
238 238 status = LFR_EXE_ERROR;
239 239 }
240 240 }
241 241
242 242 return status;
243 243 }
244 244
245 245 int action_update_info(ccsdsTelecommandPacket_t *TC, rtems_id queue_id)
246 246 {
247 247 /** This function executes specific actions when a TC_LFR_UPDATE_INFO TeleCommand has been received.
248 248 *
249 249 * @param TC points to the TeleCommand packet that is being processed
250 250 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
251 251 *
252 252 * @return LFR directive status code:
253 253 * - LFR_DEFAULT
254 254 * - LFR_SUCCESSFUL
255 255 *
256 256 */
257 257
258 258 unsigned int val;
259 259 int result;
260 260 unsigned int status;
261 261 unsigned char mode;
262 262 unsigned char * bytePosPtr;
263 263
264 264 bytePosPtr = (unsigned char *) &TC->packetID;
265 265
266 266 // check LFR mode
267 267 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET5 ] & BITS_LFR_MODE) >> SHIFT_LFR_MODE;
268 268 status = check_update_info_hk_lfr_mode( mode );
269 269 if (status == LFR_SUCCESSFUL) // check TDS mode
270 270 {
271 271 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & BITS_TDS_MODE) >> SHIFT_TDS_MODE;
272 272 status = check_update_info_hk_tds_mode( mode );
273 273 }
274 274 if (status == LFR_SUCCESSFUL) // check THR mode
275 275 {
276 276 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & BITS_THR_MODE);
277 277 status = check_update_info_hk_thr_mode( mode );
278 278 }
279 279 if (status == LFR_SUCCESSFUL) // if the parameter check is successful
280 280 {
281 281 val = (housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * CONST_256)
282 282 + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
283 283 val++;
284 284 housekeeping_packet.hk_lfr_update_info_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
285 285 housekeeping_packet.hk_lfr_update_info_tc_cnt[1] = (unsigned char) (val);
286 286 }
287 287
288 288 // pa_bia_status_info
289 289 // => pa_bia_mode_mux_set 3 bits
290 290 // => pa_bia_mode_hv_enabled 1 bit
291 291 // => pa_bia_mode_bias1_enabled 1 bit
292 292 // => pa_bia_mode_bias2_enabled 1 bit
293 293 // => pa_bia_mode_bias3_enabled 1 bit
294 294 // => pa_bia_on_off (cp_dpu_bias_on_off)
295 295 pa_bia_status_info = bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET2 ] & BITS_BIA; // [1111 1110]
296 296 pa_bia_status_info = pa_bia_status_info
297 297 | (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET1 ] & 1);
298 298
299 299 // REACTION_WHEELS_FREQUENCY, copy the incoming parameters in the local variable (to be copied in HK packets)
300
301 //cp_rpw_sc_rw_f_flags = bytePosPtr[ BYTE_POS_UPDATE_INFO_CP_RPW_SC_RW_F_FLAGS ];
302 300 getReactionWheelsFrequencies( TC );
303 301 set_hk_lfr_sc_rw_f_flags();
304 302 build_sy_lfr_rw_masks();
305 303
306 304 // once the masks are built, they have to be merged with the fbins_mask
307 305 merge_fbins_masks();
308 306
309 307 result = status;
310 308
311 309 return result;
312 310 }
313 311
314 312 int action_enable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
315 313 {
316 314 /** This function executes specific actions when a TC_LFR_ENABLE_CALIBRATION TeleCommand has been received.
317 315 *
318 316 * @param TC points to the TeleCommand packet that is being processed
319 317 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
320 318 *
321 319 */
322 320
323 321 int result;
324 322
325 323 result = LFR_DEFAULT;
326 324
327 325 setCalibration( true );
328 326
329 327 result = LFR_SUCCESSFUL;
330 328
331 329 return result;
332 330 }
333 331
334 332 int action_disable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
335 333 {
336 334 /** This function executes specific actions when a TC_LFR_DISABLE_CALIBRATION TeleCommand has been received.
337 335 *
338 336 * @param TC points to the TeleCommand packet that is being processed
339 337 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
340 338 *
341 339 */
342 340
343 341 int result;
344 342
345 343 result = LFR_DEFAULT;
346 344
347 345 setCalibration( false );
348 346
349 347 result = LFR_SUCCESSFUL;
350 348
351 349 return result;
352 350 }
353 351
354 352 int action_update_time(ccsdsTelecommandPacket_t *TC)
355 353 {
356 354 /** This function executes specific actions when a TC_LFR_UPDATE_TIME TeleCommand has been received.
357 355 *
358 356 * @param TC points to the TeleCommand packet that is being processed
359 357 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
360 358 *
361 359 * @return LFR_SUCCESSFUL
362 360 *
363 361 */
364 362
365 363 unsigned int val;
366 364
367 365 time_management_regs->coarse_time_load = (TC->dataAndCRC[BYTE_0] << SHIFT_3_BYTES)
368 366 + (TC->dataAndCRC[BYTE_1] << SHIFT_2_BYTES)
369 367 + (TC->dataAndCRC[BYTE_2] << SHIFT_1_BYTE)
370 368 + TC->dataAndCRC[BYTE_3];
371 369
372 370 val = (housekeeping_packet.hk_lfr_update_time_tc_cnt[0] * CONST_256)
373 371 + housekeeping_packet.hk_lfr_update_time_tc_cnt[1];
374 372 val++;
375 373 housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
376 374 housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char) (val);
377 375
378 376 oneTcLfrUpdateTimeReceived = 1;
379 377
380 378 return LFR_SUCCESSFUL;
381 379 }
382 380
383 381 //*******************
384 382 // ENTERING THE MODES
385 383 int check_mode_value( unsigned char requestedMode )
386 384 {
387 385 int status;
388 386
389 387 status = LFR_DEFAULT;
390 388
391 389 if ( (requestedMode != LFR_MODE_STANDBY)
392 390 && (requestedMode != LFR_MODE_NORMAL) && (requestedMode != LFR_MODE_BURST)
393 391 && (requestedMode != LFR_MODE_SBM1) && (requestedMode != LFR_MODE_SBM2) )
394 392 {
395 393 status = LFR_DEFAULT;
396 394 }
397 395 else
398 396 {
399 397 status = LFR_SUCCESSFUL;
400 398 }
401 399
402 400 return status;
403 401 }
404 402
405 403 int check_mode_transition( unsigned char requestedMode )
406 404 {
407 405 /** This function checks the validity of the transition requested by the TC_LFR_ENTER_MODE.
408 406 *
409 407 * @param requestedMode is the mode requested by the TC_LFR_ENTER_MODE
410 408 *
411 409 * @return LFR directive status codes:
412 410 * - LFR_SUCCESSFUL - the transition is authorized
413 411 * - LFR_DEFAULT - the transition is not authorized
414 412 *
415 413 */
416 414
417 415 int status;
418 416
419 417 switch (requestedMode)
420 418 {
421 419 case LFR_MODE_STANDBY:
422 420 if ( lfrCurrentMode == LFR_MODE_STANDBY ) {
423 421 status = LFR_DEFAULT;
424 422 }
425 423 else
426 424 {
427 425 status = LFR_SUCCESSFUL;
428 426 }
429 427 break;
430 428 case LFR_MODE_NORMAL:
431 429 if ( lfrCurrentMode == LFR_MODE_NORMAL ) {
432 430 status = LFR_DEFAULT;
433 431 }
434 432 else {
435 433 status = LFR_SUCCESSFUL;
436 434 }
437 435 break;
438 436 case LFR_MODE_BURST:
439 437 if ( lfrCurrentMode == LFR_MODE_BURST ) {
440 438 status = LFR_DEFAULT;
441 439 }
442 440 else {
443 441 status = LFR_SUCCESSFUL;
444 442 }
445 443 break;
446 444 case LFR_MODE_SBM1:
447 445 if ( lfrCurrentMode == LFR_MODE_SBM1 ) {
448 446 status = LFR_DEFAULT;
449 447 }
450 448 else {
451 449 status = LFR_SUCCESSFUL;
452 450 }
453 451 break;
454 452 case LFR_MODE_SBM2:
455 453 if ( lfrCurrentMode == LFR_MODE_SBM2 ) {
456 454 status = LFR_DEFAULT;
457 455 }
458 456 else {
459 457 status = LFR_SUCCESSFUL;
460 458 }
461 459 break;
462 460 default:
463 461 status = LFR_DEFAULT;
464 462 break;
465 463 }
466 464
467 465 return status;
468 466 }
469 467
470 468 void update_last_valid_transition_date( unsigned int transitionCoarseTime )
471 469 {
472 470 if (transitionCoarseTime == 0)
473 471 {
474 472 lastValidEnterModeTime = time_management_regs->coarse_time + 1;
475 473 PRINTF1("lastValidEnterModeTime = 0x%x (transitionCoarseTime = 0 => coarse_time+1)\n", lastValidEnterModeTime);
476 474 }
477 475 else
478 476 {
479 477 lastValidEnterModeTime = transitionCoarseTime;
480 478 PRINTF1("lastValidEnterModeTime = 0x%x\n", transitionCoarseTime);
481 479 }
482 480 }
483 481
484 482 int check_transition_date( unsigned int transitionCoarseTime )
485 483 {
486 484 int status;
487 485 unsigned int localCoarseTime;
488 486 unsigned int deltaCoarseTime;
489 487
490 488 status = LFR_SUCCESSFUL;
491 489
492 490 if (transitionCoarseTime == 0) // transition time = 0 means an instant transition
493 491 {
494 492 status = LFR_SUCCESSFUL;
495 493 }
496 494 else
497 495 {
498 496 localCoarseTime = time_management_regs->coarse_time & COARSE_TIME_MASK;
499 497
500 498 PRINTF2("localTime = %x, transitionTime = %x\n", localCoarseTime, transitionCoarseTime);
501 499
502 500 if ( transitionCoarseTime <= localCoarseTime ) // SSS-CP-EQS-322
503 501 {
504 502 status = LFR_DEFAULT;
505 503 PRINTF("ERR *** in check_transition_date *** transitionCoarseTime <= localCoarseTime\n");
506 504 }
507 505
508 506 if (status == LFR_SUCCESSFUL)
509 507 {
510 508 deltaCoarseTime = transitionCoarseTime - localCoarseTime;
511 509 if ( deltaCoarseTime > MAX_DELTA_COARSE_TIME ) // SSS-CP-EQS-323
512 510 {
513 511 status = LFR_DEFAULT;
514 512 PRINTF1("ERR *** in check_transition_date *** deltaCoarseTime = %x\n", deltaCoarseTime)
515 513 }
516 514 }
517 515 }
518 516
519 517 return status;
520 518 }
521 519
522 520 int restart_asm_activities( unsigned char lfrRequestedMode )
523 521 {
524 522 rtems_status_code status;
525 523
526 524 status = stop_spectral_matrices();
527 525
528 526 thisIsAnASMRestart = 1;
529 527
530 528 status = restart_asm_tasks( lfrRequestedMode );
531 529
532 530 launch_spectral_matrix();
533 531
534 532 return status;
535 533 }
536 534
537 535 int stop_spectral_matrices( void )
538 536 {
539 537 /** This function stops and restarts the current mode average spectral matrices activities.
540 538 *
541 539 * @return RTEMS directive status codes:
542 540 * - RTEMS_SUCCESSFUL - task restarted successfully
543 541 * - RTEMS_INVALID_ID - task id invalid
544 542 * - RTEMS_ALREADY_SUSPENDED - task already suspended
545 543 *
546 544 */
547 545
548 546 rtems_status_code status;
549 547
550 548 status = RTEMS_SUCCESSFUL;
551 549
552 550 // (1) mask interruptions
553 551 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // mask spectral matrix interrupt
554 552
555 553 // (2) reset spectral matrices registers
556 554 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
557 555 reset_sm_status();
558 556
559 557 // (3) clear interruptions
560 558 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
561 559
562 560 // suspend several tasks
563 561 if (lfrCurrentMode != LFR_MODE_STANDBY) {
564 562 status = suspend_asm_tasks();
565 563 }
566 564
567 565 if (status != RTEMS_SUCCESSFUL)
568 566 {
569 567 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
570 568 }
571 569
572 570 return status;
573 571 }
574 572
575 573 int stop_current_mode( void )
576 574 {
577 575 /** This function stops the current mode by masking interrupt lines and suspending science tasks.
578 576 *
579 577 * @return RTEMS directive status codes:
580 578 * - RTEMS_SUCCESSFUL - task restarted successfully
581 579 * - RTEMS_INVALID_ID - task id invalid
582 580 * - RTEMS_ALREADY_SUSPENDED - task already suspended
583 581 *
584 582 */
585 583
586 584 rtems_status_code status;
587 585
588 586 status = RTEMS_SUCCESSFUL;
589 587
590 588 // (1) mask interruptions
591 589 LEON_Mask_interrupt( IRQ_WAVEFORM_PICKER ); // mask waveform picker interrupt
592 590 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
593 591
594 592 // (2) reset waveform picker registers
595 593 reset_wfp_burst_enable(); // reset burst and enable bits
596 594 reset_wfp_status(); // reset all the status bits
597 595
598 596 // (3) reset spectral matrices registers
599 597 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
600 598 reset_sm_status();
601 599
602 600 // reset lfr VHDL module
603 601 reset_lfr();
604 602
605 603 reset_extractSWF(); // reset the extractSWF flag to false
606 604
607 605 // (4) clear interruptions
608 606 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER ); // clear waveform picker interrupt
609 607 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
610 608
611 609 // suspend several tasks
612 610 if (lfrCurrentMode != LFR_MODE_STANDBY) {
613 611 status = suspend_science_tasks();
614 612 }
615 613
616 614 if (status != RTEMS_SUCCESSFUL)
617 615 {
618 616 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
619 617 }
620 618
621 619 return status;
622 620 }
623 621
624 622 int enter_mode_standby( void )
625 623 {
626 624 /** This function is used to put LFR in the STANDBY mode.
627 625 *
628 626 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
629 627 *
630 628 * @return RTEMS directive status codes:
631 629 * - RTEMS_SUCCESSFUL - task restarted successfully
632 630 * - RTEMS_INVALID_ID - task id invalid
633 631 * - RTEMS_INCORRECT_STATE - task never started
634 632 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
635 633 *
636 634 * The STANDBY mode does not depends on a specific transition date, the effect of the TC_LFR_ENTER_MODE
637 635 * is immediate.
638 636 *
639 637 */
640 638
641 639 int status;
642 640
643 641 status = stop_current_mode(); // STOP THE CURRENT MODE
644 642
645 643 #ifdef PRINT_TASK_STATISTICS
646 644 rtems_cpu_usage_report();
647 645 #endif
648 646
649 647 #ifdef PRINT_STACK_REPORT
650 648 PRINTF("stack report selected\n")
651 649 rtems_stack_checker_report_usage();
652 650 #endif
653 651
654 652 return status;
655 653 }
656 654
657 655 int enter_mode_normal( unsigned int transitionCoarseTime )
658 656 {
659 657 /** This function is used to start the NORMAL mode.
660 658 *
661 659 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
662 660 *
663 661 * @return RTEMS directive status codes:
664 662 * - RTEMS_SUCCESSFUL - task restarted successfully
665 663 * - RTEMS_INVALID_ID - task id invalid
666 664 * - RTEMS_INCORRECT_STATE - task never started
667 665 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
668 666 *
669 667 * The way the NORMAL mode is started depends on the LFR current mode. If LFR is in SBM1 or SBM2,
670 668 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected.
671 669 *
672 670 */
673 671
674 672 int status;
675 673
676 674 #ifdef PRINT_TASK_STATISTICS
677 675 rtems_cpu_usage_reset();
678 676 #endif
679 677
680 678 status = RTEMS_UNSATISFIED;
681 679
682 680 switch( lfrCurrentMode )
683 681 {
684 682 case LFR_MODE_STANDBY:
685 683 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart science tasks
686 684 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
687 685 {
688 686 launch_spectral_matrix( );
689 687 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
690 688 }
691 689 break;
692 690 case LFR_MODE_BURST:
693 691 status = stop_current_mode(); // stop the current mode
694 692 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart the science tasks
695 693 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
696 694 {
697 695 launch_spectral_matrix( );
698 696 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
699 697 }
700 698 break;
701 699 case LFR_MODE_SBM1:
702 700 status = restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
703 701 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
704 702 update_last_valid_transition_date( transitionCoarseTime );
705 703 break;
706 704 case LFR_MODE_SBM2:
707 705 status = restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
708 706 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
709 707 update_last_valid_transition_date( transitionCoarseTime );
710 708 break;
711 709 default:
712 710 break;
713 711 }
714 712
715 713 if (status != RTEMS_SUCCESSFUL)
716 714 {
717 715 PRINTF1("ERR *** in enter_mode_normal *** status = %d\n", status)
718 716 status = RTEMS_UNSATISFIED;
719 717 }
720 718
721 719 return status;
722 720 }
723 721
724 722 int enter_mode_burst( unsigned int transitionCoarseTime )
725 723 {
726 724 /** This function is used to start the BURST mode.
727 725 *
728 726 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
729 727 *
730 728 * @return RTEMS directive status codes:
731 729 * - RTEMS_SUCCESSFUL - task restarted successfully
732 730 * - RTEMS_INVALID_ID - task id invalid
733 731 * - RTEMS_INCORRECT_STATE - task never started
734 732 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
735 733 *
736 734 * The way the BURST mode is started does not depend on the LFR current mode.
737 735 *
738 736 */
739 737
740 738
741 739 int status;
742 740
743 741 #ifdef PRINT_TASK_STATISTICS
744 742 rtems_cpu_usage_reset();
745 743 #endif
746 744
747 745 status = stop_current_mode(); // stop the current mode
748 746 status = restart_science_tasks( LFR_MODE_BURST ); // restart the science tasks
749 747 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
750 748 {
751 749 launch_spectral_matrix( );
752 750 launch_waveform_picker( LFR_MODE_BURST, transitionCoarseTime );
753 751 }
754 752
755 753 if (status != RTEMS_SUCCESSFUL)
756 754 {
757 755 PRINTF1("ERR *** in enter_mode_burst *** status = %d\n", status)
758 756 status = RTEMS_UNSATISFIED;
759 757 }
760 758
761 759 return status;
762 760 }
763 761
764 762 int enter_mode_sbm1( unsigned int transitionCoarseTime )
765 763 {
766 764 /** This function is used to start the SBM1 mode.
767 765 *
768 766 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
769 767 *
770 768 * @return RTEMS directive status codes:
771 769 * - RTEMS_SUCCESSFUL - task restarted successfully
772 770 * - RTEMS_INVALID_ID - task id invalid
773 771 * - RTEMS_INCORRECT_STATE - task never started
774 772 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
775 773 *
776 774 * The way the SBM1 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM2,
777 775 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
778 776 * cases, the acquisition is completely restarted.
779 777 *
780 778 */
781 779
782 780 int status;
783 781
784 782 #ifdef PRINT_TASK_STATISTICS
785 783 rtems_cpu_usage_reset();
786 784 #endif
787 785
788 786 status = RTEMS_UNSATISFIED;
789 787
790 788 switch( lfrCurrentMode )
791 789 {
792 790 case LFR_MODE_STANDBY:
793 791 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart science tasks
794 792 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
795 793 {
796 794 launch_spectral_matrix( );
797 795 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
798 796 }
799 797 break;
800 798 case LFR_MODE_NORMAL: // lfrCurrentMode will be updated after the execution of close_action
801 799 status = restart_asm_activities( LFR_MODE_SBM1 );
802 800 status = LFR_SUCCESSFUL;
803 801 update_last_valid_transition_date( transitionCoarseTime );
804 802 break;
805 803 case LFR_MODE_BURST:
806 804 status = stop_current_mode(); // stop the current mode
807 805 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart the science tasks
808 806 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
809 807 {
810 808 launch_spectral_matrix( );
811 809 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
812 810 }
813 811 break;
814 812 case LFR_MODE_SBM2:
815 813 status = restart_asm_activities( LFR_MODE_SBM1 );
816 814 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
817 815 update_last_valid_transition_date( transitionCoarseTime );
818 816 break;
819 817 default:
820 818 break;
821 819 }
822 820
823 821 if (status != RTEMS_SUCCESSFUL)
824 822 {
825 823 PRINTF1("ERR *** in enter_mode_sbm1 *** status = %d\n", status);
826 824 status = RTEMS_UNSATISFIED;
827 825 }
828 826
829 827 return status;
830 828 }
831 829
832 830 int enter_mode_sbm2( unsigned int transitionCoarseTime )
833 831 {
834 832 /** This function is used to start the SBM2 mode.
835 833 *
836 834 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
837 835 *
838 836 * @return RTEMS directive status codes:
839 837 * - RTEMS_SUCCESSFUL - task restarted successfully
840 838 * - RTEMS_INVALID_ID - task id invalid
841 839 * - RTEMS_INCORRECT_STATE - task never started
842 840 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
843 841 *
844 842 * The way the SBM2 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM1,
845 843 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
846 844 * cases, the acquisition is completely restarted.
847 845 *
848 846 */
849 847
850 848 int status;
851 849
852 850 #ifdef PRINT_TASK_STATISTICS
853 851 rtems_cpu_usage_reset();
854 852 #endif
855 853
856 854 status = RTEMS_UNSATISFIED;
857 855
858 856 switch( lfrCurrentMode )
859 857 {
860 858 case LFR_MODE_STANDBY:
861 859 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart science tasks
862 860 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
863 861 {
864 862 launch_spectral_matrix( );
865 863 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
866 864 }
867 865 break;
868 866 case LFR_MODE_NORMAL:
869 867 status = restart_asm_activities( LFR_MODE_SBM2 );
870 868 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
871 869 update_last_valid_transition_date( transitionCoarseTime );
872 870 break;
873 871 case LFR_MODE_BURST:
874 872 status = stop_current_mode(); // stop the current mode
875 873 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart the science tasks
876 874 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
877 875 {
878 876 launch_spectral_matrix( );
879 877 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
880 878 }
881 879 break;
882 880 case LFR_MODE_SBM1:
883 881 status = restart_asm_activities( LFR_MODE_SBM2 );
884 882 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
885 883 update_last_valid_transition_date( transitionCoarseTime );
886 884 break;
887 885 default:
888 886 break;
889 887 }
890 888
891 889 if (status != RTEMS_SUCCESSFUL)
892 890 {
893 891 PRINTF1("ERR *** in enter_mode_sbm2 *** status = %d\n", status)
894 892 status = RTEMS_UNSATISFIED;
895 893 }
896 894
897 895 return status;
898 896 }
899 897
900 898 int restart_science_tasks( unsigned char lfrRequestedMode )
901 899 {
902 900 /** This function is used to restart all science tasks.
903 901 *
904 902 * @return RTEMS directive status codes:
905 903 * - RTEMS_SUCCESSFUL - task restarted successfully
906 904 * - RTEMS_INVALID_ID - task id invalid
907 905 * - RTEMS_INCORRECT_STATE - task never started
908 906 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
909 907 *
910 908 * Science tasks are AVF0, PRC0, WFRM, CWF3, CW2, CWF1
911 909 *
912 910 */
913 911
914 912 rtems_status_code status[NB_SCIENCE_TASKS];
915 913 rtems_status_code ret;
916 914
917 915 ret = RTEMS_SUCCESSFUL;
918 916
919 917 status[STATUS_0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
920 918 if (status[STATUS_0] != RTEMS_SUCCESSFUL)
921 919 {
922 920 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[STATUS_0])
923 921 }
924 922
925 923 status[STATUS_1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
926 924 if (status[STATUS_1] != RTEMS_SUCCESSFUL)
927 925 {
928 926 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[STATUS_1])
929 927 }
930 928
931 929 status[STATUS_2] = rtems_task_restart( Task_id[TASKID_WFRM],1 );
932 930 if (status[STATUS_2] != RTEMS_SUCCESSFUL)
933 931 {
934 932 PRINTF1("in restart_science_task *** WFRM ERR %d\n", status[STATUS_2])
935 933 }
936 934
937 935 status[STATUS_3] = rtems_task_restart( Task_id[TASKID_CWF3],1 );
938 936 if (status[STATUS_3] != RTEMS_SUCCESSFUL)
939 937 {
940 938 PRINTF1("in restart_science_task *** CWF3 ERR %d\n", status[STATUS_3])
941 939 }
942 940
943 941 status[STATUS_4] = rtems_task_restart( Task_id[TASKID_CWF2],1 );
944 942 if (status[STATUS_4] != RTEMS_SUCCESSFUL)
945 943 {
946 944 PRINTF1("in restart_science_task *** CWF2 ERR %d\n", status[STATUS_4])
947 945 }
948 946
949 947 status[STATUS_5] = rtems_task_restart( Task_id[TASKID_CWF1],1 );
950 948 if (status[STATUS_5] != RTEMS_SUCCESSFUL)
951 949 {
952 950 PRINTF1("in restart_science_task *** CWF1 ERR %d\n", status[STATUS_5])
953 951 }
954 952
955 953 status[STATUS_6] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
956 954 if (status[STATUS_6] != RTEMS_SUCCESSFUL)
957 955 {
958 956 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[STATUS_6])
959 957 }
960 958
961 959 status[STATUS_7] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
962 960 if (status[STATUS_7] != RTEMS_SUCCESSFUL)
963 961 {
964 962 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[STATUS_7])
965 963 }
966 964
967 965 status[STATUS_8] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
968 966 if (status[STATUS_8] != RTEMS_SUCCESSFUL)
969 967 {
970 968 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[STATUS_8])
971 969 }
972 970
973 971 status[STATUS_9] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
974 972 if (status[STATUS_9] != RTEMS_SUCCESSFUL)
975 973 {
976 974 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[STATUS_9])
977 975 }
978 976
979 977 if ( (status[STATUS_0] != RTEMS_SUCCESSFUL) || (status[STATUS_1] != RTEMS_SUCCESSFUL) ||
980 978 (status[STATUS_2] != RTEMS_SUCCESSFUL) || (status[STATUS_3] != RTEMS_SUCCESSFUL) ||
981 979 (status[STATUS_4] != RTEMS_SUCCESSFUL) || (status[STATUS_5] != RTEMS_SUCCESSFUL) ||
982 980 (status[STATUS_6] != RTEMS_SUCCESSFUL) || (status[STATUS_7] != RTEMS_SUCCESSFUL) ||
983 981 (status[STATUS_8] != RTEMS_SUCCESSFUL) || (status[STATUS_9] != RTEMS_SUCCESSFUL) )
984 982 {
985 983 ret = RTEMS_UNSATISFIED;
986 984 }
987 985
988 986 return ret;
989 987 }
990 988
991 989 int restart_asm_tasks( unsigned char lfrRequestedMode )
992 990 {
993 991 /** This function is used to restart average spectral matrices tasks.
994 992 *
995 993 * @return RTEMS directive status codes:
996 994 * - RTEMS_SUCCESSFUL - task restarted successfully
997 995 * - RTEMS_INVALID_ID - task id invalid
998 996 * - RTEMS_INCORRECT_STATE - task never started
999 997 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
1000 998 *
1001 999 * ASM tasks are AVF0, PRC0, AVF1, PRC1, AVF2 and PRC2
1002 1000 *
1003 1001 */
1004 1002
1005 1003 rtems_status_code status[NB_ASM_TASKS];
1006 1004 rtems_status_code ret;
1007 1005
1008 1006 ret = RTEMS_SUCCESSFUL;
1009 1007
1010 1008 status[STATUS_0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
1011 1009 if (status[STATUS_0] != RTEMS_SUCCESSFUL)
1012 1010 {
1013 1011 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[STATUS_0])
1014 1012 }
1015 1013
1016 1014 status[STATUS_1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
1017 1015 if (status[STATUS_1] != RTEMS_SUCCESSFUL)
1018 1016 {
1019 1017 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[STATUS_1])
1020 1018 }
1021 1019
1022 1020 status[STATUS_2] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
1023 1021 if (status[STATUS_2] != RTEMS_SUCCESSFUL)
1024 1022 {
1025 1023 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[STATUS_2])
1026 1024 }
1027 1025
1028 1026 status[STATUS_3] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
1029 1027 if (status[STATUS_3] != RTEMS_SUCCESSFUL)
1030 1028 {
1031 1029 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[STATUS_3])
1032 1030 }
1033 1031
1034 1032 status[STATUS_4] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
1035 1033 if (status[STATUS_4] != RTEMS_SUCCESSFUL)
1036 1034 {
1037 1035 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[STATUS_4])
1038 1036 }
1039 1037
1040 1038 status[STATUS_5] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
1041 1039 if (status[STATUS_5] != RTEMS_SUCCESSFUL)
1042 1040 {
1043 1041 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[STATUS_5])
1044 1042 }
1045 1043
1046 1044 if ( (status[STATUS_0] != RTEMS_SUCCESSFUL) || (status[STATUS_1] != RTEMS_SUCCESSFUL) ||
1047 1045 (status[STATUS_2] != RTEMS_SUCCESSFUL) || (status[STATUS_3] != RTEMS_SUCCESSFUL) ||
1048 1046 (status[STATUS_4] != RTEMS_SUCCESSFUL) || (status[STATUS_5] != RTEMS_SUCCESSFUL) )
1049 1047 {
1050 1048 ret = RTEMS_UNSATISFIED;
1051 1049 }
1052 1050
1053 1051 return ret;
1054 1052 }
1055 1053
1056 1054 int suspend_science_tasks( void )
1057 1055 {
1058 1056 /** This function suspends the science tasks.
1059 1057 *
1060 1058 * @return RTEMS directive status codes:
1061 1059 * - RTEMS_SUCCESSFUL - task restarted successfully
1062 1060 * - RTEMS_INVALID_ID - task id invalid
1063 1061 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1064 1062 *
1065 1063 */
1066 1064
1067 1065 rtems_status_code status;
1068 1066
1069 1067 PRINTF("in suspend_science_tasks\n")
1070 1068
1071 1069 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1072 1070 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1073 1071 {
1074 1072 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1075 1073 }
1076 1074 else
1077 1075 {
1078 1076 status = RTEMS_SUCCESSFUL;
1079 1077 }
1080 1078 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1081 1079 {
1082 1080 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1083 1081 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1084 1082 {
1085 1083 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1086 1084 }
1087 1085 else
1088 1086 {
1089 1087 status = RTEMS_SUCCESSFUL;
1090 1088 }
1091 1089 }
1092 1090 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1093 1091 {
1094 1092 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1095 1093 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1096 1094 {
1097 1095 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1098 1096 }
1099 1097 else
1100 1098 {
1101 1099 status = RTEMS_SUCCESSFUL;
1102 1100 }
1103 1101 }
1104 1102 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1105 1103 {
1106 1104 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1107 1105 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1108 1106 {
1109 1107 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1110 1108 }
1111 1109 else
1112 1110 {
1113 1111 status = RTEMS_SUCCESSFUL;
1114 1112 }
1115 1113 }
1116 1114 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1117 1115 {
1118 1116 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1119 1117 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1120 1118 {
1121 1119 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1122 1120 }
1123 1121 else
1124 1122 {
1125 1123 status = RTEMS_SUCCESSFUL;
1126 1124 }
1127 1125 }
1128 1126 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1129 1127 {
1130 1128 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1131 1129 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1132 1130 {
1133 1131 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1134 1132 }
1135 1133 else
1136 1134 {
1137 1135 status = RTEMS_SUCCESSFUL;
1138 1136 }
1139 1137 }
1140 1138 if (status == RTEMS_SUCCESSFUL) // suspend WFRM
1141 1139 {
1142 1140 status = rtems_task_suspend( Task_id[TASKID_WFRM] );
1143 1141 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1144 1142 {
1145 1143 PRINTF1("in suspend_science_task *** WFRM ERR %d\n", status)
1146 1144 }
1147 1145 else
1148 1146 {
1149 1147 status = RTEMS_SUCCESSFUL;
1150 1148 }
1151 1149 }
1152 1150 if (status == RTEMS_SUCCESSFUL) // suspend CWF3
1153 1151 {
1154 1152 status = rtems_task_suspend( Task_id[TASKID_CWF3] );
1155 1153 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1156 1154 {
1157 1155 PRINTF1("in suspend_science_task *** CWF3 ERR %d\n", status)
1158 1156 }
1159 1157 else
1160 1158 {
1161 1159 status = RTEMS_SUCCESSFUL;
1162 1160 }
1163 1161 }
1164 1162 if (status == RTEMS_SUCCESSFUL) // suspend CWF2
1165 1163 {
1166 1164 status = rtems_task_suspend( Task_id[TASKID_CWF2] );
1167 1165 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1168 1166 {
1169 1167 PRINTF1("in suspend_science_task *** CWF2 ERR %d\n", status)
1170 1168 }
1171 1169 else
1172 1170 {
1173 1171 status = RTEMS_SUCCESSFUL;
1174 1172 }
1175 1173 }
1176 1174 if (status == RTEMS_SUCCESSFUL) // suspend CWF1
1177 1175 {
1178 1176 status = rtems_task_suspend( Task_id[TASKID_CWF1] );
1179 1177 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1180 1178 {
1181 1179 PRINTF1("in suspend_science_task *** CWF1 ERR %d\n", status)
1182 1180 }
1183 1181 else
1184 1182 {
1185 1183 status = RTEMS_SUCCESSFUL;
1186 1184 }
1187 1185 }
1188 1186
1189 1187 return status;
1190 1188 }
1191 1189
1192 1190 int suspend_asm_tasks( void )
1193 1191 {
1194 1192 /** This function suspends the science tasks.
1195 1193 *
1196 1194 * @return RTEMS directive status codes:
1197 1195 * - RTEMS_SUCCESSFUL - task restarted successfully
1198 1196 * - RTEMS_INVALID_ID - task id invalid
1199 1197 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1200 1198 *
1201 1199 */
1202 1200
1203 1201 rtems_status_code status;
1204 1202
1205 1203 PRINTF("in suspend_science_tasks\n")
1206 1204
1207 1205 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1208 1206 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1209 1207 {
1210 1208 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1211 1209 }
1212 1210 else
1213 1211 {
1214 1212 status = RTEMS_SUCCESSFUL;
1215 1213 }
1216 1214
1217 1215 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1218 1216 {
1219 1217 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1220 1218 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1221 1219 {
1222 1220 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1223 1221 }
1224 1222 else
1225 1223 {
1226 1224 status = RTEMS_SUCCESSFUL;
1227 1225 }
1228 1226 }
1229 1227
1230 1228 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1231 1229 {
1232 1230 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1233 1231 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1234 1232 {
1235 1233 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1236 1234 }
1237 1235 else
1238 1236 {
1239 1237 status = RTEMS_SUCCESSFUL;
1240 1238 }
1241 1239 }
1242 1240
1243 1241 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1244 1242 {
1245 1243 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1246 1244 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1247 1245 {
1248 1246 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1249 1247 }
1250 1248 else
1251 1249 {
1252 1250 status = RTEMS_SUCCESSFUL;
1253 1251 }
1254 1252 }
1255 1253
1256 1254 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1257 1255 {
1258 1256 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1259 1257 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1260 1258 {
1261 1259 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1262 1260 }
1263 1261 else
1264 1262 {
1265 1263 status = RTEMS_SUCCESSFUL;
1266 1264 }
1267 1265 }
1268 1266
1269 1267 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1270 1268 {
1271 1269 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1272 1270 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1273 1271 {
1274 1272 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1275 1273 }
1276 1274 else
1277 1275 {
1278 1276 status = RTEMS_SUCCESSFUL;
1279 1277 }
1280 1278 }
1281 1279
1282 1280 return status;
1283 1281 }
1284 1282
1285 1283 void launch_waveform_picker( unsigned char mode, unsigned int transitionCoarseTime )
1286 1284 {
1287 1285
1288 1286 WFP_reset_current_ring_nodes();
1289 1287
1290 1288 reset_waveform_picker_regs();
1291 1289
1292 1290 set_wfp_burst_enable_register( mode );
1293 1291
1294 1292 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER );
1295 1293 LEON_Unmask_interrupt( IRQ_WAVEFORM_PICKER );
1296 1294
1297 1295 if (transitionCoarseTime == 0)
1298 1296 {
1299 1297 // instant transition means transition on the next valid date
1300 1298 // this is mandatory to have a good snapshot period and a good correction of the snapshot period
1301 1299 waveform_picker_regs->start_date = time_management_regs->coarse_time + 1;
1302 1300 }
1303 1301 else
1304 1302 {
1305 1303 waveform_picker_regs->start_date = transitionCoarseTime;
1306 1304 }
1307 1305
1308 1306 update_last_valid_transition_date(waveform_picker_regs->start_date);
1309 1307
1310 1308 }
1311 1309
1312 1310 void launch_spectral_matrix( void )
1313 1311 {
1314 1312 SM_reset_current_ring_nodes();
1315 1313
1316 1314 reset_spectral_matrix_regs();
1317 1315
1318 1316 reset_nb_sm();
1319 1317
1320 1318 set_sm_irq_onNewMatrix( 1 );
1321 1319
1322 1320 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX );
1323 1321 LEON_Unmask_interrupt( IRQ_SPECTRAL_MATRIX );
1324 1322
1325 1323 }
1326 1324
1327 1325 void set_sm_irq_onNewMatrix( unsigned char value )
1328 1326 {
1329 1327 if (value == 1)
1330 1328 {
1331 1329 spectral_matrix_regs->config = spectral_matrix_regs->config | BIT_IRQ_ON_NEW_MATRIX;
1332 1330 }
1333 1331 else
1334 1332 {
1335 1333 spectral_matrix_regs->config = spectral_matrix_regs->config & MASK_IRQ_ON_NEW_MATRIX; // 1110
1336 1334 }
1337 1335 }
1338 1336
1339 1337 void set_sm_irq_onError( unsigned char value )
1340 1338 {
1341 1339 if (value == 1)
1342 1340 {
1343 1341 spectral_matrix_regs->config = spectral_matrix_regs->config | BIT_IRQ_ON_ERROR;
1344 1342 }
1345 1343 else
1346 1344 {
1347 1345 spectral_matrix_regs->config = spectral_matrix_regs->config & MASK_IRQ_ON_ERROR; // 1101
1348 1346 }
1349 1347 }
1350 1348
1351 1349 //*****************************
1352 1350 // CONFIGURE CALIBRATION SIGNAL
1353 1351 void setCalibrationPrescaler( unsigned int prescaler )
1354 1352 {
1355 1353 // prescaling of the master clock (25 MHz)
1356 1354 // master clock is divided by 2^prescaler
1357 1355 time_management_regs->calPrescaler = prescaler;
1358 1356 }
1359 1357
1360 1358 void setCalibrationDivisor( unsigned int divisionFactor )
1361 1359 {
1362 1360 // division of the prescaled clock by the division factor
1363 1361 time_management_regs->calDivisor = divisionFactor;
1364 1362 }
1365 1363
1366 1364 void setCalibrationData( void )
1367 1365 {
1368 1366 /** This function is used to store the values used to drive the DAC in order to generate the SCM calibration signal
1369 1367 *
1370 1368 * @param void
1371 1369 *
1372 1370 * @return void
1373 1371 *
1374 1372 */
1375 1373
1376 1374 unsigned int k;
1377 1375 unsigned short data;
1378 1376 float val;
1379 1377 float Ts;
1380 1378
1381 1379 time_management_regs->calDataPtr = INIT_CHAR;
1382 1380
1383 1381 Ts = 1 / CAL_FS;
1384 1382
1385 1383 // build the signal for the SCM calibration
1386 1384 for (k = 0; k < CAL_NB_PTS; k++)
1387 1385 {
1388 1386 val = CAL_A0 * sin( CAL_W0 * k * Ts )
1389 1387 + CAL_A1 * sin( CAL_W1 * k * Ts );
1390 1388 data = (unsigned short) ((val * CAL_SCALE_FACTOR) + CONST_2048);
1391 1389 time_management_regs->calData = data & CAL_DATA_MASK;
1392 1390 }
1393 1391 }
1394 1392
1395 1393 void setCalibrationDataInterleaved( void )
1396 1394 {
1397 1395 /** This function is used to store the values used to drive the DAC in order to generate the SCM calibration signal
1398 1396 *
1399 1397 * @param void
1400 1398 *
1401 1399 * @return void
1402 1400 *
1403 1401 * In interleaved mode, one can store more values than in normal mode.
1404 1402 * The data are stored in bunch of 18 bits, 12 bits from one sample and 6 bits from another sample.
1405 1403 * T store 3 values, one need two write operations.
1406 1404 * s1 [ b11 b10 b9 b8 b7 b6 ] s0 [ b11 b10 b9 b8 b7 b6 b5 b3 b2 b1 b0 ]
1407 1405 * s1 [ b5 b4 b3 b2 b1 b0 ] s2 [ b11 b10 b9 b8 b7 b6 b5 b3 b2 b1 b0 ]
1408 1406 *
1409 1407 */
1410 1408
1411 1409 unsigned int k;
1412 1410 float val;
1413 1411 float Ts;
1414 1412 unsigned short data[CAL_NB_PTS_INTER];
1415 1413 unsigned char *dataPtr;
1416 1414
1417 1415 Ts = 1 / CAL_FS_INTER;
1418 1416
1419 1417 time_management_regs->calDataPtr = INIT_CHAR;
1420 1418
1421 1419 // build the signal for the SCM calibration
1422 1420 for (k=0; k<CAL_NB_PTS_INTER; k++)
1423 1421 {
1424 1422 val = sin( 2 * pi * CAL_F0 * k * Ts )
1425 1423 + sin( 2 * pi * CAL_F1 * k * Ts );
1426 1424 data[k] = (unsigned short) ((val * CONST_512) + CONST_2048);
1427 1425 }
1428 1426
1429 1427 // write the signal in interleaved mode
1430 1428 for (k=0; k < STEPS_FOR_STORAGE_INTER; k++)
1431 1429 {
1432 1430 dataPtr = (unsigned char*) &data[ (k * BYTES_FOR_2_SAMPLES) + 2 ];
1433 1431 time_management_regs->calData = ( data[ k * BYTES_FOR_2_SAMPLES ] & CAL_DATA_MASK )
1434 1432 + ( (dataPtr[0] & CAL_DATA_MASK_INTER) << CAL_DATA_SHIFT_INTER);
1435 1433 time_management_regs->calData = ( data[(k * BYTES_FOR_2_SAMPLES) + 1] & CAL_DATA_MASK )
1436 1434 + ( (dataPtr[1] & CAL_DATA_MASK_INTER) << CAL_DATA_SHIFT_INTER);
1437 1435 }
1438 1436 }
1439 1437
1440 1438 void setCalibrationReload( bool state)
1441 1439 {
1442 1440 if (state == true)
1443 1441 {
1444 1442 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | BIT_CAL_RELOAD; // [0001 0000]
1445 1443 }
1446 1444 else
1447 1445 {
1448 1446 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & MASK_CAL_RELOAD; // [1110 1111]
1449 1447 }
1450 1448 }
1451 1449
1452 1450 void setCalibrationEnable( bool state )
1453 1451 {
1454 1452 // this bit drives the multiplexer
1455 1453 if (state == true)
1456 1454 {
1457 1455 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | BIT_CAL_ENABLE; // [0100 0000]
1458 1456 }
1459 1457 else
1460 1458 {
1461 1459 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & MASK_CAL_ENABLE; // [1011 1111]
1462 1460 }
1463 1461 }
1464 1462
1465 1463 void setCalibrationInterleaved( bool state )
1466 1464 {
1467 1465 // this bit drives the multiplexer
1468 1466 if (state == true)
1469 1467 {
1470 1468 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | BIT_SET_INTERLEAVED; // [0010 0000]
1471 1469 }
1472 1470 else
1473 1471 {
1474 1472 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & MASK_SET_INTERLEAVED; // [1101 1111]
1475 1473 }
1476 1474 }
1477 1475
1478 1476 void setCalibration( bool state )
1479 1477 {
1480 1478 if (state == true)
1481 1479 {
1482 1480 setCalibrationEnable( true );
1483 1481 setCalibrationReload( false );
1484 1482 set_hk_lfr_calib_enable( true );
1485 1483 }
1486 1484 else
1487 1485 {
1488 1486 setCalibrationEnable( false );
1489 1487 setCalibrationReload( true );
1490 1488 set_hk_lfr_calib_enable( false );
1491 1489 }
1492 1490 }
1493 1491
1494 1492 void configureCalibration( bool interleaved )
1495 1493 {
1496 1494 setCalibration( false );
1497 1495 if ( interleaved == true )
1498 1496 {
1499 1497 setCalibrationInterleaved( true );
1500 1498 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1501 1499 setCalibrationDivisor( CAL_F_DIVISOR_INTER ); // => 240 384
1502 1500 setCalibrationDataInterleaved();
1503 1501 }
1504 1502 else
1505 1503 {
1506 1504 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1507 1505 setCalibrationDivisor( CAL_F_DIVISOR ); // => 160 256 (39 - 1)
1508 1506 setCalibrationData();
1509 1507 }
1510 1508 }
1511 1509
1512 1510 //****************
1513 1511 // CLOSING ACTIONS
1514 1512 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC, unsigned char * time )
1515 1513 {
1516 1514 /** This function is used to update the HK packets statistics after a successful TC execution.
1517 1515 *
1518 1516 * @param TC points to the TC being processed
1519 1517 * @param time is the time used to date the TC execution
1520 1518 *
1521 1519 */
1522 1520
1523 1521 unsigned int val;
1524 1522
1525 1523 housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
1526 1524 housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
1527 1525 housekeeping_packet.hk_lfr_last_exe_tc_type[0] = INIT_CHAR;
1528 1526 housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
1529 1527 housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = INIT_CHAR;
1530 1528 housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
1531 1529 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_0] = time[BYTE_0];
1532 1530 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_1] = time[BYTE_1];
1533 1531 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_2] = time[BYTE_2];
1534 1532 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_3] = time[BYTE_3];
1535 1533 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_4] = time[BYTE_4];
1536 1534 housekeeping_packet.hk_lfr_last_exe_tc_time[BYTE_5] = time[BYTE_5];
1537 1535
1538 1536 val = (housekeeping_packet.hk_lfr_exe_tc_cnt[0] * CONST_256) + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
1539 1537 val++;
1540 1538 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
1541 1539 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
1542 1540 }
1543 1541
1544 1542 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC, unsigned char * time )
1545 1543 {
1546 1544 /** This function is used to update the HK packets statistics after a TC rejection.
1547 1545 *
1548 1546 * @param TC points to the TC being processed
1549 1547 * @param time is the time used to date the TC rejection
1550 1548 *
1551 1549 */
1552 1550
1553 1551 unsigned int val;
1554 1552
1555 1553 housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
1556 1554 housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
1557 1555 housekeeping_packet.hk_lfr_last_rej_tc_type[0] = INIT_CHAR;
1558 1556 housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
1559 1557 housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = INIT_CHAR;
1560 1558 housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
1561 1559 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_0] = time[BYTE_0];
1562 1560 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_1] = time[BYTE_1];
1563 1561 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_2] = time[BYTE_2];
1564 1562 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_3] = time[BYTE_3];
1565 1563 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_4] = time[BYTE_4];
1566 1564 housekeeping_packet.hk_lfr_last_rej_tc_time[BYTE_5] = time[BYTE_5];
1567 1565
1568 1566 val = (housekeeping_packet.hk_lfr_rej_tc_cnt[0] * CONST_256) + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
1569 1567 val++;
1570 1568 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> SHIFT_1_BYTE);
1571 1569 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
1572 1570 }
1573 1571
1574 1572 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id )
1575 1573 {
1576 1574 /** This function is the last step of the TC execution workflow.
1577 1575 *
1578 1576 * @param TC points to the TC being processed
1579 1577 * @param result is the result of the TC execution (LFR_SUCCESSFUL / LFR_DEFAULT)
1580 1578 * @param queue_id is the id of the RTEMS message queue used to send TM packets
1581 1579 * @param time is the time used to date the TC execution
1582 1580 *
1583 1581 */
1584 1582
1585 1583 unsigned char requestedMode;
1586 1584
1587 1585 if (result == LFR_SUCCESSFUL)
1588 1586 {
1589 1587 if ( !( (TC->serviceType==TC_TYPE_TIME) & (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
1590 1588 &
1591 1589 !( (TC->serviceType==TC_TYPE_GEN) & (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
1592 1590 )
1593 1591 {
1594 1592 send_tm_lfr_tc_exe_success( TC, queue_id );
1595 1593 }
1596 1594 if ( (TC->serviceType == TC_TYPE_GEN) & (TC->serviceSubType == TC_SUBTYPE_ENTER) )
1597 1595 {
1598 1596 //**********************************
1599 1597 // UPDATE THE LFRMODE LOCAL VARIABLE
1600 1598 requestedMode = TC->dataAndCRC[1];
1601 1599 updateLFRCurrentMode( requestedMode );
1602 1600 }
1603 1601 }
1604 1602 else if (result == LFR_EXE_ERROR)
1605 1603 {
1606 1604 send_tm_lfr_tc_exe_error( TC, queue_id );
1607 1605 }
1608 1606 }
1609 1607
1610 1608 //***************************
1611 1609 // Interrupt Service Routines
1612 1610 rtems_isr commutation_isr1( rtems_vector_number vector )
1613 1611 {
1614 1612 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1615 1613 PRINTF("In commutation_isr1 *** Error sending event to DUMB\n")
1616 1614 }
1617 1615 }
1618 1616
1619 1617 rtems_isr commutation_isr2( rtems_vector_number vector )
1620 1618 {
1621 1619 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1622 1620 PRINTF("In commutation_isr2 *** Error sending event to DUMB\n")
1623 1621 }
1624 1622 }
1625 1623
1626 1624 //****************
1627 1625 // OTHER FUNCTIONS
1628 1626 void updateLFRCurrentMode( unsigned char requestedMode )
1629 1627 {
1630 1628 /** This function updates the value of the global variable lfrCurrentMode.
1631 1629 *
1632 1630 * lfrCurrentMode is a parameter used by several functions to know in which mode LFR is running.
1633 1631 *
1634 1632 */
1635 1633
1636 1634 // update the local value of lfrCurrentMode with the value contained in the housekeeping_packet structure
1637 1635 housekeeping_packet.lfr_status_word[0] = (housekeeping_packet.lfr_status_word[0] & STATUS_WORD_LFR_MODE_MASK)
1638 1636 + (unsigned char) ( requestedMode << STATUS_WORD_LFR_MODE_SHIFT );
1639 1637 lfrCurrentMode = requestedMode;
1640 1638 }
1641 1639
1642 1640 void set_lfr_soft_reset( unsigned char value )
1643 1641 {
1644 1642 if (value == 1)
1645 1643 {
1646 1644 time_management_regs->ctrl = time_management_regs->ctrl | BIT_SOFT_RESET; // [0100]
1647 1645 }
1648 1646 else
1649 1647 {
1650 1648 time_management_regs->ctrl = time_management_regs->ctrl & MASK_SOFT_RESET; // [1011]
1651 1649 }
1652 1650 }
1653 1651
1654 1652 void reset_lfr( void )
1655 1653 {
1656 1654 set_lfr_soft_reset( 1 );
1657 1655
1658 1656 set_lfr_soft_reset( 0 );
1659 1657
1660 1658 set_hk_lfr_sc_potential_flag( true );
1661 1659 }
General Comments 0
You need to be logged in to leave comments. Login now