##// END OF EJS Templates
two fields added to the housekeeping parameters:...
paul -
r265:09ea64972ca9 R3a
parent child
Show More
@@ -1,57 +1,56
1 #ifndef FSW_SPACEWIRE_H_INCLUDED
1 #ifndef FSW_SPACEWIRE_H_INCLUDED
2 #define FSW_SPACEWIRE_H_INCLUDED
2 #define FSW_SPACEWIRE_H_INCLUDED
3
3
4 #include <rtems.h>
4 #include <rtems.h>
5 #include <grspw.h>
5 #include <grspw.h>
6
6
7 #include <fcntl.h> // for O_RDWR
7 #include <fcntl.h> // for O_RDWR
8 #include <unistd.h> // for the read call
8 #include <unistd.h> // for the read call
9 #include <sys/ioctl.h> // for the ioctl call
9 #include <sys/ioctl.h> // for the ioctl call
10 #include <errno.h>
10 #include <errno.h>
11
11
12 #include "fsw_params.h"
12 #include "fsw_params.h"
13 #include "tc_handler.h"
13 #include "tc_handler.h"
14 #include "fsw_init.h"
14 #include "fsw_init.h"
15
15
16 extern spw_stats grspw_stats;
16 extern spw_stats grspw_stats;
17 extern spw_stats spw_backup;
18 extern rtems_name timecode_timer_name;
17 extern rtems_name timecode_timer_name;
19 extern rtems_id timecode_timer_id;
18 extern rtems_id timecode_timer_id;
20
19
21 // RTEMS TASK
20 // RTEMS TASK
22 rtems_task spiq_task( rtems_task_argument argument );
21 rtems_task spiq_task( rtems_task_argument argument );
23 rtems_task recv_task( rtems_task_argument unused );
22 rtems_task recv_task( rtems_task_argument unused );
24 rtems_task send_task( rtems_task_argument argument );
23 rtems_task send_task( rtems_task_argument argument );
25 rtems_task link_task( rtems_task_argument argument );
24 rtems_task link_task( rtems_task_argument argument );
26
25
27 int spacewire_open_link( void );
26 int spacewire_open_link( void );
28 int spacewire_start_link( int fd );
27 int spacewire_start_link( int fd );
29 int spacewire_stop_and_start_link( int fd );
28 int spacewire_stop_and_start_link( int fd );
30 int spacewire_configure_link(int fd );
29 int spacewire_configure_link(int fd );
31 int spacewire_several_connect_attemps( void );
30 int spacewire_several_connect_attemps( void );
32 void spacewire_set_NP( unsigned char val, unsigned int regAddr ); // No Port force
31 void spacewire_set_NP( unsigned char val, unsigned int regAddr ); // No Port force
33 void spacewire_set_RE( unsigned char val, unsigned int regAddr ); // RMAP Enable
32 void spacewire_set_RE( unsigned char val, unsigned int regAddr ); // RMAP Enable
34 void spacewire_read_statistics( void );
33 void spacewire_read_statistics( void );
35 void update_hk_lfr_last_er_fields(unsigned int rid, unsigned char code);
34 void update_hk_lfr_last_er_fields(unsigned int rid, unsigned char code);
36 void update_hk_with_grspw_stats(void );
35 void update_hk_with_grspw_stats(void );
37 void increase_unsigned_char_counter( unsigned char *counter );
36 void increase_unsigned_char_counter( unsigned char *counter );
38
37
39 void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header );
38 void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header );
40 void init_header_swf( Header_TM_LFR_SCIENCE_SWF_t *header );
39 void init_header_swf( Header_TM_LFR_SCIENCE_SWF_t *header );
41 void init_header_asm( Header_TM_LFR_SCIENCE_ASM_t *header );
40 void init_header_asm( Header_TM_LFR_SCIENCE_ASM_t *header );
42 int spw_send_waveform_CWF( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_CWF_t *header );
41 int spw_send_waveform_CWF( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_CWF_t *header );
43 int spw_send_waveform_SWF( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_SWF_t *header );
42 int spw_send_waveform_SWF( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_SWF_t *header );
44 int spw_send_waveform_CWF3_light( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_CWF_t *header );
43 int spw_send_waveform_CWF3_light( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_CWF_t *header );
45 void spw_send_asm_f0( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
44 void spw_send_asm_f0( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
46 void spw_send_asm_f1( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
45 void spw_send_asm_f1( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
47 void spw_send_asm_f2( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
46 void spw_send_asm_f2( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
48 void spw_send_k_dump( ring_node *ring_node_to_send );
47 void spw_send_k_dump( ring_node *ring_node_to_send );
49
48
50 rtems_timer_service_routine timecode_timer_routine( rtems_id timer_id, void *user_data );
49 rtems_timer_service_routine timecode_timer_routine( rtems_id timer_id, void *user_data );
51 unsigned int check_timecode_and_previous_timecode_coherency(unsigned char currentTimecodeCtr);
50 unsigned int check_timecode_and_previous_timecode_coherency(unsigned char currentTimecodeCtr);
52 unsigned int check_timecode_and_internal_time_coherency(unsigned char timecode, unsigned char internalTime);
51 unsigned int check_timecode_and_internal_time_coherency(unsigned char timecode, unsigned char internalTime);
53 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc );
52 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc );
54
53
55 void (*grspw_timecode_callback) ( void *pDev, void *regs, int minor, unsigned int tc );
54 void (*grspw_timecode_callback) ( void *pDev, void *regs, int minor, unsigned int tc );
56
55
57 #endif // FSW_SPACEWIRE_H_INCLUDED
56 #endif // FSW_SPACEWIRE_H_INCLUDED
@@ -1,83 +1,80
1 /** Global variables of the LFR flight software.
1 /** Global variables of the LFR flight software.
2 *
2 *
3 * @file
3 * @file
4 * @author P. LEROY
4 * @author P. LEROY
5 *
5 *
6 * Among global variables, there are:
6 * Among global variables, there are:
7 * - RTEMS names and id.
7 * - RTEMS names and id.
8 * - APB configuration registers.
8 * - APB configuration registers.
9 * - waveforms global buffers, used by the waveform picker hardware module to store data.
9 * - waveforms global buffers, used by the waveform picker hardware module to store data.
10 * - spectral matrices buffesr, used by the hardware module to store data.
10 * - spectral matrices buffesr, used by the hardware module to store data.
11 * - variable related to LFR modes parameters.
11 * - variable related to LFR modes parameters.
12 * - the global HK packet buffer.
12 * - the global HK packet buffer.
13 * - the global dump parameter buffer.
13 * - the global dump parameter buffer.
14 *
14 *
15 */
15 */
16
16
17 #include <rtems.h>
17 #include <rtems.h>
18 #include <grspw.h>
18 #include <grspw.h>
19
19
20 #include "ccsds_types.h"
20 #include "ccsds_types.h"
21 #include "grlib_regs.h"
21 #include "grlib_regs.h"
22 #include "fsw_params.h"
22 #include "fsw_params.h"
23 #include "fsw_params_wf_handler.h"
23 #include "fsw_params_wf_handler.h"
24
24
25 // RTEMS GLOBAL VARIABLES
25 // RTEMS GLOBAL VARIABLES
26 rtems_name misc_name[5];
26 rtems_name misc_name[5];
27 rtems_name Task_name[20]; /* array of task names */
27 rtems_name Task_name[20]; /* array of task names */
28 rtems_id Task_id[20]; /* array of task ids */
28 rtems_id Task_id[20]; /* array of task ids */
29 rtems_name timecode_timer_name;
29 rtems_name timecode_timer_name;
30 rtems_id timecode_timer_id;
30 rtems_id timecode_timer_id;
31 int fdSPW = 0;
31 int fdSPW = 0;
32 int fdUART = 0;
32 int fdUART = 0;
33 unsigned char lfrCurrentMode;
33 unsigned char lfrCurrentMode;
34 unsigned char pa_bia_status_info;
34 unsigned char pa_bia_status_info;
35 unsigned char thisIsAnASMRestart = 0;
35 unsigned char thisIsAnASMRestart = 0;
36
36
37 // WAVEFORMS GLOBAL VARIABLES // 2048 * 3 * 4 + 2 * 4 = 24576 + 8 bytes = 24584
37 // WAVEFORMS GLOBAL VARIABLES // 2048 * 3 * 4 + 2 * 4 = 24576 + 8 bytes = 24584
38 // 97 * 256 = 24832 => delta = 248 bytes = 62 words
38 // 97 * 256 = 24832 => delta = 248 bytes = 62 words
39 // WAVEFORMS GLOBAL VARIABLES // 2688 * 3 * 4 + 2 * 4 = 32256 + 8 bytes = 32264
39 // WAVEFORMS GLOBAL VARIABLES // 2688 * 3 * 4 + 2 * 4 = 32256 + 8 bytes = 32264
40 // 127 * 256 = 32512 => delta = 248 bytes = 62 words
40 // 127 * 256 = 32512 => delta = 248 bytes = 62 words
41 // F0 F1 F2 F3
41 // F0 F1 F2 F3
42 volatile int wf_buffer_f0[ NB_RING_NODES_F0 * WFRM_BUFFER ] __attribute__((aligned(0x100)));
42 volatile int wf_buffer_f0[ NB_RING_NODES_F0 * WFRM_BUFFER ] __attribute__((aligned(0x100)));
43 volatile int wf_buffer_f1[ NB_RING_NODES_F1 * WFRM_BUFFER ] __attribute__((aligned(0x100)));
43 volatile int wf_buffer_f1[ NB_RING_NODES_F1 * WFRM_BUFFER ] __attribute__((aligned(0x100)));
44 volatile int wf_buffer_f2[ NB_RING_NODES_F2 * WFRM_BUFFER ] __attribute__((aligned(0x100)));
44 volatile int wf_buffer_f2[ NB_RING_NODES_F2 * WFRM_BUFFER ] __attribute__((aligned(0x100)));
45 volatile int wf_buffer_f3[ NB_RING_NODES_F3 * WFRM_BUFFER ] __attribute__((aligned(0x100)));
45 volatile int wf_buffer_f3[ NB_RING_NODES_F3 * WFRM_BUFFER ] __attribute__((aligned(0x100)));
46
46
47 //***********************************
47 //***********************************
48 // SPECTRAL MATRICES GLOBAL VARIABLES
48 // SPECTRAL MATRICES GLOBAL VARIABLES
49
49
50 // alignment constraints for the spectral matrices buffers => the first data after the time (8 bytes) shall be aligned on 0x00
50 // alignment constraints for the spectral matrices buffers => the first data after the time (8 bytes) shall be aligned on 0x00
51 volatile int sm_f0[ NB_RING_NODES_SM_F0 * TOTAL_SIZE_SM ] __attribute__((aligned(0x100)));
51 volatile int sm_f0[ NB_RING_NODES_SM_F0 * TOTAL_SIZE_SM ] __attribute__((aligned(0x100)));
52 volatile int sm_f1[ NB_RING_NODES_SM_F1 * TOTAL_SIZE_SM ] __attribute__((aligned(0x100)));
52 volatile int sm_f1[ NB_RING_NODES_SM_F1 * TOTAL_SIZE_SM ] __attribute__((aligned(0x100)));
53 volatile int sm_f2[ NB_RING_NODES_SM_F2 * TOTAL_SIZE_SM ] __attribute__((aligned(0x100)));
53 volatile int sm_f2[ NB_RING_NODES_SM_F2 * TOTAL_SIZE_SM ] __attribute__((aligned(0x100)));
54
54
55 // APB CONFIGURATION REGISTERS
55 // APB CONFIGURATION REGISTERS
56 time_management_regs_t *time_management_regs = (time_management_regs_t*) REGS_ADDR_TIME_MANAGEMENT;
56 time_management_regs_t *time_management_regs = (time_management_regs_t*) REGS_ADDR_TIME_MANAGEMENT;
57 gptimer_regs_t *gptimer_regs = (gptimer_regs_t *) REGS_ADDR_GPTIMER;
57 gptimer_regs_t *gptimer_regs = (gptimer_regs_t *) REGS_ADDR_GPTIMER;
58 waveform_picker_regs_0_1_18_t *waveform_picker_regs = (waveform_picker_regs_0_1_18_t*) REGS_ADDR_WAVEFORM_PICKER;
58 waveform_picker_regs_0_1_18_t *waveform_picker_regs = (waveform_picker_regs_0_1_18_t*) REGS_ADDR_WAVEFORM_PICKER;
59 spectral_matrix_regs_t *spectral_matrix_regs = (spectral_matrix_regs_t*) REGS_ADDR_SPECTRAL_MATRIX;
59 spectral_matrix_regs_t *spectral_matrix_regs = (spectral_matrix_regs_t*) REGS_ADDR_SPECTRAL_MATRIX;
60
60
61 // MODE PARAMETERS
61 // MODE PARAMETERS
62 Packet_TM_LFR_PARAMETER_DUMP_t parameter_dump_packet;
62 Packet_TM_LFR_PARAMETER_DUMP_t parameter_dump_packet;
63 struct param_local_str param_local;
63 struct param_local_str param_local;
64 unsigned int lastValidEnterModeTime;
64 unsigned int lastValidEnterModeTime;
65
65
66 // HK PACKETS
66 // HK PACKETS
67 Packet_TM_LFR_HK_t housekeeping_packet;
67 Packet_TM_LFR_HK_t housekeeping_packet;
68 // message queues occupancy
68 // message queues occupancy
69 unsigned char hk_lfr_q_sd_fifo_size_max;
69 unsigned char hk_lfr_q_sd_fifo_size_max;
70 unsigned char hk_lfr_q_rv_fifo_size_max;
70 unsigned char hk_lfr_q_rv_fifo_size_max;
71 unsigned char hk_lfr_q_p0_fifo_size_max;
71 unsigned char hk_lfr_q_p0_fifo_size_max;
72 unsigned char hk_lfr_q_p1_fifo_size_max;
72 unsigned char hk_lfr_q_p1_fifo_size_max;
73 unsigned char hk_lfr_q_p2_fifo_size_max;
73 unsigned char hk_lfr_q_p2_fifo_size_max;
74 // sequence counters are incremented by APID (PID + CAT) and destination ID
74 // sequence counters are incremented by APID (PID + CAT) and destination ID
75 unsigned short sequenceCounters_SCIENCE_NORMAL_BURST;
75 unsigned short sequenceCounters_SCIENCE_NORMAL_BURST;
76 unsigned short sequenceCounters_SCIENCE_SBM1_SBM2;
76 unsigned short sequenceCounters_SCIENCE_SBM1_SBM2;
77 unsigned short sequenceCounters_TC_EXE[SEQ_CNT_NB_DEST_ID];
77 unsigned short sequenceCounters_TC_EXE[SEQ_CNT_NB_DEST_ID];
78 unsigned short sequenceCounters_TM_DUMP[SEQ_CNT_NB_DEST_ID];
78 unsigned short sequenceCounters_TM_DUMP[SEQ_CNT_NB_DEST_ID];
79 unsigned short sequenceCounterHK;
79 unsigned short sequenceCounterHK;
80 spw_stats grspw_stats;
80 spw_stats grspw_stats;
81 spw_stats spw_backup;
82
83
@@ -1,1569 +1,1580
1 /** Functions related to the SpaceWire interface.
1 /** Functions related to the SpaceWire interface.
2 *
2 *
3 * @file
3 * @file
4 * @author P. LEROY
4 * @author P. LEROY
5 *
5 *
6 * A group of functions to handle SpaceWire transmissions:
6 * A group of functions to handle SpaceWire transmissions:
7 * - configuration of the SpaceWire link
7 * - configuration of the SpaceWire link
8 * - SpaceWire related interruption requests processing
8 * - SpaceWire related interruption requests processing
9 * - transmission of TeleMetry packets by a dedicated RTEMS task
9 * - transmission of TeleMetry packets by a dedicated RTEMS task
10 * - reception of TeleCommands by a dedicated RTEMS task
10 * - reception of TeleCommands by a dedicated RTEMS task
11 *
11 *
12 */
12 */
13
13
14 #include "fsw_spacewire.h"
14 #include "fsw_spacewire.h"
15
15
16 rtems_name semq_name;
16 rtems_name semq_name;
17 rtems_id semq_id;
17 rtems_id semq_id;
18
18
19 //*****************
19 //*****************
20 // waveform headers
20 // waveform headers
21 Header_TM_LFR_SCIENCE_CWF_t headerCWF;
21 Header_TM_LFR_SCIENCE_CWF_t headerCWF;
22 Header_TM_LFR_SCIENCE_SWF_t headerSWF;
22 Header_TM_LFR_SCIENCE_SWF_t headerSWF;
23 Header_TM_LFR_SCIENCE_ASM_t headerASM;
23 Header_TM_LFR_SCIENCE_ASM_t headerASM;
24
24
25 unsigned char previousTimecodeCtr = 0;
25 unsigned char previousTimecodeCtr = 0;
26 unsigned int *grspwPtr = (unsigned int *) (REGS_ADDR_GRSPW + APB_OFFSET_GRSPW_TIME_REGISTER);
26 unsigned int *grspwPtr = (unsigned int *) (REGS_ADDR_GRSPW + APB_OFFSET_GRSPW_TIME_REGISTER);
27
27
28 //***********
28 //***********
29 // RTEMS TASK
29 // RTEMS TASK
30 rtems_task spiq_task(rtems_task_argument unused)
30 rtems_task spiq_task(rtems_task_argument unused)
31 {
31 {
32 /** This RTEMS task is awaken by an rtems_event sent by the interruption subroutine of the SpaceWire driver.
32 /** This RTEMS task is awaken by an rtems_event sent by the interruption subroutine of the SpaceWire driver.
33 *
33 *
34 * @param unused is the starting argument of the RTEMS task
34 * @param unused is the starting argument of the RTEMS task
35 *
35 *
36 */
36 */
37
37
38 rtems_event_set event_out;
38 rtems_event_set event_out;
39 rtems_status_code status;
39 rtems_status_code status;
40 int linkStatus;
40 int linkStatus;
41
41
42 BOOT_PRINTF("in SPIQ *** \n")
42 BOOT_PRINTF("in SPIQ *** \n")
43
43
44 while(true){
44 while(true){
45 rtems_event_receive(SPW_LINKERR_EVENT, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an SPW_LINKERR_EVENT
45 rtems_event_receive(SPW_LINKERR_EVENT, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an SPW_LINKERR_EVENT
46 PRINTF("in SPIQ *** got SPW_LINKERR_EVENT\n")
46 PRINTF("in SPIQ *** got SPW_LINKERR_EVENT\n")
47
47
48 // [0] SUSPEND RECV AND SEND TASKS
48 // [0] SUSPEND RECV AND SEND TASKS
49 status = rtems_task_suspend( Task_id[ TASKID_RECV ] );
49 status = rtems_task_suspend( Task_id[ TASKID_RECV ] );
50 if ( status != RTEMS_SUCCESSFUL ) {
50 if ( status != RTEMS_SUCCESSFUL ) {
51 PRINTF("in SPIQ *** ERR suspending RECV Task\n")
51 PRINTF("in SPIQ *** ERR suspending RECV Task\n")
52 }
52 }
53 status = rtems_task_suspend( Task_id[ TASKID_SEND ] );
53 status = rtems_task_suspend( Task_id[ TASKID_SEND ] );
54 if ( status != RTEMS_SUCCESSFUL ) {
54 if ( status != RTEMS_SUCCESSFUL ) {
55 PRINTF("in SPIQ *** ERR suspending SEND Task\n")
55 PRINTF("in SPIQ *** ERR suspending SEND Task\n")
56 }
56 }
57
57
58 // [1] CHECK THE LINK
58 // [1] CHECK THE LINK
59 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (1)
59 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (1)
60 if ( linkStatus != 5) {
60 if ( linkStatus != 5) {
61 PRINTF1("in SPIQ *** linkStatus %d, wait...\n", linkStatus)
61 PRINTF1("in SPIQ *** linkStatus %d, wait...\n", linkStatus)
62 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
62 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
63 }
63 }
64
64
65 // [2] RECHECK THE LINK AFTER SY_LFR_DPU_CONNECT_TIMEOUT
65 // [2] RECHECK THE LINK AFTER SY_LFR_DPU_CONNECT_TIMEOUT
66 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (2)
66 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (2)
67 if ( linkStatus != 5 ) // [2.a] not in run state, reset the link
67 if ( linkStatus != 5 ) // [2.a] not in run state, reset the link
68 {
68 {
69 spacewire_read_statistics();
69 spacewire_read_statistics();
70 status = spacewire_several_connect_attemps( );
70 status = spacewire_several_connect_attemps( );
71 }
71 }
72 else // [2.b] in run state, start the link
72 else // [2.b] in run state, start the link
73 {
73 {
74 status = spacewire_stop_and_start_link( fdSPW ); // start the link
74 status = spacewire_stop_and_start_link( fdSPW ); // start the link
75 if ( status != RTEMS_SUCCESSFUL)
75 if ( status != RTEMS_SUCCESSFUL)
76 {
76 {
77 PRINTF1("in SPIQ *** ERR spacewire_stop_and_start_link %d\n", status)
77 PRINTF1("in SPIQ *** ERR spacewire_stop_and_start_link %d\n", status)
78 }
78 }
79 }
79 }
80
80
81 // [3] COMPLETE RECOVERY ACTION AFTER SY_LFR_DPU_CONNECT_ATTEMPTS
81 // [3] COMPLETE RECOVERY ACTION AFTER SY_LFR_DPU_CONNECT_ATTEMPTS
82 if ( status == RTEMS_SUCCESSFUL ) // [3.a] the link is in run state and has been started successfully
82 if ( status == RTEMS_SUCCESSFUL ) // [3.a] the link is in run state and has been started successfully
83 {
83 {
84 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
84 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
85 if ( status != RTEMS_SUCCESSFUL ) {
85 if ( status != RTEMS_SUCCESSFUL ) {
86 PRINTF("in SPIQ *** ERR resuming SEND Task\n")
86 PRINTF("in SPIQ *** ERR resuming SEND Task\n")
87 }
87 }
88 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
88 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
89 if ( status != RTEMS_SUCCESSFUL ) {
89 if ( status != RTEMS_SUCCESSFUL ) {
90 PRINTF("in SPIQ *** ERR resuming RECV Task\n")
90 PRINTF("in SPIQ *** ERR resuming RECV Task\n")
91 }
91 }
92 }
92 }
93 else // [3.b] the link is not in run state, go in STANDBY mode
93 else // [3.b] the link is not in run state, go in STANDBY mode
94 {
94 {
95 status = enter_mode_standby();
95 status = enter_mode_standby();
96 if ( status != RTEMS_SUCCESSFUL )
96 if ( status != RTEMS_SUCCESSFUL )
97 {
97 {
98 PRINTF1("in SPIQ *** ERR enter_standby_mode *** code %d\n", status)
98 PRINTF1("in SPIQ *** ERR enter_standby_mode *** code %d\n", status)
99 }
99 }
100 {
100 {
101 updateLFRCurrentMode( LFR_MODE_STANDBY );
101 updateLFRCurrentMode( LFR_MODE_STANDBY );
102 }
102 }
103 // wake the LINK task up to wait for the link recovery
103 // wake the LINK task up to wait for the link recovery
104 status = rtems_event_send ( Task_id[TASKID_LINK], RTEMS_EVENT_0 );
104 status = rtems_event_send ( Task_id[TASKID_LINK], RTEMS_EVENT_0 );
105 status = rtems_task_suspend( RTEMS_SELF );
105 status = rtems_task_suspend( RTEMS_SELF );
106 }
106 }
107 }
107 }
108 }
108 }
109
109
110 rtems_task recv_task( rtems_task_argument unused )
110 rtems_task recv_task( rtems_task_argument unused )
111 {
111 {
112 /** This RTEMS task is dedicated to the reception of incoming TeleCommands.
112 /** This RTEMS task is dedicated to the reception of incoming TeleCommands.
113 *
113 *
114 * @param unused is the starting argument of the RTEMS task
114 * @param unused is the starting argument of the RTEMS task
115 *
115 *
116 * The RECV task blocks on a call to the read system call, waiting for incoming SpaceWire data. When unblocked:
116 * The RECV task blocks on a call to the read system call, waiting for incoming SpaceWire data. When unblocked:
117 * 1. It reads the incoming data.
117 * 1. It reads the incoming data.
118 * 2. Launches the acceptance procedure.
118 * 2. Launches the acceptance procedure.
119 * 3. If the Telecommand is valid, sends it to a dedicated RTEMS message queue.
119 * 3. If the Telecommand is valid, sends it to a dedicated RTEMS message queue.
120 *
120 *
121 */
121 */
122
122
123 int len;
123 int len;
124 ccsdsTelecommandPacket_t currentTC;
124 ccsdsTelecommandPacket_t currentTC;
125 unsigned char computed_CRC[ 2 ];
125 unsigned char computed_CRC[ 2 ];
126 unsigned char currentTC_LEN_RCV[ 2 ];
126 unsigned char currentTC_LEN_RCV[ 2 ];
127 unsigned char destinationID;
127 unsigned char destinationID;
128 unsigned int estimatedPacketLength;
128 unsigned int estimatedPacketLength;
129 unsigned int parserCode;
129 unsigned int parserCode;
130 rtems_status_code status;
130 rtems_status_code status;
131 rtems_id queue_recv_id;
131 rtems_id queue_recv_id;
132 rtems_id queue_send_id;
132 rtems_id queue_send_id;
133
133
134 initLookUpTableForCRC(); // the table is used to compute Cyclic Redundancy Codes
134 initLookUpTableForCRC(); // the table is used to compute Cyclic Redundancy Codes
135
135
136 status = get_message_queue_id_recv( &queue_recv_id );
136 status = get_message_queue_id_recv( &queue_recv_id );
137 if (status != RTEMS_SUCCESSFUL)
137 if (status != RTEMS_SUCCESSFUL)
138 {
138 {
139 PRINTF1("in RECV *** ERR get_message_queue_id_recv %d\n", status)
139 PRINTF1("in RECV *** ERR get_message_queue_id_recv %d\n", status)
140 }
140 }
141
141
142 status = get_message_queue_id_send( &queue_send_id );
142 status = get_message_queue_id_send( &queue_send_id );
143 if (status != RTEMS_SUCCESSFUL)
143 if (status != RTEMS_SUCCESSFUL)
144 {
144 {
145 PRINTF1("in RECV *** ERR get_message_queue_id_send %d\n", status)
145 PRINTF1("in RECV *** ERR get_message_queue_id_send %d\n", status)
146 }
146 }
147
147
148 BOOT_PRINTF("in RECV *** \n")
148 BOOT_PRINTF("in RECV *** \n")
149
149
150 while(1)
150 while(1)
151 {
151 {
152 len = read( fdSPW, (char*) &currentTC, CCSDS_TC_PKT_MAX_SIZE ); // the call to read is blocking
152 len = read( fdSPW, (char*) &currentTC, CCSDS_TC_PKT_MAX_SIZE ); // the call to read is blocking
153 if (len == -1){ // error during the read call
153 if (len == -1){ // error during the read call
154 PRINTF1("in RECV *** last read call returned -1, ERRNO %d\n", errno)
154 PRINTF1("in RECV *** last read call returned -1, ERRNO %d\n", errno)
155 }
155 }
156 else {
156 else {
157 if ( (len+1) < CCSDS_TC_PKT_MIN_SIZE ) {
157 if ( (len+1) < CCSDS_TC_PKT_MIN_SIZE ) {
158 PRINTF("in RECV *** packet lenght too short\n")
158 PRINTF("in RECV *** packet lenght too short\n")
159 }
159 }
160 else {
160 else {
161 estimatedPacketLength = (unsigned int) (len - CCSDS_TC_TM_PACKET_OFFSET - 3); // => -3 is for Prot ID, Reserved and User App bytes
161 estimatedPacketLength = (unsigned int) (len - CCSDS_TC_TM_PACKET_OFFSET - 3); // => -3 is for Prot ID, Reserved and User App bytes
162 currentTC_LEN_RCV[ 0 ] = (unsigned char) (estimatedPacketLength >> 8);
162 currentTC_LEN_RCV[ 0 ] = (unsigned char) (estimatedPacketLength >> 8);
163 currentTC_LEN_RCV[ 1 ] = (unsigned char) (estimatedPacketLength );
163 currentTC_LEN_RCV[ 1 ] = (unsigned char) (estimatedPacketLength );
164 // CHECK THE TC
164 // CHECK THE TC
165 parserCode = tc_parser( &currentTC, estimatedPacketLength, computed_CRC ) ;
165 parserCode = tc_parser( &currentTC, estimatedPacketLength, computed_CRC ) ;
166 if ( (parserCode == ILLEGAL_APID) || (parserCode == WRONG_LEN_PKT)
166 if ( (parserCode == ILLEGAL_APID) || (parserCode == WRONG_LEN_PKT)
167 || (parserCode == INCOR_CHECKSUM) || (parserCode == ILL_TYPE)
167 || (parserCode == INCOR_CHECKSUM) || (parserCode == ILL_TYPE)
168 || (parserCode == ILL_SUBTYPE) || (parserCode == WRONG_APP_DATA)
168 || (parserCode == ILL_SUBTYPE) || (parserCode == WRONG_APP_DATA)
169 || (parserCode == WRONG_SRC_ID) )
169 || (parserCode == WRONG_SRC_ID) )
170 { // send TM_LFR_TC_EXE_CORRUPTED
170 { // send TM_LFR_TC_EXE_CORRUPTED
171 PRINTF1("TC corrupted received, with code: %d\n", parserCode)
171 PRINTF1("TC corrupted received, with code: %d\n", parserCode)
172 if ( !( (currentTC.serviceType==TC_TYPE_TIME) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_TIME) )
172 if ( !( (currentTC.serviceType==TC_TYPE_TIME) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_TIME) )
173 &&
173 &&
174 !( (currentTC.serviceType==TC_TYPE_GEN) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_INFO))
174 !( (currentTC.serviceType==TC_TYPE_GEN) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_INFO))
175 )
175 )
176 {
176 {
177 if ( parserCode == WRONG_SRC_ID )
177 if ( parserCode == WRONG_SRC_ID )
178 {
178 {
179 destinationID = SID_TC_GROUND;
179 destinationID = SID_TC_GROUND;
180 }
180 }
181 else
181 else
182 {
182 {
183 destinationID = currentTC.sourceID;
183 destinationID = currentTC.sourceID;
184 }
184 }
185 send_tm_lfr_tc_exe_corrupted( &currentTC, queue_send_id,
185 send_tm_lfr_tc_exe_corrupted( &currentTC, queue_send_id,
186 computed_CRC, currentTC_LEN_RCV,
186 computed_CRC, currentTC_LEN_RCV,
187 destinationID );
187 destinationID );
188 }
188 }
189 }
189 }
190 else
190 else
191 { // send valid TC to the action launcher
191 { // send valid TC to the action launcher
192 status = rtems_message_queue_send( queue_recv_id, &currentTC,
192 status = rtems_message_queue_send( queue_recv_id, &currentTC,
193 estimatedPacketLength + CCSDS_TC_TM_PACKET_OFFSET + 3);
193 estimatedPacketLength + CCSDS_TC_TM_PACKET_OFFSET + 3);
194 }
194 }
195 }
195 }
196 }
196 }
197
197
198 update_queue_max_count( queue_recv_id, &hk_lfr_q_rv_fifo_size_max );
198 update_queue_max_count( queue_recv_id, &hk_lfr_q_rv_fifo_size_max );
199
199
200 }
200 }
201 }
201 }
202
202
203 rtems_task send_task( rtems_task_argument argument)
203 rtems_task send_task( rtems_task_argument argument)
204 {
204 {
205 /** This RTEMS task is dedicated to the transmission of TeleMetry packets.
205 /** This RTEMS task is dedicated to the transmission of TeleMetry packets.
206 *
206 *
207 * @param unused is the starting argument of the RTEMS task
207 * @param unused is the starting argument of the RTEMS task
208 *
208 *
209 * The SEND task waits for a message to become available in the dedicated RTEMS queue. When a message arrives:
209 * The SEND task waits for a message to become available in the dedicated RTEMS queue. When a message arrives:
210 * - if the first byte is equal to CCSDS_DESTINATION_ID, the message is sent as is using the write system call.
210 * - if the first byte is equal to CCSDS_DESTINATION_ID, the message is sent as is using the write system call.
211 * - if the first byte is not equal to CCSDS_DESTINATION_ID, the message is handled as a spw_ioctl_pkt_send. After
211 * - if the first byte is not equal to CCSDS_DESTINATION_ID, the message is handled as a spw_ioctl_pkt_send. After
212 * analyzis, the packet is sent either using the write system call or using the ioctl call SPACEWIRE_IOCTRL_SEND, depending on the
212 * analyzis, the packet is sent either using the write system call or using the ioctl call SPACEWIRE_IOCTRL_SEND, depending on the
213 * data it contains.
213 * data it contains.
214 *
214 *
215 */
215 */
216
216
217 rtems_status_code status; // RTEMS status code
217 rtems_status_code status; // RTEMS status code
218 char incomingData[MSG_QUEUE_SIZE_SEND]; // incoming data buffer
218 char incomingData[MSG_QUEUE_SIZE_SEND]; // incoming data buffer
219 ring_node *incomingRingNodePtr;
219 ring_node *incomingRingNodePtr;
220 int ring_node_address;
220 int ring_node_address;
221 char *charPtr;
221 char *charPtr;
222 spw_ioctl_pkt_send *spw_ioctl_send;
222 spw_ioctl_pkt_send *spw_ioctl_send;
223 size_t size; // size of the incoming TC packet
223 size_t size; // size of the incoming TC packet
224 rtems_id queue_send_id;
224 rtems_id queue_send_id;
225 unsigned int sid;
225 unsigned int sid;
226 unsigned char sidAsUnsignedChar;
226 unsigned char sidAsUnsignedChar;
227 unsigned char type;
227 unsigned char type;
228
228
229 incomingRingNodePtr = NULL;
229 incomingRingNodePtr = NULL;
230 ring_node_address = 0;
230 ring_node_address = 0;
231 charPtr = (char *) &ring_node_address;
231 charPtr = (char *) &ring_node_address;
232 sid = 0;
232 sid = 0;
233 sidAsUnsignedChar = 0;
233 sidAsUnsignedChar = 0;
234
234
235 init_header_cwf( &headerCWF );
235 init_header_cwf( &headerCWF );
236 init_header_swf( &headerSWF );
236 init_header_swf( &headerSWF );
237 init_header_asm( &headerASM );
237 init_header_asm( &headerASM );
238
238
239 status = get_message_queue_id_send( &queue_send_id );
239 status = get_message_queue_id_send( &queue_send_id );
240 if (status != RTEMS_SUCCESSFUL)
240 if (status != RTEMS_SUCCESSFUL)
241 {
241 {
242 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
242 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
243 }
243 }
244
244
245 BOOT_PRINTF("in SEND *** \n")
245 BOOT_PRINTF("in SEND *** \n")
246
246
247 while(1)
247 while(1)
248 {
248 {
249 status = rtems_message_queue_receive( queue_send_id, incomingData, &size,
249 status = rtems_message_queue_receive( queue_send_id, incomingData, &size,
250 RTEMS_WAIT, RTEMS_NO_TIMEOUT );
250 RTEMS_WAIT, RTEMS_NO_TIMEOUT );
251
251
252 if (status!=RTEMS_SUCCESSFUL)
252 if (status!=RTEMS_SUCCESSFUL)
253 {
253 {
254 PRINTF1("in SEND *** (1) ERR = %d\n", status)
254 PRINTF1("in SEND *** (1) ERR = %d\n", status)
255 }
255 }
256 else
256 else
257 {
257 {
258 if ( size == sizeof(ring_node*) )
258 if ( size == sizeof(ring_node*) )
259 {
259 {
260 charPtr[0] = incomingData[0];
260 charPtr[0] = incomingData[0];
261 charPtr[1] = incomingData[1];
261 charPtr[1] = incomingData[1];
262 charPtr[2] = incomingData[2];
262 charPtr[2] = incomingData[2];
263 charPtr[3] = incomingData[3];
263 charPtr[3] = incomingData[3];
264 incomingRingNodePtr = (ring_node*) ring_node_address;
264 incomingRingNodePtr = (ring_node*) ring_node_address;
265 sid = incomingRingNodePtr->sid;
265 sid = incomingRingNodePtr->sid;
266 if ( (sid==SID_NORM_CWF_LONG_F3)
266 if ( (sid==SID_NORM_CWF_LONG_F3)
267 || (sid==SID_BURST_CWF_F2 )
267 || (sid==SID_BURST_CWF_F2 )
268 || (sid==SID_SBM1_CWF_F1 )
268 || (sid==SID_SBM1_CWF_F1 )
269 || (sid==SID_SBM2_CWF_F2 ))
269 || (sid==SID_SBM2_CWF_F2 ))
270 {
270 {
271 spw_send_waveform_CWF( incomingRingNodePtr, &headerCWF );
271 spw_send_waveform_CWF( incomingRingNodePtr, &headerCWF );
272 }
272 }
273 else if ( (sid==SID_NORM_SWF_F0) || (sid== SID_NORM_SWF_F1) || (sid==SID_NORM_SWF_F2) )
273 else if ( (sid==SID_NORM_SWF_F0) || (sid== SID_NORM_SWF_F1) || (sid==SID_NORM_SWF_F2) )
274 {
274 {
275 spw_send_waveform_SWF( incomingRingNodePtr, &headerSWF );
275 spw_send_waveform_SWF( incomingRingNodePtr, &headerSWF );
276 }
276 }
277 else if ( (sid==SID_NORM_CWF_F3) )
277 else if ( (sid==SID_NORM_CWF_F3) )
278 {
278 {
279 spw_send_waveform_CWF3_light( incomingRingNodePtr, &headerCWF );
279 spw_send_waveform_CWF3_light( incomingRingNodePtr, &headerCWF );
280 }
280 }
281 else if (sid==SID_NORM_ASM_F0)
281 else if (sid==SID_NORM_ASM_F0)
282 {
282 {
283 spw_send_asm_f0( incomingRingNodePtr, &headerASM );
283 spw_send_asm_f0( incomingRingNodePtr, &headerASM );
284 }
284 }
285 else if (sid==SID_NORM_ASM_F1)
285 else if (sid==SID_NORM_ASM_F1)
286 {
286 {
287 spw_send_asm_f1( incomingRingNodePtr, &headerASM );
287 spw_send_asm_f1( incomingRingNodePtr, &headerASM );
288 }
288 }
289 else if (sid==SID_NORM_ASM_F2)
289 else if (sid==SID_NORM_ASM_F2)
290 {
290 {
291 spw_send_asm_f2( incomingRingNodePtr, &headerASM );
291 spw_send_asm_f2( incomingRingNodePtr, &headerASM );
292 }
292 }
293 else if ( sid==TM_CODE_K_DUMP )
293 else if ( sid==TM_CODE_K_DUMP )
294 {
294 {
295 spw_send_k_dump( incomingRingNodePtr );
295 spw_send_k_dump( incomingRingNodePtr );
296 }
296 }
297 else
297 else
298 {
298 {
299 PRINTF1("unexpected sid = %d\n", sid);
299 PRINTF1("unexpected sid = %d\n", sid);
300 }
300 }
301 }
301 }
302 else if ( incomingData[0] == CCSDS_DESTINATION_ID ) // the incoming message is a ccsds packet
302 else if ( incomingData[0] == CCSDS_DESTINATION_ID ) // the incoming message is a ccsds packet
303 {
303 {
304 sidAsUnsignedChar = (unsigned char) incomingData[ PACKET_POS_PA_LFR_SID_PKT ];
304 sidAsUnsignedChar = (unsigned char) incomingData[ PACKET_POS_PA_LFR_SID_PKT ];
305 sid = sidAsUnsignedChar;
305 sid = sidAsUnsignedChar;
306 type = (unsigned char) incomingData[ PACKET_POS_SERVICE_TYPE ];
306 type = (unsigned char) incomingData[ PACKET_POS_SERVICE_TYPE ];
307 if (type == TM_TYPE_LFR_SCIENCE) // this is a BP packet, all other types are handled differently
307 if (type == TM_TYPE_LFR_SCIENCE) // this is a BP packet, all other types are handled differently
308 // SET THE SEQUENCE_CNT PARAMETER IN CASE OF BP0 OR BP1 PACKETS
308 // SET THE SEQUENCE_CNT PARAMETER IN CASE OF BP0 OR BP1 PACKETS
309 {
309 {
310 increment_seq_counter_source_id( (unsigned char*) &incomingData[ PACKET_POS_SEQUENCE_CNT ], sid );
310 increment_seq_counter_source_id( (unsigned char*) &incomingData[ PACKET_POS_SEQUENCE_CNT ], sid );
311 }
311 }
312
312
313 status = write( fdSPW, incomingData, size );
313 status = write( fdSPW, incomingData, size );
314 if (status == -1){
314 if (status == -1){
315 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
315 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
316 }
316 }
317 }
317 }
318 else // the incoming message is a spw_ioctl_pkt_send structure
318 else // the incoming message is a spw_ioctl_pkt_send structure
319 {
319 {
320 spw_ioctl_send = (spw_ioctl_pkt_send*) incomingData;
320 spw_ioctl_send = (spw_ioctl_pkt_send*) incomingData;
321 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, spw_ioctl_send );
321 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, spw_ioctl_send );
322 if (status == -1){
322 if (status == -1){
323 PRINTF2("in SEND *** (2.b) ERRNO = %d, RTEMS = %d\n", errno, status)
323 PRINTF2("in SEND *** (2.b) ERRNO = %d, RTEMS = %d\n", errno, status)
324 }
324 }
325 }
325 }
326 }
326 }
327
327
328 update_queue_max_count( queue_send_id, &hk_lfr_q_sd_fifo_size_max );
328 update_queue_max_count( queue_send_id, &hk_lfr_q_sd_fifo_size_max );
329
329
330 }
330 }
331 }
331 }
332
332
333 rtems_task link_task( rtems_task_argument argument )
333 rtems_task link_task( rtems_task_argument argument )
334 {
334 {
335 rtems_event_set event_out;
335 rtems_event_set event_out;
336 rtems_status_code status;
336 rtems_status_code status;
337 int linkStatus;
337 int linkStatus;
338
338
339 BOOT_PRINTF("in LINK ***\n")
339 BOOT_PRINTF("in LINK ***\n")
340
340
341 while(1)
341 while(1)
342 {
342 {
343 // wait for an RTEMS_EVENT
343 // wait for an RTEMS_EVENT
344 rtems_event_receive( RTEMS_EVENT_0,
344 rtems_event_receive( RTEMS_EVENT_0,
345 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
345 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
346 PRINTF("in LINK *** wait for the link\n")
346 PRINTF("in LINK *** wait for the link\n")
347 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
347 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
348 while( linkStatus != 5) // wait for the link
348 while( linkStatus != 5) // wait for the link
349 {
349 {
350 status = rtems_task_wake_after( 10 ); // monitor the link each 100ms
350 status = rtems_task_wake_after( 10 ); // monitor the link each 100ms
351 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
351 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
352 watchdog_reload();
352 watchdog_reload();
353 }
353 }
354
354
355 spacewire_read_statistics();
355 spacewire_read_statistics();
356 status = spacewire_stop_and_start_link( fdSPW );
356 status = spacewire_stop_and_start_link( fdSPW );
357
357
358 if (status != RTEMS_SUCCESSFUL)
358 if (status != RTEMS_SUCCESSFUL)
359 {
359 {
360 PRINTF1("in LINK *** ERR link not started %d\n", status)
360 PRINTF1("in LINK *** ERR link not started %d\n", status)
361 }
361 }
362 else
362 else
363 {
363 {
364 PRINTF("in LINK *** OK link started\n")
364 PRINTF("in LINK *** OK link started\n")
365 }
365 }
366
366
367 // restart the SPIQ task
367 // restart the SPIQ task
368 status = rtems_task_restart( Task_id[TASKID_SPIQ], 1 );
368 status = rtems_task_restart( Task_id[TASKID_SPIQ], 1 );
369 if ( status != RTEMS_SUCCESSFUL ) {
369 if ( status != RTEMS_SUCCESSFUL ) {
370 PRINTF("in SPIQ *** ERR restarting SPIQ Task\n")
370 PRINTF("in SPIQ *** ERR restarting SPIQ Task\n")
371 }
371 }
372
372
373 // restart RECV and SEND
373 // restart RECV and SEND
374 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
374 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
375 if ( status != RTEMS_SUCCESSFUL ) {
375 if ( status != RTEMS_SUCCESSFUL ) {
376 PRINTF("in SPIQ *** ERR restarting SEND Task\n")
376 PRINTF("in SPIQ *** ERR restarting SEND Task\n")
377 }
377 }
378 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
378 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
379 if ( status != RTEMS_SUCCESSFUL ) {
379 if ( status != RTEMS_SUCCESSFUL ) {
380 PRINTF("in SPIQ *** ERR restarting RECV Task\n")
380 PRINTF("in SPIQ *** ERR restarting RECV Task\n")
381 }
381 }
382 }
382 }
383 }
383 }
384
384
385 //****************
385 //****************
386 // OTHER FUNCTIONS
386 // OTHER FUNCTIONS
387 int spacewire_open_link( void ) // by default, the driver resets the core: [SPW_CTRL_WRITE(pDev, SPW_CTRL_RESET);]
387 int spacewire_open_link( void ) // by default, the driver resets the core: [SPW_CTRL_WRITE(pDev, SPW_CTRL_RESET);]
388 {
388 {
389 /** This function opens the SpaceWire link.
389 /** This function opens the SpaceWire link.
390 *
390 *
391 * @return a valid file descriptor in case of success, -1 in case of a failure
391 * @return a valid file descriptor in case of success, -1 in case of a failure
392 *
392 *
393 */
393 */
394 rtems_status_code status;
394 rtems_status_code status;
395
395
396 fdSPW = open(GRSPW_DEVICE_NAME, O_RDWR); // open the device. the open call resets the hardware
396 fdSPW = open(GRSPW_DEVICE_NAME, O_RDWR); // open the device. the open call resets the hardware
397 if ( fdSPW < 0 ) {
397 if ( fdSPW < 0 ) {
398 PRINTF1("ERR *** in configure_spw_link *** error opening "GRSPW_DEVICE_NAME" with ERR %d\n", errno)
398 PRINTF1("ERR *** in configure_spw_link *** error opening "GRSPW_DEVICE_NAME" with ERR %d\n", errno)
399 }
399 }
400 else
400 else
401 {
401 {
402 status = RTEMS_SUCCESSFUL;
402 status = RTEMS_SUCCESSFUL;
403 }
403 }
404
404
405 return status;
405 return status;
406 }
406 }
407
407
408 int spacewire_start_link( int fd )
408 int spacewire_start_link( int fd )
409 {
409 {
410 rtems_status_code status;
410 rtems_status_code status;
411
411
412 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
412 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
413 // -1 default hardcoded driver timeout
413 // -1 default hardcoded driver timeout
414
414
415 return status;
415 return status;
416 }
416 }
417
417
418 int spacewire_stop_and_start_link( int fd )
418 int spacewire_stop_and_start_link( int fd )
419 {
419 {
420 rtems_status_code status;
420 rtems_status_code status;
421
421
422 status = ioctl( fd, SPACEWIRE_IOCTRL_STOP); // start fails if link pDev->running != 0
422 status = ioctl( fd, SPACEWIRE_IOCTRL_STOP); // start fails if link pDev->running != 0
423 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
423 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
424 // -1 default hardcoded driver timeout
424 // -1 default hardcoded driver timeout
425
425
426 return status;
426 return status;
427 }
427 }
428
428
429 int spacewire_configure_link( int fd )
429 int spacewire_configure_link( int fd )
430 {
430 {
431 /** This function configures the SpaceWire link.
431 /** This function configures the SpaceWire link.
432 *
432 *
433 * @return GR-RTEMS-DRIVER directive status codes:
433 * @return GR-RTEMS-DRIVER directive status codes:
434 * - 22 EINVAL - Null pointer or an out of range value was given as the argument.
434 * - 22 EINVAL - Null pointer or an out of range value was given as the argument.
435 * - 16 EBUSY - Only used for SEND. Returned when no descriptors are avialble in non-blocking mode.
435 * - 16 EBUSY - Only used for SEND. Returned when no descriptors are avialble in non-blocking mode.
436 * - 88 ENOSYS - Returned for SET_DESTKEY if RMAP command handler is not available or if a non-implemented call is used.
436 * - 88 ENOSYS - Returned for SET_DESTKEY if RMAP command handler is not available or if a non-implemented call is used.
437 * - 116 ETIMEDOUT - REturned for SET_PACKET_SIZE and START if the link could not be brought up.
437 * - 116 ETIMEDOUT - REturned for SET_PACKET_SIZE and START if the link could not be brought up.
438 * - 12 ENOMEM - Returned for SET_PACKETSIZE if it was unable to allocate the new buffers.
438 * - 12 ENOMEM - Returned for SET_PACKETSIZE if it was unable to allocate the new buffers.
439 * - 5 EIO - Error when writing to grswp hardware registers.
439 * - 5 EIO - Error when writing to grswp hardware registers.
440 * - 2 ENOENT - No such file or directory
440 * - 2 ENOENT - No such file or directory
441 */
441 */
442
442
443 rtems_status_code status;
443 rtems_status_code status;
444
444
445 spacewire_set_NP(1, REGS_ADDR_GRSPW); // [N]o [P]ort force
445 spacewire_set_NP(1, REGS_ADDR_GRSPW); // [N]o [P]ort force
446 spacewire_set_RE(1, REGS_ADDR_GRSPW); // [R]MAP [E]nable, the dedicated call seems to break the no port force configuration
446 spacewire_set_RE(1, REGS_ADDR_GRSPW); // [R]MAP [E]nable, the dedicated call seems to break the no port force configuration
447
447
448 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_RXBLOCK, 1); // sets the blocking mode for reception
448 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_RXBLOCK, 1); // sets the blocking mode for reception
449 if (status!=RTEMS_SUCCESSFUL) {
449 if (status!=RTEMS_SUCCESSFUL) {
450 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_RXBLOCK\n")
450 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_RXBLOCK\n")
451 }
451 }
452 //
452 //
453 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_EVENT_ID, Task_id[TASKID_SPIQ]); // sets the task ID to which an event is sent when a
453 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_EVENT_ID, Task_id[TASKID_SPIQ]); // sets the task ID to which an event is sent when a
454 if (status!=RTEMS_SUCCESSFUL) {