##// END OF EJS Templates
Corrections:...
paul -
r107:c303d2da6108 VHDLib206
parent child
Show More
@@ -0,0 +1,41
1 #ifndef TIMEGEN_INIT_H_INCLUDED
2 #define TIMEGEN_INIT_H_INCLUDED
3
4 #include <rtems.h>
5 #include <leon.h>
6
7 #include "fsw_params.h"
8 #include "fsw_misc.h"
9 #include "fsw_processing.h"
10 #include "wf_handler.h"
11
12 #include "timegen_spacewire.h"
13 #include "timegen_misc.h"
14
15 extern rtems_name Task_name[20]; /* array of task names */
16 extern rtems_id Task_id[20]; /* array of task ids */
17
18 // RTEMS TASKS
19 rtems_task Init( rtems_task_argument argument);
20
21 // OTHER functions
22 void create_names( void );
23 int create_all_tasks( void );
24 int start_all_tasks( void );
25 //
26 rtems_status_code create_message_queues( void );
27 rtems_status_code get_message_queue_id_send( rtems_id *queue_id );
28 rtems_status_code get_message_queue_id_recv( rtems_id *queue_id );
29 //
30 int start_recv_send_tasks( void );
31 //
32 void init_local_mode_parameters( void );
33 void reset_local_time( void );
34
35 extern int rtems_cpu_usage_report( void );
36 extern int rtems_cpu_usage_reset( void );
37 extern void rtems_stack_checker_report_usage( void );
38
39 extern int sched_yield( void );
40
41 #endif // TIMEGEN_INIT_H_INCLUDED
@@ -0,0 +1,39
1 #ifndef TIMEGEN_MISC_H_INCLUDED
2 #define TIMEGEN_MISC_H_INCLUDED
3
4 #include <rtems.h>
5 #include <leon.h>
6
7 #include "fsw_params.h"
8 #include "TC_types.h"
9 #include "tc_acceptance.h"
10 #include "timegen_init.h"
11
12 #define TASK_PRIORITY_UPDT 40
13
14 typedef struct {
15 unsigned char targetLogicalAddress;
16 unsigned char protocolIdentifier;
17 unsigned char reserved;
18 unsigned char userApplication;
19 // PACKET HEADER
20 Packet_TC_LFR_UPDATE_TIME_t update_time;
21 } Packet_TC_LFR_UPDATE_TIME_WITH_OVERHEAD_t;
22
23 unsigned int coarseTime;
24
25 rtems_name rtems_name_updt;
26 rtems_id rtems_id_updt;
27
28 void timegen_timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc );
29
30 void initCoarseTime( void );
31
32 rtems_task updt_task( rtems_task_argument unused );
33
34 int send_tc_lfr_update_time( rtems_id queue_id );
35
36 #endif // TIMEGEN_MISC_H_INCLUDED
37
38
39
@@ -0,0 +1,48
1 #ifndef TIMEGEN_SPACEWIRE_H_INCLUDED
2 #define TIMEGEN_SPACEWIRE_H_INCLUDED
3
4 #include <rtems.h>
5 #include <grspw.h>
6
7 #include <fcntl.h> // for O_RDWR
8 #include <unistd.h> // for the read call
9 #include <sys/ioctl.h> // for the ioctl call
10 #include <errno.h>
11
12 #include "fsw_params.h"
13 #include "tc_acceptance.h"
14 #include "timegen_tc_handler.h"
15
16 #define DESTINATION_ID_LFR 0xfe
17 #define DESTINATION_ID_DPU 0x01
18 #define SPACEWIRE_LINK_LFR 0x01
19 #define NODEADDR_TIMEGEN 0xfd
20
21 extern rtems_id Task_id[20]; /* array of task ids */
22 extern int fdSPW;
23
24 extern spw_stats spacewire_stats;
25 extern spw_stats spacewire_stats_backup;
26
27 // RTEMS TASK
28 rtems_task spiq_task( rtems_task_argument argument );
29 rtems_task recv_task( rtems_task_argument unused );
30 rtems_task send_task( rtems_task_argument argument );
31 rtems_task wtdg_task( rtems_task_argument argument );
32
33 int spacewire_open_link( void );
34 int spacewire_start_link( int fd );
35 int spacewire_stop_start_link( int fd );
36 int spacewire_configure_link(int fd );
37 int spacewire_reset_link( void );
38 void spacewire_set_NP( unsigned char val, unsigned int regAddr ); // No Port force
39 void spacewire_set_RE( unsigned char val, unsigned int regAddr ); // RMAP Enable
40 void spacewire_compute_stats_offsets( void );
41 void spacewire_update_statistics( void );
42
43 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc );
44 rtems_timer_service_routine user_routine( rtems_id timer_id, void *user_data );
45
46 void (*grspw_timecode_callback) ( void *pDev, void *regs, int minor, unsigned int tc );
47
48 #endif // TIMEGEN_SPACEWIRE_H_INCLUDED
@@ -0,0 +1,56
1 #ifndef TIMEGEN_TC_HANDLER_H_INCLUDED
2 #define TIMEGEN_TC_HANDLER_H_INCLUDED
3
4 #include <rtems.h>
5 #include <leon.h>
6
7 #include "tc_load_dump_parameters.h"
8 #include "tc_acceptance.h"
9 #include "tm_lfr_tc_exe.h"
10
11 // MODE PARAMETERS
12 extern unsigned int maxCount;
13
14 //****
15 // ISR
16 rtems_isr commutation_isr1( rtems_vector_number vector );
17 rtems_isr commutation_isr2( rtems_vector_number vector );
18
19 //***********
20 // RTEMS TASK
21 rtems_task actn_task( rtems_task_argument unused );
22
23 //***********
24 // TC ACTIONS
25 int action_reset(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time);
26 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time);
27 int action_update_info(ccsdsTelecommandPacket_t *TC, rtems_id queue_id);
28 int action_enable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time);
29 int action_disable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time);
30 int action_update_time(ccsdsTelecommandPacket_t *TC);
31
32 // mode transition
33 int transition_validation(unsigned char requestedMode);
34 int stop_current_mode( void );
35 int enter_mode(unsigned char mode);
36 int restart_science_tasks();
37 int suspend_science_tasks();
38 void launch_waveform_picker( unsigned char mode );
39 void launch_spectral_matrix( unsigned char mode );
40 void set_irq_on_new_ready_matrix(unsigned char value );
41 void set_run_matrix_spectral( unsigned char value );
42 void launch_spectral_matrix_simu( unsigned char mode );
43
44 // other functions
45 void updateLFRCurrentMode();
46 void update_last_TC_exe(ccsdsTelecommandPacket_t *TC );
47 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC );
48 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id );
49
50 extern rtems_status_code get_message_queue_id_send( rtems_id *queue_id );
51 extern rtems_status_code get_message_queue_id_recv( rtems_id *queue_id );
52
53 #endif // TIMEGEN_TC_HANDLER_H_INCLUDED
54
55
56
@@ -0,0 +1,476
1 /** This is the RTEMS initialization module.
2 *
3 * @file
4 * @author P. LEROY
5 *
6 * This module contains two very different information:
7 * - specific instructions to configure the compilation of the RTEMS executive
8 * - functions related to the fligth softwre initialization, especially the INIT RTEMS task
9 *
10 */
11
12 //*************************
13 // GPL reminder to be added
14 //*************************
15
16 #include <rtems.h>
17
18 /* configuration information */
19
20 #define CONFIGURE_INIT
21
22 #include <bsp.h> /* for device driver prototypes */
23
24 /* configuration information */
25
26 #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
27 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
28
29 #define CONFIGURE_MAXIMUM_TASKS 20
30 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
31 #define CONFIGURE_EXTRA_TASK_STACKS (3 * RTEMS_MINIMUM_STACK_SIZE)
32 #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
33 #define CONFIGURE_INIT_TASK_PRIORITY 1 // instead of 100
34 #define CONFIGURE_INIT_TASK_MODE (RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT)
35 #define CONFIGURE_MAXIMUM_DRIVERS 16
36 #define CONFIGURE_MAXIMUM_PERIODS 5
37 #define CONFIGURE_MAXIMUM_TIMERS 5 // STAT (1s), send SWF (0.3s), send CWF3 (1s)
38 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 2
39 #ifdef PRINT_STACK_REPORT
40 #define CONFIGURE_STACK_CHECKER_ENABLED
41 #endif
42
43 #include <rtems/confdefs.h>
44
45 /* If --drvmgr was enabled during the configuration of the RTEMS kernel */
46 #ifdef RTEMS_DRVMGR_STARTUP
47 #ifdef LEON3
48 /* Add Timer and UART Driver */
49 #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
50 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GPTIMER
51 #endif
52 #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
53 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_APBUART
54 #endif
55 #endif
56 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GRSPW /* GRSPW Driver */
57 #include <drvmgr/drvmgr_confdefs.h>
58 #endif
59
60 #include "timegen_init.h"
61 #include "fsw_config.c"
62
63 rtems_task Init( rtems_task_argument ignored )
64 {
65 /** This is the RTEMS INIT taks, it the first task launched by the system.
66 *
67 * @param unused is the starting argument of the RTEMS task
68 *
69 * The INIT task create and run all other RTEMS tasks.
70 *
71 */
72
73 rtems_status_code status;
74 rtems_status_code status_spw;
75
76 // initCoarseTime();
77
78 // UART settings
79 send_console_outputs_on_apbuart_port();
80 set_apbuart_scaler_reload_register(REGS_ADDR_APBUART, APBUART_SCALER_RELOAD_VALUE);
81 enable_apbuart_transmitter();
82 DEBUG_PRINTF("\n\n\n\n\nIn INIT *** Now the console is on port COM1\n")
83
84 PRINTF("\n\n\n\n\n")
85 PRINTF("*************************\n")
86 PRINTF("** Time Generator **\n")
87 PRINTF1("** %d.", SW_VERSION_N1)
88 PRINTF1("%d.", SW_VERSION_N2)
89 PRINTF1("%d.", SW_VERSION_N3)
90 PRINTF1("%d **\n", SW_VERSION_N4)
91 PRINTF("*************************\n")
92 PRINTF("\n\n")
93
94 // init_local_mode_parameters();
95 // init_housekeeping_parameters();
96
97 // updateLFRCurrentMode();
98
99 // BOOT_PRINTF1("in INIT *** lfrCurrentMode is %d\n", lfrCurrentMode)
100
101 create_names(); // create all names
102
103 status = create_message_queues(); // create message queues
104 if (status != RTEMS_SUCCESSFUL)
105 {
106 PRINTF1("in INIT *** ERR in create_message_queues, code %d", status)
107 }
108
109 status = create_all_tasks(); // create all tasks
110 if (status != RTEMS_SUCCESSFUL)
111 {
112 PRINTF1("in INIT *** ERR in create_all_tasks, code %d", status)
113 }
114
115 // **************************
116 // <SPACEWIRE INITIALIZATION>
117 grspw_timecode_callback = &timegen_timecode_irq_handler;
118
119 status_spw = spacewire_open_link(); // (1) open the link
120 if ( status_spw != RTEMS_SUCCESSFUL )
121 {
122 PRINTF1("in INIT *** ERR spacewire_open_link code %d\n", status_spw )
123 }
124
125 if ( status_spw == RTEMS_SUCCESSFUL ) // (2) configure the link
126 {
127 status_spw = spacewire_configure_link( fdSPW );
128 if ( status_spw != RTEMS_SUCCESSFUL )
129 {
130 PRINTF1("in INIT *** ERR spacewire_configure_link code %d\n", status_spw )
131 }
132 }
133
134 if ( status_spw == RTEMS_SUCCESSFUL) // (3) start the link
135 {
136 status_spw = spacewire_start_link( fdSPW );
137 if ( status_spw != RTEMS_SUCCESSFUL )
138 {
139 PRINTF1("in INIT *** ERR spacewire_start_link code %d\n", status_spw )
140 }
141 }
142 // </SPACEWIRE INITIALIZATION>
143 // ***************************
144
145 status = start_all_tasks(); // start all tasks
146 if (status != RTEMS_SUCCESSFUL)
147 {
148 PRINTF1("in INIT *** ERR in start_all_tasks, code %d", status)
149 }
150
151 // start RECV and SEND *AFTER* SpaceWire Initialization, due to the timeout of the start call during the initialization
152 status = start_recv_send_tasks();
153 if ( status != RTEMS_SUCCESSFUL )
154 {
155 PRINTF1("in INIT *** ERR start_recv_send_tasks code %d\n", status )
156 }
157
158 // suspend science tasks. they will be restarted later depending on the mode
159 status = suspend_science_tasks(); // suspend science tasks (not done in stop_current_mode if current mode = STANDBY)
160 if (status != RTEMS_SUCCESSFUL)
161 {
162 PRINTF1("in INIT *** in suspend_science_tasks *** ERR code: %d\n", status)
163 }
164
165 // if the spacewire link is not up then send an event to the SPIQ task for link recovery
166 if ( status_spw != RTEMS_SUCCESSFUL )
167 {
168 status = rtems_event_send( Task_id[TASKID_SPIQ], SPW_LINKERR_EVENT );
169 if ( status != RTEMS_SUCCESSFUL ) {
170 PRINTF1("in INIT *** ERR rtems_event_send to SPIQ code %d\n", status )
171 }
172 }
173
174 BOOT_PRINTF("delete INIT\n")
175
176 status = rtems_task_delete(RTEMS_SELF);
177
178 }
179
180 void init_local_mode_parameters( void )
181 {
182 /** This function initialize the param_local global variable with default values.
183 *
184 */
185
186 unsigned int i;
187
188 // LOCAL PARAMETERS
189 // set_local_nb_interrupt_f0_MAX();
190
191 BOOT_PRINTF1("local_sbm1_nb_cwf_max %d \n", param_local.local_sbm1_nb_cwf_max)
192 BOOT_PRINTF1("local_sbm2_nb_cwf_max %d \n", param_local.local_sbm2_nb_cwf_max)
193 BOOT_PRINTF1("nb_interrupt_f0_MAX = %d\n", param_local.local_nb_interrupt_f0_MAX)
194
195 // init sequence counters
196
197 for(i = 0; i<SEQ_CNT_NB_DEST_ID; i++)
198 {
199 sequenceCounters_TC_EXE[i] = 0x00;
200 }
201 sequenceCounters_SCIENCE_NORMAL_BURST = 0x00;
202 sequenceCounters_SCIENCE_SBM1_SBM2 = 0x00;
203 }
204
205 void create_names( void ) // create all names for tasks and queues
206 {
207 /** This function creates all RTEMS names used in the software for tasks and queues.
208 *
209 * @return RTEMS directive status codes:
210 * - RTEMS_SUCCESSFUL - successful completion
211 *
212 */
213
214 // task names
215 Task_name[TASKID_RECV] = rtems_build_name( 'R', 'E', 'C', 'V' );
216 Task_name[TASKID_ACTN] = rtems_build_name( 'A', 'C', 'T', 'N' );
217 Task_name[TASKID_SPIQ] = rtems_build_name( 'S', 'P', 'I', 'Q' );
218 Task_name[TASKID_SMIQ] = rtems_build_name( 'S', 'M', 'I', 'Q' );
219 Task_name[TASKID_STAT] = rtems_build_name( 'S', 'T', 'A', 'T' );
220 Task_name[TASKID_AVF0] = rtems_build_name( 'A', 'V', 'F', '0' );
221 Task_name[TASKID_SWBD] = rtems_build_name( 'S', 'W', 'B', 'D' );
222 Task_name[TASKID_WFRM] = rtems_build_name( 'W', 'F', 'R', 'M' );
223 Task_name[TASKID_DUMB] = rtems_build_name( 'D', 'U', 'M', 'B' );
224 Task_name[TASKID_HOUS] = rtems_build_name( 'H', 'O', 'U', 'S' );
225 Task_name[TASKID_MATR] = rtems_build_name( 'M', 'A', 'T', 'R' );
226 Task_name[TASKID_CWF3] = rtems_build_name( 'C', 'W', 'F', '3' );
227 Task_name[TASKID_CWF2] = rtems_build_name( 'C', 'W', 'F', '2' );
228 Task_name[TASKID_CWF1] = rtems_build_name( 'C', 'W', 'F', '1' );
229 Task_name[TASKID_SEND] = rtems_build_name( 'S', 'E', 'N', 'D' );
230 Task_name[TASKID_WTDG] = rtems_build_name( 'W', 'T', 'D', 'G' );
231
232 // TIMEGEN
233 rtems_name_updt = rtems_build_name( 'U', 'P', 'D', 'T' );
234
235 // rate monotonic period names
236 name_hk_rate_monotonic = rtems_build_name( 'H', 'O', 'U', 'S' );
237
238 misc_name[QUEUE_RECV] = rtems_build_name( 'Q', '_', 'R', 'V' );
239 misc_name[QUEUE_SEND] = rtems_build_name( 'Q', '_', 'S', 'D' );
240 }
241
242 int create_all_tasks( void ) // create all tasks which run in the software
243 {
244 /** This function creates all RTEMS tasks used in the software.
245 *
246 * @return RTEMS directive status codes:
247 * - RTEMS_SUCCESSFUL - task created successfully
248 * - RTEMS_INVALID_ADDRESS - id is NULL
249 * - RTEMS_INVALID_NAME - invalid task name
250 * - RTEMS_INVALID_PRIORITY - invalid task priority
251 * - RTEMS_MP_NOT_CONFIGURED - multiprocessing not configured
252 * - RTEMS_TOO_MANY - too many tasks created
253 * - RTEMS_UNSATISFIED - not enough memory for stack/FP context
254 * - RTEMS_TOO_MANY - too many global objects
255 *
256 */
257
258 rtems_status_code status;
259
260 //**********
261 // SPACEWIRE
262 // RECV
263 status = rtems_task_create(
264 Task_name[TASKID_RECV], TASK_PRIORITY_RECV, RTEMS_MINIMUM_STACK_SIZE,
265 RTEMS_DEFAULT_MODES,
266 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_RECV]
267 );
268 if (status == RTEMS_SUCCESSFUL) // SEND
269 {
270 status = rtems_task_create(
271 Task_name[TASKID_SEND], TASK_PRIORITY_SEND, RTEMS_MINIMUM_STACK_SIZE,
272 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
273 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SEND]
274 );
275 }
276 if (status == RTEMS_SUCCESSFUL) // WTDG
277 {
278 status = rtems_task_create(
279 Task_name[TASKID_WTDG], TASK_PRIORITY_WTDG, RTEMS_MINIMUM_STACK_SIZE,
280 RTEMS_DEFAULT_MODES,
281 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_WTDG]
282 );
283 }
284 if (status == RTEMS_SUCCESSFUL) // ACTN
285 {
286 status = rtems_task_create(
287 Task_name[TASKID_ACTN], TASK_PRIORITY_ACTN, RTEMS_MINIMUM_STACK_SIZE,
288 RTEMS_DEFAULT_MODES,
289 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_ACTN]
290 );
291 }
292 if (status == RTEMS_SUCCESSFUL) // SPIQ
293 {
294 status = rtems_task_create(
295 Task_name[TASKID_SPIQ], TASK_PRIORITY_SPIQ, RTEMS_MINIMUM_STACK_SIZE,
296 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
297 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SPIQ]
298 );
299 }
300
301 //*****
302 // MISC
303 if (status == RTEMS_SUCCESSFUL) // STAT
304 {
305 status = rtems_task_create(
306 Task_name[TASKID_STAT], TASK_PRIORITY_STAT, RTEMS_MINIMUM_STACK_SIZE,
307 RTEMS_DEFAULT_MODES,
308 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_STAT]
309 );
310 }
311 if (status == RTEMS_SUCCESSFUL) // DUMB
312 {
313 status = rtems_task_create(
314 Task_name[TASKID_DUMB], TASK_PRIORITY_DUMB, RTEMS_MINIMUM_STACK_SIZE,
315 RTEMS_DEFAULT_MODES,
316 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_DUMB]
317 );
318 }
319 if (status == RTEMS_SUCCESSFUL) // UPDT
320 {
321 status = rtems_task_create(
322 rtems_name_updt, TASK_PRIORITY_UPDT, RTEMS_MINIMUM_STACK_SIZE,
323 RTEMS_DEFAULT_MODES,
324 RTEMS_DEFAULT_ATTRIBUTES, &rtems_id_updt
325 );
326 }
327
328 return status;
329 }
330
331 int start_recv_send_tasks( void )
332 {
333 rtems_status_code status;
334
335 status = rtems_task_start( Task_id[TASKID_RECV], recv_task, 1 );
336 if (status!=RTEMS_SUCCESSFUL) {
337 BOOT_PRINTF("in INIT *** Error starting TASK_RECV\n")
338 }
339
340 if (status == RTEMS_SUCCESSFUL) // SEND
341 {
342 status = rtems_task_start( Task_id[TASKID_SEND], send_task, 1 );
343 if (status!=RTEMS_SUCCESSFUL) {
344 BOOT_PRINTF("in INIT *** Error starting TASK_SEND\n")
345 }
346 }
347
348 return status;
349 }
350
351 int start_all_tasks( void ) // start all tasks except SEND RECV and HOUS
352 {
353 /** This function starts all RTEMS tasks used in the software.
354 *
355 * @return RTEMS directive status codes:
356 * - RTEMS_SUCCESSFUL - ask started successfully
357 * - RTEMS_INVALID_ADDRESS - invalid task entry point
358 * - RTEMS_INVALID_ID - invalid task id
359 * - RTEMS_INCORRECT_STATE - task not in the dormant state
360 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot start remote task
361 *
362 */
363 // starts all the tasks fot eh flight software
364
365 rtems_status_code status;
366
367 //**********
368 // SPACEWIRE
369 status = rtems_task_start( Task_id[TASKID_SPIQ], spiq_task, 1 );
370 if (status!=RTEMS_SUCCESSFUL) {
371 BOOT_PRINTF("in INIT *** Error starting TASK_SPIQ\n")
372 }
373
374 if (status == RTEMS_SUCCESSFUL) // WTDG
375 {
376 status = rtems_task_start( Task_id[TASKID_WTDG], wtdg_task, 1 );
377 if (status!=RTEMS_SUCCESSFUL) {
378 BOOT_PRINTF("in INIT *** Error starting TASK_WTDG\n")
379 }
380 }
381
382 if (status == RTEMS_SUCCESSFUL) // ACTN
383 {
384 status = rtems_task_start( Task_id[TASKID_ACTN], actn_task, 1 );
385 if (status!=RTEMS_SUCCESSFUL) {
386 BOOT_PRINTF("in INIT *** Error starting TASK_ACTN\n")
387 }
388 }
389
390 //*****
391 // MISC
392 if (status == RTEMS_SUCCESSFUL) // DUMB
393 {
394 status = rtems_task_start( Task_id[TASKID_DUMB], dumb_task, 1 );
395 if (status!=RTEMS_SUCCESSFUL) {
396 BOOT_PRINTF("in INIT *** Error starting TASK_DUMB\n")
397 }
398 }
399
400 if (status == RTEMS_SUCCESSFUL) // STAT
401 {
402 status = rtems_task_start( Task_id[TASKID_STAT], stat_task, 1 );
403 if (status!=RTEMS_SUCCESSFUL) {
404 BOOT_PRINTF("in INIT *** Error starting TASK_STAT\n")
405 }
406 }
407
408 if (status == RTEMS_SUCCESSFUL) // UPDT
409 {
410 status = rtems_task_start( rtems_id_updt, updt_task, 1 );
411 if (status!=RTEMS_SUCCESSFUL) {
412 BOOT_PRINTF("in INIT *** Error starting TASK_UPDT\n")
413 }
414 }
415
416 return status;
417 }
418
419 rtems_status_code create_message_queues( void ) // create the two message queues used in the software
420 {
421 rtems_status_code status_recv;
422 rtems_status_code status_send;
423 rtems_status_code ret;
424 rtems_id queue_id;
425
426 // create the queue for handling valid TCs
427 status_recv = rtems_message_queue_create( misc_name[QUEUE_RECV],
428 ACTION_MSG_QUEUE_COUNT, CCSDS_TC_PKT_MAX_SIZE,
429 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
430 if ( status_recv != RTEMS_SUCCESSFUL ) {
431 PRINTF1("in create_message_queues *** ERR creating QUEU queue, %d\n", status_recv)
432 }
433
434 // create the queue for handling TM packet sending
435 status_send = rtems_message_queue_create( misc_name[QUEUE_SEND],
436 ACTION_MSG_PKTS_COUNT, ACTION_MSG_PKTS_MAX_SIZE,
437 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
438 if ( status_send != RTEMS_SUCCESSFUL ) {
439 PRINTF1("in create_message_queues *** ERR creating PKTS queue, %d\n", status_send)
440 }
441
442 if ( status_recv != RTEMS_SUCCESSFUL )
443 {
444 ret = status_recv;
445 }
446 else
447 {
448 ret = status_send;
449 }
450
451 return ret;
452 }
453
454 rtems_status_code get_message_queue_id_send( rtems_id *queue_id )
455 {
456 rtems_status_code status;
457 rtems_name queue_name;
458
459 queue_name = rtems_build_name( 'Q', '_', 'S', 'D' );
460
461 status = rtems_message_queue_ident( queue_name, 0, queue_id );
462
463 return status;
464 }
465
466 rtems_status_code get_message_queue_id_recv( rtems_id *queue_id )
467 {
468 rtems_status_code status;
469 rtems_name queue_name;
470
471 queue_name = rtems_build_name( 'Q', '_', 'R', 'V' );
472
473 status = rtems_message_queue_ident( queue_name, 0, queue_id );
474
475 return status;
476 }
@@ -0,0 +1,110
1 /** Functions and tasks related to TeleCommand handling.
2 *
3 * @file
4 * @author P. LEROY
5 *
6 * A group of functions to handle TeleCommands:\n
7 * action launching\n
8 * TC parsing\n
9 * ...
10 *
11 */
12
13 #include "timegen_misc.h"
14 #include <stdio.h>
15
16 void timegen_timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc )
17 {
18 struct grgpio_regs_str *grgpio_regs = (struct grgpio_regs_str *) REGS_ADDR_GRGPIO;
19
20 grgpio_regs->io_port_direction_register =
21 grgpio_regs->io_port_direction_register | 0x08; // [0001 1000], 0 = output disabled, 1 = output enabled
22
23 if ( (grgpio_regs->io_port_output_register & 0x08) == 0x08 )
24 {
25 grgpio_regs->io_port_output_register = grgpio_regs->io_port_output_register & 0xf7;
26 }
27 else
28 {
29 grgpio_regs->io_port_output_register = grgpio_regs->io_port_output_register | 0x08;
30 }
31
32 rtems_event_send( rtems_id_updt, RTEMS_EVENT_0 );
33 }
34
35 void initCoarseTime()
36 {
37 coarseTime = 0x00;
38 }
39
40 rtems_task updt_task( rtems_task_argument unused )
41 {
42 rtems_event_set event_out;
43 rtems_id send_queue_id;
44
45 get_message_queue_id_send( &send_queue_id );
46
47 BOOT_PRINTF("in UPDT *** waiting for SpaceWire ticks\n")
48
49 while(1)
50 {
51 // wait for an RTEMS_EVENT
52 rtems_event_receive( RTEMS_EVENT_0,
53 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
54 // increment the coarse time
55 coarseTime = coarseTime + 1;
56 PRINTF2("next valid coarseTime = 0x%x *** %d s\n", coarseTime, coarseTime)
57 rtems_task_wake_after(70); // 10 ms * 70 = 700 ms
58 send_tc_lfr_update_time( send_queue_id );
59 }
60 }
61
62 int send_tc_lfr_update_time(rtems_id queue_id )
63 {
64
65 rtems_status_code status;
66 unsigned char messageSize;
67
68 Packet_TC_LFR_UPDATE_TIME_WITH_OVERHEAD_t packet;
69 unsigned char crcAsTwoBytes[2];
70
71 // OVERHEAD
72 packet.targetLogicalAddress = DESTINATION_ID_LFR;
73 packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
74 packet.reserved = DEFAULT_RESERVED;
75 packet.userApplication = CCSDS_USER_APP;
76
77 // TIME PACKET
78 packet.update_time.packetID[0] = (unsigned char) (TC_LFR_PACKET_ID >> 8);
79 packet.update_time.packetID[1] = (unsigned char) (TC_LFR_PACKET_ID );
80 packet.update_time.packetSequenceControl[0] = (unsigned char) (TC_LFR_PACKET_SEQUENCE_CONTROL >> 8);
81 packet.update_time.packetSequenceControl[1] = (unsigned char) (TC_LFR_PACKET_SEQUENCE_CONTROL );
82 packet.update_time.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_LFR_UPDATE_TIME >> 8);
83 packet.update_time.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_LFR_UPDATE_TIME );
84
85 packet.update_time.ccsdsSecHeaderFlag_pusVersion_ack = 0x19;
86 packet.update_time.serviceType = TC_TYPE_LFR_UPDATE_TIME;
87 packet.update_time.serviceSubType = TC_SUBTYPE_UPDATE_TIME;
88 packet.update_time.sourceID = SID_TC_RPW_INTERNAL;
89 packet.update_time.cp_rpw_time[0] = (unsigned char) (coarseTime >> 24);
90 packet.update_time.cp_rpw_time[1] = (unsigned char) (coarseTime >> 16);
91 packet.update_time.cp_rpw_time[2] = (unsigned char) (coarseTime >> 8);
92 packet.update_time.cp_rpw_time[3] = (unsigned char) (coarseTime);
93 packet.update_time.cp_rpw_time[4] = 0; // fine time MSB
94 packet.update_time.cp_rpw_time[5] = 0; // fine time LSB
95
96 GetCRCAsTwoBytes((unsigned char*) &packet.update_time, crcAsTwoBytes,
97 PACKET_LENGTH_TC_LFR_UPDATE_TIME + CCSDS_TC_TM_PACKET_OFFSET - 2);
98 packet.update_time.crc[0] = crcAsTwoBytes[0];
99 packet.update_time.crc[1] = crcAsTwoBytes[1];
100
101 messageSize = PACKET_LENGTH_TC_LFR_UPDATE_TIME + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
102
103 // SEND DATA
104 status = rtems_message_queue_send( queue_id, &packet, messageSize);
105 if (status != RTEMS_SUCCESSFUL) {
106 PRINTF("in send_tm_lfr_tc_exe_success *** ERR\n")
107 }
108
109 return status;
110 }
This diff has been collapsed as it changes many lines, (601 lines changed) Show them Hide them
@@ -0,0 +1,601
1 /** Functions related to the SpaceWire interface.
2 *
3 * @file
4 * @author P. LEROY
5 *
6 * A group of functions to handle SpaceWire transmissions:
7 * - configuration of the SpaceWire link
8 * - SpaceWire related interruption requests processing
9 * - transmission of TeleMetry packets by a dedicated RTEMS task
10 * - reception of TeleCommands by a dedicated RTEMS task
11 *
12 */
13
14 #include "timegen_spacewire.h"
15
16 rtems_name semq_name;
17 rtems_id semq_id;
18
19 //***********
20 // RTEMS TASK
21 rtems_task spiq_task(rtems_task_argument unused)
22 {
23 /** This RTEMS task is awaken by an rtems_event sent by the interruption subroutine of the SpaceWire driver.
24 *
25 * @param unused is the starting argument of the RTEMS task
26 *
27 */
28
29 rtems_event_set event_out;
30 rtems_status_code status;
31 int linkStatus;
32
33 BOOT_PRINTF("in SPIQ *** \n")
34
35 while(true){
36 rtems_event_receive(SPW_LINKERR_EVENT, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an SPW_LINKERR_EVENT
37 PRINTF("in SPIQ *** got SPW_LINKERR_EVENT\n")
38
39 // [0] SUSPEND RECV AND SEND TASKS
40 status = rtems_task_suspend( Task_id[ TASKID_RECV ] );
41 if ( status != RTEMS_SUCCESSFUL ) {
42 PRINTF("in SPIQ *** ERR suspending RECV Task\n")
43 }
44 status = rtems_task_suspend( Task_id[ TASKID_SEND ] );
45 if ( status != RTEMS_SUCCESSFUL ) {
46 PRINTF("in SPIQ *** ERR suspending SEND Task\n")
47 }
48
49 // [1] CHECK THE LINK
50 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (1)
51 if ( linkStatus != 5) {
52 PRINTF1("in SPIQ *** linkStatus %d, wait...\n", linkStatus)
53 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
54 }
55
56 // [2] RECHECK THE LINK AFTER SY_LFR_DPU_CONNECT_TIMEOUT
57 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (2)
58 if ( linkStatus != 5 ) // [2.a] not in run state, reset the link
59 {
60 spacewire_compute_stats_offsets();
61 status = spacewire_reset_link( );
62 }
63 else // [2.b] in run state, start the link
64 {
65 status = spacewire_stop_start_link( fdSPW ); // start the link
66 if ( status != RTEMS_SUCCESSFUL)
67 {
68 PRINTF1("in SPIQ *** ERR spacewire_start_link %d\n", status)
69 }
70 }
71
72 // [3] COMPLETE RECOVERY ACTION AFTER SY_LFR_DPU_CONNECT_ATTEMPTS
73 if ( status == RTEMS_SUCCESSFUL ) // [3.a] the link is in run state and has been started successfully
74 {
75 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
76 if ( status != RTEMS_SUCCESSFUL ) {
77 PRINTF("in SPIQ *** ERR resuming SEND Task\n")
78 }
79 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
80 if ( status != RTEMS_SUCCESSFUL ) {
81 PRINTF("in SPIQ *** ERR resuming RECV Task\n")
82 }
83 }
84 else // [3.b] the link is not in run state, go in STANDBY mode
85 {
86 status = stop_current_mode();
87 if ( status != RTEMS_SUCCESSFUL ) {
88 PRINTF1("in SPIQ *** ERR stop_current_mode *** code %d\n", status)
89 }
90 status = enter_mode( LFR_MODE_STANDBY );
91 if ( status != RTEMS_SUCCESSFUL ) {
92 PRINTF1("in SPIQ *** ERR enter_standby_mode *** code %d\n", status)
93 }
94 // wake the WTDG task up to wait for the link recovery
95 status = rtems_event_send ( Task_id[TASKID_WTDG], RTEMS_EVENT_0 );
96 status = rtems_task_suspend( RTEMS_SELF );
97 }
98 }
99 }
100
101 rtems_task recv_task( rtems_task_argument unused )
102 {
103 /** This RTEMS task is dedicated to the reception of incoming TeleCommands.
104 *
105 * @param unused is the starting argument of the RTEMS task
106 *
107 * The RECV task blocks on a call to the read system call, waiting for incoming SpaceWire data. When unblocked:
108 * 1. It reads the incoming data.
109 * 2. Launches the acceptance procedure.
110 * 3. If the Telecommand is valid, sends it to a dedicated RTEMS message queue.
111 *
112 */
113
114 int len;
115 ccsdsTelecommandPacket_t currentTC;
116 unsigned char computed_CRC[ 2 ];
117 unsigned char currentTC_LEN_RCV[ 2 ];
118 unsigned char destinationID;
119 unsigned int currentTC_LEN_RCV_AsUnsignedInt;
120 unsigned int parserCode;
121 unsigned char time[6];
122 rtems_status_code status;
123 rtems_id queue_recv_id;
124 rtems_id queue_send_id;
125
126 initLookUpTableForCRC(); // the table is used to compute Cyclic Redundancy Codes
127
128 status = get_message_queue_id_recv( &queue_recv_id );
129 if (status != RTEMS_SUCCESSFUL)
130 {
131 PRINTF1("in RECV *** ERR get_message_queue_id_recv %d\n", status)
132 }
133
134 status = get_message_queue_id_send( &queue_send_id );
135 if (status != RTEMS_SUCCESSFUL)
136 {
137 PRINTF1("in RECV *** ERR get_message_queue_id_send %d\n", status)
138 }
139
140 BOOT_PRINTF("in RECV *** \n")
141
142 while(1)
143 {
144 len = read( fdSPW, (char*) &currentTC, CCSDS_TC_PKT_MAX_SIZE ); // the call to read is blocking
145 if (len == -1){ // error during the read call
146 PRINTF1("in RECV *** last read call returned -1, ERRNO %d\n", errno)
147 }
148 else {
149 if ( (len+1) < CCSDS_TC_PKT_MIN_SIZE ) {
150 PRINTF("in RECV *** packet lenght too short\n")
151 }
152 else {
153 currentTC_LEN_RCV_AsUnsignedInt = (unsigned int) (len - CCSDS_TC_TM_PACKET_OFFSET - 3); // => -3 is for Prot ID, Reserved and User App bytes
154 currentTC_LEN_RCV[ 0 ] = (unsigned char) (currentTC_LEN_RCV_AsUnsignedInt >> 8);
155 currentTC_LEN_RCV[ 1 ] = (unsigned char) (currentTC_LEN_RCV_AsUnsignedInt );
156 // CHECK THE TC
157 parserCode = tc_parser( &currentTC, currentTC_LEN_RCV_AsUnsignedInt, computed_CRC ) ;
158 if ( (parserCode == ILLEGAL_APID) || (parserCode == WRONG_LEN_PKT)
159 || (parserCode == INCOR_CHECKSUM) || (parserCode == ILL_TYPE)
160 || (parserCode == ILL_SUBTYPE) || (parserCode == WRONG_APP_DATA)
161 || (parserCode == WRONG_SRC_ID) )
162 { // send TM_LFR_TC_EXE_CORRUPTED
163 if ( !( (currentTC.serviceType==TC_TYPE_TIME) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_TIME) )
164 &&
165 !( (currentTC.serviceType==TC_TYPE_GEN) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_INFO))
166 )
167 {
168 if ( parserCode == WRONG_SRC_ID )
169 {
170 destinationID = SID_TC_GROUND;
171 }
172 else
173 {
174 destinationID = currentTC.sourceID;
175 }
176 getTime( time );
177 close_action( &currentTC, LFR_DEFAULT, queue_send_id );
178 send_tm_lfr_tc_exe_corrupted( &currentTC, queue_send_id,
179 computed_CRC, currentTC_LEN_RCV,
180 destinationID );
181 }
182 }
183 else
184 { // send valid TC to the action launcher
185 status = rtems_message_queue_send( queue_recv_id, &currentTC,
186 currentTC_LEN_RCV_AsUnsignedInt + CCSDS_TC_TM_PACKET_OFFSET + 3);
187 }
188 }
189 }
190 }
191 }
192
193 rtems_task send_task( rtems_task_argument argument)
194 {
195 /** This RTEMS task is dedicated to the transmission of TeleMetry packets.
196 *
197 * @param unused is the starting argument of the RTEMS task
198 *
199 * The SEND task waits for a message to become available in the dedicated RTEMS queue. When a message arrives:
200 * - if the first byte is equal to CCSDS_DESTINATION_ID, the message is sent as is using the write system call.
201 * - if the first byte is not equal to CCSDS_DESTINATION_ID, the message is handled as a spw_ioctl_pkt_send. After
202 * analyzis, the packet is sent either using the write system call or using the ioctl call SPACEWIRE_IOCTRL_SEND, depending on the
203 * data it contains.
204 *
205 */
206
207 rtems_status_code status; // RTEMS status code
208 char incomingData[ACTION_MSG_PKTS_MAX_SIZE]; // incoming data buffer
209 size_t size; // size of the incoming TC packet
210 u_int32_t count;
211 rtems_id queue_id;
212
213 status = get_message_queue_id_send( &queue_id );
214 if (status != RTEMS_SUCCESSFUL)
215 {
216 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
217 }
218
219 BOOT_PRINTF("in SEND *** \n")
220
221 while(1)
222 {
223 status = rtems_message_queue_receive( queue_id, incomingData, &size,
224 RTEMS_WAIT, RTEMS_NO_TIMEOUT );
225
226 if (status!=RTEMS_SUCCESSFUL)
227 {
228 PRINTF1("in SEND *** (1) ERR = %d\n", status)
229 }
230 else
231 {
232 status = write( fdSPW, incomingData, size );
233 if (status == -1){
234 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
235 }
236 }
237
238 status = rtems_message_queue_get_number_pending( queue_id, &count );
239 if (status != RTEMS_SUCCESSFUL)
240 {
241 PRINTF1("in SEND *** (3) ERR = %d\n", status)
242 }
243 else
244 {
245 if (count > maxCount)
246 {
247 maxCount = count;
248 }
249 }
250 }
251 }
252
253 rtems_task wtdg_task( rtems_task_argument argument )
254 {
255 rtems_event_set event_out;
256 rtems_status_code status;
257 int linkStatus;
258
259 BOOT_PRINTF("in WTDG ***\n")
260
261 while(1)
262 {
263 // wait for an RTEMS_EVENT
264 rtems_event_receive( RTEMS_EVENT_0,
265 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
266 PRINTF("in WTDG *** wait for the link\n")
267 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
268 while( linkStatus != 5) // wait for the link
269 {
270 rtems_task_wake_after( 10 );
271 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
272 }
273
274 status = spacewire_stop_start_link( fdSPW );
275
276 if (status != RTEMS_SUCCESSFUL)
277 {
278 PRINTF1("in WTDG *** ERR link not started %d\n", status)
279 }
280 else
281 {
282 PRINTF("in WTDG *** OK link started\n")
283 }
284
285 // restart the SPIQ task
286 status = rtems_task_restart( Task_id[TASKID_SPIQ], 1 );
287 if ( status != RTEMS_SUCCESSFUL ) {
288 PRINTF("in SPIQ *** ERR restarting SPIQ Task\n")
289 }
290
291 // restart RECV and SEND
292 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
293 if ( status != RTEMS_SUCCESSFUL ) {
294 PRINTF("in SPIQ *** ERR restarting SEND Task\n")
295 }
296 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
297 if ( status != RTEMS_SUCCESSFUL ) {
298 PRINTF("in SPIQ *** ERR restarting RECV Task\n")
299 }
300 }
301 }
302
303 //****************
304 // OTHER FUNCTIONS
305 int spacewire_open_link( void )
306 {
307 /** This function opens the SpaceWire link.
308 *
309 * @return a valid file descriptor in case of success, -1 in case of a failure
310 *
311 */
312 rtems_status_code status;
313
314 fdSPW = open(GRSPW_DEVICE_NAME, O_RDWR); // open the device. the open call resets the hardware
315 if ( fdSPW < 0 ) {
316 PRINTF1("ERR *** in configure_spw_link *** error opening "GRSPW_DEVICE_NAME" with ERR %d\n", errno)
317 }
318 else
319 {
320 status = RTEMS_SUCCESSFUL;
321 }
322
323 return status;
324 }
325
326 int spacewire_start_link( int fd )
327 {
328 rtems_status_code status;
329
330 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
331 // -1 default hardcoded driver timeout
332
333 return status;
334 }
335
336 int spacewire_stop_start_link( int fd )
337 {
338 rtems_status_code status;
339
340 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_STOP); // start fails if link pDev->running != 0
341 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
342 // -1 default hardcoded driver timeout
343
344 return status;
345 }
346
347 int spacewire_configure_link( int fd )
348 {
349 /** This function configures the SpaceWire link.
350 *
351 * @return GR-RTEMS-DRIVER directive status codes:
352 * - 22 EINVAL - Null pointer or an out of range value was given as the argument.
353 * - 16 EBUSY - Only used for SEND. Returned when no descriptors are avialble in non-blocking mode.
354 * - 88 ENOSYS - Returned for SET_DESTKEY if RMAP command handler is not available or if a non-implemented call is used.
355 * - 116 ETIMEDOUT - REturned for SET_PACKET_SIZE and START if the link could not be brought up.
356 * - 12 ENOMEM - Returned for SET_PACKETSIZE if it was unable to allocate the new buffers.
357 * - 5 EIO - Error when writing to grswp hardware registers.
358 * - 2 ENOENT - No such file or directory
359 */
360
361 rtems_status_code status;
362
363 spacewire_set_NP(1, REGS_ADDR_GRSPW); // [N]o [P]ort force
364 spacewire_set_RE(1, REGS_ADDR_GRSPW); // [R]MAP [E]nable, the dedicated call seems to break the no port force configuration
365
366 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_RXBLOCK, 1); // sets the blocking mode for reception
367 if (status!=RTEMS_SUCCESSFUL) PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_RXBLOCK\n")
368 //
369 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_EVENT_ID, Task_id[TASKID_SPIQ]); // sets the task ID to which an event is sent when a
370 if (status!=RTEMS_SUCCESSFUL) PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_EVENT_ID\n") // link-error interrupt occurs
371 //
372 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_DISABLE_ERR, 0); // automatic link-disabling due to link-error interrupts
373 if (status!=RTEMS_SUCCESSFUL) PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_DISABLE_ERR\n")
374 //
375 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ, 1); // sets the link-error interrupt bit
376 if (status!=RTEMS_SUCCESSFUL) PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ\n")
377 //
378 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK, 0); // transmission blocks
379 if (status!=RTEMS_SUCCESSFUL) PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK\n")
380 //
381 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL, 1); // transmission blocks when no transmission descriptor is available
382 if (status!=RTEMS_SUCCESSFUL) PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL\n")
383 //
384 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TCODE_CTRL, 0x0909); // [Time Rx : Time Tx : Link error : Tick-out IRQ]
385 if (status!=RTEMS_SUCCESSFUL) PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TCODE_CTRL\n")
386
387 return status;
388 }
389
390 int spacewire_reset_link( void )
391 {
392 /** This function is executed by the SPIQ rtems_task wehn it has been awaken by an interruption raised by the SpaceWire driver.
393 *
394 * @return RTEMS directive status code:
395 * - RTEMS_UNSATISFIED is returned is the link is not in the running state after 10 s.
396 * - RTEMS_SUCCESSFUL is returned if the link is up before the timeout.
397 *
398 */
399
400 rtems_status_code status_spw;
401 int i;
402
403 for ( i=0; i<SY_LFR_DPU_CONNECT_ATTEMPT; i++ )
404 {
405 PRINTF1("in spacewire_reset_link *** link recovery, try %d\n", i);
406
407 // CLOSING THE DRIVER AT THIS POINT WILL MAKE THE SEND TASK BLOCK THE SYSTEM
408
409 status_spw = spacewire_stop_start_link( fdSPW );
410 if ( status_spw != RTEMS_SUCCESSFUL )
411 {
412 PRINTF1("in spacewire_reset_link *** ERR spacewire_start_link code %d\n", status_spw)
413 }
414
415 if ( status_spw == RTEMS_SUCCESSFUL)
416 {
417 break;
418 }
419 }
420
421 return status_spw;
422 }
423
424 void spacewire_set_NP( unsigned char val, unsigned int regAddr ) // [N]o [P]ort force
425 {
426 /** This function sets the [N]o [P]ort force bit of the GRSPW control register.
427 *
428 * @param val is the value, 0 or 1, used to set the value of the NP bit.
429 * @param regAddr is the address of the GRSPW control register.
430 *
431 * NP is the bit 20 of the GRSPW control register.
432 *
433 */
434
435 unsigned int *spwptr = (unsigned int*) regAddr;
436
437 if (val == 1) {
438 *spwptr = *spwptr | 0x00100000; // [NP] set the No port force bit
439 }
440 if (val== 0) {
441 *spwptr = *spwptr & 0xffdfffff;
442 }
443 }
444
445 void spacewire_set_RE( unsigned char val, unsigned int regAddr ) // [R]MAP [E]nable
446 {
447 /** This function sets the [R]MAP [E]nable bit of the GRSPW control register.
448 *
449 * @param val is the value, 0 or 1, used to set the value of the RE bit.
450 * @param regAddr is the address of the GRSPW control register.
451 *
452 * RE is the bit 16 of the GRSPW control register.
453 *
454 */
455
456 unsigned int *spwptr = (unsigned int*) regAddr;
457
458 if (val == 1)
459 {
460 *spwptr = *spwptr | 0x00010000; // [RE] set the RMAP Enable bit
461 }
462 if (val== 0)
463 {
464 *spwptr = *spwptr & 0xfffdffff;
465 }
466 }
467
468 void spacewire_compute_stats_offsets( void )
469 {
470 /** This function computes the SpaceWire statistics offsets in case of a SpaceWire related interruption raising.
471 *
472 * The offsets keep a record of the statistics in case of a reset of the statistics. They are added to the current statistics
473 * to keep the counters consistent even after a reset of the SpaceWire driver (the counter are set to zero by the driver when it
474 * during the open systel call).
475 *
476 */
477
478 spw_stats spacewire_stats_grspw;
479 rtems_status_code status;
480
481 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &spacewire_stats_grspw );
482
483 spacewire_stats_backup.packets_received = spacewire_stats_grspw.packets_received
484 + spacewire_stats.packets_received;
485 spacewire_stats_backup.packets_sent = spacewire_stats_grspw.packets_sent
486 + spacewire_stats.packets_sent;
487 spacewire_stats_backup.parity_err = spacewire_stats_grspw.parity_err
488 + spacewire_stats.parity_err;
489 spacewire_stats_backup.disconnect_err = spacewire_stats_grspw.disconnect_err
490 + spacewire_stats.disconnect_err;
491 spacewire_stats_backup.escape_err = spacewire_stats_grspw.escape_err
492 + spacewire_stats.escape_err;
493 spacewire_stats_backup.credit_err = spacewire_stats_grspw.credit_err
494 + spacewire_stats.credit_err;
495 spacewire_stats_backup.write_sync_err = spacewire_stats_grspw.write_sync_err
496 + spacewire_stats.write_sync_err;
497 spacewire_stats_backup.rx_rmap_header_crc_err = spacewire_stats_grspw.rx_rmap_header_crc_err
498 + spacewire_stats.rx_rmap_header_crc_err;
499 spacewire_stats_backup.rx_rmap_data_crc_err = spacewire_stats_grspw.rx_rmap_data_crc_err
500 + spacewire_stats.rx_rmap_data_crc_err;
501 spacewire_stats_backup.early_ep = spacewire_stats_grspw.early_ep
502 + spacewire_stats.early_ep;
503 spacewire_stats_backup.invalid_address = spacewire_stats_grspw.invalid_address
504 + spacewire_stats.invalid_address;
505 spacewire_stats_backup.rx_eep_err = spacewire_stats_grspw.rx_eep_err
506 + spacewire_stats.rx_eep_err;
507 spacewire_stats_backup.rx_truncated = spacewire_stats_grspw.rx_truncated
508 + spacewire_stats.rx_truncated;
509 }
510
511 void spacewire_update_statistics( void )
512 {
513 rtems_status_code status;
514 spw_stats spacewire_stats_grspw;
515
516 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &spacewire_stats_grspw );
517
518 spacewire_stats.packets_received = spacewire_stats_backup.packets_received
519 + spacewire_stats_grspw.packets_received;
520 spacewire_stats.packets_sent = spacewire_stats_backup.packets_sent
521 + spacewire_stats_grspw.packets_sent;
522 spacewire_stats.parity_err = spacewire_stats_backup.parity_err
523 + spacewire_stats_grspw.parity_err;
524 spacewire_stats.disconnect_err = spacewire_stats_backup.disconnect_err
525 + spacewire_stats_grspw.disconnect_err;
526 spacewire_stats.escape_err = spacewire_stats_backup.escape_err
527 + spacewire_stats_grspw.escape_err;
528 spacewire_stats.credit_err = spacewire_stats_backup.credit_err
529 + spacewire_stats_grspw.credit_err;
530 spacewire_stats.write_sync_err = spacewire_stats_backup.write_sync_err
531 + spacewire_stats_grspw.write_sync_err;
532 spacewire_stats.rx_rmap_header_crc_err = spacewire_stats_backup.rx_rmap_header_crc_err
533 + spacewire_stats_grspw.rx_rmap_header_crc_err;
534 spacewire_stats.rx_rmap_data_crc_err = spacewire_stats_backup.rx_rmap_data_crc_err
535 + spacewire_stats_grspw.rx_rmap_data_crc_err;
536 spacewire_stats.early_ep = spacewire_stats_backup.early_ep
537 + spacewire_stats_grspw.early_ep;
538 spacewire_stats.invalid_address = spacewire_stats_backup.invalid_address
539 + spacewire_stats_grspw.invalid_address;
540 spacewire_stats.rx_eep_err = spacewire_stats_backup.rx_eep_err
541 + spacewire_stats_grspw.rx_eep_err;
542 spacewire_stats.rx_truncated = spacewire_stats_backup.rx_truncated
543 + spacewire_stats_grspw.rx_truncated;
544 //spacewire_stats.tx_link_err;
545
546 //****************************
547 // DPU_SPACEWIRE_IF_STATISTICS
548 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[0] = (unsigned char) (spacewire_stats.packets_received >> 8);
549 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[1] = (unsigned char) (spacewire_stats.packets_received);
550 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[0] = (unsigned char) (spacewire_stats.packets_sent >> 8);
551 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[1] = (unsigned char) (spacewire_stats.packets_sent);
552 //housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt;
553 //housekeeping_packet.hk_lfr_dpu_spw_last_timc;
554
555 //******************************************
556 // ERROR COUNTERS / SPACEWIRE / LOW SEVERITY
557 housekeeping_packet.hk_lfr_dpu_spw_parity = (unsigned char) spacewire_stats.parity_err;
558 housekeeping_packet.hk_lfr_dpu_spw_disconnect = (unsigned char) spacewire_stats.disconnect_err;
559 housekeeping_packet.hk_lfr_dpu_spw_escape = (unsigned char) spacewire_stats.escape_err;
560 housekeeping_packet.hk_lfr_dpu_spw_credit = (unsigned char) spacewire_stats.credit_err;
561 housekeeping_packet.hk_lfr_dpu_spw_write_sync = (unsigned char) spacewire_stats.write_sync_err;
562
563 //*********************************************
564 // ERROR COUNTERS / SPACEWIRE / MEDIUM SEVERITY
565 housekeeping_packet.hk_lfr_dpu_spw_early_eop = (unsigned char) spacewire_stats.early_ep;
566 housekeeping_packet.hk_lfr_dpu_spw_invalid_addr = (unsigned char) spacewire_stats.invalid_address;
567 housekeeping_packet.hk_lfr_dpu_spw_eep = (unsigned char) spacewire_stats.rx_eep_err;
568 housekeeping_packet.hk_lfr_dpu_spw_rx_too_big = (unsigned char) spacewire_stats.rx_truncated;
569 }
570
571 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc )
572 {
573 // rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_1 );
574 struct grgpio_regs_str *grgpio_regs = (struct grgpio_regs_str *) REGS_ADDR_GRGPIO;
575
576 grgpio_regs->io_port_direction_register =
577 grgpio_regs->io_port_direction_register | 0x08; // [0001 1000], 0 = output disabled, 1 = output enabled
578
579 if ( (grgpio_regs->io_port_output_register & 0x08) == 0x08 )
580 {
581 grgpio_regs->io_port_output_register = grgpio_regs->io_port_output_register & 0xf7;
582 }
583 else
584 {
585 grgpio_regs->io_port_output_register = grgpio_regs->io_port_output_register | 0x08;
586 }
587
588 }
589
590 rtems_timer_service_routine user_routine( rtems_id timer_id, void *user_data )
591 {
592 int linkStatus;
593 rtems_status_code status;
594
595 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
596
597 if ( linkStatus == 5) {
598 PRINTF("in spacewire_reset_link *** link is running\n")
599 status = RTEMS_SUCCESSFUL;
600 }
601 }
This diff has been collapsed as it changes many lines, (793 lines changed) Show them Hide them
@@ -0,0 +1,793
1 /** Functions and tasks related to TeleCommand handling.
2 *
3 * @file
4 * @author P. LEROY
5 *
6 * A group of functions to handle TeleCommands:\n
7 * action launching\n
8 * TC parsing\n
9 * ...
10 *
11 */
12
13 #include "timegen_tc_handler.h"
14
15 //***********
16 // RTEMS TASK
17
18 rtems_task actn_task( rtems_task_argument unused )
19 {
20 /** This RTEMS task is responsible for launching actions upton the reception of valid TeleCommands.
21 *
22 * @param unused is the starting argument of the RTEMS task
23 *
24 * The ACTN task waits for data coming from an RTEMS msesage queue. When data arrives, it launches specific actions depending
25 * on the incoming TeleCommand.
26 *
27 */
28
29 int result;
30 rtems_status_code status; // RTEMS status code
31 ccsdsTelecommandPacket_t TC; // TC sent to the ACTN task
32 size_t size; // size of the incoming TC packet
33 unsigned char subtype; // subtype of the current TC packet
34 unsigned char time[6];
35 rtems_id queue_rcv_id;
36 rtems_id queue_snd_id;
37
38 status = get_message_queue_id_recv( &queue_rcv_id );
39 if (status != RTEMS_SUCCESSFUL)
40 {
41 PRINTF1("in ACTN *** ERR get_message_queue_id_recv %d\n", status)
42 }
43
44 status = get_message_queue_id_send( &queue_snd_id );
45 if (status != RTEMS_SUCCESSFUL)
46 {
47 PRINTF1("in ACTN *** ERR get_message_queue_id_send %d\n", status)
48 }
49
50 result = LFR_SUCCESSFUL;
51 subtype = 0; // subtype of the current TC packet
52
53 BOOT_PRINTF("in ACTN *** \n")
54
55 while(1)
56 {
57 status = rtems_message_queue_receive( queue_rcv_id, (char*) &TC, &size,
58 RTEMS_WAIT, RTEMS_NO_TIMEOUT);
59 getTime( time ); // set time to the current time
60 if (status!=RTEMS_SUCCESSFUL)
61 {
62 PRINTF1("ERR *** in task ACTN *** error receiving a message, code %d \n", status)
63 }
64 else
65 {
66 subtype = TC.serviceSubType;
67 switch(subtype)
68 {
69 case TC_SUBTYPE_RESET:
70 // result = action_reset( &TC, queue_snd_id, time );
71 close_action( &TC, result, queue_snd_id );
72 break;
73 //
74 case TC_SUBTYPE_LOAD_COMM:
75 // result = action_load_common_par( &TC );
76 close_action( &TC, result, queue_snd_id );
77 break;
78 //
79 case TC_SUBTYPE_LOAD_NORM:
80 // result = action_load_normal_par( &TC, queue_snd_id, time );
81 close_action( &TC, result, queue_snd_id );
82 break;
83 //
84 case TC_SUBTYPE_LOAD_BURST:
85 // result = action_load_burst_par( &TC, queue_snd_id, time );
86 close_action( &TC, result, queue_snd_id );
87 break;
88 //
89 case TC_SUBTYPE_LOAD_SBM1:
90 // result = action_load_sbm1_par( &TC, queue_snd_id, time );
91 close_action( &TC, result, queue_snd_id );
92 break;
93 //
94 case TC_SUBTYPE_LOAD_SBM2:
95 // result = action_load_sbm2_par( &TC, queue_snd_id, time );
96 close_action( &TC, result, queue_snd_id );
97 break;
98 //
99 case TC_SUBTYPE_DUMP:
100 // result = action_dump_par( queue_snd_id );
101 close_action( &TC, result, queue_snd_id );
102 break;
103 //
104 case TC_SUBTYPE_ENTER:
105 result = action_enter_mode( &TC, queue_snd_id, time );
106 close_action( &TC, result, queue_snd_id );
107 break;
108 //
109 case TC_SUBTYPE_UPDT_INFO:
110 // result = action_update_info( &TC, queue_snd_id );
111 close_action( &TC, result, queue_snd_id );
112 break;
113 //
114 case TC_SUBTYPE_EN_CAL:
115 // result = action_enable_calibration( &TC, queue_snd_id, time );
116 close_action( &TC, result, queue_snd_id );
117 break;
118 //
119 case TC_SUBTYPE_DIS_CAL:
120 // result = action_disable_calibration( &TC, queue_snd_id, time );
121 close_action( &TC, result, queue_snd_id );
122 break;
123 //
124 case TC_SUBTYPE_UPDT_TIME:
125 result = action_update_time( &TC );
126 close_action( &TC, result, queue_snd_id );
127 break;
128 //
129 default:
130 break;
131 }
132 }
133 }
134 }
135
136 //***********
137 // TC ACTIONS
138
139 int action_reset(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
140 {
141 /** This function executes specific actions when a TC_LFR_RESET TeleCommand has been received.
142 *
143 * @param TC points to the TeleCommand packet that is being processed
144 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
145 *
146 */
147
148 send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time );
149 return LFR_DEFAULT;
150 }
151
152 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
153 {
154 /** This function executes specific actions when a TC_LFR_ENTER_MODE TeleCommand has been received.
155 *
156 * @param TC points to the TeleCommand packet that is being processed
157 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
158 *
159 */
160
161 rtems_status_code status;
162 unsigned char requestedMode;
163
164 requestedMode = TC->dataAndCRC[1];
165
166 if ( (requestedMode != LFR_MODE_STANDBY)
167 && (requestedMode != LFR_MODE_NORMAL) && (requestedMode != LFR_MODE_BURST)
168 && (requestedMode != LFR_MODE_SBM1) && (requestedMode != LFR_MODE_SBM2) )
169 {
170 status = RTEMS_UNSATISFIED;
171 send_tm_lfr_tc_exe_inconsistent( TC, queue_id, BYTE_POS_CP_LFR_MODE, requestedMode );
172 }
173 else
174 {
175 printf("in action_enter_mode *** enter mode %d\n", requestedMode);
176
177 status = transition_validation(requestedMode);
178
179 if ( status == LFR_SUCCESSFUL ) {
180 if ( lfrCurrentMode != LFR_MODE_STANDBY)
181 {
182 status = stop_current_mode();
183 }
184 if (status != RTEMS_SUCCESSFUL)
185 {
186 PRINTF("ERR *** in action_enter *** stop_current_mode\n")
187 }
188 status = enter_mode( requestedMode );
189 }
190 else
191 {
192 PRINTF("ERR *** in action_enter *** transition rejected\n")
193 send_tm_lfr_tc_exe_not_executable( TC, queue_id );
194 }
195 }
196
197 return status;
198 }
199
200 int action_update_info(ccsdsTelecommandPacket_t *TC, rtems_id queue_id)
201 {
202 // /** This function executes specific actions when a TC_LFR_UPDATE_INFO TeleCommand has been received.
203 // *
204 // * @param TC points to the TeleCommand packet that is being processed
205 // * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
206 // *
207 // * @return LFR directive status code:
208 // * - LFR_DEFAULT
209 // * - LFR_SUCCESSFUL
210 // *
211 // */
212
213 // unsigned int val;
214 int result;
215
216 result = LFR_DEFAULT;
217 // unsigned int status;
218 // unsigned char mode;
219
220 // // check LFR MODE
221 // mode = (TC->dataAndCRC[ BYTE_POS_HK_UPDATE_INFO_PAR_SET5 ] & 0x1e) >> 1;
222 // status = check_update_info_hk_lfr_mode( mode );
223 // if (status != LFR_DEFAULT) // check TDS mode
224 // {
225 // mode = (TC->dataAndCRC[ BYTE_POS_HK_UPDATE_INFO_PAR_SET6 ] & 0xf0) >> 4;
226 // status = check_update_info_hk_tds_mode( mode );
227 // }
228 // if (status != LFR_DEFAULT) // check THR mode
229 // {
230 // mode = (TC->dataAndCRC[ BYTE_POS_HK_UPDATE_INFO_PAR_SET6 ] & 0x0f);
231 // status = check_update_info_hk_thr_mode( mode );
232 // }
233 // if (status != LFR_DEFAULT) // if the parameter check is successful
234 // {
235 // val = housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * 256
236 // + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
237 // val++;
238 // housekeeping_packet.hk_lfr_update_info_tc_cnt[0] = (unsigned char) (val >> 8);
239 // housekeeping_packet.hk_lfr_update_info_tc_cnt[1] = (unsigned char) (val);
240 // }
241
242 // result = status;
243
244 return result;
245 }
246
247 int action_enable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
248 {
249 /** This function executes specific actions when a TC_LFR_ENABLE_CALIBRATION TeleCommand has been received.
250 *
251 * @param TC points to the TeleCommand packet that is being processed
252 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
253 *
254 */
255
256 int result;
257 unsigned char lfrMode;
258
259 result = LFR_DEFAULT;
260 lfrMode = (housekeeping_packet.lfr_status_word[0] & 0xf0) >> 4;
261
262 send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time );
263 result = LFR_DEFAULT;
264
265 return result;
266 }
267
268 int action_disable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
269 {
270 /** This function executes specific actions when a TC_LFR_DISABLE_CALIBRATION TeleCommand has been received.
271 *
272 * @param TC points to the TeleCommand packet that is being processed
273 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
274 *
275 */
276
277 int result;
278 unsigned char lfrMode;
279
280 result = LFR_DEFAULT;
281 lfrMode = (housekeeping_packet.lfr_status_word[0] & 0xf0) >> 4;
282
283 send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time );
284 result = LFR_DEFAULT;
285
286 return result;
287 }
288
289 int action_update_time(ccsdsTelecommandPacket_t *TC)
290 {
291 /** This function executes specific actions when a TC_LFR_UPDATE_TIME TeleCommand has been received.
292 *
293 * @param TC points to the TeleCommand packet that is being processed
294 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
295 *
296 * @return LFR_SUCCESSFUL
297 *
298 */
299
300 unsigned int val;
301
302 time_management_regs->coarse_time_load = (TC->dataAndCRC[0] << 24)
303 + (TC->dataAndCRC[1] << 16)
304 + (TC->dataAndCRC[2] << 8)
305 + TC->dataAndCRC[3];
306 val = housekeeping_packet.hk_lfr_update_time_tc_cnt[0] * 256
307 + housekeeping_packet.hk_lfr_update_time_tc_cnt[1];
308 val++;
309 housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char) (val >> 8);
310 housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char) (val);
311 // time_management_regs->ctrl = time_management_regs->ctrl | 1; // force tick
312
313 return LFR_SUCCESSFUL;
314 }
315
316 //*******************
317 // ENTERING THE MODES
318
319 int transition_validation(unsigned char requestedMode)
320 {
321 /** This function checks the validity of the transition requested by the TC_LFR_ENTER_MODE.
322 *
323 * @param requestedMode is the mode requested by the TC_LFR_ENTER_MODE
324 *
325 * @return LFR directive status codes:
326 * - LFR_SUCCESSFUL - the transition is authorized
327 * - LFR_DEFAULT - the transition is not authorized
328 *
329 */
330
331 int status;
332
333 switch (requestedMode)
334 {
335 case LFR_MODE_STANDBY:
336 if ( lfrCurrentMode == LFR_MODE_STANDBY ) {
337 status = LFR_DEFAULT;
338 }
339 else
340 {
341 status = LFR_SUCCESSFUL;
342 }
343 break;
344 case LFR_MODE_NORMAL:
345 if ( lfrCurrentMode == LFR_MODE_NORMAL ) {
346 status = LFR_DEFAULT;
347 }
348 else {
349 status = LFR_SUCCESSFUL;
350 }
351 break;
352 case LFR_MODE_BURST:
353 if ( lfrCurrentMode == LFR_MODE_BURST ) {
354 status = LFR_DEFAULT;
355 }
356 else {
357 status = LFR_SUCCESSFUL;
358 }
359 break;
360 case LFR_MODE_SBM1:
361 if ( lfrCurrentMode == LFR_MODE_SBM1 ) {
362 status = LFR_DEFAULT;
363 }
364 else {
365 status = LFR_SUCCESSFUL;
366 }
367 break;
368 case LFR_MODE_SBM2:
369 if ( lfrCurrentMode == LFR_MODE_SBM2 ) {
370 status = LFR_DEFAULT;
371 }
372 else {
373 status = LFR_SUCCESSFUL;
374 }
375 break;
376 default:
377 status = LFR_DEFAULT;
378 break;
379 }
380
381 return status;
382 }
383
384 int stop_current_mode(void)
385 {
386 /** This function stops the current mode by masking interrupt lines and suspending science tasks.
387 *
388 * @return RTEMS directive status codes:
389 * - RTEMS_SUCCESSFUL - task restarted successfully
390 * - RTEMS_INVALID_ID - task id invalid
391 * - RTEMS_ALREADY_SUSPENDED - task already suspended
392 *
393 */
394
395 rtems_status_code status;
396
397 status = RTEMS_SUCCESSFUL;
398
399 // (1) mask interruptions
400 LEON_Mask_interrupt( IRQ_WAVEFORM_PICKER ); // mask waveform picker interrupt
401 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
402
403 // (2) clear interruptions
404 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER ); // clear waveform picker interrupt
405 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
406
407 // (3) reset registers
408 // waveform picker
409 // reset_wfp_burst_enable(); // reset burst and enable bits
410 // reset_wfp_status(); // reset all the status bits
411 // spectral matrices
412 set_irq_on_new_ready_matrix( 0 ); // stop the spectral matrices
413 set_run_matrix_spectral( 0 ); // run_matrix_spectral is set to 0
414 // reset_extractSWF(); // reset the extractSWF flag to false
415
416 // <Spectral Matrices simulator>
417 LEON_Mask_interrupt( IRQ_SM_SIMULATOR ); // mask spectral matrix interrupt simulator
418 timer_stop( (gptimer_regs_t*) REGS_ADDR_GPTIMER, TIMER_SM_SIMULATOR );
419 LEON_Clear_interrupt( IRQ_SM_SIMULATOR ); // clear spectral matrix interrupt simulator
420 // </Spectral Matrices simulator>
421
422 // suspend several tasks
423 if (lfrCurrentMode != LFR_MODE_STANDBY) {
424 status = suspend_science_tasks();
425 }
426
427 if (status != RTEMS_SUCCESSFUL)
428 {
429 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
430 }
431
432 return status;
433 }
434
435 int enter_mode(unsigned char mode )
436 {
437 /** This function is launched after a mode transition validation.
438 *
439 * @param mode is the mode in which LFR will be put.
440 *
441 * @return RTEMS directive status codes:
442 * - RTEMS_SUCCESSFUL - the mode has been entered successfully
443 * - RTEMS_NOT_SATISFIED - the mode has not been entered successfully
444 *
445 */
446
447 rtems_status_code status;
448
449 status = RTEMS_UNSATISFIED;
450
451 housekeeping_packet.lfr_status_word[0] = (unsigned char) ((mode << 4) + 0x0d);
452 updateLFRCurrentMode();
453
454 if ( (mode == LFR_MODE_NORMAL) || (mode == LFR_MODE_BURST)
455 || (mode == LFR_MODE_SBM1) || (mode == LFR_MODE_SBM2) )
456 {
457 #ifdef PRINT_TASK_STATISTICS
458 rtems_cpu_usage_reset();
459 maxCount = 0;
460 #endif
461 status = restart_science_tasks();
462 // launch_waveform_picker( mode );
463 // launch_spectral_matrix( mode );
464 }
465 else if ( mode == LFR_MODE_STANDBY )
466 {
467 #ifdef PRINT_TASK_STATISTICS
468 rtems_cpu_usage_report();
469 #endif
470
471 #ifdef PRINT_STACK_REPORT
472 rtems_stack_checker_report_usage();
473 #endif
474 status = stop_current_mode();
475 PRINTF1("maxCount = %d\n", maxCount)
476 }
477 else
478 {
479 status = RTEMS_UNSATISFIED;
480 }
481
482 if (status != RTEMS_SUCCESSFUL)
483 {
484 PRINTF1("in enter_mode *** ERR = %d\n", status)
485 status = RTEMS_UNSATISFIED;
486 }
487
488 return status;
489 }
490
491 int restart_science_tasks()
492 {
493 /** This function is used to restart all science tasks.
494 *
495 * @return RTEMS directive status codes:
496 * - RTEMS_SUCCESSFUL - task restarted successfully
497 * - RTEMS_INVALID_ID - task id invalid
498 * - RTEMS_INCORRECT_STATE - task never started
499 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
500 *
501 * Science tasks are AVF0, BPF0, WFRM, CWF3, CW2, CWF1
502 *
503 */
504
505 rtems_status_code status[6];
506 rtems_status_code ret;
507
508 ret = RTEMS_SUCCESSFUL;
509
510 status[0] = rtems_task_restart( Task_id[TASKID_AVF0], 1 );
511 if (status[0] != RTEMS_SUCCESSFUL)
512 {
513 PRINTF1("in restart_science_task *** 0 ERR %d\n", status[0])
514 }
515
516 status[2] = rtems_task_restart( Task_id[TASKID_WFRM],1 );
517 if (status[2] != RTEMS_SUCCESSFUL)
518 {
519 PRINTF1("in restart_science_task *** 2 ERR %d\n", status[2])
520 }
521
522 status[3] = rtems_task_restart( Task_id[TASKID_CWF3],1 );
523 if (status[3] != RTEMS_SUCCESSFUL)
524 {
525 PRINTF1("in restart_science_task *** 3 ERR %d\n", status[3])
526 }
527
528 status[4] = rtems_task_restart( Task_id[TASKID_CWF2],1 );
529 if (status[4] != RTEMS_SUCCESSFUL)
530 {
531 PRINTF1("in restart_science_task *** 4 ERR %d\n", status[4])
532 }
533
534 status[5] = rtems_task_restart( Task_id[TASKID_CWF1],1 );
535 if (status[5] != RTEMS_SUCCESSFUL)
536 {
537 PRINTF1("in restart_science_task *** 5 ERR %d\n", status[5])
538 }
539
540 if ( (status[0] != RTEMS_SUCCESSFUL) || (status[2] != RTEMS_SUCCESSFUL) ||
541 (status[3] != RTEMS_SUCCESSFUL) || (status[4] != RTEMS_SUCCESSFUL) || (status[5] != RTEMS_SUCCESSFUL) )
542 {
543 ret = RTEMS_UNSATISFIED;
544 }
545
546 return ret;
547 }
548
549 int suspend_science_tasks()
550 {
551 /** This function suspends the science tasks.
552 *
553 * @return RTEMS directive status codes:
554 * - RTEMS_SUCCESSFUL - task restarted successfully
555 * - RTEMS_INVALID_ID - task id invalid
556 * - RTEMS_ALREADY_SUSPENDED - task already suspended
557 *
558 */
559
560 rtems_status_code status;
561
562 status = rtems_task_suspend( Task_id[TASKID_AVF0] );
563 if (status != RTEMS_SUCCESSFUL)
564 {
565 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
566 }
567
568 if (status == RTEMS_SUCCESSFUL) // suspend WFRM
569 {
570 status = rtems_task_suspend( Task_id[TASKID_WFRM] );
571 if (status != RTEMS_SUCCESSFUL)
572 {
573 PRINTF1("in suspend_science_task *** WFRM ERR %d\n", status)
574 }
575 }
576
577 if (status == RTEMS_SUCCESSFUL) // suspend CWF3
578 {
579 status = rtems_task_suspend( Task_id[TASKID_CWF3] );
580 if (status != RTEMS_SUCCESSFUL)
581 {
582 PRINTF1("in suspend_science_task *** CWF3 ERR %d\n", status)
583 }
584 }
585
586 if (status == RTEMS_SUCCESSFUL) // suspend CWF2
587 {
588 status = rtems_task_suspend( Task_id[TASKID_CWF2] );
589 if (status != RTEMS_SUCCESSFUL)
590 {
591 PRINTF1("in suspend_science_task *** CWF2 ERR %d\n", status)
592 }
593 }
594
595 if (status == RTEMS_SUCCESSFUL) // suspend CWF1
596 {
597 status = rtems_task_suspend( Task_id[TASKID_CWF1] );
598 if (status != RTEMS_SUCCESSFUL)
599 {
600 PRINTF1("in suspend_science_task *** CWF1 ERR %d\n", status)
601 }
602 }
603
604 return status;
605 }
606
607 void launch_waveform_picker( unsigned char mode )
608 {
609 // int startDate;
610
611 // reset_current_ring_nodes();
612 // reset_waveform_picker_regs();
613 // set_wfp_burst_enable_register( mode );
614
615 // LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER );
616 // LEON_Unmask_interrupt( IRQ_WAVEFORM_PICKER );
617
618 // startDate = time_management_regs->coarse_time + 2;
619 // waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x80; // [1000 0000]
620 // waveform_picker_regs->start_date = startDate;
621 }
622
623 void launch_spectral_matrix( unsigned char mode )
624 {
625 // reset_nb_sm_f0();
626 // reset_current_sm_ring_nodes();
627 // reset_spectral_matrix_regs();
628
629 //#ifdef VHDL_DEV
630 // set_irq_on_new_ready_matrix( 1 );
631 // LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX );
632 // LEON_Unmask_interrupt( IRQ_SPECTRAL_MATRIX );
633 // set_run_matrix_spectral( 1 );
634 //#else
635 // // Spectral Matrices simulator
636 // timer_start( (gptimer_regs_t*) REGS_ADDR_GPTIMER, TIMER_SM_SIMULATOR );
637 // LEON_Clear_interrupt( IRQ_SM_SIMULATOR );
638 // LEON_Unmask_interrupt( IRQ_SM_SIMULATOR );
639 //#endif
640 }
641
642 void set_irq_on_new_ready_matrix( unsigned char value )
643 {
644 if (value == 1)
645 {
646 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x01;
647 }
648 else
649 {
650 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffe; // 1110
651 }
652 }
653
654 void set_run_matrix_spectral( unsigned char value )
655 {
656 if (value == 1)
657 {
658 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x4; // 0100 set run_matrix spectral to 1
659 }
660 else
661 {
662 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffb; // 1011 set run_matrix spectral to 0
663 }
664 }
665
666 void launch_spectral_matrix_simu( unsigned char mode )
667 {
668 // reset_nb_sm_f0();
669 // reset_current_sm_ring_nodes();
670 // reset_spectral_matrix_regs();
671
672 // // Spectral Matrices simulator
673 // timer_start( (gptimer_regs_t*) REGS_ADDR_GPTIMER, TIMER_SM_SIMULATOR );
674 // LEON_Clear_interrupt( IRQ_SM_SIMULATOR );
675 // LEON_Unmask_interrupt( IRQ_SM_SIMULATOR );
676 // set_local_nb_interrupt_f0_MAX();
677 }
678
679 //****************
680 // CLOSING ACTIONS
681 void update_last_TC_exe(ccsdsTelecommandPacket_t *TC)
682 {
683 /** This function is used to update the HK packets statistics after a successful TC execution.
684 *
685 * @param TC points to the TC being processed
686 * @param time is the time used to date the TC execution
687 *
688 */
689
690 housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
691 housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
692 housekeeping_packet.hk_lfr_last_exe_tc_type[0] = 0x00;
693 housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
694 housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = 0x00;
695 housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
696 housekeeping_packet.hk_lfr_last_exe_tc_time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
697 housekeeping_packet.hk_lfr_last_exe_tc_time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
698 housekeeping_packet.hk_lfr_last_exe_tc_time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
699 housekeeping_packet.hk_lfr_last_exe_tc_time[3] = (unsigned char) (time_management_regs->coarse_time);
700 housekeeping_packet.hk_lfr_last_exe_tc_time[4] = (unsigned char) (time_management_regs->fine_time>>8);
701 housekeeping_packet.hk_lfr_last_exe_tc_time[5] = (unsigned char) (time_management_regs->fine_time);
702 }
703
704 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC )
705 {
706 /** This function is used to update the HK packets statistics after a TC rejection.
707 *
708 * @param TC points to the TC being processed
709 * @param time is the time used to date the TC rejection
710 *
711 */
712
713 housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
714 housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
715 housekeeping_packet.hk_lfr_last_rej_tc_type[0] = 0x00;
716 housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
717 housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = 0x00;
718 housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
719 housekeeping_packet.hk_lfr_last_rej_tc_time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
720 housekeeping_packet.hk_lfr_last_rej_tc_time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
721 housekeeping_packet.hk_lfr_last_rej_tc_time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
722 housekeeping_packet.hk_lfr_last_rej_tc_time[3] = (unsigned char) (time_management_regs->coarse_time);
723 housekeeping_packet.hk_lfr_last_rej_tc_time[4] = (unsigned char) (time_management_regs->fine_time>>8);
724 housekeeping_packet.hk_lfr_last_rej_tc_time[5] = (unsigned char) (time_management_regs->fine_time);
725 }
726
727 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id )
728 {
729 /** This function is the last step of the TC execution workflow.
730 *
731 * @param TC points to the TC being processed
732 * @param result is the result of the TC execution (LFR_SUCCESSFUL / LFR_DEFAULT)
733 * @param queue_id is the id of the RTEMS message queue used to send TM packets
734 * @param time is the time used to date the TC execution
735 *
736 */
737
738 unsigned int val = 0;
739
740 if (result == LFR_SUCCESSFUL)
741 {
742 if ( !( (TC->serviceType==TC_TYPE_TIME) && (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
743 &&
744 !( (TC->serviceType==TC_TYPE_GEN) && (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
745 )
746 {
747 send_tm_lfr_tc_exe_success( TC, queue_id );
748 }
749 update_last_TC_exe( TC );
750 val = housekeeping_packet.hk_lfr_exe_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
751 val++;
752 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> 8);
753 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
754 }
755 else
756 {
757 update_last_TC_rej( TC );
758 val = housekeeping_packet.hk_lfr_rej_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
759 val++;
760 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> 8);
761 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
762 }
763 }
764
765 //***************************
766 // Interrupt Service Routines
767 rtems_isr commutation_isr1( rtems_vector_number vector )
768 {
769 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
770 printf("In commutation_isr1 *** Error sending event to DUMB\n");
771 }
772 }
773
774 rtems_isr commutation_isr2( rtems_vector_number vector )
775 {
776 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
777 printf("In commutation_isr2 *** Error sending event to DUMB\n");
778 }
779 }
780
781 //****************
782 // OTHER FUNCTIONS
783 void updateLFRCurrentMode()
784 {
785 /** This function updates the value of the global variable lfrCurrentMode.
786 *
787 * lfrCurrentMode is a parameter used by several functions to know in which mode LFR is running.
788 *
789 */
790 // update the local value of lfrCurrentMode with the value contained in the housekeeping_packet structure
791 lfrCurrentMode = (housekeeping_packet.lfr_status_word[0] & 0xf0) >> 4;
792 }
793
@@ -1,6 +1,6
1 1 #############################################################################
2 2 # Makefile for building: bin/fsw
3 # Generated by qmake (2.01a) (Qt 4.8.5) on: Tue Mar 11 15:58:37 2014
3 # Generated by qmake (2.01a) (Qt 4.8.5) on: Tue Mar 25 09:47:02 2014
4 4 # Project: fsw-qt.pro
5 5 # Template: app
6 6 # Command: /usr/bin/qmake-qt4 -spec /usr/lib64/qt4/mkspecs/linux-g++ -o Makefile fsw-qt.pro
@@ -10,7 +10,7
10 10
11 11 CC = sparc-rtems-gcc
12 12 CXX = sparc-rtems-g++
13 DEFINES = -DSW_VERSION_N1=1 -DSW_VERSION_N2=0 -DSW_VERSION_N3=0 -DSW_VERSION_N4=3 -DPRINT_MESSAGES_ON_CONSOLE -DDEBUG_MESSAGES
13 DEFINES = -DSW_VERSION_N1=1 -DSW_VERSION_N2=0 -DSW_VERSION_N3=0 -DSW_VERSION_N4=3 -DVHDL_DEV -DPRINT_MESSAGES_ON_CONSOLE
14 14 CFLAGS = -pipe -O3 -Wall $(DEFINES)
15 15 CXXFLAGS = -pipe -O3 -Wall $(DEFINES)
16 16 INCPATH = -I/usr/lib64/qt4/mkspecs/linux-g++ -I. -I../src -I../header -I../../LFR_basic-parameters
@@ -1,5 +1,8
1 1 #!/usr/bin/lppmon -e
2 2
3 RMAPPlugin0.setValueSpaceWireLinkNumber( 1 )
4 RMAPPlugin0.setValueTargetLogicalAddress( 254 )
5
3 6 dsu3plugin0.openFile("/opt/DEV_PLE/FSW-qt/bin/fsw")
4 7 dsu3plugin0.loadFile()
5 8 dsu3plugin0.run()
@@ -1,7 +1,7
1 1 TEMPLATE = app
2 2 # CONFIG += console v8 sim
3 # CONFIG options = verbose *** boot_messages *** debug_messages *** cpu_usage_report *** stack_report *** vhdl_dev
4 CONFIG += console verbose debug_messages
3 # CONFIG options = verbose *** boot_messages *** debug_messages *** cpu_usage_report *** stack_report *** vhdl_dev *** debug_tch
4 CONFIG += console verbose vhdl_dev
5 5 CONFIG -= qt
6 6
7 7 include(./sparc.pri)
@@ -13,6 +13,10 DEFINES += SW_VERSION_N2=0 # minor
13 13 DEFINES += SW_VERSION_N3=0 # patch
14 14 DEFINES += SW_VERSION_N4=3 # internal
15 15
16 contains( CONFIG, debug_tch ) {
17 DEFINES += DEBUG_TCH
18 }
19
16 20 contains( CONFIG, vhdl_dev ) {
17 21 DEFINES += VHDL_DEV
18 22 }
@@ -1,6 +1,6
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2 <!DOCTYPE QtCreatorProject>
3 <!-- Written by QtCreator 3.0.1, 2014-03-13T15:53:26. -->
3 <!-- Written by QtCreator 3.0.1, 2014-03-25T08:40:48. -->
4 4 <qtcreator>
5 5 <data>
6 6 <variable>ProjectExplorer.Project.ActiveTarget</variable>
@@ -31,6 +31,7
31 31 #define TM_PACKET_CAT_HK 4
32 32 #define TM_PACKET_CAT_PARAMETER_DUMP 9
33 33 #define TM_PACKET_CAT_SCIENCE 12
34 #define TC_PACKET_CAT 12
34 35
35 36 // PACKET SEQUENCE CONTROL
36 37 #define TM_PACKET_SEQ_CTRL_CONTINUATION 0x00 // [0000 0000]
@@ -104,6 +104,7 typedef struct ring_node
104 104 #define REGS_ADDR_GPTIMER 0x80000300
105 105 #define REGS_ADDR_GRSPW 0x80000500
106 106 #define REGS_ADDR_TIME_MANAGEMENT 0x80000600
107 #define REGS_ADDR_GRGPIO 0x80000b00
107 108
108 109 #ifdef VHDL_DEV
109 110 #define REGS_ADDR_SPECTRAL_MATRIX 0x80000f00
@@ -4,6 +4,9
4 4 #define NB_BINS_PER_SM 128
5 5 #define NB_VALUES_PER_SM 25
6 6 #define TOTAL_SIZE_SM 3200 // 25 * 128
7 #define TOTAL_SIZE_BP1_F0 99 // 11 * 9 = 99
8 #define TOTAL_SIZE_BP1_F1 117 // 13 * 9 = 117
9 #define TOTAL_SIZE_BP1_F2 108 // 12 * 9 = 108
7 10 //
8 11 #define NB_RING_NODES_ASM_F0 12 // AT LEAST 3
9 12 #define NB_RING_NODES_ASM_F1 2 // AT LEAST 3
@@ -10,7 +10,6
10 10
11 11 #include "fsw_params.h"
12 12 #include "fsw_spacewire.h"
13 #include "basic_parameters.h"
14 13
15 14 extern volatile int sm_f0[ ];
16 15 extern volatile int sm_f1[ ];
@@ -11,11 +11,16 struct apbuart_regs_str{
11 11 volatile unsigned int fifoDebug;
12 12 };
13 13
14 struct ahbuart_regs_str{
15 volatile unsigned int unused;
16 volatile unsigned int status;
17 volatile unsigned int ctrl;
18 volatile unsigned int scaler;
14 struct grgpio_regs_str{
15 volatile int io_port_data_register;
16 int io_port_output_register;
17 int io_port_direction_register;
18 int interrupt_mak_register;
19 int interrupt_polarity_register;
20 int interrupt_edge_register;
21 int bypass_register;
22 int reserved;
23 // 0x20-0x3c interrupt map register(s)
19 24 };
20 25
21 26 typedef struct {
@@ -45,9 +45,9 void launch_spectral_matrix_simu( unsign
45 45
46 46 // other functions
47 47 void updateLFRCurrentMode();
48 void update_last_TC_exe(ccsdsTelecommandPacket_t *TC );
49 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC );
50 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id );
48 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC , unsigned char *time );
49 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC , unsigned char *time );
50 void close_action( ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id );
51 51
52 52 extern rtems_status_code get_message_queue_id_send( rtems_id *queue_id );
53 53 extern rtems_status_code get_message_queue_id_recv( rtems_id *queue_id );
@@ -24,9 +24,13 ring_node *current_ring_node_sm_f2;
24 24 BP1_t data_BP1[ NB_BINS_COMPRESSED_SM_F0 ];
25 25 float averaged_sm_f0 [ TIME_OFFSET + TOTAL_SIZE_SM ];
26 26 float averaged_sm_f0_reorganized[ TIME_OFFSET + TOTAL_SIZE_SM ];
27 char averaged_sm_f0_char [ TIME_OFFSET_IN_BYTES + TOTAL_SIZE_SM * 2 ];
27 char averaged_sm_f0_char [ TIME_OFFSET_IN_BYTES + TOTAL_SIZE_SM ];
28 28 float compressed_sm_f0 [ TOTAL_SIZE_COMPRESSED_ASM_F0 ];
29 29
30 unsigned char LFR_BP1_F0[ TIME_OFFSET_IN_BYTES + TOTAL_SIZE_BP1_F0 * 2 ];
31 unsigned char LFR_BP1_F1[ TIME_OFFSET_IN_BYTES + TOTAL_SIZE_BP1_F1 ];
32 unsigned char LFR_BP1_F2[ TIME_OFFSET_IN_BYTES + TOTAL_SIZE_BP1_F2 ];
33
30 34 unsigned int nb_sm_f0;
31 35
32 36 void init_sm_rings( void )
@@ -258,7 +262,7 rtems_task matr_task(rtems_task_argument
258 262 // 1) compress the matrix for Basic Parameters calculation
259 263 ASM_compress( averaged_sm_f0, 0, compressed_sm_f0 );
260 264 // 2)
261 //BP1_set(compressed_sm_f0, NB_BINS_COMPRESSED_SM_F0, LFR_BP1_F0);
265 // BP1_set( (float *) &compressed_sm_f0[TIME_OFFSET], NB_BINS_COMPRESSED_SM_F0, (unsigned char *) &LFR_BP1_F0[TIME_OFFSET_IN_BYTES] );
262 266 // 3) convert the float array in a char array
263 267 ASM_reorganize( averaged_sm_f0, averaged_sm_f0_reorganized );
264 268 ASM_convert( averaged_sm_f0_reorganized, averaged_sm_f0_char);
@@ -311,11 +315,13 void ASM_compress( float *averaged_spec_
311 315 {
312 316 for( frequencyBin = 0; frequencyBin < NB_BINS_COMPRESSED_SM_F0; frequencyBin++ )
313 317 {
314 offsetASM = asmComponent * NB_BINS_PER_SM
318 offsetCompressed = TIME_OFFSET
319 + frequencyBin * NB_VALUES_PER_SM
320 + asmComponent;
321 offsetASM = TIME_OFFSET
322 + asmComponent * NB_BINS_PER_SM
315 323 + ASM_F0_INDICE_START
316 324 + frequencyBin * NB_BINS_TO_AVERAGE_ASM_F0;
317 offsetCompressed = frequencyBin * NB_VALUES_PER_SM
318 + asmComponent;
319 325 compressed_spec_mat[ offsetCompressed ] = 0;
320 326 for ( k = 0; k < NB_BINS_TO_AVERAGE_ASM_F0; k++ )
321 327 {
@@ -118,7 +118,6 rtems_task recv_task( rtems_task_argumen
118 118 unsigned char destinationID;
119 119 unsigned int currentTC_LEN_RCV_AsUnsignedInt;
120 120 unsigned int parserCode;
121 unsigned char time[6];
122 121 rtems_status_code status;
123 122 rtems_id queue_recv_id;
124 123 rtems_id queue_send_id;
@@ -160,6 +159,7 rtems_task recv_task( rtems_task_argumen
160 159 || (parserCode == ILL_SUBTYPE) || (parserCode == WRONG_APP_DATA)
161 160 || (parserCode == WRONG_SRC_ID) )
162 161 { // send TM_LFR_TC_EXE_CORRUPTED
162 PRINTF1("TC corrupted received, with code: %d\n", parserCode)
163 163 if ( !( (currentTC.serviceType==TC_TYPE_TIME) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_TIME) )
164 164 &&
165 165 !( (currentTC.serviceType==TC_TYPE_GEN) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_INFO))
@@ -173,8 +173,6 rtems_task recv_task( rtems_task_argumen
173 173 {
174 174 destinationID = currentTC.sourceID;
175 175 }
176 getTime( time );
177 close_action( &currentTC, LFR_DEFAULT, queue_send_id );
178 176 send_tm_lfr_tc_exe_corrupted( &currentTC, queue_send_id,
179 177 computed_CRC, currentTC_LEN_RCV,
180 178 destinationID );
@@ -582,9 +580,21 void spacewire_update_statistics( void )
582 580
583 581 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc )
584 582 {
585 //if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_1 ) != RTEMS_SUCCESSFUL) {
586 // printf("In timecode_irq_handler *** Error sending event to DUMB\n");
587 //}
583 // rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_1 );
584 struct grgpio_regs_str *grgpio_regs = (struct grgpio_regs_str *) REGS_ADDR_GRGPIO;
585
586 grgpio_regs->io_port_direction_register =
587 grgpio_regs->io_port_direction_register | 0x08; // [0001 1000], 0 = output disabled, 1 = output enabled
588
589 if ( (grgpio_regs->io_port_output_register & 0x08) == 0x08 )
590 {
591 grgpio_regs->io_port_output_register = grgpio_regs->io_port_output_register & 0xf7;
592 }
593 else
594 {
595 grgpio_regs->io_port_output_register = grgpio_regs->io_port_output_register | 0x08;
596 }
597
588 598 }
589 599
590 600 rtems_timer_service_routine user_routine( rtems_id timer_id, void *user_data )
@@ -215,20 +215,20 int action_update_info(ccsdsTelecommandP
215 215 unsigned int status;
216 216 unsigned char mode;
217 217
218 // check LFR MODE
218 // check LFR mode
219 219 mode = (TC->dataAndCRC[ BYTE_POS_HK_UPDATE_INFO_PAR_SET5 ] & 0x1e) >> 1;
220 220 status = check_update_info_hk_lfr_mode( mode );
221 if (status != LFR_DEFAULT) // check TDS mode
221 if (status == LFR_SUCCESSFUL) // check TDS mode
222 222 {
223 223 mode = (TC->dataAndCRC[ BYTE_POS_HK_UPDATE_INFO_PAR_SET6 ] & 0xf0) >> 4;
224 224 status = check_update_info_hk_tds_mode( mode );
225 225 }
226 if (status != LFR_DEFAULT) // check THR mode
226 if (status == LFR_SUCCESSFUL) // check THR mode
227 227 {
228 228 mode = (TC->dataAndCRC[ BYTE_POS_HK_UPDATE_INFO_PAR_SET6 ] & 0x0f);
229 229 status = check_update_info_hk_thr_mode( mode );
230 230 }
231 if (status != LFR_DEFAULT) // if the parameter check is successful
231 if (status == LFR_SUCCESSFUL) // if the parameter check is successful
232 232 {
233 233 val = housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * 256
234 234 + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
@@ -306,7 +306,7 int action_update_time(ccsdsTelecommandP
306 306 val++;
307 307 housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char) (val >> 8);
308 308 housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char) (val);
309 time_management_regs->ctrl = time_management_regs->ctrl | 1;
309 // time_management_regs->ctrl = time_management_regs->ctrl | 1; // force tick
310 310
311 311 return LFR_SUCCESSFUL;
312 312 }
@@ -653,11 +653,11 void set_run_matrix_spectral( unsigned c
653 653 {
654 654 if (value == 1)
655 655 {
656 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x4; // 0100 set run_matrix spectral to 1
656 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x4; // [0100] set run_matrix spectral to 1
657 657 }
658 658 else
659 659 {
660 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffb; // 1011 set run_matrix spectral to 0
660 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffb; // [1011] set run_matrix spectral to 0
661 661 }
662 662 }
663 663
@@ -676,7 +676,7 void launch_spectral_matrix_simu( unsign
676 676
677 677 //****************
678 678 // CLOSING ACTIONS
679 void update_last_TC_exe(ccsdsTelecommandPacket_t *TC)
679 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC, unsigned char * time )
680 680 {
681 681 /** This function is used to update the HK packets statistics after a successful TC execution.
682 682 *
@@ -685,21 +685,28 void update_last_TC_exe(ccsdsTelecommand
685 685 *
686 686 */
687 687
688 unsigned int val;
689
688 690 housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
689 691 housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
690 692 housekeeping_packet.hk_lfr_last_exe_tc_type[0] = 0x00;
691 693 housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
692 694 housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = 0x00;
693 695 housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
694 housekeeping_packet.hk_lfr_last_exe_tc_time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
695 housekeeping_packet.hk_lfr_last_exe_tc_time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
696 housekeeping_packet.hk_lfr_last_exe_tc_time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
697 housekeeping_packet.hk_lfr_last_exe_tc_time[3] = (unsigned char) (time_management_regs->coarse_time);
698 housekeeping_packet.hk_lfr_last_exe_tc_time[4] = (unsigned char) (time_management_regs->fine_time>>8);
699 housekeeping_packet.hk_lfr_last_exe_tc_time[5] = (unsigned char) (time_management_regs->fine_time);
696 housekeeping_packet.hk_lfr_last_exe_tc_time[0] = time[0];
697 housekeeping_packet.hk_lfr_last_exe_tc_time[1] = time[1];
698 housekeeping_packet.hk_lfr_last_exe_tc_time[2] = time[2];
699 housekeeping_packet.hk_lfr_last_exe_tc_time[3] = time[3];
700 housekeeping_packet.hk_lfr_last_exe_tc_time[4] = time[4];
701 housekeeping_packet.hk_lfr_last_exe_tc_time[5] = time[5];
702
703 val = housekeeping_packet.hk_lfr_exe_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
704 val++;
705 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> 8);
706 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
700 707 }
701 708
702 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC )
709 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC, unsigned char * time )
703 710 {
704 711 /** This function is used to update the HK packets statistics after a TC rejection.
705 712 *
@@ -708,18 +715,25 void update_last_TC_rej(ccsdsTelecommand
708 715 *
709 716 */
710 717
718 unsigned int val;
719
711 720 housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
712 721 housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
713 722 housekeeping_packet.hk_lfr_last_rej_tc_type[0] = 0x00;
714 723 housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
715 724 housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = 0x00;
716 725 housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
717 housekeeping_packet.hk_lfr_last_rej_tc_time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
718 housekeeping_packet.hk_lfr_last_rej_tc_time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
719 housekeeping_packet.hk_lfr_last_rej_tc_time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
720 housekeeping_packet.hk_lfr_last_rej_tc_time[3] = (unsigned char) (time_management_regs->coarse_time);
721 housekeeping_packet.hk_lfr_last_rej_tc_time[4] = (unsigned char) (time_management_regs->fine_time>>8);
722 housekeeping_packet.hk_lfr_last_rej_tc_time[5] = (unsigned char) (time_management_regs->fine_time);
726 housekeeping_packet.hk_lfr_last_rej_tc_time[0] = time[0];
727 housekeeping_packet.hk_lfr_last_rej_tc_time[1] = time[1];
728 housekeeping_packet.hk_lfr_last_rej_tc_time[2] = time[2];
729 housekeeping_packet.hk_lfr_last_rej_tc_time[3] = time[3];
730 housekeeping_packet.hk_lfr_last_rej_tc_time[4] = time[4];
731 housekeeping_packet.hk_lfr_last_rej_tc_time[5] = time[5];
732
733 val = housekeeping_packet.hk_lfr_rej_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
734 val++;
735 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> 8);
736 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
723 737 }
724 738
725 739 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id )
@@ -733,30 +747,15 void close_action(ccsdsTelecommandPacket
733 747 *
734 748 */
735 749
736 unsigned int val = 0;
737
738 750 if (result == LFR_SUCCESSFUL)
739 751 {
740 if ( !( (TC->serviceType==TC_TYPE_TIME) && (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
741 &&
742 !( (TC->serviceType==TC_TYPE_GEN) && (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
752 if ( !( (TC->serviceType==TC_TYPE_TIME) & (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
753 &
754 !( (TC->serviceType==TC_TYPE_GEN) & (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
743 755 )
744 756 {
745 757 send_tm_lfr_tc_exe_success( TC, queue_id );
746 758 }
747 update_last_TC_exe( TC );
748 val = housekeeping_packet.hk_lfr_exe_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
749 val++;
750 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> 8);
751 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
752 }
753 else
754 {
755 update_last_TC_rej( TC );
756 val = housekeeping_packet.hk_lfr_rej_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
757 val++;
758 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> 8);
759 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
760 759 }
761 760 }
762 761
@@ -417,7 +417,7 unsigned int check_update_info_hk_lfr_mo
417 417 unsigned int status;
418 418
419 419 if ( (mode == LFR_MODE_STANDBY) || (mode == LFR_MODE_NORMAL)
420 || (mode = LFR_MODE_BURST)
420 || (mode == LFR_MODE_BURST)
421 421 || (mode == LFR_MODE_SBM1) || (mode == LFR_MODE_SBM2))
422 422 {
423 423 status = LFR_SUCCESSFUL;
@@ -435,7 +435,7 unsigned int check_update_info_hk_tds_mo
435 435 unsigned int status;
436 436
437 437 if ( (mode == TDS_MODE_STANDBY) || (mode == TDS_MODE_NORMAL)
438 || (mode = TDS_MODE_BURST)
438 || (mode == TDS_MODE_BURST)
439 439 || (mode == TDS_MODE_SBM1) || (mode == TDS_MODE_SBM2)
440 440 || (mode == TDS_MODE_LFM))
441 441 {
@@ -454,7 +454,7 unsigned int check_update_info_hk_thr_mo
454 454 unsigned int status;
455 455
456 456 if ( (mode == THR_MODE_STANDBY) || (mode == THR_MODE_NORMAL)
457 || (mode = THR_MODE_BURST))
457 || (mode == THR_MODE_BURST))
458 458 {
459 459 status = LFR_SUCCESSFUL;
460 460 }
@@ -71,6 +71,9 int send_tm_lfr_tc_exe_success( ccsdsTel
71 71 PRINTF("in send_tm_lfr_tc_exe_success *** ERR\n")
72 72 }
73 73
74 // UPDATE HK FIELDS
75 update_last_TC_exe( TC, TM.time );
76
74 77 return status;
75 78 }
76 79
@@ -139,6 +142,9 int send_tm_lfr_tc_exe_inconsistent( ccs
139 142 PRINTF("in send_tm_lfr_tc_exe_inconsistent *** ERR\n")
140 143 }
141 144
145 // UPDATE HK FIELDS
146 update_last_TC_rej( TC, TM.time );
147
142 148 return status;
143 149 }
144 150
@@ -204,6 +210,9 int send_tm_lfr_tc_exe_not_executable( c
204 210 PRINTF("in send_tm_lfr_tc_exe_not_executable *** ERR\n")
205 211 }
206 212
213 // UPDATE HK FIELDS
214 update_last_TC_rej( TC, TM.time );
215
207 216 return status;
208 217 }
209 218
@@ -267,6 +276,9 int send_tm_lfr_tc_exe_not_implemented(
267 276 PRINTF("in send_tm_lfr_tc_exe_not_implemented *** ERR\n")
268 277 }
269 278
279 // UPDATE HK FIELDS
280 update_last_TC_rej( TC, TM.time );
281
270 282 return status;
271 283 }
272 284
@@ -330,6 +342,9 int send_tm_lfr_tc_exe_error( ccsdsTelec
330 342 PRINTF("in send_tm_lfr_tc_exe_error *** ERR\n")
331 343 }
332 344
345 // UPDATE HK FIELDS
346 update_last_TC_rej( TC, TM.time );
347
333 348 return status;
334 349 }
335 350
@@ -410,6 +425,9 int send_tm_lfr_tc_exe_corrupted(ccsdsTe
410 425 PRINTF("in send_tm_lfr_tc_exe_error *** ERR\n")
411 426 }
412 427
428 // UPDATE HK FIELDS
429 update_last_TC_rej( TC, TM.time );
430
413 431 return status;
414 432 }
415 433
@@ -1015,11 +1015,9 void build_snapshot_from_ring( ring_node
1015 1015
1016 1016 // get the f0 acquisition time
1017 1017 build_acquisition_time( &acquisitionTimeF0_asLong, current_ring_node_f0 );
1018 PRINTF1("acquisitionTimeF0_asLong %llx \n", acquisitionTimeF0_asLong)
1019 1018
1020 1019 // compute the central reference time
1021 1020 centerTime_asLong = acquisitionTimeF0_asLong + deltaT_F0;
1022 PRINTF1("centerTime_asLong %llx \n", centerTime_asLong)
1023 1021
1024 1022 // compute the acquisition time of the current snapshot
1025 1023 switch(frequencyChannel)
@@ -1042,7 +1040,6 void build_snapshot_from_ring( ring_node
1042 1040 nbTicksPerSample_asLong = 256;
1043 1041 break;
1044 1042 }
1045 PRINTF1("acquisitionTime_asLong %llx\n", acquisitionTime_asLong)
1046 1043
1047 1044 //****************************************************************************
1048 1045 // 1) search the ring_node with the acquisition time <= acquisitionTime_asLong
@@ -1064,12 +1061,10 void build_snapshot_from_ring( ring_node
1064 1061 // compute the number of samples to take in the current buffer
1065 1062 sampleOffset_asLong = ((acquisitionTime_asLong - bufferAcquisitionTime_asLong) * frequency_asLong ) >> 16;
1066 1063 nbSamplesPart1_asLong = NB_SAMPLES_PER_SNAPSHOT - sampleOffset_asLong;
1067 PRINTF2("sampleOffset_asLong = %lld, nbSamplesPart1 = %lld\n", sampleOffset_asLong, nbSamplesPart1_asLong)
1068 1064
1069 1065 // compute the final acquisition time
1070 1066 acquisitionTime_asLong = bufferAcquisitionTime_asLong +
1071 1067 sampleOffset_asLong * nbTicksPerSample_asLong;
1072 PRINTF1("FINAL acquisitionTime_asLong %llx\n\n", acquisitionTime_asLong)
1073 1068
1074 1069 // copy the acquisition time at the beginning of the extrated snapshot
1075 1070 ptr1 = (unsigned char*) &acquisitionTime_asLong;
@@ -1162,7 +1157,7 void reset_waveform_picker_regs(void)
1162 1157 *
1163 1158 */
1164 1159
1165 waveform_picker_regs->data_shaping = 0x01; // 0x00 *** R1 R0 SP1 SP0 BW
1160 // waveform_picker_regs->data_shaping = 0x01; // 0x00 *** R1 R0 SP1 SP0 BW
1166 1161 waveform_picker_regs->run_burst_enable = 0x00; // 0x04 *** [run *** burst f2, f1, f0 *** enable f3, f2, f1, f0 ]
1167 1162 waveform_picker_regs->addr_data_f0 = current_ring_node_f0->buffer_address; // 0x08
1168 1163 waveform_picker_regs->addr_data_f1 = current_ring_node_f1->buffer_address; // 0x0c
General Comments 0
You need to be logged in to leave comments. Login now