##// END OF EJS Templates
sync
paul -
r184:392adb5bc7c9 VHDL_0_1_28
parent child
Show More
@@ -1,2 +1,2
1 cc82265fd480dbd0344bbf888476c76602b3e9c0 LFR_basic-parameters
1 a586fe639ac179e95bdc150ebdbab0312f31dc30 LFR_basic-parameters
2 95a8d83f1d0c59f28a679e66e23464f21c12dd8a header/lfr_common_headers
2 b984c315bf99562bdfbbd6bda8de296d2e692adc header/lfr_common_headers
@@ -1,1115 +1,1120
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 //***********
25 //***********
26 // RTEMS TASK
26 // RTEMS TASK
27 rtems_task spiq_task(rtems_task_argument unused)
27 rtems_task spiq_task(rtems_task_argument unused)
28 {
28 {
29 /** This RTEMS task is awaken by an rtems_event sent by the interruption subroutine of the SpaceWire driver.
29 /** This RTEMS task is awaken by an rtems_event sent by the interruption subroutine of the SpaceWire driver.
30 *
30 *
31 * @param unused is the starting argument of the RTEMS task
31 * @param unused is the starting argument of the RTEMS task
32 *
32 *
33 */
33 */
34
34
35 rtems_event_set event_out;
35 rtems_event_set event_out;
36 rtems_status_code status;
36 rtems_status_code status;
37 int linkStatus;
37 int linkStatus;
38
38
39 BOOT_PRINTF("in SPIQ *** \n")
39 BOOT_PRINTF("in SPIQ *** \n")
40
40
41 while(true){
41 while(true){
42 rtems_event_receive(SPW_LINKERR_EVENT, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an SPW_LINKERR_EVENT
42 rtems_event_receive(SPW_LINKERR_EVENT, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an SPW_LINKERR_EVENT
43 PRINTF("in SPIQ *** got SPW_LINKERR_EVENT\n")
43 PRINTF("in SPIQ *** got SPW_LINKERR_EVENT\n")
44
44
45 // [0] SUSPEND RECV AND SEND TASKS
45 // [0] SUSPEND RECV AND SEND TASKS
46 status = rtems_task_suspend( Task_id[ TASKID_RECV ] );
46 status = rtems_task_suspend( Task_id[ TASKID_RECV ] );
47 if ( status != RTEMS_SUCCESSFUL ) {
47 if ( status != RTEMS_SUCCESSFUL ) {
48 PRINTF("in SPIQ *** ERR suspending RECV Task\n")
48 PRINTF("in SPIQ *** ERR suspending RECV Task\n")
49 }
49 }
50 status = rtems_task_suspend( Task_id[ TASKID_SEND ] );
50 status = rtems_task_suspend( Task_id[ TASKID_SEND ] );
51 if ( status != RTEMS_SUCCESSFUL ) {
51 if ( status != RTEMS_SUCCESSFUL ) {
52 PRINTF("in SPIQ *** ERR suspending SEND Task\n")
52 PRINTF("in SPIQ *** ERR suspending SEND Task\n")
53 }
53 }
54
54
55 // [1] CHECK THE LINK
55 // [1] CHECK THE LINK
56 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (1)
56 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (1)
57 if ( linkStatus != 5) {
57 if ( linkStatus != 5) {
58 PRINTF1("in SPIQ *** linkStatus %d, wait...\n", linkStatus)
58 PRINTF1("in SPIQ *** linkStatus %d, wait...\n", linkStatus)
59 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
59 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
60 }
60 }
61
61
62 // [2] RECHECK THE LINK AFTER SY_LFR_DPU_CONNECT_TIMEOUT
62 // [2] RECHECK THE LINK AFTER SY_LFR_DPU_CONNECT_TIMEOUT
63 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (2)
63 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (2)
64 if ( linkStatus != 5 ) // [2.a] not in run state, reset the link
64 if ( linkStatus != 5 ) // [2.a] not in run state, reset the link
65 {
65 {
66 spacewire_compute_stats_offsets();
66 spacewire_compute_stats_offsets();
67 status = spacewire_reset_link( );
67 status = spacewire_reset_link( );
68 }
68 }
69 else // [2.b] in run state, start the link
69 else // [2.b] in run state, start the link
70 {
70 {
71 status = spacewire_stop_and_start_link( fdSPW ); // start the link
71 status = spacewire_stop_and_start_link( fdSPW ); // start the link
72 if ( status != RTEMS_SUCCESSFUL)
72 if ( status != RTEMS_SUCCESSFUL)
73 {
73 {
74 PRINTF1("in SPIQ *** ERR spacewire_start_link %d\n", status)
74 PRINTF1("in SPIQ *** ERR spacewire_start_link %d\n", status)
75 }
75 }
76 }
76 }
77
77
78 // [3] COMPLETE RECOVERY ACTION AFTER SY_LFR_DPU_CONNECT_ATTEMPTS
78 // [3] COMPLETE RECOVERY ACTION AFTER SY_LFR_DPU_CONNECT_ATTEMPTS
79 if ( status == RTEMS_SUCCESSFUL ) // [3.a] the link is in run state and has been started successfully
79 if ( status == RTEMS_SUCCESSFUL ) // [3.a] the link is in run state and has been started successfully
80 {
80 {
81 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
81 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
82 if ( status != RTEMS_SUCCESSFUL ) {
82 if ( status != RTEMS_SUCCESSFUL ) {
83 PRINTF("in SPIQ *** ERR resuming SEND Task\n")
83 PRINTF("in SPIQ *** ERR resuming SEND Task\n")
84 }
84 }
85 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
85 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
86 if ( status != RTEMS_SUCCESSFUL ) {
86 if ( status != RTEMS_SUCCESSFUL ) {
87 PRINTF("in SPIQ *** ERR resuming RECV Task\n")
87 PRINTF("in SPIQ *** ERR resuming RECV Task\n")
88 }
88 }
89 }
89 }
90 else // [3.b] the link is not in run state, go in STANDBY mode
90 else // [3.b] the link is not in run state, go in STANDBY mode
91 {
91 {
92 status = stop_current_mode();
92 status = stop_current_mode();
93 if ( status != RTEMS_SUCCESSFUL ) {
93 if ( status != RTEMS_SUCCESSFUL ) {
94 PRINTF1("in SPIQ *** ERR stop_current_mode *** code %d\n", status)
94 PRINTF1("in SPIQ *** ERR stop_current_mode *** code %d\n", status)
95 }
95 }
96 status = enter_mode( LFR_MODE_STANDBY, 0 );
96 status = enter_mode( LFR_MODE_STANDBY, 0 );
97 if ( status != RTEMS_SUCCESSFUL ) {
97 if ( status != RTEMS_SUCCESSFUL ) {
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 // wake the WTDG task up to wait for the link recovery
100 // wake the WTDG task up to wait for the link recovery
101 status = rtems_event_send ( Task_id[TASKID_WTDG], RTEMS_EVENT_0 );
101 status = rtems_event_send ( Task_id[TASKID_WTDG], RTEMS_EVENT_0 );
102 status = rtems_task_suspend( RTEMS_SELF );
102 status = rtems_task_suspend( RTEMS_SELF );
103 }
103 }
104 }
104 }
105 }
105 }
106
106
107 rtems_task recv_task( rtems_task_argument unused )
107 rtems_task recv_task( rtems_task_argument unused )
108 {
108 {
109 /** This RTEMS task is dedicated to the reception of incoming TeleCommands.
109 /** This RTEMS task is dedicated to the reception of incoming TeleCommands.
110 *
110 *
111 * @param unused is the starting argument of the RTEMS task
111 * @param unused is the starting argument of the RTEMS task
112 *
112 *
113 * The RECV task blocks on a call to the read system call, waiting for incoming SpaceWire data. When unblocked:
113 * The RECV task blocks on a call to the read system call, waiting for incoming SpaceWire data. When unblocked:
114 * 1. It reads the incoming data.
114 * 1. It reads the incoming data.
115 * 2. Launches the acceptance procedure.
115 * 2. Launches the acceptance procedure.
116 * 3. If the Telecommand is valid, sends it to a dedicated RTEMS message queue.
116 * 3. If the Telecommand is valid, sends it to a dedicated RTEMS message queue.
117 *
117 *
118 */
118 */
119
119
120 int len;
120 int len;
121 ccsdsTelecommandPacket_t currentTC;
121 ccsdsTelecommandPacket_t currentTC;
122 unsigned char computed_CRC[ 2 ];
122 unsigned char computed_CRC[ 2 ];
123 unsigned char currentTC_LEN_RCV[ 2 ];
123 unsigned char currentTC_LEN_RCV[ 2 ];
124 unsigned char destinationID;
124 unsigned char destinationID;
125 unsigned int estimatedPacketLength;
125 unsigned int estimatedPacketLength;
126 unsigned int parserCode;
126 unsigned int parserCode;
127 rtems_status_code status;
127 rtems_status_code status;
128 rtems_id queue_recv_id;
128 rtems_id queue_recv_id;
129 rtems_id queue_send_id;
129 rtems_id queue_send_id;
130
130
131 initLookUpTableForCRC(); // the table is used to compute Cyclic Redundancy Codes
131 initLookUpTableForCRC(); // the table is used to compute Cyclic Redundancy Codes
132
132
133 status = get_message_queue_id_recv( &queue_recv_id );
133 status = get_message_queue_id_recv( &queue_recv_id );
134 if (status != RTEMS_SUCCESSFUL)
134 if (status != RTEMS_SUCCESSFUL)
135 {
135 {
136 PRINTF1("in RECV *** ERR get_message_queue_id_recv %d\n", status)
136 PRINTF1("in RECV *** ERR get_message_queue_id_recv %d\n", status)
137 }
137 }
138
138
139 status = get_message_queue_id_send( &queue_send_id );
139 status = get_message_queue_id_send( &queue_send_id );
140 if (status != RTEMS_SUCCESSFUL)
140 if (status != RTEMS_SUCCESSFUL)
141 {
141 {
142 PRINTF1("in RECV *** ERR get_message_queue_id_send %d\n", status)
142 PRINTF1("in RECV *** ERR get_message_queue_id_send %d\n", status)
143 }
143 }
144
144
145 BOOT_PRINTF("in RECV *** \n")
145 BOOT_PRINTF("in RECV *** \n")
146
146
147 while(1)
147 while(1)
148 {
148 {
149 len = read( fdSPW, (char*) &currentTC, CCSDS_TC_PKT_MAX_SIZE ); // the call to read is blocking
149 len = read( fdSPW, (char*) &currentTC, CCSDS_TC_PKT_MAX_SIZE ); // the call to read is blocking
150 if (len == -1){ // error during the read call
150 if (len == -1){ // error during the read call
151 PRINTF1("in RECV *** last read call returned -1, ERRNO %d\n", errno)
151 PRINTF1("in RECV *** last read call returned -1, ERRNO %d\n", errno)
152 }
152 }
153 else {
153 else {
154 if ( (len+1) < CCSDS_TC_PKT_MIN_SIZE ) {
154 if ( (len+1) < CCSDS_TC_PKT_MIN_SIZE ) {
155 PRINTF("in RECV *** packet lenght too short\n")
155 PRINTF("in RECV *** packet lenght too short\n")
156 }
156 }
157 else {
157 else {
158 estimatedPacketLength = (unsigned int) (len - CCSDS_TC_TM_PACKET_OFFSET - 3); // => -3 is for Prot ID, Reserved and User App bytes
158 estimatedPacketLength = (unsigned int) (len - CCSDS_TC_TM_PACKET_OFFSET - 3); // => -3 is for Prot ID, Reserved and User App bytes
159 currentTC_LEN_RCV[ 0 ] = (unsigned char) (estimatedPacketLength >> 8);
159 currentTC_LEN_RCV[ 0 ] = (unsigned char) (estimatedPacketLength >> 8);
160 currentTC_LEN_RCV[ 1 ] = (unsigned char) (estimatedPacketLength );
160 currentTC_LEN_RCV[ 1 ] = (unsigned char) (estimatedPacketLength );
161 // CHECK THE TC
161 // CHECK THE TC
162 parserCode = tc_parser( &currentTC, estimatedPacketLength, computed_CRC ) ;
162 parserCode = tc_parser( &currentTC, estimatedPacketLength, computed_CRC ) ;
163 if ( (parserCode == ILLEGAL_APID) || (parserCode == WRONG_LEN_PKT)
163 if ( (parserCode == ILLEGAL_APID) || (parserCode == WRONG_LEN_PKT)
164 || (parserCode == INCOR_CHECKSUM) || (parserCode == ILL_TYPE)
164 || (parserCode == INCOR_CHECKSUM) || (parserCode == ILL_TYPE)
165 || (parserCode == ILL_SUBTYPE) || (parserCode == WRONG_APP_DATA)
165 || (parserCode == ILL_SUBTYPE) || (parserCode == WRONG_APP_DATA)
166 || (parserCode == WRONG_SRC_ID) )
166 || (parserCode == WRONG_SRC_ID) )
167 { // send TM_LFR_TC_EXE_CORRUPTED
167 { // send TM_LFR_TC_EXE_CORRUPTED
168 PRINTF1("TC corrupted received, with code: %d\n", parserCode)
168 PRINTF1("TC corrupted received, with code: %d\n", parserCode)
169 if ( !( (currentTC.serviceType==TC_TYPE_TIME) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_TIME) )
169 if ( !( (currentTC.serviceType==TC_TYPE_TIME) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_TIME) )
170 &&
170 &&
171 !( (currentTC.serviceType==TC_TYPE_GEN) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_INFO))
171 !( (currentTC.serviceType==TC_TYPE_GEN) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_INFO))
172 )
172 )
173 {
173 {
174 if ( parserCode == WRONG_SRC_ID )
174 if ( parserCode == WRONG_SRC_ID )
175 {
175 {
176 destinationID = SID_TC_GROUND;
176 destinationID = SID_TC_GROUND;
177 }
177 }
178 else
178 else
179 {
179 {
180 destinationID = currentTC.sourceID;
180 destinationID = currentTC.sourceID;
181 }
181 }
182 send_tm_lfr_tc_exe_corrupted( &currentTC, queue_send_id,
182 send_tm_lfr_tc_exe_corrupted( &currentTC, queue_send_id,
183 computed_CRC, currentTC_LEN_RCV,
183 computed_CRC, currentTC_LEN_RCV,
184 destinationID );
184 destinationID );
185 }
185 }
186 }
186 }
187 else
187 else
188 { // send valid TC to the action launcher
188 { // send valid TC to the action launcher
189 status = rtems_message_queue_send( queue_recv_id, &currentTC,
189 status = rtems_message_queue_send( queue_recv_id, &currentTC,
190 estimatedPacketLength + CCSDS_TC_TM_PACKET_OFFSET + 3);
190 estimatedPacketLength + CCSDS_TC_TM_PACKET_OFFSET + 3);
191 }
191 }
192 }
192 }
193 }
193 }
194 }
194 }
195 }
195 }
196
196
197 rtems_task send_task( rtems_task_argument argument)
197 rtems_task send_task( rtems_task_argument argument)
198 {
198 {
199 /** This RTEMS task is dedicated to the transmission of TeleMetry packets.
199 /** This RTEMS task is dedicated to the transmission of TeleMetry packets.
200 *
200 *
201 * @param unused is the starting argument of the RTEMS task
201 * @param unused is the starting argument of the RTEMS task
202 *
202 *
203 * The SEND task waits for a message to become available in the dedicated RTEMS queue. When a message arrives:
203 * The SEND task waits for a message to become available in the dedicated RTEMS queue. When a message arrives:
204 * - if the first byte is equal to CCSDS_DESTINATION_ID, the message is sent as is using the write system call.
204 * - if the first byte is equal to CCSDS_DESTINATION_ID, the message is sent as is using the write system call.
205 * - if the first byte is not equal to CCSDS_DESTINATION_ID, the message is handled as a spw_ioctl_pkt_send. After
205 * - if the first byte is not equal to CCSDS_DESTINATION_ID, the message is handled as a spw_ioctl_pkt_send. After
206 * analyzis, the packet is sent either using the write system call or using the ioctl call SPACEWIRE_IOCTRL_SEND, depending on the
206 * analyzis, the packet is sent either using the write system call or using the ioctl call SPACEWIRE_IOCTRL_SEND, depending on the
207 * data it contains.
207 * data it contains.
208 *
208 *
209 */
209 */
210
210
211 rtems_status_code status; // RTEMS status code
211 rtems_status_code status; // RTEMS status code
212 char incomingData[MSG_QUEUE_SIZE_SEND]; // incoming data buffer
212 char incomingData[MSG_QUEUE_SIZE_SEND]; // incoming data buffer
213 ring_node *incomingRingNodePtr;
213 ring_node *incomingRingNodePtr;
214 int ring_node_address;
214 int ring_node_address;
215 char *charPtr;
215 char *charPtr;
216 spw_ioctl_pkt_send *spw_ioctl_send;
216 spw_ioctl_pkt_send *spw_ioctl_send;
217 size_t size; // size of the incoming TC packet
217 size_t size; // size of the incoming TC packet
218 u_int32_t count;
218 u_int32_t count;
219 rtems_id queue_id;
219 rtems_id queue_id;
220 unsigned char sid;
220 unsigned char sid;
221
221
222 incomingRingNodePtr = NULL;
222 incomingRingNodePtr = NULL;
223 ring_node_address = 0;
223 ring_node_address = 0;
224 charPtr = (char *) &ring_node_address;
224 charPtr = (char *) &ring_node_address;
225 sid = 0;
225 sid = 0;
226
226
227 init_header_cwf( &headerCWF );
227 init_header_cwf( &headerCWF );
228 init_header_swf( &headerSWF );
228 init_header_swf( &headerSWF );
229 init_header_asm( &headerASM );
229 init_header_asm( &headerASM );
230
230
231 status = get_message_queue_id_send( &queue_id );
231 status = get_message_queue_id_send( &queue_id );
232 if (status != RTEMS_SUCCESSFUL)
232 if (status != RTEMS_SUCCESSFUL)
233 {
233 {
234 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
234 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
235 }
235 }
236
236
237 BOOT_PRINTF("in SEND *** \n")
237 BOOT_PRINTF("in SEND *** \n")
238
238
239 while(1)
239 while(1)
240 {
240 {
241 status = rtems_message_queue_receive( queue_id, incomingData, &size,
241 status = rtems_message_queue_receive( queue_id, incomingData, &size,
242 RTEMS_WAIT, RTEMS_NO_TIMEOUT );
242 RTEMS_WAIT, RTEMS_NO_TIMEOUT );
243
243
244 if (status!=RTEMS_SUCCESSFUL)
244 if (status!=RTEMS_SUCCESSFUL)
245 {
245 {
246 PRINTF1("in SEND *** (1) ERR = %d\n", status)
246 PRINTF1("in SEND *** (1) ERR = %d\n", status)
247 }
247 }
248 else
248 else
249 {
249 {
250 if ( size == sizeof(ring_node*) )
250 if ( size == sizeof(ring_node*) )
251 {
251 {
252 charPtr[0] = incomingData[0];
252 charPtr[0] = incomingData[0];
253 charPtr[1] = incomingData[1];
253 charPtr[1] = incomingData[1];
254 charPtr[2] = incomingData[2];
254 charPtr[2] = incomingData[2];
255 charPtr[3] = incomingData[3];
255 charPtr[3] = incomingData[3];
256 incomingRingNodePtr = (ring_node*) ring_node_address;
256 incomingRingNodePtr = (ring_node*) ring_node_address;
257 sid = incomingRingNodePtr->sid;
257 sid = incomingRingNodePtr->sid;
258 if ( (sid==SID_NORM_CWF_LONG_F3)
258 if ( (sid==SID_NORM_CWF_LONG_F3)
259 || (sid==SID_BURST_CWF_F2 )
259 || (sid==SID_BURST_CWF_F2 )
260 || (sid==SID_SBM1_CWF_F1 )
260 || (sid==SID_SBM1_CWF_F1 )
261 || (sid==SID_SBM2_CWF_F2 ))
261 || (sid==SID_SBM2_CWF_F2 ))
262 {
262 {
263 spw_send_waveform_CWF( incomingRingNodePtr, &headerCWF );
263 spw_send_waveform_CWF( incomingRingNodePtr, &headerCWF );
264 }
264 }
265 else if ( (sid==SID_NORM_SWF_F0) || (sid== SID_NORM_SWF_F1) || (sid==SID_NORM_SWF_F2) )
265 else if ( (sid==SID_NORM_SWF_F0) || (sid== SID_NORM_SWF_F1) || (sid==SID_NORM_SWF_F2) )
266 {
266 {
267 spw_send_waveform_SWF( incomingRingNodePtr, &headerSWF );
267 spw_send_waveform_SWF( incomingRingNodePtr, &headerSWF );
268 }
268 }
269 else if ( (sid==SID_NORM_CWF_F3) )
269 else if ( (sid==SID_NORM_CWF_F3) )
270 {
270 {
271 spw_send_waveform_CWF3_light( incomingRingNodePtr, &headerCWF );
271 spw_send_waveform_CWF3_light( incomingRingNodePtr, &headerCWF );
272 }
272 }
273 else if ( (sid==SID_NORM_ASM_F0) || (SID_NORM_ASM_F1) || (SID_NORM_ASM_F2) )
273 else if ( (sid==SID_NORM_ASM_F0) || (SID_NORM_ASM_F1) || (SID_NORM_ASM_F2) )
274 {
274 {
275 spw_send_asm( incomingRingNodePtr, &headerASM );
275 spw_send_asm( incomingRingNodePtr, &headerASM );
276 }
276 }
277 else
277 else
278 {
278 {
279 printf("unexpected sid = %d\n", sid);
279 printf("unexpected sid = %d\n", sid);
280 }
280 }
281 }
281 }
282 else if ( incomingData[0] == CCSDS_DESTINATION_ID ) // the incoming message is a ccsds packet
282 else if ( incomingData[0] == CCSDS_DESTINATION_ID ) // the incoming message is a ccsds packet
283 {
283 {
284 status = write( fdSPW, incomingData, size );
284 status = write( fdSPW, incomingData, size );
285 if (status == -1){
285 if (status == -1){
286 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
286 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
287 }
287 }
288 }
288 }
289 else // the incoming message is a spw_ioctl_pkt_send structure
289 else // the incoming message is a spw_ioctl_pkt_send structure
290 {
290 {
291 spw_ioctl_send = (spw_ioctl_pkt_send*) incomingData;
291 spw_ioctl_send = (spw_ioctl_pkt_send*) incomingData;
292 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, spw_ioctl_send );
292 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, spw_ioctl_send );
293 if (status == -1){
293 if (status == -1){
294 printf("size = %d, %x, %x, %x, %x, %x\n",
294 printf("size = %d, %x, %x, %x, %x, %x\n",
295 size,
295 size,
296 incomingData[0],
296 incomingData[0],
297 incomingData[1],
297 incomingData[1],
298 incomingData[2],
298 incomingData[2],
299 incomingData[3],
299 incomingData[3],
300 incomingData[4]);
300 incomingData[4]);
301 PRINTF2("in SEND *** (2.b) ERRNO = %d, RTEMS = %d\n", errno, status)
301 PRINTF2("in SEND *** (2.b) ERRNO = %d, RTEMS = %d\n", errno, status)
302 }
302 }
303 }
303 }
304 }
304 }
305
305
306 status = rtems_message_queue_get_number_pending( queue_id, &count );
306 status = rtems_message_queue_get_number_pending( queue_id, &count );
307 if (status != RTEMS_SUCCESSFUL)
307 if (status != RTEMS_SUCCESSFUL)
308 {
308 {
309 PRINTF1("in SEND *** (3) ERR = %d\n", status)
309 PRINTF1("in SEND *** (3) ERR = %d\n", status)
310 }
310 }
311 else
311 else
312 {
312 {
313 if (count > maxCount)
313 if (count > maxCount)
314 {
314 {
315 maxCount = count;
315 maxCount = count;
316 }
316 }
317 }
317 }
318 }
318 }
319 }
319 }
320
320
321 rtems_task wtdg_task( rtems_task_argument argument )
321 rtems_task wtdg_task( rtems_task_argument argument )
322 {
322 {
323 rtems_event_set event_out;
323 rtems_event_set event_out;
324 rtems_status_code status;
324 rtems_status_code status;
325 int linkStatus;
325 int linkStatus;
326
326
327 BOOT_PRINTF("in WTDG ***\n")
327 BOOT_PRINTF("in WTDG ***\n")
328
328
329 while(1)
329 while(1)
330 {
330 {
331 // wait for an RTEMS_EVENT
331 // wait for an RTEMS_EVENT
332 rtems_event_receive( RTEMS_EVENT_0,
332 rtems_event_receive( RTEMS_EVENT_0,
333 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
333 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
334 PRINTF("in WTDG *** wait for the link\n")
334 PRINTF("in WTDG *** wait for the link\n")
335 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
335 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
336 while( linkStatus != 5) // wait for the link
336 while( linkStatus != 5) // wait for the link
337 {
337 {
338 rtems_task_wake_after( 10 );
338 status = rtems_task_wake_after( 10 ); // monitor the link each 100ms
339 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
339 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
340 }
340 }
341
341
342 status = spacewire_stop_and_start_link( fdSPW );
342 status = spacewire_stop_and_start_link( fdSPW );
343
343
344 if (status != RTEMS_SUCCESSFUL)
344 if (status != RTEMS_SUCCESSFUL)
345 {
345 {
346 PRINTF1("in WTDG *** ERR link not started %d\n", status)
346 PRINTF1("in WTDG *** ERR link not started %d\n", status)
347 }
347 }
348 else
348 else
349 {
349 {
350 PRINTF("in WTDG *** OK link started\n")
350 PRINTF("in WTDG *** OK link started\n")
351 }
351 }
352
352
353 // restart the SPIQ task
353 // restart the SPIQ task
354 status = rtems_task_restart( Task_id[TASKID_SPIQ], 1 );
354 status = rtems_task_restart( Task_id[TASKID_SPIQ], 1 );
355 if ( status != RTEMS_SUCCESSFUL ) {
355 if ( status != RTEMS_SUCCESSFUL ) {
356 PRINTF("in SPIQ *** ERR restarting SPIQ Task\n")
356 PRINTF("in SPIQ *** ERR restarting SPIQ Task\n")
357 }
357 }
358
358
359 // restart RECV and SEND
359 // restart RECV and SEND
360 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
360 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
361 if ( status != RTEMS_SUCCESSFUL ) {
361 if ( status != RTEMS_SUCCESSFUL ) {
362 PRINTF("in SPIQ *** ERR restarting SEND Task\n")
362 PRINTF("in SPIQ *** ERR restarting SEND Task\n")
363 }
363 }
364 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
364 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
365 if ( status != RTEMS_SUCCESSFUL ) {
365 if ( status != RTEMS_SUCCESSFUL ) {
366 PRINTF("in SPIQ *** ERR restarting RECV Task\n")
366 PRINTF("in SPIQ *** ERR restarting RECV Task\n")
367 }
367 }
368 }
368 }
369 }
369 }
370
370
371 //****************
371 //****************
372 // OTHER FUNCTIONS
372 // OTHER FUNCTIONS
373 int spacewire_open_link( void ) // by default, the driver resets the core: [SPW_CTRL_WRITE(pDev, SPW_CTRL_RESET);]
373 int spacewire_open_link( void ) // by default, the driver resets the core: [SPW_CTRL_WRITE(pDev, SPW_CTRL_RESET);]
374 {
374 {
375 /** This function opens the SpaceWire link.
375 /** This function opens the SpaceWire link.
376 *
376 *
377 * @return a valid file descriptor in case of success, -1 in case of a failure
377 * @return a valid file descriptor in case of success, -1 in case of a failure
378 *
378 *
379 */
379 */
380 rtems_status_code status;
380 rtems_status_code status;
381
381
382 fdSPW = open(GRSPW_DEVICE_NAME, O_RDWR); // open the device. the open call resets the hardware
382 fdSPW = open(GRSPW_DEVICE_NAME, O_RDWR); // open the device. the open call resets the hardware
383 if ( fdSPW < 0 ) {
383 if ( fdSPW < 0 ) {
384 PRINTF1("ERR *** in configure_spw_link *** error opening "GRSPW_DEVICE_NAME" with ERR %d\n", errno)
384 PRINTF1("ERR *** in configure_spw_link *** error opening "GRSPW_DEVICE_NAME" with ERR %d\n", errno)
385 }
385 }
386 else
386 else
387 {
387 {
388 status = RTEMS_SUCCESSFUL;
388 status = RTEMS_SUCCESSFUL;
389 }
389 }
390
390
391 return status;
391 return status;
392 }
392 }
393
393
394 int spacewire_start_link( int fd )
394 int spacewire_start_link( int fd )
395 {
395 {
396 rtems_status_code status;
396 rtems_status_code status;
397
397
398 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
398 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
399 // -1 default hardcoded driver timeout
399 // -1 default hardcoded driver timeout
400
400
401 return status;
401 return status;
402 }
402 }
403
403
404 int spacewire_stop_and_start_link( int fd )
404 int spacewire_stop_and_start_link( int fd )
405 {
405 {
406 rtems_status_code status;
406 rtems_status_code status;
407
407
408 status = ioctl( fd, SPACEWIRE_IOCTRL_STOP); // start fails if link pDev->running != 0
408 status = ioctl( fd, SPACEWIRE_IOCTRL_STOP); // start fails if link pDev->running != 0
409 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
409 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
410 // -1 default hardcoded driver timeout
410 // -1 default hardcoded driver timeout
411
411
412 return status;
412 return status;
413 }
413 }
414
414
415 int spacewire_configure_link( int fd )
415 int spacewire_configure_link( int fd )
416 {
416 {
417 /** This function configures the SpaceWire link.
417 /** This function configures the SpaceWire link.
418 *
418 *
419 * @return GR-RTEMS-DRIVER directive status codes:
419 * @return GR-RTEMS-DRIVER directive status codes:
420 * - 22 EINVAL - Null pointer or an out of range value was given as the argument.
420 * - 22 EINVAL - Null pointer or an out of range value was given as the argument.
421 * - 16 EBUSY - Only used for SEND. Returned when no descriptors are avialble in non-blocking mode.
421 * - 16 EBUSY - Only used for SEND. Returned when no descriptors are avialble in non-blocking mode.
422 * - 88 ENOSYS - Returned for SET_DESTKEY if RMAP command handler is not available or if a non-implemented call is used.
422 * - 88 ENOSYS - Returned for SET_DESTKEY if RMAP command handler is not available or if a non-implemented call is used.
423 * - 116 ETIMEDOUT - REturned for SET_PACKET_SIZE and START if the link could not be brought up.
423 * - 116 ETIMEDOUT - REturned for SET_PACKET_SIZE and START if the link could not be brought up.
424 * - 12 ENOMEM - Returned for SET_PACKETSIZE if it was unable to allocate the new buffers.
424 * - 12 ENOMEM - Returned for SET_PACKETSIZE if it was unable to allocate the new buffers.
425 * - 5 EIO - Error when writing to grswp hardware registers.
425 * - 5 EIO - Error when writing to grswp hardware registers.
426 * - 2 ENOENT - No such file or directory
426 * - 2 ENOENT - No such file or directory
427 */
427 */
428
428
429 rtems_status_code status;
429 rtems_status_code status;
430
430
431 spacewire_set_NP(1, REGS_ADDR_GRSPW); // [N]o [P]ort force
431 spacewire_set_NP(1, REGS_ADDR_GRSPW); // [N]o [P]ort force
432 spacewire_set_RE(1, REGS_ADDR_GRSPW); // [R]MAP [E]nable, the dedicated call seems to break the no port force configuration
432 spacewire_set_RE(1, REGS_ADDR_GRSPW); // [R]MAP [E]nable, the dedicated call seems to break the no port force configuration
433
433
434 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_RXBLOCK, 1); // sets the blocking mode for reception
434 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_RXBLOCK, 1); // sets the blocking mode for reception
435 if (status!=RTEMS_SUCCESSFUL) {
435 if (status!=RTEMS_SUCCESSFUL) {
436 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_RXBLOCK\n")
436 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_RXBLOCK\n")
437 }
437 }
438 //
438 //
439 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_EVENT_ID, Task_id[TASKID_SPIQ]); // sets the task ID to which an event is sent when a
439 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_EVENT_ID, Task_id[TASKID_SPIQ]); // sets the task ID to which an event is sent when a
440 if (status!=RTEMS_SUCCESSFUL) {
440 if (status!=RTEMS_SUCCESSFUL) {
441 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_EVENT_ID\n") // link-error interrupt occurs
441 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_EVENT_ID\n") // link-error interrupt occurs
442 }
442 }
443 //
443 //
444 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_DISABLE_ERR, 0); // automatic link-disabling due to link-error interrupts
444 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_DISABLE_ERR, 0); // automatic link-disabling due to link-error interrupts
445 if (status!=RTEMS_SUCCESSFUL) {
445 if (status!=RTEMS_SUCCESSFUL) {
446 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_DISABLE_ERR\n")
446 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_DISABLE_ERR\n")
447 }
447 }
448 //
448 //
449 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ, 1); // sets the link-error interrupt bit
449 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ, 1); // sets the link-error interrupt bit
450 if (status!=RTEMS_SUCCESSFUL) {
450 if (status!=RTEMS_SUCCESSFUL) {
451 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ\n")
451 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ\n")
452 }
452 }
453 //
453 //
454 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK, 1); // transmission blocks
454 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK, 1); // transmission blocks
455 if (status!=RTEMS_SUCCESSFUL) {
455 if (status!=RTEMS_SUCCESSFUL) {
456 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK\n")
456 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK\n")
457 }
457 }
458 //
458 //
459 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL, 1); // transmission blocks when no transmission descriptor is available
459 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL, 1); // transmission blocks when no transmission descriptor is available
460 if (status!=RTEMS_SUCCESSFUL) {
460 if (status!=RTEMS_SUCCESSFUL) {
461 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL\n")
461 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL\n")
462 }
462 }
463 //
463 //
464 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TCODE_CTRL, 0x0909); // [Time Rx : Time Tx : Link error : Tick-out IRQ]
464 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TCODE_CTRL, 0x0909); // [Time Rx : Time Tx : Link error : Tick-out IRQ]
465 if (status!=RTEMS_SUCCESSFUL) {
465 if (status!=RTEMS_SUCCESSFUL) {
466 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TCODE_CTRL,\n")
466 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TCODE_CTRL,\n")
467 }
467 }
468
468
469 return status;
469 return status;
470 }
470 }
471
471
472 int spacewire_reset_link( void )
472 int spacewire_reset_link( void )
473 {
473 {
474 /** This function is executed by the SPIQ rtems_task wehn it has been awaken by an interruption raised by the SpaceWire driver.
474 /** This function is executed by the SPIQ rtems_task wehn it has been awaken by an interruption raised by the SpaceWire driver.
475 *
475 *
476 * @return RTEMS directive status code:
476 * @return RTEMS directive status code:
477 * - RTEMS_UNSATISFIED is returned is the link is not in the running state after 10 s.
477 * - RTEMS_UNSATISFIED is returned is the link is not in the running state after 10 s.
478 * - RTEMS_SUCCESSFUL is returned if the link is up before the timeout.
478 * - RTEMS_SUCCESSFUL is returned if the link is up before the timeout.
479 *
479 *
480 */
480 */
481
481
482 rtems_status_code status_spw;
482 rtems_status_code status_spw;
483 rtems_status_code status;
483 int i;
484 int i;
484
485
485 for ( i=0; i<SY_LFR_DPU_CONNECT_ATTEMPT; i++ )
486 for ( i=0; i<SY_LFR_DPU_CONNECT_ATTEMPT; i++ )
486 {
487 {
487 PRINTF1("in spacewire_reset_link *** link recovery, try %d\n", i);
488 PRINTF1("in spacewire_reset_link *** link recovery, try %d\n", i);
488
489
489 // CLOSING THE DRIVER AT THIS POINT WILL MAKE THE SEND TASK BLOCK THE SYSTEM
490 // CLOSING THE DRIVER AT THIS POINT WILL MAKE THE SEND TASK BLOCK THE SYSTEM
490
491
492 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
493
491 status_spw = spacewire_stop_and_start_link( fdSPW );
494 status_spw = spacewire_stop_and_start_link( fdSPW );
492 if ( status_spw != RTEMS_SUCCESSFUL )
495 if ( status_spw != RTEMS_SUCCESSFUL )
493 {
496 {
494 PRINTF1("in spacewire_reset_link *** ERR spacewire_start_link code %d\n", status_spw)
497 PRINTF1("in spacewire_reset_link *** ERR spacewire_start_link code %d\n", status_spw)
495 }
498 }
496
499
497 if ( status_spw == RTEMS_SUCCESSFUL)
500 if ( status_spw == RTEMS_SUCCESSFUL)
498 {
501 {
499 break;
502 break;
500 }
503 }
501 }
504 }
502
505
503 return status_spw;
506 return status_spw;
504 }
507 }
505
508
506 void spacewire_set_NP( unsigned char val, unsigned int regAddr ) // [N]o [P]ort force
509 void spacewire_set_NP( unsigned char val, unsigned int regAddr ) // [N]o [P]ort force
507 {
510 {
508 /** This function sets the [N]o [P]ort force bit of the GRSPW control register.
511 /** This function sets the [N]o [P]ort force bit of the GRSPW control register.
509 *
512 *
510 * @param val is the value, 0 or 1, used to set the value of the NP bit.
513 * @param val is the value, 0 or 1, used to set the value of the NP bit.
511 * @param regAddr is the address of the GRSPW control register.
514 * @param regAddr is the address of the GRSPW control register.
512 *
515 *
513 * NP is the bit 20 of the GRSPW control register.
516 * NP is the bit 20 of the GRSPW control register.
514 *
517 *
515 */
518 */
516
519
517 unsigned int *spwptr = (unsigned int*) regAddr;
520 unsigned int *spwptr = (unsigned int*) regAddr;
518
521
519 if (val == 1) {
522 if (val == 1) {
520 *spwptr = *spwptr | 0x00100000; // [NP] set the No port force bit
523 *spwptr = *spwptr | 0x00100000; // [NP] set the No port force bit
521 }
524 }
522 if (val== 0) {
525 if (val== 0) {
523 *spwptr = *spwptr & 0xffdfffff;
526 *spwptr = *spwptr & 0xffdfffff;
524 }
527 }
525 }
528 }
526
529
527 void spacewire_set_RE( unsigned char val, unsigned int regAddr ) // [R]MAP [E]nable
530 void spacewire_set_RE( unsigned char val, unsigned int regAddr ) // [R]MAP [E]nable
528 {
531 {
529 /** This function sets the [R]MAP [E]nable bit of the GRSPW control register.
532 /** This function sets the [R]MAP [E]nable bit of the GRSPW control register.
530 *
533 *
531 * @param val is the value, 0 or 1, used to set the value of the RE bit.
534 * @param val is the value, 0 or 1, used to set the value of the RE bit.
532 * @param regAddr is the address of the GRSPW control register.
535 * @param regAddr is the address of the GRSPW control register.
533 *
536 *
534 * RE is the bit 16 of the GRSPW control register.
537 * RE is the bit 16 of the GRSPW control register.
535 *
538 *
536 */
539 */
537
540
538 unsigned int *spwptr = (unsigned int*) regAddr;
541 unsigned int *spwptr = (unsigned int*) regAddr;
539
542
540 if (val == 1)
543 if (val == 1)
541 {
544 {
542 *spwptr = *spwptr | 0x00010000; // [RE] set the RMAP Enable bit
545 *spwptr = *spwptr | 0x00010000; // [RE] set the RMAP Enable bit
543 }
546 }
544 if (val== 0)
547 if (val== 0)
545 {
548 {
546 *spwptr = *spwptr & 0xfffdffff;
549 *spwptr = *spwptr & 0xfffdffff;
547 }
550 }
548 }
551 }
549
552
550 void spacewire_compute_stats_offsets( void )
553 void spacewire_compute_stats_offsets( void )
551 {
554 {
552 /** This function computes the SpaceWire statistics offsets in case of a SpaceWire related interruption raising.
555 /** This function computes the SpaceWire statistics offsets in case of a SpaceWire related interruption raising.
553 *
556 *
554 * The offsets keep a record of the statistics in case of a reset of the statistics. They are added to the current statistics
557 * The offsets keep a record of the statistics in case of a reset of the statistics. They are added to the current statistics
555 * to keep the counters consistent even after a reset of the SpaceWire driver (the counter are set to zero by the driver when it
558 * to keep the counters consistent even after a reset of the SpaceWire driver (the counter are set to zero by the driver when it
556 * during the open systel call).
559 * during the open systel call).
557 *
560 *
558 */
561 */
559
562
560 spw_stats spacewire_stats_grspw;
563 spw_stats spacewire_stats_grspw;
561 rtems_status_code status;
564 rtems_status_code status;
562
565
563 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &spacewire_stats_grspw );
566 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &spacewire_stats_grspw );
564
567
565 spacewire_stats_backup.packets_received = spacewire_stats_grspw.packets_received
568 spacewire_stats_backup.packets_received = spacewire_stats_grspw.packets_received
566 + spacewire_stats.packets_received;
569 + spacewire_stats.packets_received;
567 spacewire_stats_backup.packets_sent = spacewire_stats_grspw.packets_sent
570 spacewire_stats_backup.packets_sent = spacewire_stats_grspw.packets_sent
568 + spacewire_stats.packets_sent;
571 + spacewire_stats.packets_sent;
569 spacewire_stats_backup.parity_err = spacewire_stats_grspw.parity_err
572 spacewire_stats_backup.parity_err = spacewire_stats_grspw.parity_err
570 + spacewire_stats.parity_err;
573 + spacewire_stats.parity_err;
571 spacewire_stats_backup.disconnect_err = spacewire_stats_grspw.disconnect_err
574 spacewire_stats_backup.disconnect_err = spacewire_stats_grspw.disconnect_err
572 + spacewire_stats.disconnect_err;
575 + spacewire_stats.disconnect_err;
573 spacewire_stats_backup.escape_err = spacewire_stats_grspw.escape_err
576 spacewire_stats_backup.escape_err = spacewire_stats_grspw.escape_err
574 + spacewire_stats.escape_err;
577 + spacewire_stats.escape_err;
575 spacewire_stats_backup.credit_err = spacewire_stats_grspw.credit_err
578 spacewire_stats_backup.credit_err = spacewire_stats_grspw.credit_err
576 + spacewire_stats.credit_err;
579 + spacewire_stats.credit_err;
577 spacewire_stats_backup.write_sync_err = spacewire_stats_grspw.write_sync_err
580 spacewire_stats_backup.write_sync_err = spacewire_stats_grspw.write_sync_err
578 + spacewire_stats.write_sync_err;
581 + spacewire_stats.write_sync_err;
579 spacewire_stats_backup.rx_rmap_header_crc_err = spacewire_stats_grspw.rx_rmap_header_crc_err
582 spacewire_stats_backup.rx_rmap_header_crc_err = spacewire_stats_grspw.rx_rmap_header_crc_err
580 + spacewire_stats.rx_rmap_header_crc_err;
583 + spacewire_stats.rx_rmap_header_crc_err;
581 spacewire_stats_backup.rx_rmap_data_crc_err = spacewire_stats_grspw.rx_rmap_data_crc_err
584 spacewire_stats_backup.rx_rmap_data_crc_err = spacewire_stats_grspw.rx_rmap_data_crc_err
582 + spacewire_stats.rx_rmap_data_crc_err;
585 + spacewire_stats.rx_rmap_data_crc_err;
583 spacewire_stats_backup.early_ep = spacewire_stats_grspw.early_ep
586 spacewire_stats_backup.early_ep = spacewire_stats_grspw.early_ep
584 + spacewire_stats.early_ep;
587 + spacewire_stats.early_ep;
585 spacewire_stats_backup.invalid_address = spacewire_stats_grspw.invalid_address
588 spacewire_stats_backup.invalid_address = spacewire_stats_grspw.invalid_address
586 + spacewire_stats.invalid_address;
589 + spacewire_stats.invalid_address;
587 spacewire_stats_backup.rx_eep_err = spacewire_stats_grspw.rx_eep_err
590 spacewire_stats_backup.rx_eep_err = spacewire_stats_grspw.rx_eep_err
588 + spacewire_stats.rx_eep_err;
591 + spacewire_stats.rx_eep_err;
589 spacewire_stats_backup.rx_truncated = spacewire_stats_grspw.rx_truncated
592 spacewire_stats_backup.rx_truncated = spacewire_stats_grspw.rx_truncated
590 + spacewire_stats.rx_truncated;
593 + spacewire_stats.rx_truncated;
591 }
594 }
592
595
593 void spacewire_update_statistics( void )
596 void spacewire_update_statistics( void )
594 {
597 {
595 rtems_status_code status;
598 rtems_status_code status;
596 spw_stats spacewire_stats_grspw;
599 spw_stats spacewire_stats_grspw;
597
600
598 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &spacewire_stats_grspw );
601 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &spacewire_stats_grspw );
599
602
600 spacewire_stats.packets_received = spacewire_stats_backup.packets_received
603 spacewire_stats.packets_received = spacewire_stats_backup.packets_received
601 + spacewire_stats_grspw.packets_received;
604 + spacewire_stats_grspw.packets_received;
602 spacewire_stats.packets_sent = spacewire_stats_backup.packets_sent
605 spacewire_stats.packets_sent = spacewire_stats_backup.packets_sent
603 + spacewire_stats_grspw.packets_sent;
606 + spacewire_stats_grspw.packets_sent;
604 spacewire_stats.parity_err = spacewire_stats_backup.parity_err
607 spacewire_stats.parity_err = spacewire_stats_backup.parity_err
605 + spacewire_stats_grspw.parity_err;
608 + spacewire_stats_grspw.parity_err;
606 spacewire_stats.disconnect_err = spacewire_stats_backup.disconnect_err
609 spacewire_stats.disconnect_err = spacewire_stats_backup.disconnect_err
607 + spacewire_stats_grspw.disconnect_err;
610 + spacewire_stats_grspw.disconnect_err;
608 spacewire_stats.escape_err = spacewire_stats_backup.escape_err
611 spacewire_stats.escape_err = spacewire_stats_backup.escape_err
609 + spacewire_stats_grspw.escape_err;
612 + spacewire_stats_grspw.escape_err;
610 spacewire_stats.credit_err = spacewire_stats_backup.credit_err
613 spacewire_stats.credit_err = spacewire_stats_backup.credit_err
611 + spacewire_stats_grspw.credit_err;
614 + spacewire_stats_grspw.credit_err;
612 spacewire_stats.write_sync_err = spacewire_stats_backup.write_sync_err
615 spacewire_stats.write_sync_err = spacewire_stats_backup.write_sync_err
613 + spacewire_stats_grspw.write_sync_err;
616 + spacewire_stats_grspw.write_sync_err;
614 spacewire_stats.rx_rmap_header_crc_err = spacewire_stats_backup.rx_rmap_header_crc_err
617 spacewire_stats.rx_rmap_header_crc_err = spacewire_stats_backup.rx_rmap_header_crc_err
615 + spacewire_stats_grspw.rx_rmap_header_crc_err;
618 + spacewire_stats_grspw.rx_rmap_header_crc_err;
616 spacewire_stats.rx_rmap_data_crc_err = spacewire_stats_backup.rx_rmap_data_crc_err
619 spacewire_stats.rx_rmap_data_crc_err = spacewire_stats_backup.rx_rmap_data_crc_err
617 + spacewire_stats_grspw.rx_rmap_data_crc_err;
620 + spacewire_stats_grspw.rx_rmap_data_crc_err;
618 spacewire_stats.early_ep = spacewire_stats_backup.early_ep
621 spacewire_stats.early_ep = spacewire_stats_backup.early_ep
619 + spacewire_stats_grspw.early_ep;
622 + spacewire_stats_grspw.early_ep;
620 spacewire_stats.invalid_address = spacewire_stats_backup.invalid_address
623 spacewire_stats.invalid_address = spacewire_stats_backup.invalid_address
621 + spacewire_stats_grspw.invalid_address;
624 + spacewire_stats_grspw.invalid_address;
622 spacewire_stats.rx_eep_err = spacewire_stats_backup.rx_eep_err
625 spacewire_stats.rx_eep_err = spacewire_stats_backup.rx_eep_err
623 + spacewire_stats_grspw.rx_eep_err;
626 + spacewire_stats_grspw.rx_eep_err;
624 spacewire_stats.rx_truncated = spacewire_stats_backup.rx_truncated
627 spacewire_stats.rx_truncated = spacewire_stats_backup.rx_truncated
625 + spacewire_stats_grspw.rx_truncated;
628 + spacewire_stats_grspw.rx_truncated;
626 //spacewire_stats.tx_link_err;
629 //spacewire_stats.tx_link_err;
627
630
628 //****************************
631 //****************************
629 // DPU_SPACEWIRE_IF_STATISTICS
632 // DPU_SPACEWIRE_IF_STATISTICS
630 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[0] = (unsigned char) (spacewire_stats.packets_received >> 8);
633 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[0] = (unsigned char) (spacewire_stats.packets_received >> 8);
631 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[1] = (unsigned char) (spacewire_stats.packets_received);
634 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[1] = (unsigned char) (spacewire_stats.packets_received);
632 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[0] = (unsigned char) (spacewire_stats.packets_sent >> 8);
635 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[0] = (unsigned char) (spacewire_stats.packets_sent >> 8);
633 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[1] = (unsigned char) (spacewire_stats.packets_sent);
636 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[1] = (unsigned char) (spacewire_stats.packets_sent);
634 //housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt;
637 //housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt;
635 //housekeeping_packet.hk_lfr_dpu_spw_last_timc;
638 //housekeeping_packet.hk_lfr_dpu_spw_last_timc;
636
639
637 //******************************************
640 //******************************************
638 // ERROR COUNTERS / SPACEWIRE / LOW SEVERITY
641 // ERROR COUNTERS / SPACEWIRE / LOW SEVERITY
639 housekeeping_packet.hk_lfr_dpu_spw_parity = (unsigned char) spacewire_stats.parity_err;
642 housekeeping_packet.hk_lfr_dpu_spw_parity = (unsigned char) spacewire_stats.parity_err;
640 housekeeping_packet.hk_lfr_dpu_spw_disconnect = (unsigned char) spacewire_stats.disconnect_err;
643 housekeeping_packet.hk_lfr_dpu_spw_disconnect = (unsigned char) spacewire_stats.disconnect_err;
641 housekeeping_packet.hk_lfr_dpu_spw_escape = (unsigned char) spacewire_stats.escape_err;
644 housekeeping_packet.hk_lfr_dpu_spw_escape = (unsigned char) spacewire_stats.escape_err;
642 housekeeping_packet.hk_lfr_dpu_spw_credit = (unsigned char) spacewire_stats.credit_err;
645 housekeeping_packet.hk_lfr_dpu_spw_credit = (unsigned char) spacewire_stats.credit_err;
643 housekeeping_packet.hk_lfr_dpu_spw_write_sync = (unsigned char) spacewire_stats.write_sync_err;
646 housekeeping_packet.hk_lfr_dpu_spw_write_sync = (unsigned char) spacewire_stats.write_sync_err;
644
647
645 //*********************************************
648 //*********************************************
646 // ERROR COUNTERS / SPACEWIRE / MEDIUM SEVERITY
649 // ERROR COUNTERS / SPACEWIRE / MEDIUM SEVERITY
647 housekeeping_packet.hk_lfr_dpu_spw_early_eop = (unsigned char) spacewire_stats.early_ep;
650 housekeeping_packet.hk_lfr_dpu_spw_early_eop = (unsigned char) spacewire_stats.early_ep;
648 housekeeping_packet.hk_lfr_dpu_spw_invalid_addr = (unsigned char) spacewire_stats.invalid_address;
651 housekeeping_packet.hk_lfr_dpu_spw_invalid_addr = (unsigned char) spacewire_stats.invalid_address;
649 housekeeping_packet.hk_lfr_dpu_spw_eep = (unsigned char) spacewire_stats.rx_eep_err;
652 housekeeping_packet.hk_lfr_dpu_spw_eep = (unsigned char) spacewire_stats.rx_eep_err;
650 housekeeping_packet.hk_lfr_dpu_spw_rx_too_big = (unsigned char) spacewire_stats.rx_truncated;
653 housekeeping_packet.hk_lfr_dpu_spw_rx_too_big = (unsigned char) spacewire_stats.rx_truncated;
651 }
654 }
652
655
653 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc )
656 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc )
654 {
657 {
655 // rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_9 );
658 // a valid timecode has been received, write it in the HK report
656 struct grgpio_regs_str *grgpio_regs = (struct grgpio_regs_str *) REGS_ADDR_GRGPIO;
659 unsigned int * grspwPtr;
660
661 grspwPtr = (unsigned int *) (REGS_ADDR_GRSPW + APB_OFFSET_GRSPW_TIME_REGISTER);
657
662
658 grgpio_regs->io_port_direction_register =
663 housekeeping_packet.hk_lfr_dpu_spw_last_timc = (unsigned char) (grspwPtr[0] & 0x3f); // [11 1111]
659 grgpio_regs->io_port_direction_register | 0x04; // [0000 0100], 0 = output disabled, 1 = output enabled
660
664
661 if ( (grgpio_regs->io_port_output_register & 0x04) == 0x04 )
665 // update the number of valid timecodes that have been received
666 if (housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt == 255)
662 {
667 {
663 grgpio_regs->io_port_output_register = grgpio_regs->io_port_output_register & 0xfb; // [1111 1011]
668 housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt = 0;
664 }
669 }
665 else
670 else
666 {
671 {
667 grgpio_regs->io_port_output_register = grgpio_regs->io_port_output_register | 0x04; // [0000 0100]
672 housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt = housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt + 1;
668 }
673 }
669 }
674 }
670
675
671 rtems_timer_service_routine user_routine( rtems_id timer_id, void *user_data )
676 rtems_timer_service_routine user_routine( rtems_id timer_id, void *user_data )
672 {
677 {
673 int linkStatus;
678 int linkStatus;
674 rtems_status_code status;
679 rtems_status_code status;
675
680
676 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
681 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
677
682
678 if ( linkStatus == 5) {
683 if ( linkStatus == 5) {
679 PRINTF("in spacewire_reset_link *** link is running\n")
684 PRINTF("in spacewire_reset_link *** link is running\n")
680 status = RTEMS_SUCCESSFUL;
685 status = RTEMS_SUCCESSFUL;
681 }
686 }
682 }
687 }
683
688
684 void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header )
689 void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header )
685 {
690 {
686 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
691 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
687 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
692 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
688 header->reserved = DEFAULT_RESERVED;
693 header->reserved = DEFAULT_RESERVED;
689 header->userApplication = CCSDS_USER_APP;
694 header->userApplication = CCSDS_USER_APP;
690 header->packetSequenceControl[0]= TM_PACKET_SEQ_CTRL_STANDALONE;
695 header->packetSequenceControl[0]= TM_PACKET_SEQ_CTRL_STANDALONE;
691 header->packetSequenceControl[1]= TM_PACKET_SEQ_CNT_DEFAULT;
696 header->packetSequenceControl[1]= TM_PACKET_SEQ_CNT_DEFAULT;
692 header->packetLength[0] = 0x00;
697 header->packetLength[0] = 0x00;
693 header->packetLength[1] = 0x00;
698 header->packetLength[1] = 0x00;
694 // DATA FIELD HEADER
699 // DATA FIELD HEADER
695 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
700 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
696 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
701 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
697 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE; // service subtype
702 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE; // service subtype
698 header->destinationID = TM_DESTINATION_ID_GROUND;
703 header->destinationID = TM_DESTINATION_ID_GROUND;
699 header->time[0] = 0x00;
704 header->time[0] = 0x00;
700 header->time[0] = 0x00;
705 header->time[0] = 0x00;
701 header->time[0] = 0x00;
706 header->time[0] = 0x00;
702 header->time[0] = 0x00;
707 header->time[0] = 0x00;
703 header->time[0] = 0x00;
708 header->time[0] = 0x00;
704 header->time[0] = 0x00;
709 header->time[0] = 0x00;
705 // AUXILIARY DATA HEADER
710 // AUXILIARY DATA HEADER
706 header->sid = 0x00;
711 header->sid = 0x00;
707 header->hkBIA = DEFAULT_HKBIA;
712 header->hkBIA = DEFAULT_HKBIA;
708 header->blkNr[0] = 0x00;
713 header->blkNr[0] = 0x00;
709 header->blkNr[1] = 0x00;
714 header->blkNr[1] = 0x00;
710 }
715 }
711
716
712 void init_header_swf( Header_TM_LFR_SCIENCE_SWF_t *header )
717 void init_header_swf( Header_TM_LFR_SCIENCE_SWF_t *header )
713 {
718 {
714 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
719 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
715 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
720 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
716 header->reserved = DEFAULT_RESERVED;
721 header->reserved = DEFAULT_RESERVED;
717 header->userApplication = CCSDS_USER_APP;
722 header->userApplication = CCSDS_USER_APP;
718 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
723 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
719 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
724 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
720 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
725 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
721 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
726 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
722 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
727 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
723 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
728 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
724 // DATA FIELD HEADER
729 // DATA FIELD HEADER
725 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
730 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
726 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
731 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
727 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE; // service subtype
732 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE; // service subtype
728 header->destinationID = TM_DESTINATION_ID_GROUND;
733 header->destinationID = TM_DESTINATION_ID_GROUND;
729 header->time[0] = 0x00;
734 header->time[0] = 0x00;
730 header->time[0] = 0x00;
735 header->time[0] = 0x00;
731 header->time[0] = 0x00;
736 header->time[0] = 0x00;
732 header->time[0] = 0x00;
737 header->time[0] = 0x00;
733 header->time[0] = 0x00;
738 header->time[0] = 0x00;
734 header->time[0] = 0x00;
739 header->time[0] = 0x00;
735 // AUXILIARY DATA HEADER
740 // AUXILIARY DATA HEADER
736 header->sid = 0x00;
741 header->sid = 0x00;
737 header->hkBIA = DEFAULT_HKBIA;
742 header->hkBIA = DEFAULT_HKBIA;
738 header->pktCnt = DEFAULT_PKTCNT; // PKT_CNT
743 header->pktCnt = DEFAULT_PKTCNT; // PKT_CNT
739 header->pktNr = 0x00;
744 header->pktNr = 0x00;
740 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
745 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
741 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
746 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
742 }
747 }
743
748
744 void init_header_asm( Header_TM_LFR_SCIENCE_ASM_t *header )
749 void init_header_asm( Header_TM_LFR_SCIENCE_ASM_t *header )
745 {
750 {
746 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
751 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
747 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
752 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
748 header->reserved = DEFAULT_RESERVED;
753 header->reserved = DEFAULT_RESERVED;
749 header->userApplication = CCSDS_USER_APP;
754 header->userApplication = CCSDS_USER_APP;
750 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
755 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
751 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
756 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
752 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
757 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
753 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
758 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
754 header->packetLength[0] = 0x00;
759 header->packetLength[0] = 0x00;
755 header->packetLength[1] = 0x00;
760 header->packetLength[1] = 0x00;
756 // DATA FIELD HEADER
761 // DATA FIELD HEADER
757 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
762 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
758 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
763 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
759 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE; // service subtype
764 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE; // service subtype
760 header->destinationID = TM_DESTINATION_ID_GROUND;
765 header->destinationID = TM_DESTINATION_ID_GROUND;
761 header->time[0] = 0x00;
766 header->time[0] = 0x00;
762 header->time[0] = 0x00;
767 header->time[0] = 0x00;
763 header->time[0] = 0x00;
768 header->time[0] = 0x00;
764 header->time[0] = 0x00;
769 header->time[0] = 0x00;
765 header->time[0] = 0x00;
770 header->time[0] = 0x00;
766 header->time[0] = 0x00;
771 header->time[0] = 0x00;
767 // AUXILIARY DATA HEADER
772 // AUXILIARY DATA HEADER
768 header->sid = 0x00;
773 header->sid = 0x00;
769 header->biaStatusInfo = 0x00;
774 header->biaStatusInfo = 0x00;
770 header->pa_lfr_pkt_cnt_asm = 0x00;
775 header->pa_lfr_pkt_cnt_asm = 0x00;
771 header->pa_lfr_pkt_nr_asm = 0x00;
776 header->pa_lfr_pkt_nr_asm = 0x00;
772 header->pa_lfr_asm_blk_nr[0] = 0x00;
777 header->pa_lfr_asm_blk_nr[0] = 0x00;
773 header->pa_lfr_asm_blk_nr[1] = 0x00;
778 header->pa_lfr_asm_blk_nr[1] = 0x00;
774 }
779 }
775
780
776 int spw_send_waveform_CWF( ring_node *ring_node_to_send,
781 int spw_send_waveform_CWF( ring_node *ring_node_to_send,
777 Header_TM_LFR_SCIENCE_CWF_t *header )
782 Header_TM_LFR_SCIENCE_CWF_t *header )
778 {
783 {
779 /** This function sends CWF CCSDS packets (F2, F1 or F0).
784 /** This function sends CWF CCSDS packets (F2, F1 or F0).
780 *
785 *
781 * @param waveform points to the buffer containing the data that will be send.
786 * @param waveform points to the buffer containing the data that will be send.
782 * @param sid is the source identifier of the data that will be sent.
787 * @param sid is the source identifier of the data that will be sent.
783 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
788 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
784 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
789 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
785 * contain information to setup the transmission of the data packets.
790 * contain information to setup the transmission of the data packets.
786 *
791 *
787 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
792 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
788 *
793 *
789 */
794 */
790
795
791 unsigned int i;
796 unsigned int i;
792 int ret;
797 int ret;
793 unsigned int coarseTime;
798 unsigned int coarseTime;
794 unsigned int fineTime;
799 unsigned int fineTime;
795 rtems_status_code status;
800 rtems_status_code status;
796 spw_ioctl_pkt_send spw_ioctl_send_CWF;
801 spw_ioctl_pkt_send spw_ioctl_send_CWF;
797 int *dataPtr;
802 int *dataPtr;
798 unsigned char sid;
803 unsigned char sid;
799
804
800 spw_ioctl_send_CWF.hlen = TM_HEADER_LEN + 4 + 10; // + 4 is for the protocole extra header, + 10 is for the auxiliary header
805 spw_ioctl_send_CWF.hlen = TM_HEADER_LEN + 4 + 10; // + 4 is for the protocole extra header, + 10 is for the auxiliary header
801 spw_ioctl_send_CWF.options = 0;
806 spw_ioctl_send_CWF.options = 0;
802
807
803 ret = LFR_DEFAULT;
808 ret = LFR_DEFAULT;
804 sid = (unsigned char) ring_node_to_send->sid;
809 sid = (unsigned char) ring_node_to_send->sid;
805
810
806 coarseTime = ring_node_to_send->coarseTime;
811 coarseTime = ring_node_to_send->coarseTime;
807 fineTime = ring_node_to_send->fineTime;
812 fineTime = ring_node_to_send->fineTime;
808 dataPtr = (int*) ring_node_to_send->buffer_address;
813 dataPtr = (int*) ring_node_to_send->buffer_address;
809
814
810 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
815 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
811 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
816 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
812 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
817 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
813 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
818 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
814
819
815 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF; i++) // send waveform
820 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF; i++) // send waveform
816 {
821 {
817 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF * NB_WORDS_SWF_BLK) ];
822 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF * NB_WORDS_SWF_BLK) ];
818 spw_ioctl_send_CWF.hdr = (char*) header;
823 spw_ioctl_send_CWF.hdr = (char*) header;
819 // BUILD THE DATA
824 // BUILD THE DATA
820 spw_ioctl_send_CWF.dlen = BLK_NR_CWF * NB_BYTES_SWF_BLK;
825 spw_ioctl_send_CWF.dlen = BLK_NR_CWF * NB_BYTES_SWF_BLK;
821
826
822 // SET PACKET SEQUENCE CONTROL
827 // SET PACKET SEQUENCE CONTROL
823 increment_seq_counter_source_id( header->packetSequenceControl, sid );
828 increment_seq_counter_source_id( header->packetSequenceControl, sid );
824
829
825 // SET SID
830 // SET SID
826 header->sid = sid;
831 header->sid = sid;
827
832
828 // SET PACKET TIME
833 // SET PACKET TIME
829 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime);
834 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime);
830 //
835 //
831 header->time[0] = header->acquisitionTime[0];
836 header->time[0] = header->acquisitionTime[0];
832 header->time[1] = header->acquisitionTime[1];
837 header->time[1] = header->acquisitionTime[1];
833 header->time[2] = header->acquisitionTime[2];
838 header->time[2] = header->acquisitionTime[2];
834 header->time[3] = header->acquisitionTime[3];
839 header->time[3] = header->acquisitionTime[3];
835 header->time[4] = header->acquisitionTime[4];
840 header->time[4] = header->acquisitionTime[4];
836 header->time[5] = header->acquisitionTime[5];
841 header->time[5] = header->acquisitionTime[5];
837
842
838 // SET PACKET ID
843 // SET PACKET ID
839 if ( (sid == SID_SBM1_CWF_F1) || (sid == SID_SBM2_CWF_F2) )
844 if ( (sid == SID_SBM1_CWF_F1) || (sid == SID_SBM2_CWF_F2) )
840 {
845 {
841 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2 >> 8);
846 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2 >> 8);
842 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2);
847 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2);
843 }
848 }
844 else
849 else
845 {
850 {
846 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
851 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
847 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
852 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
848 }
853 }
849
854
850 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
855 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
851 if (status != RTEMS_SUCCESSFUL) {
856 if (status != RTEMS_SUCCESSFUL) {
852 printf("%d-%d, ERR %d\n", sid, i, (int) status);
857 printf("%d-%d, ERR %d\n", sid, i, (int) status);
853 ret = LFR_DEFAULT;
858 ret = LFR_DEFAULT;
854 }
859 }
855 }
860 }
856
861
857 return ret;
862 return ret;
858 }
863 }
859
864
860 int spw_send_waveform_SWF( ring_node *ring_node_to_send,
865 int spw_send_waveform_SWF( ring_node *ring_node_to_send,
861 Header_TM_LFR_SCIENCE_SWF_t *header )
866 Header_TM_LFR_SCIENCE_SWF_t *header )
862 {
867 {
863 /** This function sends SWF CCSDS packets (F2, F1 or F0).
868 /** This function sends SWF CCSDS packets (F2, F1 or F0).
864 *
869 *
865 * @param waveform points to the buffer containing the data that will be send.
870 * @param waveform points to the buffer containing the data that will be send.
866 * @param sid is the source identifier of the data that will be sent.
871 * @param sid is the source identifier of the data that will be sent.
867 * @param headerSWF points to a table of headers that have been prepared for the data transmission.
872 * @param headerSWF points to a table of headers that have been prepared for the data transmission.
868 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
873 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
869 * contain information to setup the transmission of the data packets.
874 * contain information to setup the transmission of the data packets.
870 *
875 *
871 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
876 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
872 *
877 *
873 */
878 */
874
879
875 unsigned int i;
880 unsigned int i;
876 int ret;
881 int ret;
877 unsigned int coarseTime;
882 unsigned int coarseTime;
878 unsigned int fineTime;
883 unsigned int fineTime;
879 rtems_status_code status;
884 rtems_status_code status;
880 spw_ioctl_pkt_send spw_ioctl_send_SWF;
885 spw_ioctl_pkt_send spw_ioctl_send_SWF;
881 int *dataPtr;
886 int *dataPtr;
882 unsigned char sid;
887 unsigned char sid;
883
888
884 spw_ioctl_send_SWF.hlen = TM_HEADER_LEN + 4 + 12; // + 4 is for the protocole extra header, + 12 is for the auxiliary header
889 spw_ioctl_send_SWF.hlen = TM_HEADER_LEN + 4 + 12; // + 4 is for the protocole extra header, + 12 is for the auxiliary header
885 spw_ioctl_send_SWF.options = 0;
890 spw_ioctl_send_SWF.options = 0;
886
891
887 ret = LFR_DEFAULT;
892 ret = LFR_DEFAULT;
888
893
889 coarseTime = ring_node_to_send->coarseTime;
894 coarseTime = ring_node_to_send->coarseTime;
890 fineTime = ring_node_to_send->fineTime;
895 fineTime = ring_node_to_send->fineTime;
891 dataPtr = (int*) ring_node_to_send->buffer_address;
896 dataPtr = (int*) ring_node_to_send->buffer_address;
892 sid = ring_node_to_send->sid;
897 sid = ring_node_to_send->sid;
893
898
894 for (i=0; i<7; i++) // send waveform
899 for (i=0; i<7; i++) // send waveform
895 {
900 {
896 spw_ioctl_send_SWF.data = (char*) &dataPtr[ (i * BLK_NR_304 * NB_WORDS_SWF_BLK) ];
901 spw_ioctl_send_SWF.data = (char*) &dataPtr[ (i * BLK_NR_304 * NB_WORDS_SWF_BLK) ];
897 spw_ioctl_send_SWF.hdr = (char*) header;
902 spw_ioctl_send_SWF.hdr = (char*) header;
898
903
899 // SET PACKET SEQUENCE CONTROL
904 // SET PACKET SEQUENCE CONTROL
900 increment_seq_counter_source_id( header->packetSequenceControl, sid );
905 increment_seq_counter_source_id( header->packetSequenceControl, sid );
901
906
902 // SET PACKET LENGTH AND BLKNR
907 // SET PACKET LENGTH AND BLKNR
903 if (i == 6)
908 if (i == 6)
904 {
909 {
905 spw_ioctl_send_SWF.dlen = BLK_NR_224 * NB_BYTES_SWF_BLK;
910 spw_ioctl_send_SWF.dlen = BLK_NR_224 * NB_BYTES_SWF_BLK;
906 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_224 >> 8);
911 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_224 >> 8);
907 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_224 );
912 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_224 );
908 header->blkNr[0] = (unsigned char) (BLK_NR_224 >> 8);
913 header->blkNr[0] = (unsigned char) (BLK_NR_224 >> 8);
909 header->blkNr[1] = (unsigned char) (BLK_NR_224 );
914 header->blkNr[1] = (unsigned char) (BLK_NR_224 );
910 }
915 }
911 else
916 else
912 {
917 {
913 spw_ioctl_send_SWF.dlen = BLK_NR_304 * NB_BYTES_SWF_BLK;
918 spw_ioctl_send_SWF.dlen = BLK_NR_304 * NB_BYTES_SWF_BLK;
914 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_304 >> 8);
919 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_304 >> 8);
915 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_304 );
920 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_304 );
916 header->blkNr[0] = (unsigned char) (BLK_NR_304 >> 8);
921 header->blkNr[0] = (unsigned char) (BLK_NR_304 >> 8);
917 header->blkNr[1] = (unsigned char) (BLK_NR_304 );
922 header->blkNr[1] = (unsigned char) (BLK_NR_304 );
918 }
923 }
919
924
920 // SET PACKET TIME
925 // SET PACKET TIME
921 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime );
926 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime );
922 //
927 //
923 header->time[0] = header->acquisitionTime[0];
928 header->time[0] = header->acquisitionTime[0];
924 header->time[1] = header->acquisitionTime[1];
929 header->time[1] = header->acquisitionTime[1];
925 header->time[2] = header->acquisitionTime[2];
930 header->time[2] = header->acquisitionTime[2];
926 header->time[3] = header->acquisitionTime[3];
931 header->time[3] = header->acquisitionTime[3];
927 header->time[4] = header->acquisitionTime[4];
932 header->time[4] = header->acquisitionTime[4];
928 header->time[5] = header->acquisitionTime[5];
933 header->time[5] = header->acquisitionTime[5];
929
934
930 // SET SID
935 // SET SID
931 header->sid = sid;
936 header->sid = sid;
932
937
933 // SET PKTNR
938 // SET PKTNR
934 header->pktNr = i+1; // PKT_NR
939 header->pktNr = i+1; // PKT_NR
935
940
936 // SEND PACKET
941 // SEND PACKET
937 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_SWF );
942 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_SWF );
938 if (status != RTEMS_SUCCESSFUL) {
943 if (status != RTEMS_SUCCESSFUL) {
939 printf("%d-%d, ERR %d\n", sid, i, (int) status);
944 printf("%d-%d, ERR %d\n", sid, i, (int) status);
940 ret = LFR_DEFAULT;
945 ret = LFR_DEFAULT;
941 }
946 }
942 }
947 }
943
948
944 return ret;
949 return ret;
945 }
950 }
946
951
947 int spw_send_waveform_CWF3_light( ring_node *ring_node_to_send,
952 int spw_send_waveform_CWF3_light( ring_node *ring_node_to_send,
948 Header_TM_LFR_SCIENCE_CWF_t *header )
953 Header_TM_LFR_SCIENCE_CWF_t *header )
949 {
954 {
950 /** This function sends CWF_F3 CCSDS packets without the b1, b2 and b3 data.
955 /** This function sends CWF_F3 CCSDS packets without the b1, b2 and b3 data.
951 *
956 *
952 * @param waveform points to the buffer containing the data that will be send.
957 * @param waveform points to the buffer containing the data that will be send.
953 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
958 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
954 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
959 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
955 * contain information to setup the transmission of the data packets.
960 * contain information to setup the transmission of the data packets.
956 *
961 *
957 * By default, CWF_F3 packet are send without the b1, b2 and b3 data. This function rebuilds a data buffer
962 * By default, CWF_F3 packet are send without the b1, b2 and b3 data. This function rebuilds a data buffer
958 * from the incoming data and sends it in 7 packets, 6 containing 340 blocks and 1 one containing 8 blocks.
963 * from the incoming data and sends it in 7 packets, 6 containing 340 blocks and 1 one containing 8 blocks.
959 *
964 *
960 */
965 */
961
966
962 unsigned int i;
967 unsigned int i;
963 int ret;
968 int ret;
964 unsigned int coarseTime;
969 unsigned int coarseTime;
965 unsigned int fineTime;
970 unsigned int fineTime;
966 rtems_status_code status;
971 rtems_status_code status;
967 spw_ioctl_pkt_send spw_ioctl_send_CWF;
972 spw_ioctl_pkt_send spw_ioctl_send_CWF;
968 char *dataPtr;
973 char *dataPtr;
969 unsigned char sid;
974 unsigned char sid;
970
975
971 spw_ioctl_send_CWF.hlen = TM_HEADER_LEN + 4 + 10; // + 4 is for the protocole extra header, + 10 is for the auxiliary header
976 spw_ioctl_send_CWF.hlen = TM_HEADER_LEN + 4 + 10; // + 4 is for the protocole extra header, + 10 is for the auxiliary header
972 spw_ioctl_send_CWF.options = 0;
977 spw_ioctl_send_CWF.options = 0;
973
978
974 ret = LFR_DEFAULT;
979 ret = LFR_DEFAULT;
975 sid = ring_node_to_send->sid;
980 sid = ring_node_to_send->sid;
976
981
977 coarseTime = ring_node_to_send->coarseTime;
982 coarseTime = ring_node_to_send->coarseTime;
978 fineTime = ring_node_to_send->fineTime;
983 fineTime = ring_node_to_send->fineTime;
979 dataPtr = (char*) ring_node_to_send->buffer_address;
984 dataPtr = (char*) ring_node_to_send->buffer_address;
980
985
981 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_672 >> 8);
986 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_672 >> 8);
982 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_672 );
987 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_672 );
983 header->blkNr[0] = (unsigned char) (BLK_NR_CWF_SHORT_F3 >> 8);
988 header->blkNr[0] = (unsigned char) (BLK_NR_CWF_SHORT_F3 >> 8);
984 header->blkNr[1] = (unsigned char) (BLK_NR_CWF_SHORT_F3 );
989 header->blkNr[1] = (unsigned char) (BLK_NR_CWF_SHORT_F3 );
985
990
986 printf("spw_send_waveform_CWF3_light => [0] = %x, [1] = %x, [2] = %x, [3] = %x, [4] = %x, [5] = %x\n",
991 printf("spw_send_waveform_CWF3_light => [0] = %x, [1] = %x, [2] = %x, [3] = %x, [4] = %x, [5] = %x\n",
987 dataPtr[0], dataPtr[1], dataPtr[2], dataPtr[3], dataPtr[4], dataPtr[5]);
992 dataPtr[0], dataPtr[1], dataPtr[2], dataPtr[3], dataPtr[4], dataPtr[5]);
988
993
989 //*********************
994 //*********************
990 // SEND CWF3_light DATA
995 // SEND CWF3_light DATA
991 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF_LIGHT; i++) // send waveform
996 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF_LIGHT; i++) // send waveform
992 {
997 {
993 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK) ];
998 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK) ];
994 spw_ioctl_send_CWF.hdr = (char*) header;
999 spw_ioctl_send_CWF.hdr = (char*) header;
995 // BUILD THE DATA
1000 // BUILD THE DATA
996 spw_ioctl_send_CWF.dlen = BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK;
1001 spw_ioctl_send_CWF.dlen = BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK;
997
1002
998 // SET PACKET SEQUENCE COUNTER
1003 // SET PACKET SEQUENCE COUNTER
999 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1004 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1000
1005
1001 // SET SID
1006 // SET SID
1002 header->sid = sid;
1007 header->sid = sid;
1003
1008
1004 // SET PACKET TIME
1009 // SET PACKET TIME
1005 compute_acquisition_time( coarseTime, fineTime, SID_NORM_CWF_F3, i, header->acquisitionTime );
1010 compute_acquisition_time( coarseTime, fineTime, SID_NORM_CWF_F3, i, header->acquisitionTime );
1006 //
1011 //
1007 header->time[0] = header->acquisitionTime[0];
1012 header->time[0] = header->acquisitionTime[0];
1008 header->time[1] = header->acquisitionTime[1];
1013 header->time[1] = header->acquisitionTime[1];
1009 header->time[2] = header->acquisitionTime[2];
1014 header->time[2] = header->acquisitionTime[2];
1010 header->time[3] = header->acquisitionTime[3];
1015 header->time[3] = header->acquisitionTime[3];
1011 header->time[4] = header->acquisitionTime[4];
1016 header->time[4] = header->acquisitionTime[4];
1012 header->time[5] = header->acquisitionTime[5];
1017 header->time[5] = header->acquisitionTime[5];
1013
1018
1014 // SET PACKET ID
1019 // SET PACKET ID
1015 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1020 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1016 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1021 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1017
1022
1018 // SEND PACKET
1023 // SEND PACKET
1019 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
1024 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
1020 if (status != RTEMS_SUCCESSFUL) {
1025 if (status != RTEMS_SUCCESSFUL) {
1021 printf("%d-%d, ERR %d\n", sid, i, (int) status);
1026 printf("%d-%d, ERR %d\n", sid, i, (int) status);
1022 ret = LFR_DEFAULT;
1027 ret = LFR_DEFAULT;
1023 }
1028 }
1024 }
1029 }
1025
1030
1026 return ret;
1031 return ret;
1027 }
1032 }
1028
1033
1029 void spw_send_asm( ring_node *ring_node_to_send,
1034 void spw_send_asm( ring_node *ring_node_to_send,
1030 Header_TM_LFR_SCIENCE_ASM_t *header )
1035 Header_TM_LFR_SCIENCE_ASM_t *header )
1031 {
1036 {
1032 unsigned int i;
1037 unsigned int i;
1033 unsigned int length = 0;
1038 unsigned int length = 0;
1034 rtems_status_code status;
1039 rtems_status_code status;
1035 unsigned int sid;
1040 unsigned int sid;
1036 char *spectral_matrix;
1041 char *spectral_matrix;
1037 int coarseTime;
1042 int coarseTime;
1038 int fineTime;
1043 int fineTime;
1039 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1044 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1040
1045
1041 sid = ring_node_to_send->sid;
1046 sid = ring_node_to_send->sid;
1042 spectral_matrix = (char*) ring_node_to_send->buffer_address;
1047 spectral_matrix = (char*) ring_node_to_send->buffer_address;
1043 coarseTime = ring_node_to_send->coarseTime;
1048 coarseTime = ring_node_to_send->coarseTime;
1044 fineTime = ring_node_to_send->fineTime;
1049 fineTime = ring_node_to_send->fineTime;
1045
1050
1046 for (i=0; i<2; i++)
1051 for (i=0; i<2; i++)
1047 {
1052 {
1048 // (1) BUILD THE DATA
1053 // (1) BUILD THE DATA
1049 switch(sid)
1054 switch(sid)
1050 {
1055 {
1051 case SID_NORM_ASM_F0:
1056 case SID_NORM_ASM_F0:
1052 spw_ioctl_send_ASM.dlen = TOTAL_SIZE_ASM_F0_IN_BYTES / 2; // 2 packets will be sent
1057 spw_ioctl_send_ASM.dlen = TOTAL_SIZE_ASM_F0_IN_BYTES / 2; // 2 packets will be sent
1053 spw_ioctl_send_ASM.data = &spectral_matrix[
1058 spw_ioctl_send_ASM.data = &spectral_matrix[
1054 ( (ASM_F0_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F0) ) * NB_VALUES_PER_SM ) * 2
1059 ( (ASM_F0_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F0) ) * NB_VALUES_PER_SM ) * 2
1055 ];
1060 ];
1056 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0;
1061 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0;
1057 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0) >> 8 ); // BLK_NR MSB
1062 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0) >> 8 ); // BLK_NR MSB
1058 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0); // BLK_NR LSB
1063 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0); // BLK_NR LSB
1059 break;
1064 break;
1060 case SID_NORM_ASM_F1:
1065 case SID_NORM_ASM_F1:
1061 spw_ioctl_send_ASM.dlen = TOTAL_SIZE_ASM_F1_IN_BYTES / 2; // 2 packets will be sent
1066 spw_ioctl_send_ASM.dlen = TOTAL_SIZE_ASM_F1_IN_BYTES / 2; // 2 packets will be sent
1062 spw_ioctl_send_ASM.data = &spectral_matrix[
1067 spw_ioctl_send_ASM.data = &spectral_matrix[
1063 ( (ASM_F1_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F1) ) * NB_VALUES_PER_SM ) * 2
1068 ( (ASM_F1_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F1) ) * NB_VALUES_PER_SM ) * 2
1064 ];
1069 ];
1065 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F1;
1070 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F1;
1066 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F1) >> 8 ); // BLK_NR MSB
1071 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F1) >> 8 ); // BLK_NR MSB
1067 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F1); // BLK_NR LSB
1072 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F1); // BLK_NR LSB
1068 break;
1073 break;
1069 case SID_NORM_ASM_F2:
1074 case SID_NORM_ASM_F2:
1070 spw_ioctl_send_ASM.dlen = TOTAL_SIZE_ASM_F2_IN_BYTES / 2; // 2 packets will be sent
1075 spw_ioctl_send_ASM.dlen = TOTAL_SIZE_ASM_F2_IN_BYTES / 2; // 2 packets will be sent
1071 spw_ioctl_send_ASM.data = &spectral_matrix[
1076 spw_ioctl_send_ASM.data = &spectral_matrix[
1072 ( (ASM_F2_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F2) ) * NB_VALUES_PER_SM ) * 2
1077 ( (ASM_F2_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F2) ) * NB_VALUES_PER_SM ) * 2
1073 ];
1078 ];
1074 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F2;
1079 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F2;
1075 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F2) >> 8 ); // BLK_NR MSB
1080 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F2) >> 8 ); // BLK_NR MSB
1076 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F2); // BLK_NR LSB
1081 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F2); // BLK_NR LSB
1077 break;
1082 break;
1078 default:
1083 default:
1079 PRINTF1("ERR *** in spw_send_asm *** unexpected sid %d\n", sid)
1084 PRINTF1("ERR *** in spw_send_asm *** unexpected sid %d\n", sid)
1080 break;
1085 break;
1081 }
1086 }
1082 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM + CCSDS_PROTOCOLE_EXTRA_BYTES;
1087 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM + CCSDS_PROTOCOLE_EXTRA_BYTES;
1083 spw_ioctl_send_ASM.hdr = (char *) header;
1088 spw_ioctl_send_ASM.hdr = (char *) header;
1084 spw_ioctl_send_ASM.options = 0;
1089 spw_ioctl_send_ASM.options = 0;
1085
1090
1086 // (2) BUILD THE HEADER
1091 // (2) BUILD THE HEADER
1087 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1092 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1088 header->packetLength[0] = (unsigned char) (length>>8);
1093 header->packetLength[0] = (unsigned char) (length>>8);
1089 header->packetLength[1] = (unsigned char) (length);
1094 header->packetLength[1] = (unsigned char) (length);
1090 header->sid = (unsigned char) sid; // SID
1095 header->sid = (unsigned char) sid; // SID
1091 header->pa_lfr_pkt_cnt_asm = 2;
1096 header->pa_lfr_pkt_cnt_asm = 2;
1092 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1097 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1093
1098
1094 // (3) SET PACKET TIME
1099 // (3) SET PACKET TIME
1095 header->time[0] = (unsigned char) (coarseTime>>24);
1100 header->time[0] = (unsigned char) (coarseTime>>24);
1096 header->time[1] = (unsigned char) (coarseTime>>16);
1101 header->time[1] = (unsigned char) (coarseTime>>16);
1097 header->time[2] = (unsigned char) (coarseTime>>8);
1102 header->time[2] = (unsigned char) (coarseTime>>8);
1098 header->time[3] = (unsigned char) (coarseTime);
1103 header->time[3] = (unsigned char) (coarseTime);
1099 header->time[4] = (unsigned char) (fineTime>>8);
1104 header->time[4] = (unsigned char) (fineTime>>8);
1100 header->time[5] = (unsigned char) (fineTime);
1105 header->time[5] = (unsigned char) (fineTime);
1101 //
1106 //
1102 header->acquisitionTime[0] = header->time[0];
1107 header->acquisitionTime[0] = header->time[0];
1103 header->acquisitionTime[1] = header->time[1];
1108 header->acquisitionTime[1] = header->time[1];
1104 header->acquisitionTime[2] = header->time[2];
1109 header->acquisitionTime[2] = header->time[2];
1105 header->acquisitionTime[3] = header->time[3];
1110 header->acquisitionTime[3] = header->time[3];
1106 header->acquisitionTime[4] = header->time[4];
1111 header->acquisitionTime[4] = header->time[4];
1107 header->acquisitionTime[5] = header->time[5];
1112 header->acquisitionTime[5] = header->time[5];
1108
1113
1109 // (4) SEND PACKET
1114 // (4) SEND PACKET
1110 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1115 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1111 if (status != RTEMS_SUCCESSFUL) {
1116 if (status != RTEMS_SUCCESSFUL) {
1112 printf("in ASM_send *** ERR %d\n", (int) status);
1117 printf("in ASM_send *** ERR %d\n", (int) status);
1113 }
1118 }
1114 }
1119 }
1115 }
1120 }
General Comments 0
You need to be logged in to leave comments. Login now