##// END OF EJS Templates
601 corrected: hk_lfr_le_me_he_update moved
paul -
r261:197b0a2858dd R3a
parent child
Show More
@@ -1,783 +1,783
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 void timer_configure(unsigned char timer, unsigned int clock_divider,
11 11 unsigned char interrupt_level, rtems_isr (*timer_isr)() )
12 12 {
13 13 /** This function configures a GPTIMER timer instantiated in the VHDL design.
14 14 *
15 15 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
16 16 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
17 17 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
18 18 * @param interrupt_level is the interrupt level that the timer drives.
19 19 * @param timer_isr is the interrupt subroutine that will be attached to the IRQ driven by the timer.
20 20 *
21 21 * Interrupt levels are described in the SPARC documentation sparcv8.pdf p.76
22 22 *
23 23 */
24 24
25 25 rtems_status_code status;
26 26 rtems_isr_entry old_isr_handler;
27 27
28 28 gptimer_regs->timer[timer].ctrl = 0x00; // reset the control register
29 29
30 30 status = rtems_interrupt_catch( timer_isr, interrupt_level, &old_isr_handler) ; // see sparcv8.pdf p.76 for interrupt levels
31 31 if (status!=RTEMS_SUCCESSFUL)
32 32 {
33 33 PRINTF("in configure_timer *** ERR rtems_interrupt_catch\n")
34 34 }
35 35
36 36 timer_set_clock_divider( timer, clock_divider);
37 37 }
38 38
39 39 void timer_start(unsigned char timer)
40 40 {
41 41 /** This function starts a GPTIMER timer.
42 42 *
43 43 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
44 44 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
45 45 *
46 46 */
47 47
48 48 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
49 49 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000004; // LD load value from the reload register
50 50 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000001; // EN enable the timer
51 51 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000002; // RS restart
52 52 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000008; // IE interrupt enable
53 53 }
54 54
55 55 void timer_stop(unsigned char timer)
56 56 {
57 57 /** This function stops a GPTIMER timer.
58 58 *
59 59 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
60 60 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
61 61 *
62 62 */
63 63
64 64 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xfffffffe; // EN enable the timer
65 65 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xffffffef; // IE interrupt enable
66 66 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
67 67 }
68 68
69 69 void timer_set_clock_divider(unsigned char timer, unsigned int clock_divider)
70 70 {
71 71 /** This function sets the clock divider of a GPTIMER timer.
72 72 *
73 73 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
74 74 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
75 75 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
76 76 *
77 77 */
78 78
79 79 gptimer_regs->timer[timer].reload = clock_divider; // base clock frequency is 1 MHz
80 80 }
81 81
82 82 // WATCHDOG
83 83
84 84 rtems_isr watchdog_isr( rtems_vector_number vector )
85 85 {
86 86 rtems_status_code status_code;
87 87
88 88 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_12 );
89 89 }
90 90
91 91 void watchdog_configure(void)
92 92 {
93 93 /** This function configure the watchdog.
94 94 *
95 95 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
96 96 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
97 97 *
98 98 * The watchdog is a timer provided by the GPTIMER IP core of the GRLIB.
99 99 *
100 100 */
101 101
102 102 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt during configuration
103 103
104 104 timer_configure( TIMER_WATCHDOG, CLKDIV_WATCHDOG, IRQ_SPARC_GPTIMER_WATCHDOG, watchdog_isr );
105 105
106 106 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
107 107 }
108 108
109 109 void watchdog_stop(void)
110 110 {
111 111 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt line
112 112 timer_stop( TIMER_WATCHDOG );
113 113 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
114 114 }
115 115
116 116 void watchdog_reload(void)
117 117 {
118 118 /** This function reloads the watchdog timer counter with the timer reload value.
119 119 *
120 120 * @param void
121 121 *
122 122 * @return void
123 123 *
124 124 */
125 125
126 126 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000004; // LD load value from the reload register
127 127 }
128 128
129 129 void watchdog_start(void)
130 130 {
131 131 /** This function starts the watchdog timer.
132 132 *
133 133 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
134 134 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
135 135 *
136 136 */
137 137
138 138 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG );
139 139
140 140 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000010; // clear pending IRQ if any
141 141 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000004; // LD load value from the reload register
142 142 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000001; // EN enable the timer
143 143 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000008; // IE interrupt enable
144 144
145 145 LEON_Unmask_interrupt( IRQ_GPTIMER_WATCHDOG );
146 146
147 147 }
148 148
149 149 int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register
150 150 {
151 151 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
152 152
153 153 apbuart_regs->ctrl = APBUART_CTRL_REG_MASK_TE;
154 154
155 155 return 0;
156 156 }
157 157
158 158 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value)
159 159 {
160 160 /** This function sets the scaler reload register of the apbuart module
161 161 *
162 162 * @param regs is the address of the apbuart registers in memory
163 163 * @param value is the value that will be stored in the scaler register
164 164 *
165 165 * The value shall be set by the software to get data on the serial interface.
166 166 *
167 167 */
168 168
169 169 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs;
170 170
171 171 apbuart_regs->scaler = value;
172 172
173 173 BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value)
174 174 }
175 175
176 176 //************
177 177 // RTEMS TASKS
178 178
179 179 rtems_task load_task(rtems_task_argument argument)
180 180 {
181 181 BOOT_PRINTF("in LOAD *** \n")
182 182
183 183 rtems_status_code status;
184 184 unsigned int i;
185 185 unsigned int j;
186 186 rtems_name name_watchdog_rate_monotonic; // name of the watchdog rate monotonic
187 187 rtems_id watchdog_period_id; // id of the watchdog rate monotonic period
188 188
189 189 name_watchdog_rate_monotonic = rtems_build_name( 'L', 'O', 'A', 'D' );
190 190
191 191 status = rtems_rate_monotonic_create( name_watchdog_rate_monotonic, &watchdog_period_id );
192 192 if( status != RTEMS_SUCCESSFUL ) {
193 193 PRINTF1( "in LOAD *** rtems_rate_monotonic_create failed with status of %d\n", status )
194 194 }
195 195
196 196 i = 0;
197 197 j = 0;
198 198
199 199 watchdog_configure();
200 200
201 201 watchdog_start();
202 202
203 203 while(1){
204 204 status = rtems_rate_monotonic_period( watchdog_period_id, WATCHDOG_PERIOD );
205 205 watchdog_reload();
206 206 i = i + 1;
207 207 if ( i == 10 )
208 208 {
209 209 i = 0;
210 210 j = j + 1;
211 211 PRINTF1("%d\n", j)
212 212 }
213 213 #ifdef DEBUG_WATCHDOG
214 214 if (j == 3 )
215 215 {
216 216 status = rtems_task_delete(RTEMS_SELF);
217 217 }
218 218 #endif
219 219 }
220 220 }
221 221
222 222 rtems_task hous_task(rtems_task_argument argument)
223 223 {
224 224 rtems_status_code status;
225 225 rtems_status_code spare_status;
226 226 rtems_id queue_id;
227 227 rtems_rate_monotonic_period_status period_status;
228 228
229 229 status = get_message_queue_id_send( &queue_id );
230 230 if (status != RTEMS_SUCCESSFUL)
231 231 {
232 232 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
233 233 }
234 234
235 235 BOOT_PRINTF("in HOUS ***\n");
236 236
237 237 if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
238 238 status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id );
239 239 if( status != RTEMS_SUCCESSFUL ) {
240 240 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status );
241 241 }
242 242 }
243 243
244 244 status = rtems_rate_monotonic_cancel(HK_id);
245 245 if( status != RTEMS_SUCCESSFUL ) {
246 246 PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status );
247 247 }
248 248 else {
249 249 DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n");
250 250 }
251 251
252 252 // startup phase
253 253 status = rtems_rate_monotonic_period( HK_id, SY_LFR_TIME_SYN_TIMEOUT_in_ticks );
254 254 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
255 255 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
256 256 while(period_status.state != RATE_MONOTONIC_EXPIRED ) // after SY_LFR_TIME_SYN_TIMEOUT ms, starts HK anyway
257 257 {
258 258 if ((time_management_regs->coarse_time & 0x80000000) == 0x00000000) // check time synchronization
259 259 {
260 260 break; // break if LFR is synchronized
261 261 }
262 262 else
263 263 {
264 264 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
265 265 // sched_yield();
266 266 status = rtems_task_wake_after( 10 ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 100 ms = 10 * 10 ms
267 267 }
268 268 }
269 269 status = rtems_rate_monotonic_cancel(HK_id);
270 270 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
271 271
272 272 set_hk_lfr_reset_cause( POWER_ON );
273 273
274 274 while(1){ // launch the rate monotonic task
275 275 status = rtems_rate_monotonic_period( HK_id, HK_PERIOD );
276 276 if ( status != RTEMS_SUCCESSFUL ) {
277 277 PRINTF1( "in HOUS *** ERR period: %d\n", status);
278 278 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 );
279 279 }
280 280 else {
281 281 housekeeping_packet.packetSequenceControl[0] = (unsigned char) (sequenceCounterHK >> 8);
282 282 housekeeping_packet.packetSequenceControl[1] = (unsigned char) (sequenceCounterHK );
283 283 increment_seq_counter( &sequenceCounterHK );
284 284
285 285 housekeeping_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
286 286 housekeeping_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
287 287 housekeeping_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
288 288 housekeeping_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
289 289 housekeeping_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
290 290 housekeeping_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
291 291
292 292 spacewire_update_statistics();
293 293
294 hk_lfr_le_me_he_update();
295
296 294 set_hk_lfr_time_not_synchro();
297 295
298 296 housekeeping_packet.hk_lfr_q_sd_fifo_size_max = hk_lfr_q_sd_fifo_size_max;
299 297 housekeeping_packet.hk_lfr_q_rv_fifo_size_max = hk_lfr_q_rv_fifo_size_max;
300 298 housekeeping_packet.hk_lfr_q_p0_fifo_size_max = hk_lfr_q_p0_fifo_size_max;
301 299 housekeeping_packet.hk_lfr_q_p1_fifo_size_max = hk_lfr_q_p1_fifo_size_max;
302 300 housekeeping_packet.hk_lfr_q_p2_fifo_size_max = hk_lfr_q_p2_fifo_size_max;
303 301
304 302 housekeeping_packet.sy_lfr_common_parameters_spare = parameter_dump_packet.sy_lfr_common_parameters_spare;
305 303 housekeeping_packet.sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
306 304 get_temperatures( housekeeping_packet.hk_lfr_temp_scm );
307 305 get_v_e1_e2_f3( housekeeping_packet.hk_lfr_sc_v_f3 );
308 306 get_cpu_load( (unsigned char *) &housekeeping_packet.hk_lfr_cpu_load );
309 307
308 hk_lfr_le_me_he_update();
309
310 310 // SEND PACKET
311 311 status = rtems_message_queue_send( queue_id, &housekeeping_packet,
312 312 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
313 313 if (status != RTEMS_SUCCESSFUL) {
314 314 PRINTF1("in HOUS *** ERR send: %d\n", status)
315 315 }
316 316 }
317 317 }
318 318
319 319 PRINTF("in HOUS *** deleting task\n")
320 320
321 321 status = rtems_task_delete( RTEMS_SELF ); // should not return
322 322
323 323 return;
324 324 }
325 325
326 326 rtems_task dumb_task( rtems_task_argument unused )
327 327 {
328 328 /** This RTEMS taks is used to print messages without affecting the general behaviour of the software.
329 329 *
330 330 * @param unused is the starting argument of the RTEMS task
331 331 *
332 332 * The DUMB taks waits for RTEMS events and print messages depending on the incoming events.
333 333 *
334 334 */
335 335
336 336 unsigned int i;
337 337 unsigned int intEventOut;
338 338 unsigned int coarse_time = 0;
339 339 unsigned int fine_time = 0;
340 340 rtems_event_set event_out;
341 341
342 342 char *DumbMessages[15] = {"in DUMB *** default", // RTEMS_EVENT_0
343 343 "in DUMB *** timecode_irq_handler", // RTEMS_EVENT_1
344 344 "in DUMB *** f3 buffer changed", // RTEMS_EVENT_2
345 345 "in DUMB *** in SMIQ *** Error sending event to AVF0", // RTEMS_EVENT_3
346 346 "in DUMB *** spectral_matrices_isr *** Error sending event to SMIQ", // RTEMS_EVENT_4
347 347 "in DUMB *** waveforms_simulator_isr", // RTEMS_EVENT_5
348 348 "VHDL SM *** two buffers f0 ready", // RTEMS_EVENT_6
349 349 "ready for dump", // RTEMS_EVENT_7
350 350 "VHDL ERR *** spectral matrix", // RTEMS_EVENT_8
351 351 "tick", // RTEMS_EVENT_9
352 352 "VHDL ERR *** waveform picker", // RTEMS_EVENT_10
353 353 "VHDL ERR *** unexpected ready matrix values", // RTEMS_EVENT_11
354 354 "WATCHDOG timer", // RTEMS_EVENT_12
355 355 "TIMECODE timer", // RTEMS_EVENT_13
356 356 "TIMECODE ISR" // RTEMS_EVENT_14
357 357 };
358 358
359 359 BOOT_PRINTF("in DUMB *** \n")
360 360
361 361 while(1){
362 362 rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3
363 363 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7
364 364 | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12 | RTEMS_EVENT_13
365 365 | RTEMS_EVENT_14,
366 366 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT
367 367 intEventOut = (unsigned int) event_out;
368 368 for ( i=0; i<32; i++)
369 369 {
370 370 if ( ((intEventOut >> i) & 0x0001) != 0)
371 371 {
372 372 coarse_time = time_management_regs->coarse_time;
373 373 fine_time = time_management_regs->fine_time;
374 374 if (i==12)
375 375 {
376 376 PRINTF1("%s\n", DumbMessages[12])
377 377 }
378 378 if (i==13)
379 379 {
380 380 PRINTF1("%s\n", DumbMessages[13])
381 381 }
382 382 if (i==14)
383 383 {
384 384 PRINTF1("%s\n", DumbMessages[1])
385 385 }
386 386 }
387 387 }
388 388 }
389 389 }
390 390
391 391 //*****************************
392 392 // init housekeeping parameters
393 393
394 394 void init_housekeeping_parameters( void )
395 395 {
396 396 /** This function initialize the housekeeping_packet global variable with default values.
397 397 *
398 398 */
399 399
400 400 unsigned int i = 0;
401 401 unsigned char *parameters;
402 402 unsigned char sizeOfHK;
403 403
404 404 sizeOfHK = sizeof( Packet_TM_LFR_HK_t );
405 405
406 406 parameters = (unsigned char*) &housekeeping_packet;
407 407
408 408 for(i = 0; i< sizeOfHK; i++)
409 409 {
410 410 parameters[i] = 0x00;
411 411 }
412 412
413 413 housekeeping_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
414 414 housekeeping_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
415 415 housekeeping_packet.reserved = DEFAULT_RESERVED;
416 416 housekeeping_packet.userApplication = CCSDS_USER_APP;
417 417 housekeeping_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
418 418 housekeeping_packet.packetID[1] = (unsigned char) (APID_TM_HK);
419 419 housekeeping_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
420 420 housekeeping_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
421 421 housekeeping_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
422 422 housekeeping_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
423 423 housekeeping_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
424 424 housekeeping_packet.serviceType = TM_TYPE_HK;
425 425 housekeeping_packet.serviceSubType = TM_SUBTYPE_HK;
426 426 housekeeping_packet.destinationID = TM_DESTINATION_ID_GROUND;
427 427 housekeeping_packet.sid = SID_HK;
428 428
429 429 // init status word
430 430 housekeeping_packet.lfr_status_word[0] = DEFAULT_STATUS_WORD_BYTE0;
431 431 housekeeping_packet.lfr_status_word[1] = DEFAULT_STATUS_WORD_BYTE1;
432 432 // init software version
433 433 housekeeping_packet.lfr_sw_version[0] = SW_VERSION_N1;
434 434 housekeeping_packet.lfr_sw_version[1] = SW_VERSION_N2;
435 435 housekeeping_packet.lfr_sw_version[2] = SW_VERSION_N3;
436 436 housekeeping_packet.lfr_sw_version[3] = SW_VERSION_N4;
437 437 // init fpga version
438 438 parameters = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
439 439 housekeeping_packet.lfr_fpga_version[0] = parameters[1]; // n1
440 440 housekeeping_packet.lfr_fpga_version[1] = parameters[2]; // n2
441 441 housekeeping_packet.lfr_fpga_version[2] = parameters[3]; // n3
442 442
443 443 housekeeping_packet.hk_lfr_q_sd_fifo_size = MSG_QUEUE_COUNT_SEND;
444 444 housekeeping_packet.hk_lfr_q_rv_fifo_size = MSG_QUEUE_COUNT_RECV;
445 445 housekeeping_packet.hk_lfr_q_p0_fifo_size = MSG_QUEUE_COUNT_PRC0;
446 446 housekeeping_packet.hk_lfr_q_p1_fifo_size = MSG_QUEUE_COUNT_PRC1;
447 447 housekeeping_packet.hk_lfr_q_p2_fifo_size = MSG_QUEUE_COUNT_PRC2;
448 448 }
449 449
450 450 void increment_seq_counter( unsigned short *packetSequenceControl )
451 451 {
452 452 /** This function increment the sequence counter passes in argument.
453 453 *
454 454 * The increment does not affect the grouping flag. In case of an overflow, the counter is reset to 0.
455 455 *
456 456 */
457 457
458 458 unsigned short segmentation_grouping_flag;
459 459 unsigned short sequence_cnt;
460 460
461 461 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << 8; // keep bits 7 downto 6
462 462 sequence_cnt = (*packetSequenceControl) & 0x3fff; // [0011 1111 1111 1111]
463 463
464 464 if ( sequence_cnt < SEQ_CNT_MAX)
465 465 {
466 466 sequence_cnt = sequence_cnt + 1;
467 467 }
468 468 else
469 469 {
470 470 sequence_cnt = 0;
471 471 }
472 472
473 473 *packetSequenceControl = segmentation_grouping_flag | sequence_cnt ;
474 474 }
475 475
476 476 void getTime( unsigned char *time)
477 477 {
478 478 /** This function write the current local time in the time buffer passed in argument.
479 479 *
480 480 */
481 481
482 482 time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
483 483 time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
484 484 time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
485 485 time[3] = (unsigned char) (time_management_regs->coarse_time);
486 486 time[4] = (unsigned char) (time_management_regs->fine_time>>8);
487 487 time[5] = (unsigned char) (time_management_regs->fine_time);
488 488 }
489 489
490 490 unsigned long long int getTimeAsUnsignedLongLongInt( )
491 491 {
492 492 /** This function write the current local time in the time buffer passed in argument.
493 493 *
494 494 */
495 495 unsigned long long int time;
496 496
497 497 time = ( (unsigned long long int) (time_management_regs->coarse_time & 0x7fffffff) << 16 )
498 498 + time_management_regs->fine_time;
499 499
500 500 return time;
501 501 }
502 502
503 503 void send_dumb_hk( void )
504 504 {
505 505 Packet_TM_LFR_HK_t dummy_hk_packet;
506 506 unsigned char *parameters;
507 507 unsigned int i;
508 508 rtems_id queue_id;
509 509
510 510 dummy_hk_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
511 511 dummy_hk_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
512 512 dummy_hk_packet.reserved = DEFAULT_RESERVED;
513 513 dummy_hk_packet.userApplication = CCSDS_USER_APP;
514 514 dummy_hk_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
515 515 dummy_hk_packet.packetID[1] = (unsigned char) (APID_TM_HK);
516 516 dummy_hk_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
517 517 dummy_hk_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
518 518 dummy_hk_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
519 519 dummy_hk_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
520 520 dummy_hk_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
521 521 dummy_hk_packet.serviceType = TM_TYPE_HK;
522 522 dummy_hk_packet.serviceSubType = TM_SUBTYPE_HK;
523 523 dummy_hk_packet.destinationID = TM_DESTINATION_ID_GROUND;
524 524 dummy_hk_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
525 525 dummy_hk_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
526 526 dummy_hk_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
527 527 dummy_hk_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
528 528 dummy_hk_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
529 529 dummy_hk_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
530 530 dummy_hk_packet.sid = SID_HK;
531 531
532 532 // init status word
533 533 dummy_hk_packet.lfr_status_word[0] = 0xff;
534 534 dummy_hk_packet.lfr_status_word[1] = 0xff;
535 535 // init software version
536 536 dummy_hk_packet.lfr_sw_version[0] = SW_VERSION_N1;
537 537 dummy_hk_packet.lfr_sw_version[1] = SW_VERSION_N2;
538 538 dummy_hk_packet.lfr_sw_version[2] = SW_VERSION_N3;
539 539 dummy_hk_packet.lfr_sw_version[3] = SW_VERSION_N4;
540 540 // init fpga version
541 541 parameters = (unsigned char *) (REGS_ADDR_WAVEFORM_PICKER + 0xb0);
542 542 dummy_hk_packet.lfr_fpga_version[0] = parameters[1]; // n1
543 543 dummy_hk_packet.lfr_fpga_version[1] = parameters[2]; // n2
544 544 dummy_hk_packet.lfr_fpga_version[2] = parameters[3]; // n3
545 545
546 546 parameters = (unsigned char *) &dummy_hk_packet.hk_lfr_cpu_load;
547 547
548 548 for (i=0; i<100; i++)
549 549 {
550 550 parameters[i] = 0xff;
551 551 }
552 552
553 553 get_message_queue_id_send( &queue_id );
554 554
555 555 rtems_message_queue_send( queue_id, &dummy_hk_packet,
556 556 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
557 557 }
558 558
559 559 void get_temperatures( unsigned char *temperatures )
560 560 {
561 561 unsigned char* temp_scm_ptr;
562 562 unsigned char* temp_pcb_ptr;
563 563 unsigned char* temp_fpga_ptr;
564 564
565 565 // SEL1 SEL0
566 566 // 0 0 => PCB
567 567 // 0 1 => FPGA
568 568 // 1 0 => SCM
569 569
570 570 temp_scm_ptr = (unsigned char *) &time_management_regs->temp_scm;
571 571 temp_pcb_ptr = (unsigned char *) &time_management_regs->temp_pcb;
572 572 temp_fpga_ptr = (unsigned char *) &time_management_regs->temp_fpga;
573 573
574 574 temperatures[0] = temp_scm_ptr[2];
575 575 temperatures[1] = temp_scm_ptr[3];
576 576 temperatures[2] = temp_pcb_ptr[2];
577 577 temperatures[3] = temp_pcb_ptr[3];
578 578 temperatures[4] = temp_fpga_ptr[2];
579 579 temperatures[5] = temp_fpga_ptr[3];
580 580 }
581 581
582 582 void get_v_e1_e2_f3( unsigned char *spacecraft_potential )
583 583 {
584 584 unsigned char* v_ptr;
585 585 unsigned char* e1_ptr;
586 586 unsigned char* e2_ptr;
587 587
588 588 v_ptr = (unsigned char *) &waveform_picker_regs->v;
589 589 e1_ptr = (unsigned char *) &waveform_picker_regs->e1;
590 590 e2_ptr = (unsigned char *) &waveform_picker_regs->e2;
591 591
592 592 spacecraft_potential[0] = v_ptr[2];
593 593 spacecraft_potential[1] = v_ptr[3];
594 594 spacecraft_potential[2] = e1_ptr[2];
595 595 spacecraft_potential[3] = e1_ptr[3];
596 596 spacecraft_potential[4] = e2_ptr[2];
597 597 spacecraft_potential[5] = e2_ptr[3];
598 598 }
599 599
600 600 void get_cpu_load( unsigned char *resource_statistics )
601 601 {
602 602 unsigned char cpu_load;
603 603
604 604 cpu_load = lfr_rtems_cpu_usage_report();
605 605
606 606 // HK_LFR_CPU_LOAD
607 607 resource_statistics[0] = cpu_load;
608 608
609 609 // HK_LFR_CPU_LOAD_MAX
610 610 if (cpu_load > resource_statistics[1])
611 611 {
612 612 resource_statistics[1] = cpu_load;
613 613 }
614 614
615 615 // CPU_LOAD_AVE
616 616 resource_statistics[2] = 0;
617 617
618 618 #ifndef PRINT_TASK_STATISTICS
619 619 rtems_cpu_usage_reset();
620 620 #endif
621 621
622 622 }
623 623
624 624 void set_hk_lfr_sc_potential_flag( bool state )
625 625 {
626 626 if (state == true)
627 627 {
628 628 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x40; // [0100 0000]
629 629 }
630 630 else
631 631 {
632 632 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xbf; // [1011 1111]
633 633 }
634 634 }
635 635
636 636 void set_hk_lfr_mag_fields_flag( bool state )
637 637 {
638 638 if (state == true)
639 639 {
640 640 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x20; // [0010 0000]
641 641 }
642 642 else
643 643 {
644 644 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xd7; // [1101 1111]
645 645 }
646 646 }
647 647
648 648 void set_hk_lfr_calib_enable( bool state )
649 649 {
650 650 if (state == true)
651 651 {
652 652 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x08; // [0000 1000]
653 653 }
654 654 else
655 655 {
656 656 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xf7; // [1111 0111]
657 657 }
658 658 }
659 659
660 660 void set_hk_lfr_reset_cause( enum lfr_reset_cause_t lfr_reset_cause )
661 661 {
662 662 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1]
663 663 | (lfr_reset_cause & 0x07 ); // [0000 0111]
664 664 }
665 665
666 666 void hk_lfr_le_me_he_update()
667 667 {
668 668 unsigned int hk_lfr_le_cnt;
669 669 unsigned int hk_lfr_me_cnt;
670 670 unsigned int hk_lfr_he_cnt;
671 671
672 672 hk_lfr_le_cnt = 0;
673 673 hk_lfr_me_cnt = 0;
674 674 hk_lfr_he_cnt = 0;
675 675
676 676 //update the low severity error counter
677 677 hk_lfr_le_cnt =
678 678 housekeeping_packet.hk_lfr_dpu_spw_parity
679 679 + housekeeping_packet.hk_lfr_dpu_spw_disconnect
680 680 + housekeeping_packet.hk_lfr_dpu_spw_escape
681 681 + housekeeping_packet.hk_lfr_dpu_spw_credit
682 682 + housekeeping_packet.hk_lfr_dpu_spw_write_sync
683 + housekeeping_packet.hk_lfr_dpu_spw_rx_ahb
684 + housekeeping_packet.hk_lfr_dpu_spw_tx_ahb
685 683 + housekeeping_packet.hk_lfr_timecode_erroneous
686 684 + housekeeping_packet.hk_lfr_timecode_missing
687 685 + housekeeping_packet.hk_lfr_timecode_invalid
688 686 + housekeeping_packet.hk_lfr_time_timecode_it
689 687 + housekeeping_packet.hk_lfr_time_not_synchro
690 688 + housekeeping_packet.hk_lfr_time_timecode_ctr;
689 // housekeeping_packet.hk_lfr_dpu_spw_rx_ahb => not handled by the grspw driver
690 // housekeeping_packet.hk_lfr_dpu_spw_tx_ahb => not handled by the grspw driver
691 691
692 692 //update the medium severity error counter
693 693 hk_lfr_me_cnt =
694 694 housekeeping_packet.hk_lfr_dpu_spw_early_eop
695 695 + housekeeping_packet.hk_lfr_dpu_spw_invalid_addr
696 696 + housekeeping_packet.hk_lfr_dpu_spw_eep
697 697 + housekeeping_packet.hk_lfr_dpu_spw_rx_too_big;
698 698
699 699 //update the high severity error counter
700 700 hk_lfr_he_cnt = 0;
701 701
702 702 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
703 703 // LE
704 704 housekeeping_packet.hk_lfr_le_cnt[0] = (unsigned char) ((hk_lfr_le_cnt & 0xff00) >> 8);
705 705 housekeeping_packet.hk_lfr_le_cnt[1] = (unsigned char) (hk_lfr_le_cnt & 0x00ff);
706 706 // ME
707 707 housekeeping_packet.hk_lfr_me_cnt[0] = (unsigned char) ((hk_lfr_me_cnt & 0xff00) >> 8);
708 708 housekeeping_packet.hk_lfr_me_cnt[1] = (unsigned char) (hk_lfr_me_cnt & 0x00ff);
709 709 // HE
710 710 housekeeping_packet.hk_lfr_he_cnt[0] = (unsigned char) ((hk_lfr_he_cnt & 0xff00) >> 8);
711 711 housekeeping_packet.hk_lfr_he_cnt[1] = (unsigned char) (hk_lfr_he_cnt & 0x00ff);
712 712
713 713 }
714 714
715 715 void set_hk_lfr_time_not_synchro()
716 716 {
717 717 static unsigned char synchroLost = 1;
718 718 int synchronizationBit;
719 719
720 720 // get the synchronization bit
721 721 synchronizationBit = (time_management_regs->coarse_time & 0x80000000) >> 31; // 1000 0000 0000 0000
722 722
723 723 switch (synchronizationBit)
724 724 {
725 725 case 0:
726 726 if (synchroLost == 1)
727 727 {
728 728 synchroLost = 0;
729 729 }
730 730 break;
731 731 case 1:
732 732 if (synchroLost == 0 )
733 733 {
734 734 synchroLost = 1;
735 735 increase_unsigned_char_counter(&housekeeping_packet.hk_lfr_time_not_synchro);
736 736 }
737 737 break;
738 738 default:
739 739 PRINTF1("in hk_lfr_time_not_synchro *** unexpected value for synchronizationBit = %d\n", synchronizationBit);
740 740 break;
741 741 }
742 742
743 743 }
744 744
745 745 void set_hk_lfr_ahb_correctable()
746 746 {
747 747 /** This function builds the error counter hk_lfr_ahb_correctable using the statistics provided
748 748 * by the Cache Control Register (ASI 2, offset 0) and in the Register Protection Control Register (ASR16) on the
749 749 * detected errors in the cache, in the integer unit and in the floating point unit.
750 750 *
751 751 * @param void
752 752 *
753 753 * @return void
754 754 *
755 755 * All errors are summed to set the value of the hk_lfr_ahb_correctable counter.
756 756 *
757 757 */
758 758
759 759 unsigned int ahb_correctable;
760 760 unsigned int instructionErrorCounter;
761 761 unsigned int dataErrorCounter;
762 762 unsigned int fprfErrorCounter;
763 763 unsigned int iurfErrorCounter;
764 764
765 765 CCR_getInstructionAndDataErrorCounters( &instructionErrorCounter, &dataErrorCounter);
766 766 ASR16_get_FPRF_IURF_ErrorCounters( &fprfErrorCounter, &iurfErrorCounter);
767 767
768 768 ahb_correctable = instructionErrorCounter
769 769 + dataErrorCounter
770 770 + fprfErrorCounter
771 771 + iurfErrorCounter
772 772 + housekeeping_packet.hk_lfr_ahb_correctable;
773 773
774 774 if (ahb_correctable > 255)
775 775 {
776 776 housekeeping_packet.hk_lfr_ahb_correctable = 255;
777 777 }
778 778 else
779 779 {
780 780 housekeeping_packet.hk_lfr_ahb_correctable = ahb_correctable;
781 781 }
782 782
783 783 }
General Comments 0
You need to be logged in to leave comments. Login now