##// END OF EJS Templates
a wrong date implies the generation of a TM_LFR_TC_EXE_NOT_EXECUTABLE...
paul -
r254:aca3cbff85cc R3a
parent child
Show More
@@ -1,2 +1,2
1 1 3081d1f9bb20b2b64a192585337a292a9804e0c5 LFR_basic-parameters
2 084fd0db5e4139a1096789935e32ef498192f395 header/lfr_common_headers
2 80d727bb9d808ae67c801c4c6101811d68b94af6 header/lfr_common_headers
@@ -1,56 +1,56
1 1 #ifndef FSW_SPACEWIRE_H_INCLUDED
2 2 #define FSW_SPACEWIRE_H_INCLUDED
3 3
4 4 #include <rtems.h>
5 5 #include <grspw.h>
6 6
7 7 #include <fcntl.h> // for O_RDWR
8 8 #include <unistd.h> // for the read call
9 9 #include <sys/ioctl.h> // for the ioctl call
10 10 #include <errno.h>
11 11
12 12 #include "fsw_params.h"
13 13 #include "tc_handler.h"
14 14 #include "fsw_init.h"
15 15
16 16 extern spw_stats spacewire_stats;
17 17 extern spw_stats spacewire_stats_backup;
18 18 extern rtems_name timecode_timer_name;
19 19 extern rtems_id timecode_timer_id;
20 20
21 21 // RTEMS TASK
22 22 rtems_task spiq_task( rtems_task_argument argument );
23 23 rtems_task recv_task( rtems_task_argument unused );
24 24 rtems_task send_task( rtems_task_argument argument );
25 rtems_task wtdg_task( rtems_task_argument argument );
25 rtems_task link_task( rtems_task_argument argument );
26 26
27 27 int spacewire_open_link( void );
28 28 int spacewire_start_link( int fd );
29 29 int spacewire_stop_and_start_link( int fd );
30 30 int spacewire_configure_link(int fd );
31 31 int spacewire_several_connect_attemps( void );
32 32 void spacewire_set_NP( unsigned char val, unsigned int regAddr ); // No Port force
33 33 void spacewire_set_RE( unsigned char val, unsigned int regAddr ); // RMAP Enable
34 34 void spacewire_compute_stats_offsets( void );
35 35 void spacewire_update_statistics( void );
36 36 void increase_unsigned_char_counter( unsigned char *counter );
37 37
38 38 void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header );
39 39 void init_header_swf( Header_TM_LFR_SCIENCE_SWF_t *header );
40 40 void init_header_asm( Header_TM_LFR_SCIENCE_ASM_t *header );
41 41 int spw_send_waveform_CWF( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_CWF_t *header );
42 42 int spw_send_waveform_SWF( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_SWF_t *header );
43 43 int spw_send_waveform_CWF3_light( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_CWF_t *header );
44 44 void spw_send_asm_f0( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
45 45 void spw_send_asm_f1( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
46 46 void spw_send_asm_f2( ring_node *ring_node_to_send, Header_TM_LFR_SCIENCE_ASM_t *header );
47 47 void spw_send_k_dump( ring_node *ring_node_to_send );
48 48
49 49 rtems_timer_service_routine timecode_timer_routine( rtems_id timer_id, void *user_data );
50 50 unsigned int check_timecode_and_previous_timecode_coherency(unsigned char currentTimecodeCtr);
51 51 unsigned int check_timecode_and_internal_time_coherency(unsigned char timecode, unsigned char internalTime);
52 52 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc );
53 53
54 54 void (*grspw_timecode_callback) ( void *pDev, void *regs, int minor, unsigned int tc );
55 55
56 56 #endif // FSW_SPACEWIRE_H_INCLUDED
@@ -1,80 +1,80
1 1 #ifndef TC_HANDLER_H_INCLUDED
2 2 #define TC_HANDLER_H_INCLUDED
3 3
4 4 #include <rtems.h>
5 5 #include <leon.h>
6 6
7 7 #include "tc_load_dump_parameters.h"
8 8 #include "tc_acceptance.h"
9 9 #include "tm_lfr_tc_exe.h"
10 10 #include "wf_handler.h"
11 11 #include "fsw_processing.h"
12 12
13 13 #include "lfr_cpu_usage_report.h"
14 14
15 15 extern unsigned int lastValidEnterModeTime;
16 16
17 17 //****
18 18 // ISR
19 19 rtems_isr commutation_isr1( rtems_vector_number vector );
20 20 rtems_isr commutation_isr2( rtems_vector_number vector );
21 21
22 22 //***********
23 23 // RTEMS TASK
24 24 rtems_task actn_task( rtems_task_argument unused );
25 25
26 26 //***********
27 27 // TC ACTIONS
28 28 int action_reset( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time );
29 29 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id);
30 30 int action_update_info( ccsdsTelecommandPacket_t *TC, rtems_id queue_id );
31 31 int action_enable_calibration( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time );
32 32 int action_disable_calibration( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time );
33 33 int action_update_time( ccsdsTelecommandPacket_t *TC);
34 34
35 35 // mode transition
36 36 int check_mode_value( unsigned char requestedMode );
37 37 int check_mode_transition( unsigned char requestedMode );
38 38 void update_last_valid_transition_date( unsigned int transitionCoarseTime );
39 39 int check_transition_date( unsigned int transitionCoarseTime );
40 40 int stop_spectral_matrices( void );
41 41 int stop_current_mode( void );
42 int enter_mode_standby( void );
42 int enter_mode_standby(void );
43 43 int enter_mode_normal( unsigned int transitionCoarseTime );
44 44 int enter_mode_burst( unsigned int transitionCoarseTime );
45 45 int enter_mode_sbm1( unsigned int transitionCoarseTime );
46 46 int enter_mode_sbm2( unsigned int transitionCoarseTime );
47 47 int restart_science_tasks( unsigned char lfrRequestedMode );
48 48 int restart_asm_tasks(unsigned char lfrRequestedMode );
49 49 int suspend_science_tasks(void);
50 50 int suspend_asm_tasks( void );
51 51 void launch_waveform_picker( unsigned char mode , unsigned int transitionCoarseTime );
52 52 void launch_spectral_matrix( void );
53 53 void set_sm_irq_onNewMatrix( unsigned char value );
54 54 void set_sm_irq_onError( unsigned char value );
55 55
56 56 // other functions
57 void updateLFRCurrentMode();
57 void updateLFRCurrentMode(unsigned char requestedMode);
58 58 void set_lfr_soft_reset( unsigned char value );
59 59 void reset_lfr( void );
60 60 // CALIBRATION
61 61 void setCalibrationPrescaler( unsigned int prescaler );
62 62 void setCalibrationDivisor( unsigned int divisionFactor );
63 63 void setCalibrationData( void );
64 64 void setCalibrationReload( bool state);
65 65 void setCalibrationEnable( bool state );
66 66 void setCalibrationInterleaved( bool state );
67 67 void setCalibration( bool state );
68 68 void configureCalibration( bool interleaved );
69 69 //
70 70 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC , unsigned char *time );
71 71 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC , unsigned char *time );
72 72 void close_action( ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id );
73 73
74 74 extern rtems_status_code get_message_queue_id_send( rtems_id *queue_id );
75 75 extern rtems_status_code get_message_queue_id_recv( rtems_id *queue_id );
76 76
77 77 #endif // TC_HANDLER_H_INCLUDED
78 78
79 79
80 80
@@ -1,909 +1,909
1 1 /** This is the RTEMS initialization module.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * This module contains two very different information:
7 7 * - specific instructions to configure the compilation of the RTEMS executive
8 8 * - functions related to the fligth softwre initialization, especially the INIT RTEMS task
9 9 *
10 10 */
11 11
12 12 //*************************
13 13 // GPL reminder to be added
14 14 //*************************
15 15
16 16 #include <rtems.h>
17 17
18 18 /* configuration information */
19 19
20 20 #define CONFIGURE_INIT
21 21
22 22 #include <bsp.h> /* for device driver prototypes */
23 23
24 24 /* configuration information */
25 25
26 26 #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
27 27 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
28 28
29 29 #define CONFIGURE_MAXIMUM_TASKS 20
30 30 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
31 31 #define CONFIGURE_EXTRA_TASK_STACKS (3 * RTEMS_MINIMUM_STACK_SIZE)
32 32 #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
33 33 #define CONFIGURE_INIT_TASK_PRIORITY 1 // instead of 100
34 34 #define CONFIGURE_INIT_TASK_MODE (RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT)
35 35 #define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT)
36 36 #define CONFIGURE_MAXIMUM_DRIVERS 16
37 37 #define CONFIGURE_MAXIMUM_PERIODS 5
38 #define CONFIGURE_MAXIMUM_TIMERS 5 // [spiq] [wtdg] [spacewire_reset_link]
38 #define CONFIGURE_MAXIMUM_TIMERS 5 // [spiq] [link] [spacewire_reset_link]
39 39 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 5
40 40 #ifdef PRINT_STACK_REPORT
41 41 #define CONFIGURE_STACK_CHECKER_ENABLED
42 42 #endif
43 43
44 44 #include <rtems/confdefs.h>
45 45
46 46 /* If --drvmgr was enabled during the configuration of the RTEMS kernel */
47 47 #ifdef RTEMS_DRVMGR_STARTUP
48 48 #ifdef LEON3
49 49 /* Add Timer and UART Driver */
50 50 #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
51 51 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GPTIMER
52 52 #endif
53 53 #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
54 54 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_APBUART
55 55 #endif
56 56 #endif
57 57 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GRSPW /* GRSPW Driver */
58 58 #include <drvmgr/drvmgr_confdefs.h>
59 59 #endif
60 60
61 61 #include "fsw_init.h"
62 62 #include "fsw_config.c"
63 63 #include "GscMemoryLPP.hpp"
64 64
65 65 void initCache()
66 66 {
67 67 // ASI 2 contains a few control registers that have not been assigned as ancillary state registers.
68 68 // These should only be read and written using 32-bit LDA/STA instructions.
69 69 // All cache registers are accessed through load/store operations to the alternate address space (LDA/STA), using ASI = 2.
70 70 // The table below shows the register addresses:
71 71 // 0x00 Cache control register
72 72 // 0x04 Reserved
73 73 // 0x08 Instruction cache configuration register
74 74 // 0x0C Data cache configuration register
75 75
76 76 // Cache Control Register Leon3 / Leon3FT
77 77 // 31..30 29 28 27..24 23 22 21 20..19 18 17 16
78 78 // RFT PS TB DS FD FI FT ST IB
79 79 // 15 14 13..12 11..10 9..8 7..6 5 4 3..2 1..0
80 80 // IP DP ITE IDE DTE DDE DF IF DCS ICS
81 81
82 82 unsigned int cacheControlRegister;
83 83
84 84 cacheControlRegister = CCR_getValue();
85 85 PRINTF1("(0) cacheControlRegister = %x\n", cacheControlRegister);
86 86
87 87 CCR_resetCacheControlRegister();
88 88
89 89 CCR_enableInstructionCache(); // ICS bits
90 90 CCR_enableDataCache(); // DCS bits
91 91 CCR_enableInstructionBurstFetch(); // IB bit
92 92
93 93 cacheControlRegister = CCR_getValue();
94 94 PRINTF1("(1) cacheControlRegister = %x\n", cacheControlRegister);
95 95
96 96 CCR_faultTolerantScheme();
97 97
98 98 PRINTF("\n");
99 99 }
100 100
101 101 rtems_task Init( rtems_task_argument ignored )
102 102 {
103 103 /** This is the RTEMS INIT taks, it is the first task launched by the system.
104 104 *
105 105 * @param unused is the starting argument of the RTEMS task
106 106 *
107 107 * The INIT task create and run all other RTEMS tasks.
108 108 *
109 109 */
110 110
111 111 //***********
112 112 // INIT CACHE
113 113
114 114 unsigned char *vhdlVersion;
115 115
116 116 reset_lfr();
117 117
118 118 reset_local_time();
119 119
120 120 rtems_cpu_usage_reset();
121 121
122 122 rtems_status_code status;
123 123 rtems_status_code status_spw;
124 124 rtems_isr_entry old_isr_handler;
125 125
126 126 // UART settings
127 127 enable_apbuart_transmitter();
128 128 set_apbuart_scaler_reload_register(REGS_ADDR_APBUART, APBUART_SCALER_RELOAD_VALUE);
129 129
130 130 DEBUG_PRINTF("\n\n\n\n\nIn INIT *** Now the console is on port COM1\n")
131 131
132 132
133 133 PRINTF("\n\n\n\n\n")
134 134
135 135 initCache();
136 136
137 137 PRINTF("*************************\n")
138 138 PRINTF("** LFR Flight Software **\n")
139 139 PRINTF1("** %d.", SW_VERSION_N1)
140 140 PRINTF1("%d." , SW_VERSION_N2)
141 141 PRINTF1("%d." , SW_VERSION_N3)
142 142 PRINTF1("%d **\n", SW_VERSION_N4)
143 143
144 144 vhdlVersion = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
145 145 PRINTF("** VHDL **\n")
146 146 PRINTF1("** %d.", vhdlVersion[1])
147 147 PRINTF1("%d." , vhdlVersion[2])
148 148 PRINTF1("%d **\n", vhdlVersion[3])
149 149 PRINTF("*************************\n")
150 150 PRINTF("\n\n")
151 151
152 152 init_parameter_dump();
153 153 init_kcoefficients_dump();
154 154 init_local_mode_parameters();
155 155 init_housekeeping_parameters();
156 156 init_k_coefficients_prc0();
157 157 init_k_coefficients_prc1();
158 158 init_k_coefficients_prc2();
159 159 pa_bia_status_info = 0x00;
160 160 update_last_valid_transition_date( DEFAULT_LAST_VALID_TRANSITION_DATE );
161 161
162 162 // waveform picker initialization
163 163 WFP_init_rings(); LEON_Clear_interrupt( IRQ_SPARC_GPTIMER_WATCHDOG ); // initialize the waveform rings
164 164 WFP_reset_current_ring_nodes();
165 165 reset_waveform_picker_regs();
166 166
167 167 // spectral matrices initialization
168 168 SM_init_rings(); // initialize spectral matrices rings
169 169 SM_reset_current_ring_nodes();
170 170 reset_spectral_matrix_regs();
171 171
172 172 // configure calibration
173 173 configureCalibration( false ); // true means interleaved mode, false is for normal mode
174 174
175 updateLFRCurrentMode();
175 updateLFRCurrentMode( LFR_MODE_STANDBY );
176 176
177 177 BOOT_PRINTF1("in INIT *** lfrCurrentMode is %d\n", lfrCurrentMode)
178 178
179 179 create_names(); // create all names
180 180
181 181 status = create_timecode_timer(); // create the timer used by timecode_irq_handler
182 182 if (status != RTEMS_SUCCESSFUL)
183 183 {
184 184 PRINTF1("in INIT *** ERR in create_timer_timecode, code %d", status)
185 185 }
186 186
187 187 status = create_message_queues(); // create message queues
188 188 if (status != RTEMS_SUCCESSFUL)
189 189 {
190 190 PRINTF1("in INIT *** ERR in create_message_queues, code %d", status)
191 191 }
192 192
193 193 status = create_all_tasks(); // create all tasks
194 194 if (status != RTEMS_SUCCESSFUL)
195 195 {
196 196 PRINTF1("in INIT *** ERR in create_all_tasks, code %d\n", status)
197 197 }
198 198
199 199 // **************************
200 200 // <SPACEWIRE INITIALIZATION>
201 201 grspw_timecode_callback = &timecode_irq_handler;
202 202
203 203 status_spw = spacewire_open_link(); // (1) open the link
204 204 if ( status_spw != RTEMS_SUCCESSFUL )
205 205 {
206 206 PRINTF1("in INIT *** ERR spacewire_open_link code %d\n", status_spw )
207 207 }
208 208
209 209 if ( status_spw == RTEMS_SUCCESSFUL ) // (2) configure the link
210 210 {
211 211 status_spw = spacewire_configure_link( fdSPW );
212 212 if ( status_spw != RTEMS_SUCCESSFUL )
213 213 {
214 214 PRINTF1("in INIT *** ERR spacewire_configure_link code %d\n", status_spw )
215 215 }
216 216 }
217 217
218 218 if ( status_spw == RTEMS_SUCCESSFUL) // (3) start the link
219 219 {
220 220 status_spw = spacewire_start_link( fdSPW );
221 221 if ( status_spw != RTEMS_SUCCESSFUL )
222 222 {
223 223 PRINTF1("in INIT *** ERR spacewire_start_link code %d\n", status_spw )
224 224 }
225 225 }
226 226 // </SPACEWIRE INITIALIZATION>
227 227 // ***************************
228 228
229 229 status = start_all_tasks(); // start all tasks
230 230 if (status != RTEMS_SUCCESSFUL)
231 231 {
232 232 PRINTF1("in INIT *** ERR in start_all_tasks, code %d", status)
233 233 }
234 234
235 235 // start RECV and SEND *AFTER* SpaceWire Initialization, due to the timeout of the start call during the initialization
236 236 status = start_recv_send_tasks();
237 237 if ( status != RTEMS_SUCCESSFUL )
238 238 {
239 239 PRINTF1("in INIT *** ERR start_recv_send_tasks code %d\n", status )
240 240 }
241 241
242 242 // suspend science tasks, they will be restarted later depending on the mode
243 243 status = suspend_science_tasks(); // suspend science tasks (not done in stop_current_mode if current mode = STANDBY)
244 244 if (status != RTEMS_SUCCESSFUL)
245 245 {
246 246 PRINTF1("in INIT *** in suspend_science_tasks *** ERR code: %d\n", status)
247 247 }
248 248
249 249 // configure IRQ handling for the waveform picker unit
250 250 status = rtems_interrupt_catch( waveforms_isr,
251 251 IRQ_SPARC_WAVEFORM_PICKER,
252 252 &old_isr_handler) ;
253 253 // configure IRQ handling for the spectral matrices unit
254 254 status = rtems_interrupt_catch( spectral_matrices_isr,
255 255 IRQ_SPARC_SPECTRAL_MATRIX,
256 256 &old_isr_handler) ;
257 257
258 258 // if the spacewire link is not up then send an event to the SPIQ task for link recovery
259 259 if ( status_spw != RTEMS_SUCCESSFUL )
260 260 {
261 261 status = rtems_event_send( Task_id[TASKID_SPIQ], SPW_LINKERR_EVENT );
262 262 if ( status != RTEMS_SUCCESSFUL ) {
263 263 PRINTF1("in INIT *** ERR rtems_event_send to SPIQ code %d\n", status )
264 264 }
265 265 }
266 266
267 267 BOOT_PRINTF("delete INIT\n")
268 268
269 269 set_hk_lfr_sc_potential_flag( true );
270 270
271 271 status = rtems_task_delete(RTEMS_SELF);
272 272
273 273 }
274 274
275 275 void init_local_mode_parameters( void )
276 276 {
277 277 /** This function initialize the param_local global variable with default values.
278 278 *
279 279 */
280 280
281 281 unsigned int i;
282 282
283 283 // LOCAL PARAMETERS
284 284
285 285 BOOT_PRINTF1("local_sbm1_nb_cwf_max %d \n", param_local.local_sbm1_nb_cwf_max)
286 286 BOOT_PRINTF1("local_sbm2_nb_cwf_max %d \n", param_local.local_sbm2_nb_cwf_max)
287 287 BOOT_PRINTF1("nb_interrupt_f0_MAX = %d\n", param_local.local_nb_interrupt_f0_MAX)
288 288
289 289 // init sequence counters
290 290
291 291 for(i = 0; i<SEQ_CNT_NB_DEST_ID; i++)
292 292 {
293 293 sequenceCounters_TC_EXE[i] = 0x00;
294 294 sequenceCounters_TM_DUMP[i] = 0x00;
295 295 }
296 296 sequenceCounters_SCIENCE_NORMAL_BURST = 0x00;
297 297 sequenceCounters_SCIENCE_SBM1_SBM2 = 0x00;
298 298 sequenceCounterHK = TM_PACKET_SEQ_CTRL_STANDALONE << 8;
299 299 }
300 300
301 301 void reset_local_time( void )
302 302 {
303 303 time_management_regs->ctrl = time_management_regs->ctrl | 0x02; // [0010] software reset, coarse time = 0x80000000
304 304 }
305 305
306 306 void create_names( void ) // create all names for tasks and queues
307 307 {
308 308 /** This function creates all RTEMS names used in the software for tasks and queues.
309 309 *
310 310 * @return RTEMS directive status codes:
311 311 * - RTEMS_SUCCESSFUL - successful completion
312 312 *
313 313 */
314 314
315 315 // task names
316 316 Task_name[TASKID_RECV] = rtems_build_name( 'R', 'E', 'C', 'V' );
317 317 Task_name[TASKID_ACTN] = rtems_build_name( 'A', 'C', 'T', 'N' );
318 318 Task_name[TASKID_SPIQ] = rtems_build_name( 'S', 'P', 'I', 'Q' );
319 319 Task_name[TASKID_LOAD] = rtems_build_name( 'L', 'O', 'A', 'D' );
320 320 Task_name[TASKID_AVF0] = rtems_build_name( 'A', 'V', 'F', '0' );
321 321 Task_name[TASKID_SWBD] = rtems_build_name( 'S', 'W', 'B', 'D' );
322 322 Task_name[TASKID_WFRM] = rtems_build_name( 'W', 'F', 'R', 'M' );
323 323 Task_name[TASKID_DUMB] = rtems_build_name( 'D', 'U', 'M', 'B' );
324 324 Task_name[TASKID_HOUS] = rtems_build_name( 'H', 'O', 'U', 'S' );
325 325 Task_name[TASKID_PRC0] = rtems_build_name( 'P', 'R', 'C', '0' );
326 326 Task_name[TASKID_CWF3] = rtems_build_name( 'C', 'W', 'F', '3' );
327 327 Task_name[TASKID_CWF2] = rtems_build_name( 'C', 'W', 'F', '2' );
328 328 Task_name[TASKID_CWF1] = rtems_build_name( 'C', 'W', 'F', '1' );
329 329 Task_name[TASKID_SEND] = rtems_build_name( 'S', 'E', 'N', 'D' );
330 Task_name[TASKID_WTDG] = rtems_build_name( 'W', 'T', 'D', 'G' );
330 Task_name[TASKID_LINK] = rtems_build_name( 'L', 'I', 'N', 'K' );
331 331 Task_name[TASKID_AVF1] = rtems_build_name( 'A', 'V', 'F', '1' );
332 332 Task_name[TASKID_PRC1] = rtems_build_name( 'P', 'R', 'C', '1' );
333 333 Task_name[TASKID_AVF2] = rtems_build_name( 'A', 'V', 'F', '2' );
334 334 Task_name[TASKID_PRC2] = rtems_build_name( 'P', 'R', 'C', '2' );
335 335
336 336 // rate monotonic period names
337 337 name_hk_rate_monotonic = rtems_build_name( 'H', 'O', 'U', 'S' );
338 338
339 339 misc_name[QUEUE_RECV] = rtems_build_name( 'Q', '_', 'R', 'V' );
340 340 misc_name[QUEUE_SEND] = rtems_build_name( 'Q', '_', 'S', 'D' );
341 341 misc_name[QUEUE_PRC0] = rtems_build_name( 'Q', '_', 'P', '0' );
342 342 misc_name[QUEUE_PRC1] = rtems_build_name( 'Q', '_', 'P', '1' );
343 343 misc_name[QUEUE_PRC2] = rtems_build_name( 'Q', '_', 'P', '2' );
344 344
345 345 timecode_timer_name = rtems_build_name( 'S', 'P', 'T', 'C' );
346 346 }
347 347
348 348 int create_all_tasks( void ) // create all tasks which run in the software
349 349 {
350 350 /** This function creates all RTEMS tasks used in the software.
351 351 *
352 352 * @return RTEMS directive status codes:
353 353 * - RTEMS_SUCCESSFUL - task created successfully
354 354 * - RTEMS_INVALID_ADDRESS - id is NULL
355 355 * - RTEMS_INVALID_NAME - invalid task name
356 356 * - RTEMS_INVALID_PRIORITY - invalid task priority
357 357 * - RTEMS_MP_NOT_CONFIGURED - multiprocessing not configured
358 358 * - RTEMS_TOO_MANY - too many tasks created
359 359 * - RTEMS_UNSATISFIED - not enough memory for stack/FP context
360 360 * - RTEMS_TOO_MANY - too many global objects
361 361 *
362 362 */
363 363
364 364 rtems_status_code status;
365 365
366 366 //**********
367 367 // SPACEWIRE
368 368 // RECV
369 369 status = rtems_task_create(
370 370 Task_name[TASKID_RECV], TASK_PRIORITY_RECV, RTEMS_MINIMUM_STACK_SIZE,
371 371 RTEMS_DEFAULT_MODES,
372 372 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_RECV]
373 373 );
374 374 if (status == RTEMS_SUCCESSFUL) // SEND
375 375 {
376 376 status = rtems_task_create(
377 377 Task_name[TASKID_SEND], TASK_PRIORITY_SEND, RTEMS_MINIMUM_STACK_SIZE * 2,
378 378 RTEMS_DEFAULT_MODES,
379 379 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SEND]
380 380 );
381 381 }
382 if (status == RTEMS_SUCCESSFUL) // WTDG
382 if (status == RTEMS_SUCCESSFUL) // LINK
383 383 {
384 384 status = rtems_task_create(
385 Task_name[TASKID_WTDG], TASK_PRIORITY_WTDG, RTEMS_MINIMUM_STACK_SIZE,
385 Task_name[TASKID_LINK], TASK_PRIORITY_LINK, RTEMS_MINIMUM_STACK_SIZE,
386 386 RTEMS_DEFAULT_MODES,
387 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_WTDG]
387 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_LINK]
388 388 );
389 389 }
390 390 if (status == RTEMS_SUCCESSFUL) // ACTN
391 391 {
392 392 status = rtems_task_create(
393 393 Task_name[TASKID_ACTN], TASK_PRIORITY_ACTN, RTEMS_MINIMUM_STACK_SIZE,
394 394 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
395 395 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_ACTN]
396 396 );
397 397 }
398 398 if (status == RTEMS_SUCCESSFUL) // SPIQ
399 399 {
400 400 status = rtems_task_create(
401 401 Task_name[TASKID_SPIQ], TASK_PRIORITY_SPIQ, RTEMS_MINIMUM_STACK_SIZE,
402 402 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
403 403 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SPIQ]
404 404 );
405 405 }
406 406
407 407 //******************
408 408 // SPECTRAL MATRICES
409 409 if (status == RTEMS_SUCCESSFUL) // AVF0
410 410 {
411 411 status = rtems_task_create(
412 412 Task_name[TASKID_AVF0], TASK_PRIORITY_AVF0, RTEMS_MINIMUM_STACK_SIZE,
413 413 RTEMS_DEFAULT_MODES,
414 414 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF0]
415 415 );
416 416 }
417 417 if (status == RTEMS_SUCCESSFUL) // PRC0
418 418 {
419 419 status = rtems_task_create(
420 420 Task_name[TASKID_PRC0], TASK_PRIORITY_PRC0, RTEMS_MINIMUM_STACK_SIZE * 2,
421 421 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
422 422 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC0]
423 423 );
424 424 }
425 425 if (status == RTEMS_SUCCESSFUL) // AVF1
426 426 {
427 427 status = rtems_task_create(
428 428 Task_name[TASKID_AVF1], TASK_PRIORITY_AVF1, RTEMS_MINIMUM_STACK_SIZE,
429 429 RTEMS_DEFAULT_MODES,
430 430 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF1]
431 431 );
432 432 }
433 433 if (status == RTEMS_SUCCESSFUL) // PRC1
434 434 {
435 435 status = rtems_task_create(
436 436 Task_name[TASKID_PRC1], TASK_PRIORITY_PRC1, RTEMS_MINIMUM_STACK_SIZE * 2,
437 437 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
438 438 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC1]
439 439 );
440 440 }
441 441 if (status == RTEMS_SUCCESSFUL) // AVF2
442 442 {
443 443 status = rtems_task_create(
444 444 Task_name[TASKID_AVF2], TASK_PRIORITY_AVF2, RTEMS_MINIMUM_STACK_SIZE,
445 445 RTEMS_DEFAULT_MODES,
446 446 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF2]
447 447 );
448 448 }
449 449 if (status == RTEMS_SUCCESSFUL) // PRC2
450 450 {
451 451 status = rtems_task_create(
452 452 Task_name[TASKID_PRC2], TASK_PRIORITY_PRC2, RTEMS_MINIMUM_STACK_SIZE * 2,
453 453 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
454 454 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC2]
455 455 );
456 456 }
457 457
458 458 //****************
459 459 // WAVEFORM PICKER
460 460 if (status == RTEMS_SUCCESSFUL) // WFRM
461 461 {
462 462 status = rtems_task_create(
463 463 Task_name[TASKID_WFRM], TASK_PRIORITY_WFRM, RTEMS_MINIMUM_STACK_SIZE,
464 464 RTEMS_DEFAULT_MODES,
465 465 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_WFRM]
466 466 );
467 467 }
468 468 if (status == RTEMS_SUCCESSFUL) // CWF3
469 469 {
470 470 status = rtems_task_create(
471 471 Task_name[TASKID_CWF3], TASK_PRIORITY_CWF3, RTEMS_MINIMUM_STACK_SIZE,
472 472 RTEMS_DEFAULT_MODES,
473 473 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF3]
474 474 );
475 475 }
476 476 if (status == RTEMS_SUCCESSFUL) // CWF2
477 477 {
478 478 status = rtems_task_create(
479 479 Task_name[TASKID_CWF2], TASK_PRIORITY_CWF2, RTEMS_MINIMUM_STACK_SIZE,
480 480 RTEMS_DEFAULT_MODES,
481 481 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF2]
482 482 );
483 483 }
484 484 if (status == RTEMS_SUCCESSFUL) // CWF1
485 485 {
486 486 status = rtems_task_create(
487 487 Task_name[TASKID_CWF1], TASK_PRIORITY_CWF1, RTEMS_MINIMUM_STACK_SIZE,
488 488 RTEMS_DEFAULT_MODES,
489 489 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF1]
490 490 );
491 491 }
492 492 if (status == RTEMS_SUCCESSFUL) // SWBD
493 493 {
494 494 status = rtems_task_create(
495 495 Task_name[TASKID_SWBD], TASK_PRIORITY_SWBD, RTEMS_MINIMUM_STACK_SIZE,
496 496 RTEMS_DEFAULT_MODES,
497 497 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SWBD]
498 498 );
499 499 }
500 500
501 501 //*****
502 502 // MISC
503 503 if (status == RTEMS_SUCCESSFUL) // LOAD
504 504 {
505 505 status = rtems_task_create(
506 506 Task_name[TASKID_LOAD], TASK_PRIORITY_LOAD, RTEMS_MINIMUM_STACK_SIZE,
507 507 RTEMS_DEFAULT_MODES,
508 508 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_LOAD]
509 509 );
510 510 }
511 511 if (status == RTEMS_SUCCESSFUL) // DUMB
512 512 {
513 513 status = rtems_task_create(
514 514 Task_name[TASKID_DUMB], TASK_PRIORITY_DUMB, RTEMS_MINIMUM_STACK_SIZE,
515 515 RTEMS_DEFAULT_MODES,
516 516 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_DUMB]
517 517 );
518 518 }
519 519 if (status == RTEMS_SUCCESSFUL) // HOUS
520 520 {
521 521 status = rtems_task_create(
522 522 Task_name[TASKID_HOUS], TASK_PRIORITY_HOUS, RTEMS_MINIMUM_STACK_SIZE,
523 523 RTEMS_DEFAULT_MODES,
524 524 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_HOUS]
525 525 );
526 526 }
527 527
528 528 return status;
529 529 }
530 530
531 531 int start_recv_send_tasks( void )
532 532 {
533 533 rtems_status_code status;
534 534
535 535 status = rtems_task_start( Task_id[TASKID_RECV], recv_task, 1 );
536 536 if (status!=RTEMS_SUCCESSFUL) {
537 537 BOOT_PRINTF("in INIT *** Error starting TASK_RECV\n")
538 538 }
539 539
540 540 if (status == RTEMS_SUCCESSFUL) // SEND
541 541 {
542 542 status = rtems_task_start( Task_id[TASKID_SEND], send_task, 1 );
543 543 if (status!=RTEMS_SUCCESSFUL) {
544 544 BOOT_PRINTF("in INIT *** Error starting TASK_SEND\n")
545 545 }
546 546 }
547 547
548 548 return status;
549 549 }
550 550
551 551 int start_all_tasks( void ) // start all tasks except SEND RECV and HOUS
552 552 {
553 553 /** This function starts all RTEMS tasks used in the software.
554 554 *
555 555 * @return RTEMS directive status codes:
556 556 * - RTEMS_SUCCESSFUL - ask started successfully
557 557 * - RTEMS_INVALID_ADDRESS - invalid task entry point
558 558 * - RTEMS_INVALID_ID - invalid task id
559 559 * - RTEMS_INCORRECT_STATE - task not in the dormant state
560 560 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot start remote task
561 561 *
562 562 */
563 563 // starts all the tasks fot eh flight software
564 564
565 565 rtems_status_code status;
566 566
567 567 //**********
568 568 // SPACEWIRE
569 569 status = rtems_task_start( Task_id[TASKID_SPIQ], spiq_task, 1 );
570 570 if (status!=RTEMS_SUCCESSFUL) {
571 571 BOOT_PRINTF("in INIT *** Error starting TASK_SPIQ\n")
572 572 }
573 573
574 if (status == RTEMS_SUCCESSFUL) // WTDG
574 if (status == RTEMS_SUCCESSFUL) // LINK
575 575 {
576 status = rtems_task_start( Task_id[TASKID_WTDG], wtdg_task, 1 );
576 status = rtems_task_start( Task_id[TASKID_LINK], link_task, 1 );
577 577 if (status!=RTEMS_SUCCESSFUL) {
578 BOOT_PRINTF("in INIT *** Error starting TASK_WTDG\n")
578 BOOT_PRINTF("in INIT *** Error starting TASK_LINK\n")
579 579 }
580 580 }
581 581
582 582 if (status == RTEMS_SUCCESSFUL) // ACTN
583 583 {
584 584 status = rtems_task_start( Task_id[TASKID_ACTN], actn_task, 1 );
585 585 if (status!=RTEMS_SUCCESSFUL) {
586 586 BOOT_PRINTF("in INIT *** Error starting TASK_ACTN\n")
587 587 }
588 588 }
589 589
590 590 //******************
591 591 // SPECTRAL MATRICES
592 592 if (status == RTEMS_SUCCESSFUL) // AVF0
593 593 {
594 594 status = rtems_task_start( Task_id[TASKID_AVF0], avf0_task, LFR_MODE_STANDBY );
595 595 if (status!=RTEMS_SUCCESSFUL) {
596 596 BOOT_PRINTF("in INIT *** Error starting TASK_AVF0\n")
597 597 }
598 598 }
599 599 if (status == RTEMS_SUCCESSFUL) // PRC0
600 600 {
601 601 status = rtems_task_start( Task_id[TASKID_PRC0], prc0_task, LFR_MODE_STANDBY );
602 602 if (status!=RTEMS_SUCCESSFUL) {
603 603 BOOT_PRINTF("in INIT *** Error starting TASK_PRC0\n")
604 604 }
605 605 }
606 606 if (status == RTEMS_SUCCESSFUL) // AVF1
607 607 {
608 608 status = rtems_task_start( Task_id[TASKID_AVF1], avf1_task, LFR_MODE_STANDBY );
609 609 if (status!=RTEMS_SUCCESSFUL) {
610 610 BOOT_PRINTF("in INIT *** Error starting TASK_AVF1\n")
611 611 }
612 612 }
613 613 if (status == RTEMS_SUCCESSFUL) // PRC1
614 614 {
615 615 status = rtems_task_start( Task_id[TASKID_PRC1], prc1_task, LFR_MODE_STANDBY );
616 616 if (status!=RTEMS_SUCCESSFUL) {
617 617 BOOT_PRINTF("in INIT *** Error starting TASK_PRC1\n")
618 618 }
619 619 }
620 620 if (status == RTEMS_SUCCESSFUL) // AVF2
621 621 {
622 622 status = rtems_task_start( Task_id[TASKID_AVF2], avf2_task, 1 );
623 623 if (status!=RTEMS_SUCCESSFUL) {
624 624 BOOT_PRINTF("in INIT *** Error starting TASK_AVF2\n")
625 625 }
626 626 }
627 627 if (status == RTEMS_SUCCESSFUL) // PRC2
628 628 {
629 629 status = rtems_task_start( Task_id[TASKID_PRC2], prc2_task, 1 );
630 630 if (status!=RTEMS_SUCCESSFUL) {
631 631 BOOT_PRINTF("in INIT *** Error starting TASK_PRC2\n")
632 632 }
633 633 }
634 634
635 635 //****************
636 636 // WAVEFORM PICKER
637 637 if (status == RTEMS_SUCCESSFUL) // WFRM
638 638 {
639 639 status = rtems_task_start( Task_id[TASKID_WFRM], wfrm_task, 1 );
640 640 if (status!=RTEMS_SUCCESSFUL) {
641 641 BOOT_PRINTF("in INIT *** Error starting TASK_WFRM\n")
642 642 }
643 643 }
644 644 if (status == RTEMS_SUCCESSFUL) // CWF3
645 645 {
646 646 status = rtems_task_start( Task_id[TASKID_CWF3], cwf3_task, 1 );
647 647 if (status!=RTEMS_SUCCESSFUL) {
648 648 BOOT_PRINTF("in INIT *** Error starting TASK_CWF3\n")
649 649 }
650 650 }
651 651 if (status == RTEMS_SUCCESSFUL) // CWF2
652 652 {
653 653 status = rtems_task_start( Task_id[TASKID_CWF2], cwf2_task, 1 );
654 654 if (status!=RTEMS_SUCCESSFUL) {
655 655 BOOT_PRINTF("in INIT *** Error starting TASK_CWF2\n")
656 656 }
657 657 }
658 658 if (status == RTEMS_SUCCESSFUL) // CWF1
659 659 {
660 660 status = rtems_task_start( Task_id[TASKID_CWF1], cwf1_task, 1 );
661 661 if (status!=RTEMS_SUCCESSFUL) {
662 662 BOOT_PRINTF("in INIT *** Error starting TASK_CWF1\n")
663 663 }
664 664 }
665 665 if (status == RTEMS_SUCCESSFUL) // SWBD
666 666 {
667 667 status = rtems_task_start( Task_id[TASKID_SWBD], swbd_task, 1 );
668 668 if (status!=RTEMS_SUCCESSFUL) {
669 669 BOOT_PRINTF("in INIT *** Error starting TASK_SWBD\n")
670 670 }
671 671 }
672 672
673 673 //*****
674 674 // MISC
675 675 if (status == RTEMS_SUCCESSFUL) // HOUS
676 676 {
677 677 status = rtems_task_start( Task_id[TASKID_HOUS], hous_task, 1 );
678 678 if (status!=RTEMS_SUCCESSFUL) {
679 679 BOOT_PRINTF("in INIT *** Error starting TASK_HOUS\n")
680 680 }
681 681 }
682 682 if (status == RTEMS_SUCCESSFUL) // DUMB
683 683 {
684 684 status = rtems_task_start( Task_id[TASKID_DUMB], dumb_task, 1 );
685 685 if (status!=RTEMS_SUCCESSFUL) {
686 686 BOOT_PRINTF("in INIT *** Error starting TASK_DUMB\n")
687 687 }
688 688 }
689 689 if (status == RTEMS_SUCCESSFUL) // LOAD
690 690 {
691 691 status = rtems_task_start( Task_id[TASKID_LOAD], load_task, 1 );
692 692 if (status!=RTEMS_SUCCESSFUL) {
693 693 BOOT_PRINTF("in INIT *** Error starting TASK_LOAD\n")
694 694 }
695 695 }
696 696
697 697 return status;
698 698 }
699 699
700 700 rtems_status_code create_message_queues( void ) // create the two message queues used in the software
701 701 {
702 702 rtems_status_code status_recv;
703 703 rtems_status_code status_send;
704 704 rtems_status_code status_q_p0;
705 705 rtems_status_code status_q_p1;
706 706 rtems_status_code status_q_p2;
707 707 rtems_status_code ret;
708 708 rtems_id queue_id;
709 709
710 710 //****************************************
711 711 // create the queue for handling valid TCs
712 712 status_recv = rtems_message_queue_create( misc_name[QUEUE_RECV],
713 713 MSG_QUEUE_COUNT_RECV, CCSDS_TC_PKT_MAX_SIZE,
714 714 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
715 715 if ( status_recv != RTEMS_SUCCESSFUL ) {
716 716 PRINTF1("in create_message_queues *** ERR creating QUEU queue, %d\n", status_recv)
717 717 }
718 718
719 719 //************************************************
720 720 // create the queue for handling TM packet sending
721 721 status_send = rtems_message_queue_create( misc_name[QUEUE_SEND],
722 722 MSG_QUEUE_COUNT_SEND, MSG_QUEUE_SIZE_SEND,
723 723 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
724 724 if ( status_send != RTEMS_SUCCESSFUL ) {
725 725 PRINTF1("in create_message_queues *** ERR creating PKTS queue, %d\n", status_send)
726 726 }
727 727
728 728 //*****************************************************************************
729 729 // create the queue for handling averaged spectral matrices for processing @ f0
730 730 status_q_p0 = rtems_message_queue_create( misc_name[QUEUE_PRC0],
731 731 MSG_QUEUE_COUNT_PRC0, MSG_QUEUE_SIZE_PRC0,
732 732 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
733 733 if ( status_q_p0 != RTEMS_SUCCESSFUL ) {
734 734 PRINTF1("in create_message_queues *** ERR creating Q_P0 queue, %d\n", status_q_p0)
735 735 }
736 736
737 737 //*****************************************************************************
738 738 // create the queue for handling averaged spectral matrices for processing @ f1
739 739 status_q_p1 = rtems_message_queue_create( misc_name[QUEUE_PRC1],
740 740 MSG_QUEUE_COUNT_PRC1, MSG_QUEUE_SIZE_PRC1,
741 741 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
742 742 if ( status_q_p1 != RTEMS_SUCCESSFUL ) {
743 743 PRINTF1("in create_message_queues *** ERR creating Q_P1 queue, %d\n", status_q_p1)
744 744 }
745 745
746 746 //*****************************************************************************
747 747 // create the queue for handling averaged spectral matrices for processing @ f2
748 748 status_q_p2 = rtems_message_queue_create( misc_name[QUEUE_PRC2],
749 749 MSG_QUEUE_COUNT_PRC2, MSG_QUEUE_SIZE_PRC2,
750 750 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
751 751 if ( status_q_p2 != RTEMS_SUCCESSFUL ) {
752 752 PRINTF1("in create_message_queues *** ERR creating Q_P2 queue, %d\n", status_q_p2)
753 753 }
754 754
755 755 if ( status_recv != RTEMS_SUCCESSFUL )
756 756 {
757 757 ret = status_recv;
758 758 }
759 759 else if( status_send != RTEMS_SUCCESSFUL )
760 760 {
761 761 ret = status_send;
762 762 }
763 763 else if( status_q_p0 != RTEMS_SUCCESSFUL )
764 764 {
765 765 ret = status_q_p0;
766 766 }
767 767 else if( status_q_p1 != RTEMS_SUCCESSFUL )
768 768 {
769 769 ret = status_q_p1;
770 770 }
771 771 else
772 772 {
773 773 ret = status_q_p2;
774 774 }
775 775
776 776 return ret;
777 777 }
778 778
779 779 rtems_status_code create_timecode_timer( void )
780 780 {
781 781 rtems_status_code status;
782 782
783 783 status = rtems_timer_create( timecode_timer_name, &timecode_timer_id );
784 784
785 785 if ( status != RTEMS_SUCCESSFUL )
786 786 {
787 787 PRINTF1("in create_timer_timecode *** ERR creating SPTC timer, %d\n", status)
788 788 }
789 789 else
790 790 {
791 791 PRINTF("in create_timer_timecode *** OK creating SPTC timer\n")
792 792 }
793 793
794 794 return status;
795 795 }
796 796
797 797 rtems_status_code get_message_queue_id_send( rtems_id *queue_id )
798 798 {
799 799 rtems_status_code status;
800 800 rtems_name queue_name;
801 801
802 802 queue_name = rtems_build_name( 'Q', '_', 'S', 'D' );
803 803
804 804 status = rtems_message_queue_ident( queue_name, 0, queue_id );
805 805
806 806 return status;
807 807 }
808 808
809 809 rtems_status_code get_message_queue_id_recv( rtems_id *queue_id )
810 810 {
811 811 rtems_status_code status;
812 812 rtems_name queue_name;
813 813
814 814 queue_name = rtems_build_name( 'Q', '_', 'R', 'V' );
815 815
816 816 status = rtems_message_queue_ident( queue_name, 0, queue_id );
817 817
818 818 return status;
819 819 }
820 820
821 821 rtems_status_code get_message_queue_id_prc0( rtems_id *queue_id )
822 822 {
823 823 rtems_status_code status;
824 824 rtems_name queue_name;
825 825
826 826 queue_name = rtems_build_name( 'Q', '_', 'P', '0' );
827 827
828 828 status = rtems_message_queue_ident( queue_name, 0, queue_id );
829 829
830 830 return status;
831 831 }
832 832
833 833 rtems_status_code get_message_queue_id_prc1( rtems_id *queue_id )
834 834 {
835 835 rtems_status_code status;
836 836 rtems_name queue_name;
837 837
838 838 queue_name = rtems_build_name( 'Q', '_', 'P', '1' );
839 839
840 840 status = rtems_message_queue_ident( queue_name, 0, queue_id );
841 841
842 842 return status;
843 843 }
844 844
845 845 rtems_status_code get_message_queue_id_prc2( rtems_id *queue_id )
846 846 {
847 847 rtems_status_code status;
848 848 rtems_name queue_name;
849 849
850 850 queue_name = rtems_build_name( 'Q', '_', 'P', '2' );
851 851
852 852 status = rtems_message_queue_ident( queue_name, 0, queue_id );
853 853
854 854 return status;
855 855 }
856 856
857 857 void update_queue_max_count( rtems_id queue_id, unsigned char*fifo_size_max )
858 858 {
859 859 u_int32_t count;
860 860 rtems_status_code status;
861 861
862 862 status = rtems_message_queue_get_number_pending( queue_id, &count );
863 863
864 864 count = count + 1;
865 865
866 866 if (status != RTEMS_SUCCESSFUL)
867 867 {
868 868 PRINTF1("in update_queue_max_count *** ERR = %d\n", status)
869 869 }
870 870 else
871 871 {
872 872 if (count > *fifo_size_max)
873 873 {
874 874 *fifo_size_max = count;
875 875 }
876 876 }
877 877 }
878 878
879 879 void init_ring(ring_node ring[], unsigned char nbNodes, volatile int buffer[], unsigned int bufferSize )
880 880 {
881 881 unsigned char i;
882 882
883 883 //***************
884 884 // BUFFER ADDRESS
885 885 for(i=0; i<nbNodes; i++)
886 886 {
887 887 ring[i].coarseTime = 0xffffffff;
888 888 ring[i].fineTime = 0xffffffff;
889 889 ring[i].sid = 0x00;
890 890 ring[i].status = 0x00;
891 891 ring[i].buffer_address = (int) &buffer[ i * bufferSize ];
892 892 }
893 893
894 894 //*****
895 895 // NEXT
896 896 ring[ nbNodes - 1 ].next = (ring_node*) &ring[ 0 ];
897 897 for(i=0; i<nbNodes-1; i++)
898 898 {
899 899 ring[i].next = (ring_node*) &ring[ i + 1 ];
900 900 }
901 901
902 902 //*********
903 903 // PREVIOUS
904 904 ring[ 0 ].previous = (ring_node*) &ring[ nbNodes - 1 ];
905 905 for(i=1; i<nbNodes; i++)
906 906 {
907 907 ring[i].previous = (ring_node*) &ring[ i - 1 ];
908 908 }
909 909 }
@@ -1,1423 +1,1426
1 1 /** Functions related to the SpaceWire interface.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * A group of functions to handle SpaceWire transmissions:
7 7 * - configuration of the SpaceWire link
8 8 * - SpaceWire related interruption requests processing
9 9 * - transmission of TeleMetry packets by a dedicated RTEMS task
10 10 * - reception of TeleCommands by a dedicated RTEMS task
11 11 *
12 12 */
13 13
14 14 #include "fsw_spacewire.h"
15 15
16 16 rtems_name semq_name;
17 17 rtems_id semq_id;
18 18
19 19 //*****************
20 20 // waveform headers
21 21 Header_TM_LFR_SCIENCE_CWF_t headerCWF;
22 22 Header_TM_LFR_SCIENCE_SWF_t headerSWF;
23 23 Header_TM_LFR_SCIENCE_ASM_t headerASM;
24 24
25 25 unsigned char previousTimecodeCtr = 0;
26 26 unsigned int *grspwPtr = (unsigned int *) (REGS_ADDR_GRSPW + APB_OFFSET_GRSPW_TIME_REGISTER);
27 27
28 28 //***********
29 29 // RTEMS TASK
30 30 rtems_task spiq_task(rtems_task_argument unused)
31 31 {
32 32 /** This RTEMS task is awaken by an rtems_event sent by the interruption subroutine of the SpaceWire driver.
33 33 *
34 34 * @param unused is the starting argument of the RTEMS task
35 35 *
36 36 */
37 37
38 38 rtems_event_set event_out;
39 39 rtems_status_code status;
40 40 int linkStatus;
41 41
42 42 BOOT_PRINTF("in SPIQ *** \n")
43 43
44 44 while(true){
45 45 rtems_event_receive(SPW_LINKERR_EVENT, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an SPW_LINKERR_EVENT
46 46 PRINTF("in SPIQ *** got SPW_LINKERR_EVENT\n")
47 47
48 48 // [0] SUSPEND RECV AND SEND TASKS
49 49 status = rtems_task_suspend( Task_id[ TASKID_RECV ] );
50 50 if ( status != RTEMS_SUCCESSFUL ) {
51 51 PRINTF("in SPIQ *** ERR suspending RECV Task\n")
52 52 }
53 53 status = rtems_task_suspend( Task_id[ TASKID_SEND ] );
54 54 if ( status != RTEMS_SUCCESSFUL ) {
55 55 PRINTF("in SPIQ *** ERR suspending SEND Task\n")
56 56 }
57 57
58 58 // [1] CHECK THE LINK
59 59 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (1)
60 60 if ( linkStatus != 5) {
61 61 PRINTF1("in SPIQ *** linkStatus %d, wait...\n", linkStatus)
62 62 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
63 63 }
64 64
65 65 // [2] RECHECK THE LINK AFTER SY_LFR_DPU_CONNECT_TIMEOUT
66 66 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (2)
67 67 if ( linkStatus != 5 ) // [2.a] not in run state, reset the link
68 68 {
69 69 spacewire_compute_stats_offsets();
70 70 status = spacewire_several_connect_attemps( );
71 71 }
72 72 else // [2.b] in run state, start the link
73 73 {
74 74 status = spacewire_stop_and_start_link( fdSPW ); // start the link
75 75 if ( status != RTEMS_SUCCESSFUL)
76 76 {
77 77 PRINTF1("in SPIQ *** ERR spacewire_stop_and_start_link %d\n", status)
78 78 }
79 79 }
80 80
81 81 // [3] COMPLETE RECOVERY ACTION AFTER SY_LFR_DPU_CONNECT_ATTEMPTS
82 82 if ( status == RTEMS_SUCCESSFUL ) // [3.a] the link is in run state and has been started successfully
83 83 {
84 84 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
85 85 if ( status != RTEMS_SUCCESSFUL ) {
86 86 PRINTF("in SPIQ *** ERR resuming SEND Task\n")
87 87 }
88 88 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
89 89 if ( status != RTEMS_SUCCESSFUL ) {
90 90 PRINTF("in SPIQ *** ERR resuming RECV Task\n")
91 91 }
92 92 }
93 93 else // [3.b] the link is not in run state, go in STANDBY mode
94 94 {
95 95 status = enter_mode_standby();
96 96 if ( status != RTEMS_SUCCESSFUL )
97 97 {
98 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
101 status = rtems_event_send ( Task_id[TASKID_WTDG], RTEMS_EVENT_0 );
100 {
101 updateLFRCurrentMode( LFR_MODE_STANDBY );
102 }
103 // wake the LINK task up to wait for the link recovery
104 status = rtems_event_send ( Task_id[TASKID_LINK], RTEMS_EVENT_0 );
102 105 status = rtems_task_suspend( RTEMS_SELF );
103 106 }
104 107 }
105 108 }
106 109
107 110 rtems_task recv_task( rtems_task_argument unused )
108 111 {
109 112 /** This RTEMS task is dedicated to the reception of incoming TeleCommands.
110 113 *
111 114 * @param unused is the starting argument of the RTEMS task
112 115 *
113 116 * The RECV task blocks on a call to the read system call, waiting for incoming SpaceWire data. When unblocked:
114 117 * 1. It reads the incoming data.
115 118 * 2. Launches the acceptance procedure.
116 119 * 3. If the Telecommand is valid, sends it to a dedicated RTEMS message queue.
117 120 *
118 121 */
119 122
120 123 int len;
121 124 ccsdsTelecommandPacket_t currentTC;
122 125 unsigned char computed_CRC[ 2 ];
123 126 unsigned char currentTC_LEN_RCV[ 2 ];
124 127 unsigned char destinationID;
125 128 unsigned int estimatedPacketLength;
126 129 unsigned int parserCode;
127 130 rtems_status_code status;
128 131 rtems_id queue_recv_id;
129 132 rtems_id queue_send_id;
130 133
131 134 initLookUpTableForCRC(); // the table is used to compute Cyclic Redundancy Codes
132 135
133 136 status = get_message_queue_id_recv( &queue_recv_id );
134 137 if (status != RTEMS_SUCCESSFUL)
135 138 {
136 139 PRINTF1("in RECV *** ERR get_message_queue_id_recv %d\n", status)
137 140 }
138 141
139 142 status = get_message_queue_id_send( &queue_send_id );
140 143 if (status != RTEMS_SUCCESSFUL)
141 144 {
142 145 PRINTF1("in RECV *** ERR get_message_queue_id_send %d\n", status)
143 146 }
144 147
145 148 BOOT_PRINTF("in RECV *** \n")
146 149
147 150 while(1)
148 151 {
149 152 len = read( fdSPW, (char*) &currentTC, CCSDS_TC_PKT_MAX_SIZE ); // the call to read is blocking
150 153 if (len == -1){ // error during the read call
151 154 PRINTF1("in RECV *** last read call returned -1, ERRNO %d\n", errno)
152 155 }
153 156 else {
154 157 if ( (len+1) < CCSDS_TC_PKT_MIN_SIZE ) {
155 158 PRINTF("in RECV *** packet lenght too short\n")
156 159 }
157 160 else {
158 161 estimatedPacketLength = (unsigned int) (len - CCSDS_TC_TM_PACKET_OFFSET - 3); // => -3 is for Prot ID, Reserved and User App bytes
159 162 currentTC_LEN_RCV[ 0 ] = (unsigned char) (estimatedPacketLength >> 8);
160 163 currentTC_LEN_RCV[ 1 ] = (unsigned char) (estimatedPacketLength );
161 164 // CHECK THE TC
162 165 parserCode = tc_parser( &currentTC, estimatedPacketLength, computed_CRC ) ;
163 166 if ( (parserCode == ILLEGAL_APID) || (parserCode == WRONG_LEN_PKT)
164 167 || (parserCode == INCOR_CHECKSUM) || (parserCode == ILL_TYPE)
165 168 || (parserCode == ILL_SUBTYPE) || (parserCode == WRONG_APP_DATA)
166 169 || (parserCode == WRONG_SRC_ID) )
167 170 { // send TM_LFR_TC_EXE_CORRUPTED
168 171 PRINTF1("TC corrupted received, with code: %d\n", parserCode)
169 172 if ( !( (currentTC.serviceType==TC_TYPE_TIME) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_TIME) )
170 173 &&
171 174 !( (currentTC.serviceType==TC_TYPE_GEN) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_INFO))
172 175 )
173 176 {
174 177 if ( parserCode == WRONG_SRC_ID )
175 178 {
176 179 destinationID = SID_TC_GROUND;
177 180 }
178 181 else
179 182 {
180 183 destinationID = currentTC.sourceID;
181 184 }
182 185 send_tm_lfr_tc_exe_corrupted( &currentTC, queue_send_id,
183 186 computed_CRC, currentTC_LEN_RCV,
184 187 destinationID );
185 188 }
186 189 }
187 190 else
188 191 { // send valid TC to the action launcher
189 192 status = rtems_message_queue_send( queue_recv_id, &currentTC,
190 193 estimatedPacketLength + CCSDS_TC_TM_PACKET_OFFSET + 3);
191 194 }
192 195 }
193 196 }
194 197
195 198 update_queue_max_count( queue_recv_id, &hk_lfr_q_rv_fifo_size_max );
196 199
197 200 }
198 201 }
199 202
200 203 rtems_task send_task( rtems_task_argument argument)
201 204 {
202 205 /** This RTEMS task is dedicated to the transmission of TeleMetry packets.
203 206 *
204 207 * @param unused is the starting argument of the RTEMS task
205 208 *
206 209 * The SEND task waits for a message to become available in the dedicated RTEMS queue. When a message arrives:
207 210 * - if the first byte is equal to CCSDS_DESTINATION_ID, the message is sent as is using the write system call.
208 211 * - if the first byte is not equal to CCSDS_DESTINATION_ID, the message is handled as a spw_ioctl_pkt_send. After
209 212 * analyzis, the packet is sent either using the write system call or using the ioctl call SPACEWIRE_IOCTRL_SEND, depending on the
210 213 * data it contains.
211 214 *
212 215 */
213 216
214 217 rtems_status_code status; // RTEMS status code
215 218 char incomingData[MSG_QUEUE_SIZE_SEND]; // incoming data buffer
216 219 ring_node *incomingRingNodePtr;
217 220 int ring_node_address;
218 221 char *charPtr;
219 222 spw_ioctl_pkt_send *spw_ioctl_send;
220 223 size_t size; // size of the incoming TC packet
221 224 rtems_id queue_send_id;
222 225 unsigned int sid;
223 226 unsigned char sidAsUnsignedChar;
224 227 unsigned char type;
225 228
226 229 incomingRingNodePtr = NULL;
227 230 ring_node_address = 0;
228 231 charPtr = (char *) &ring_node_address;
229 232 sid = 0;
230 233 sidAsUnsignedChar = 0;
231 234
232 235 init_header_cwf( &headerCWF );
233 236 init_header_swf( &headerSWF );
234 237 init_header_asm( &headerASM );
235 238
236 239 status = get_message_queue_id_send( &queue_send_id );
237 240 if (status != RTEMS_SUCCESSFUL)
238 241 {
239 242 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
240 243 }
241 244
242 245 BOOT_PRINTF("in SEND *** \n")
243 246
244 247 while(1)
245 248 {
246 249 status = rtems_message_queue_receive( queue_send_id, incomingData, &size,
247 250 RTEMS_WAIT, RTEMS_NO_TIMEOUT );
248 251
249 252 if (status!=RTEMS_SUCCESSFUL)
250 253 {
251 254 PRINTF1("in SEND *** (1) ERR = %d\n", status)
252 255 }
253 256 else
254 257 {
255 258 if ( size == sizeof(ring_node*) )
256 259 {
257 260 charPtr[0] = incomingData[0];
258 261 charPtr[1] = incomingData[1];
259 262 charPtr[2] = incomingData[2];
260 263 charPtr[3] = incomingData[3];
261 264 incomingRingNodePtr = (ring_node*) ring_node_address;
262 265 sid = incomingRingNodePtr->sid;
263 266 if ( (sid==SID_NORM_CWF_LONG_F3)
264 267 || (sid==SID_BURST_CWF_F2 )
265 268 || (sid==SID_SBM1_CWF_F1 )
266 269 || (sid==SID_SBM2_CWF_F2 ))
267 270 {
268 271 spw_send_waveform_CWF( incomingRingNodePtr, &headerCWF );
269 272 }
270 273 else if ( (sid==SID_NORM_SWF_F0) || (sid== SID_NORM_SWF_F1) || (sid==SID_NORM_SWF_F2) )
271 274 {
272 275 spw_send_waveform_SWF( incomingRingNodePtr, &headerSWF );
273 276 }
274 277 else if ( (sid==SID_NORM_CWF_F3) )
275 278 {
276 279 spw_send_waveform_CWF3_light( incomingRingNodePtr, &headerCWF );
277 280 }
278 281 else if (sid==SID_NORM_ASM_F0)
279 282 {
280 283 spw_send_asm_f0( incomingRingNodePtr, &headerASM );
281 284 }
282 285 else if (sid==SID_NORM_ASM_F1)
283 286 {
284 287 spw_send_asm_f1( incomingRingNodePtr, &headerASM );
285 288 }
286 289 else if (sid==SID_NORM_ASM_F2)
287 290 {
288 291 spw_send_asm_f2( incomingRingNodePtr, &headerASM );
289 292 }
290 293 else if ( sid==TM_CODE_K_DUMP )
291 294 {
292 295 spw_send_k_dump( incomingRingNodePtr );
293 296 }
294 297 else
295 298 {
296 299 PRINTF1("unexpected sid = %d\n", sid);
297 300 }
298 301 }
299 302 else if ( incomingData[0] == CCSDS_DESTINATION_ID ) // the incoming message is a ccsds packet
300 303 {
301 304 sidAsUnsignedChar = (unsigned char) incomingData[ PACKET_POS_PA_LFR_SID_PKT ];
302 305 sid = sidAsUnsignedChar;
303 306 type = (unsigned char) incomingData[ PACKET_POS_SERVICE_TYPE ];
304 307 if (type == TM_TYPE_LFR_SCIENCE) // this is a BP packet, all other types are handled differently
305 308 // SET THE SEQUENCE_CNT PARAMETER IN CASE OF BP0 OR BP1 PACKETS
306 309 {
307 310 increment_seq_counter_source_id( (unsigned char*) &incomingData[ PACKET_POS_SEQUENCE_CNT ], sid );
308 311 }
309 312
310 313 status = write( fdSPW, incomingData, size );
311 314 if (status == -1){
312 315 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
313 316 }
314 317 }
315 318 else // the incoming message is a spw_ioctl_pkt_send structure
316 319 {
317 320 spw_ioctl_send = (spw_ioctl_pkt_send*) incomingData;
318 321 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, spw_ioctl_send );
319 322 if (status == -1){
320 323 PRINTF2("in SEND *** (2.b) ERRNO = %d, RTEMS = %d\n", errno, status)
321 324 }
322 325 }
323 326 }
324 327
325 328 update_queue_max_count( queue_send_id, &hk_lfr_q_sd_fifo_size_max );
326 329
327 330 }
328 331 }
329 332
330 rtems_task wtdg_task( rtems_task_argument argument )
333 rtems_task link_task( rtems_task_argument argument )
331 334 {
332 335 rtems_event_set event_out;
333 336 rtems_status_code status;
334 337 int linkStatus;
335 338
336 BOOT_PRINTF("in WTDG ***\n")
339 BOOT_PRINTF("in LINK ***\n")
337 340
338 341 while(1)
339 342 {
340 343 // wait for an RTEMS_EVENT
341 344 rtems_event_receive( RTEMS_EVENT_0,
342 345 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
343 PRINTF("in WTDG *** wait for the link\n")
346 PRINTF("in LINK *** wait for the link\n")
344 347 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
345 348 while( linkStatus != 5) // wait for the link
346 349 {
347 350 status = rtems_task_wake_after( 10 ); // monitor the link each 100ms
348 351 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
349 352 }
350 353
351 354 status = spacewire_stop_and_start_link( fdSPW );
352 355
353 356 if (status != RTEMS_SUCCESSFUL)
354 357 {
355 PRINTF1("in WTDG *** ERR link not started %d\n", status)
358 PRINTF1("in LINK *** ERR link not started %d\n", status)
356 359 }
357 360 else
358 361 {
359 PRINTF("in WTDG *** OK link started\n")
362 PRINTF("in LINK *** OK link started\n")
360 363 }
361 364
362 365 // restart the SPIQ task
363 366 status = rtems_task_restart( Task_id[TASKID_SPIQ], 1 );
364 367 if ( status != RTEMS_SUCCESSFUL ) {
365 368 PRINTF("in SPIQ *** ERR restarting SPIQ Task\n")
366 369 }
367 370
368 371 // restart RECV and SEND
369 372 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
370 373 if ( status != RTEMS_SUCCESSFUL ) {
371 374 PRINTF("in SPIQ *** ERR restarting SEND Task\n")
372 375 }
373 376 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
374 377 if ( status != RTEMS_SUCCESSFUL ) {
375 378 PRINTF("in SPIQ *** ERR restarting RECV Task\n")
376 379 }
377 380 }
378 381 }
379 382
380 383 //****************
381 384 // OTHER FUNCTIONS
382 385 int spacewire_open_link( void ) // by default, the driver resets the core: [SPW_CTRL_WRITE(pDev, SPW_CTRL_RESET);]
383 386 {
384 387 /** This function opens the SpaceWire link.
385 388 *
386 389 * @return a valid file descriptor in case of success, -1 in case of a failure
387 390 *
388 391 */
389 392 rtems_status_code status;
390 393
391 394 fdSPW = open(GRSPW_DEVICE_NAME, O_RDWR); // open the device. the open call resets the hardware
392 395 if ( fdSPW < 0 ) {
393 396 PRINTF1("ERR *** in configure_spw_link *** error opening "GRSPW_DEVICE_NAME" with ERR %d\n", errno)
394 397 }
395 398 else
396 399 {
397 400 status = RTEMS_SUCCESSFUL;
398 401 }
399 402
400 403 return status;
401 404 }
402 405
403 406 int spacewire_start_link( int fd )
404 407 {
405 408 rtems_status_code status;
406 409
407 410 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
408 411 // -1 default hardcoded driver timeout
409 412
410 413 return status;
411 414 }
412 415
413 416 int spacewire_stop_and_start_link( int fd )
414 417 {
415 418 rtems_status_code status;
416 419
417 420 status = ioctl( fd, SPACEWIRE_IOCTRL_STOP); // start fails if link pDev->running != 0
418 421 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
419 422 // -1 default hardcoded driver timeout
420 423
421 424 return status;
422 425 }
423 426
424 427 int spacewire_configure_link( int fd )
425 428 {
426 429 /** This function configures the SpaceWire link.
427 430 *
428 431 * @return GR-RTEMS-DRIVER directive status codes:
429 432 * - 22 EINVAL - Null pointer or an out of range value was given as the argument.
430 433 * - 16 EBUSY - Only used for SEND. Returned when no descriptors are avialble in non-blocking mode.
431 434 * - 88 ENOSYS - Returned for SET_DESTKEY if RMAP command handler is not available or if a non-implemented call is used.
432 435 * - 116 ETIMEDOUT - REturned for SET_PACKET_SIZE and START if the link could not be brought up.
433 436 * - 12 ENOMEM - Returned for SET_PACKETSIZE if it was unable to allocate the new buffers.
434 437 * - 5 EIO - Error when writing to grswp hardware registers.
435 438 * - 2 ENOENT - No such file or directory
436 439 */
437 440
438 441 rtems_status_code status;
439 442
440 443 spacewire_set_NP(1, REGS_ADDR_GRSPW); // [N]o [P]ort force
441 444 spacewire_set_RE(1, REGS_ADDR_GRSPW); // [R]MAP [E]nable, the dedicated call seems to break the no port force configuration
442 445
443 446 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_RXBLOCK, 1); // sets the blocking mode for reception
444 447 if (status!=RTEMS_SUCCESSFUL) {
445 448 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_RXBLOCK\n")
446 449 }
447 450 //
448 451 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_EVENT_ID, Task_id[TASKID_SPIQ]); // sets the task ID to which an event is sent when a
449 452 if (status!=RTEMS_SUCCESSFUL) {
450 453 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_EVENT_ID\n") // link-error interrupt occurs
451 454 }
452 455 //
453 456 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_DISABLE_ERR, 0); // automatic link-disabling due to link-error interrupts
454 457 if (status!=RTEMS_SUCCESSFUL) {
455 458 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_DISABLE_ERR\n")
456 459 }
457 460 //
458 461 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ, 1); // sets the link-error interrupt bit
459 462 if (status!=RTEMS_SUCCESSFUL) {
460 463 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ\n")
461 464 }
462 465 //
463 466 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK, 1); // transmission blocks
464 467 if (status!=RTEMS_SUCCESSFUL) {
465 468 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK\n")
466 469 }
467 470 //
468 471 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL, 1); // transmission blocks when no transmission descriptor is available
469 472 if (status!=RTEMS_SUCCESSFUL) {
470 473 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL\n")
471 474 }
472 475 //
473 476 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TCODE_CTRL, 0x0909); // [Time Rx : Time Tx : Link error : Tick-out IRQ]
474 477 if (status!=RTEMS_SUCCESSFUL) {
475 478 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TCODE_CTRL,\n")
476 479 }
477 480
478 481 return status;
479 482 }
480 483
481 484 int spacewire_several_connect_attemps( void )
482 485 {
483 486 /** This function is executed by the SPIQ rtems_task wehn it has been awaken by an interruption raised by the SpaceWire driver.
484 487 *
485 488 * @return RTEMS directive status code:
486 489 * - RTEMS_UNSATISFIED is returned is the link is not in the running state after 10 s.
487 490 * - RTEMS_SUCCESSFUL is returned if the link is up before the timeout.
488 491 *
489 492 */
490 493
491 494 rtems_status_code status_spw;
492 495 rtems_status_code status;
493 496 int i;
494 497
495 498 for ( i=0; i<SY_LFR_DPU_CONNECT_ATTEMPT; i++ )
496 499 {
497 500 PRINTF1("in spacewire_reset_link *** link recovery, try %d\n", i);
498 501
499 502 // CLOSING THE DRIVER AT THIS POINT WILL MAKE THE SEND TASK BLOCK THE SYSTEM
500 503
501 504 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
502 505
503 506 status_spw = spacewire_stop_and_start_link( fdSPW );
504 507 if ( status_spw != RTEMS_SUCCESSFUL )
505 508 {
506 509 PRINTF1("in spacewire_reset_link *** ERR spacewire_start_link code %d\n", status_spw)
507 510 }
508 511
509 512 if ( status_spw == RTEMS_SUCCESSFUL)
510 513 {
511 514 break;
512 515 }
513 516 }
514 517
515 518 return status_spw;
516 519 }
517 520
518 521 void spacewire_set_NP( unsigned char val, unsigned int regAddr ) // [N]o [P]ort force
519 522 {
520 523 /** This function sets the [N]o [P]ort force bit of the GRSPW control register.
521 524 *
522 525 * @param val is the value, 0 or 1, used to set the value of the NP bit.
523 526 * @param regAddr is the address of the GRSPW control register.
524 527 *
525 528 * NP is the bit 20 of the GRSPW control register.
526 529 *
527 530 */
528 531
529 532 unsigned int *spwptr = (unsigned int*) regAddr;
530 533
531 534 if (val == 1) {
532 535 *spwptr = *spwptr | 0x00100000; // [NP] set the No port force bit
533 536 }
534 537 if (val== 0) {
535 538 *spwptr = *spwptr & 0xffdfffff;
536 539 }
537 540 }
538 541
539 542 void spacewire_set_RE( unsigned char val, unsigned int regAddr ) // [R]MAP [E]nable
540 543 {
541 544 /** This function sets the [R]MAP [E]nable bit of the GRSPW control register.
542 545 *
543 546 * @param val is the value, 0 or 1, used to set the value of the RE bit.
544 547 * @param regAddr is the address of the GRSPW control register.
545 548 *
546 549 * RE is the bit 16 of the GRSPW control register.
547 550 *
548 551 */
549 552
550 553 unsigned int *spwptr = (unsigned int*) regAddr;
551 554
552 555 if (val == 1)
553 556 {
554 557 *spwptr = *spwptr | 0x00010000; // [RE] set the RMAP Enable bit
555 558 }
556 559 if (val== 0)
557 560 {
558 561 *spwptr = *spwptr & 0xfffdffff;
559 562 }
560 563 }
561 564
562 565 void spacewire_compute_stats_offsets( void )
563 566 {
564 567 /** This function computes the SpaceWire statistics offsets in case of a SpaceWire related interruption raising.
565 568 *
566 569 * The offsets keep a record of the statistics in case of a reset of the statistics. They are added to the current statistics
567 570 * to keep the counters consistent even after a reset of the SpaceWire driver (the counter are set to zero by the driver when it
568 571 * during the open systel call).
569 572 *
570 573 */
571 574
572 575 spw_stats spacewire_stats_grspw;
573 576 rtems_status_code status;
574 577
575 578 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &spacewire_stats_grspw );
576 579
577 580 spacewire_stats_backup.packets_received = spacewire_stats_grspw.packets_received
578 581 + spacewire_stats.packets_received;
579 582 spacewire_stats_backup.packets_sent = spacewire_stats_grspw.packets_sent
580 583 + spacewire_stats.packets_sent;
581 584 spacewire_stats_backup.parity_err = spacewire_stats_grspw.parity_err
582 585 + spacewire_stats.parity_err;
583 586 spacewire_stats_backup.disconnect_err = spacewire_stats_grspw.disconnect_err
584 587 + spacewire_stats.disconnect_err;
585 588 spacewire_stats_backup.escape_err = spacewire_stats_grspw.escape_err
586 589 + spacewire_stats.escape_err;
587 590 spacewire_stats_backup.credit_err = spacewire_stats_grspw.credit_err
588 591 + spacewire_stats.credit_err;
589 592 spacewire_stats_backup.write_sync_err = spacewire_stats_grspw.write_sync_err
590 593 + spacewire_stats.write_sync_err;
591 594 spacewire_stats_backup.rx_rmap_header_crc_err = spacewire_stats_grspw.rx_rmap_header_crc_err
592 595 + spacewire_stats.rx_rmap_header_crc_err;
593 596 spacewire_stats_backup.rx_rmap_data_crc_err = spacewire_stats_grspw.rx_rmap_data_crc_err
594 597 + spacewire_stats.rx_rmap_data_crc_err;
595 598 spacewire_stats_backup.early_ep = spacewire_stats_grspw.early_ep
596 599 + spacewire_stats.early_ep;
597 600 spacewire_stats_backup.invalid_address = spacewire_stats_grspw.invalid_address
598 601 + spacewire_stats.invalid_address;
599 602 spacewire_stats_backup.rx_eep_err = spacewire_stats_grspw.rx_eep_err
600 603 + spacewire_stats.rx_eep_err;
601 604 spacewire_stats_backup.rx_truncated = spacewire_stats_grspw.rx_truncated
602 605 + spacewire_stats.rx_truncated;
603 606 }
604 607
605 608 void spacewire_update_statistics( void )
606 609 {
607 610 rtems_status_code status;
608 611 spw_stats spacewire_stats_grspw;
609 612
610 613 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &spacewire_stats_grspw );
611 614
612 615 spacewire_stats.packets_received = spacewire_stats_backup.packets_received
613 616 + spacewire_stats_grspw.packets_received;
614 617 spacewire_stats.packets_sent = spacewire_stats_backup.packets_sent
615 618 + spacewire_stats_grspw.packets_sent;
616 619 spacewire_stats.parity_err = spacewire_stats_backup.parity_err
617 620 + spacewire_stats_grspw.parity_err;
618 621 spacewire_stats.disconnect_err = spacewire_stats_backup.disconnect_err
619 622 + spacewire_stats_grspw.disconnect_err;
620 623 spacewire_stats.escape_err = spacewire_stats_backup.escape_err
621 624 + spacewire_stats_grspw.escape_err;
622 625 spacewire_stats.credit_err = spacewire_stats_backup.credit_err
623 626 + spacewire_stats_grspw.credit_err;
624 627 spacewire_stats.write_sync_err = spacewire_stats_backup.write_sync_err
625 628 + spacewire_stats_grspw.write_sync_err;
626 629 spacewire_stats.rx_rmap_header_crc_err = spacewire_stats_backup.rx_rmap_header_crc_err
627 630 + spacewire_stats_grspw.rx_rmap_header_crc_err;
628 631 spacewire_stats.rx_rmap_data_crc_err = spacewire_stats_backup.rx_rmap_data_crc_err
629 632 + spacewire_stats_grspw.rx_rmap_data_crc_err;
630 633 spacewire_stats.early_ep = spacewire_stats_backup.early_ep
631 634 + spacewire_stats_grspw.early_ep;
632 635 spacewire_stats.invalid_address = spacewire_stats_backup.invalid_address
633 636 + spacewire_stats_grspw.invalid_address;
634 637 spacewire_stats.rx_eep_err = spacewire_stats_backup.rx_eep_err
635 638 + spacewire_stats_grspw.rx_eep_err;
636 639 spacewire_stats.rx_truncated = spacewire_stats_backup.rx_truncated
637 640 + spacewire_stats_grspw.rx_truncated;
638 641 //spacewire_stats.tx_link_err;
639 642
640 643 //****************************
641 644 // DPU_SPACEWIRE_IF_STATISTICS
642 645 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[0] = (unsigned char) (spacewire_stats.packets_received >> 8);
643 646 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[1] = (unsigned char) (spacewire_stats.packets_received);
644 647 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[0] = (unsigned char) (spacewire_stats.packets_sent >> 8);
645 648 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[1] = (unsigned char) (spacewire_stats.packets_sent);
646 649 //housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt;
647 650 //housekeeping_packet.hk_lfr_dpu_spw_last_timc;
648 651
649 652 //******************************************
650 653 // ERROR COUNTERS / SPACEWIRE / LOW SEVERITY
651 654 housekeeping_packet.hk_lfr_dpu_spw_parity = (unsigned char) spacewire_stats.parity_err;
652 655 housekeeping_packet.hk_lfr_dpu_spw_disconnect = (unsigned char) spacewire_stats.disconnect_err;
653 656 housekeeping_packet.hk_lfr_dpu_spw_escape = (unsigned char) spacewire_stats.escape_err;
654 657 housekeeping_packet.hk_lfr_dpu_spw_credit = (unsigned char) spacewire_stats.credit_err;
655 658 housekeeping_packet.hk_lfr_dpu_spw_write_sync = (unsigned char) spacewire_stats.write_sync_err;
656 659
657 660 //*********************************************
658 661 // ERROR COUNTERS / SPACEWIRE / MEDIUM SEVERITY
659 662 housekeeping_packet.hk_lfr_dpu_spw_early_eop = (unsigned char) spacewire_stats.early_ep;
660 663 housekeeping_packet.hk_lfr_dpu_spw_invalid_addr = (unsigned char) spacewire_stats.invalid_address;
661 664 housekeeping_packet.hk_lfr_dpu_spw_eep = (unsigned char) spacewire_stats.rx_eep_err;
662 665 housekeeping_packet.hk_lfr_dpu_spw_rx_too_big = (unsigned char) spacewire_stats.rx_truncated;
663 666 }
664 667
665 668 void increase_unsigned_char_counter( unsigned char *counter )
666 669 {
667 670 // update the number of valid timecodes that have been received
668 671 if (*counter == 255)
669 672 {
670 673 *counter = 0;
671 674 }
672 675 else
673 676 {
674 677 *counter = *counter + 1;
675 678 }
676 679 }
677 680
678 681 rtems_timer_service_routine timecode_timer_routine( rtems_id timer_id, void *user_data )
679 682 {
680 683
681 684 unsigned char currentTimecodeCtr;
682 685
683 686 currentTimecodeCtr = (unsigned char) (grspwPtr[0] & TIMECODE_MASK);
684 687
685 688 if (currentTimecodeCtr == previousTimecodeCtr)
686 689 {
687 690 //************************
688 691 // HK_LFR_TIMECODE_MISSING
689 692 // the timecode value has not changed, no valid timecode has been received, the timecode is MISSING
690 693 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_missing );
691 694 }
692 695 else if (currentTimecodeCtr == (previousTimecodeCtr+1))
693 696 {
694 697 // the timecode value has changed and the value is valid, this is unexpected because
695 698 // the timer should not have fired, the timecode_irq_handler should have been raised
696 699 }
697 700 else
698 701 {
699 702 //************************
700 703 // HK_LFR_TIMECODE_INVALID
701 704 // the timecode value has changed and the value is not valid, no tickout has been generated
702 705 // this is why the timer has fired
703 706 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_invalid );
704 707 }
705 708
706 709 rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_13 );
707 710 }
708 711
709 712 unsigned int check_timecode_and_previous_timecode_coherency(unsigned char currentTimecodeCtr)
710 713 {
711 714 /** This function checks the coherency between the incoming timecode and the last valid timecode.
712 715 *
713 716 * @param currentTimecodeCtr is the incoming timecode
714 717 *
715 718 * @return returned codes::
716 719 * - LFR_DEFAULT
717 720 * - LFR_SUCCESSFUL
718 721 *
719 722 */
720 723
721 724 static unsigned char firstTickout = 1;
722 725 unsigned char ret;
723 726
724 727 ret = LFR_DEFAULT;
725 728
726 729 if (firstTickout == 0)
727 730 {
728 731 if (currentTimecodeCtr == 0)
729 732 {
730 733 if (previousTimecodeCtr == 63)
731 734 {
732 735 ret = LFR_SUCCESSFUL;
733 736 }
734 737 else
735 738 {
736 739 ret = LFR_DEFAULT;
737 740 }
738 741 }
739 742 else
740 743 {
741 744 if (currentTimecodeCtr == (previousTimecodeCtr +1))
742 745 {
743 746 ret = LFR_SUCCESSFUL;
744 747 }
745 748 else
746 749 {
747 750 ret = LFR_DEFAULT;
748 751 }
749 752 }
750 753 }
751 754 else
752 755 {
753 756 firstTickout = 0;
754 757 ret = LFR_SUCCESSFUL;
755 758 }
756 759
757 760 return ret;
758 761 }
759 762
760 763 unsigned int check_timecode_and_internal_time_coherency(unsigned char timecode, unsigned char internalTime)
761 764 {
762 765 unsigned int ret;
763 766
764 767 ret = LFR_DEFAULT;
765 768
766 769 if (timecode == internalTime)
767 770 {
768 771 ret = LFR_SUCCESSFUL;
769 772 }
770 773 else
771 774 {
772 775 ret = LFR_DEFAULT;
773 776 }
774 777
775 778 return ret;
776 779 }
777 780
778 781 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc )
779 782 {
780 783 // a tickout has been emitted, perform actions on the incoming timecode
781 784
782 785 unsigned char incomingTimecode;
783 786 unsigned char updateTime;
784 787 unsigned char internalTime;
785 788 rtems_status_code status;
786 789
787 790 incomingTimecode = (unsigned char) (grspwPtr[0] & TIMECODE_MASK);
788 791 updateTime = time_management_regs->coarse_time_load & TIMECODE_MASK;
789 792 internalTime = time_management_regs->coarse_time & TIMECODE_MASK;
790 793
791 794 housekeeping_packet.hk_lfr_dpu_spw_last_timc = incomingTimecode;
792 795
793 796 // update the number of tickout that have been generated
794 797 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt );
795 798
796 799 //**************************
797 800 // HK_LFR_TIMECODE_ERRONEOUS
798 801 // MISSING and INVALID are handled by the timecode_timer_routine service routine
799 802 if (check_timecode_and_previous_timecode_coherency( incomingTimecode ) == LFR_DEFAULT)
800 803 {
801 804 // this is unexpected but a tickout could have been raised despite of the timecode being erroneous
802 805 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_erroneous );
803 806 }
804 807
805 808 //************************
806 809 // HK_LFR_TIME_TIMECODE_IT
807 810 // check the coherency between the SpaceWire timecode and the Internal Time
808 811 if (check_timecode_and_internal_time_coherency( incomingTimecode, internalTime ) == LFR_DEFAULT)
809 812 {
810 813 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_time_timecode_it );
811 814 }
812 815
813 816 //********************
814 817 // HK_LFR_TIMECODE_CTR
815 818 // check the value of the timecode with respect to the last TC_LFR_UPDATE_TIME => SSS-CP-FS-370
816 819 if (incomingTimecode != updateTime)
817 820 {
818 821 increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_time_timecode_ctr );
819 822 }
820 823
821 824 // launch the timecode timer to detect missing or invalid timecodes
822 825 previousTimecodeCtr = incomingTimecode; // update the previousTimecodeCtr value
823 826 status = rtems_timer_fire_after( timecode_timer_id, TIMECODE_TIMER_TIMEOUT, timecode_timer_routine, NULL );
824 827 }
825 828
826 829 void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header )
827 830 {
828 831 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
829 832 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
830 833 header->reserved = DEFAULT_RESERVED;
831 834 header->userApplication = CCSDS_USER_APP;
832 835 header->packetSequenceControl[0]= TM_PACKET_SEQ_CTRL_STANDALONE;
833 836 header->packetSequenceControl[1]= TM_PACKET_SEQ_CNT_DEFAULT;
834 837 header->packetLength[0] = 0x00;
835 838 header->packetLength[1] = 0x00;
836 839 // DATA FIELD HEADER
837 840 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
838 841 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
839 842 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6; // service subtype
840 843 header->destinationID = TM_DESTINATION_ID_GROUND;
841 844 header->time[0] = 0x00;
842 845 header->time[0] = 0x00;
843 846 header->time[0] = 0x00;
844 847 header->time[0] = 0x00;
845 848 header->time[0] = 0x00;
846 849 header->time[0] = 0x00;
847 850 // AUXILIARY DATA HEADER
848 851 header->sid = 0x00;
849 852 header->hkBIA = DEFAULT_HKBIA;
850 853 header->blkNr[0] = 0x00;
851 854 header->blkNr[1] = 0x00;
852 855 }
853 856
854 857 void init_header_swf( Header_TM_LFR_SCIENCE_SWF_t *header )
855 858 {
856 859 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
857 860 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
858 861 header->reserved = DEFAULT_RESERVED;
859 862 header->userApplication = CCSDS_USER_APP;
860 863 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
861 864 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
862 865 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
863 866 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
864 867 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
865 868 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
866 869 // DATA FIELD HEADER
867 870 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
868 871 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
869 872 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6; // service subtype
870 873 header->destinationID = TM_DESTINATION_ID_GROUND;
871 874 header->time[0] = 0x00;
872 875 header->time[0] = 0x00;
873 876 header->time[0] = 0x00;
874 877 header->time[0] = 0x00;
875 878 header->time[0] = 0x00;
876 879 header->time[0] = 0x00;
877 880 // AUXILIARY DATA HEADER
878 881 header->sid = 0x00;
879 882 header->hkBIA = DEFAULT_HKBIA;
880 883 header->pktCnt = DEFAULT_PKTCNT; // PKT_CNT
881 884 header->pktNr = 0x00;
882 885 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
883 886 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
884 887 }
885 888
886 889 void init_header_asm( Header_TM_LFR_SCIENCE_ASM_t *header )
887 890 {
888 891 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
889 892 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
890 893 header->reserved = DEFAULT_RESERVED;
891 894 header->userApplication = CCSDS_USER_APP;
892 895 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
893 896 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
894 897 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
895 898 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
896 899 header->packetLength[0] = 0x00;
897 900 header->packetLength[1] = 0x00;
898 901 // DATA FIELD HEADER
899 902 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
900 903 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
901 904 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3; // service subtype
902 905 header->destinationID = TM_DESTINATION_ID_GROUND;
903 906 header->time[0] = 0x00;
904 907 header->time[0] = 0x00;
905 908 header->time[0] = 0x00;
906 909 header->time[0] = 0x00;
907 910 header->time[0] = 0x00;
908 911 header->time[0] = 0x00;
909 912 // AUXILIARY DATA HEADER
910 913 header->sid = 0x00;
911 914 header->biaStatusInfo = 0x00;
912 915 header->pa_lfr_pkt_cnt_asm = 0x00;
913 916 header->pa_lfr_pkt_nr_asm = 0x00;
914 917 header->pa_lfr_asm_blk_nr[0] = 0x00;
915 918 header->pa_lfr_asm_blk_nr[1] = 0x00;
916 919 }
917 920
918 921 int spw_send_waveform_CWF( ring_node *ring_node_to_send,
919 922 Header_TM_LFR_SCIENCE_CWF_t *header )
920 923 {
921 924 /** This function sends CWF CCSDS packets (F2, F1 or F0).
922 925 *
923 926 * @param waveform points to the buffer containing the data that will be send.
924 927 * @param sid is the source identifier of the data that will be sent.
925 928 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
926 929 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
927 930 * contain information to setup the transmission of the data packets.
928 931 *
929 932 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
930 933 *
931 934 */
932 935
933 936 unsigned int i;
934 937 int ret;
935 938 unsigned int coarseTime;
936 939 unsigned int fineTime;
937 940 rtems_status_code status;
938 941 spw_ioctl_pkt_send spw_ioctl_send_CWF;
939 942 int *dataPtr;
940 943 unsigned char sid;
941 944
942 945 spw_ioctl_send_CWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_CWF;
943 946 spw_ioctl_send_CWF.options = 0;
944 947
945 948 ret = LFR_DEFAULT;
946 949 sid = (unsigned char) ring_node_to_send->sid;
947 950
948 951 coarseTime = ring_node_to_send->coarseTime;
949 952 fineTime = ring_node_to_send->fineTime;
950 953 dataPtr = (int*) ring_node_to_send->buffer_address;
951 954
952 955 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
953 956 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
954 957 header->hkBIA = pa_bia_status_info;
955 958 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
956 959 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
957 960 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
958 961
959 962 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF; i++) // send waveform
960 963 {
961 964 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF * NB_WORDS_SWF_BLK) ];
962 965 spw_ioctl_send_CWF.hdr = (char*) header;
963 966 // BUILD THE DATA
964 967 spw_ioctl_send_CWF.dlen = BLK_NR_CWF * NB_BYTES_SWF_BLK;
965 968
966 969 // SET PACKET SEQUENCE CONTROL
967 970 increment_seq_counter_source_id( header->packetSequenceControl, sid );
968 971
969 972 // SET SID
970 973 header->sid = sid;
971 974
972 975 // SET PACKET TIME
973 976 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime);
974 977 //
975 978 header->time[0] = header->acquisitionTime[0];
976 979 header->time[1] = header->acquisitionTime[1];
977 980 header->time[2] = header->acquisitionTime[2];
978 981 header->time[3] = header->acquisitionTime[3];
979 982 header->time[4] = header->acquisitionTime[4];
980 983 header->time[5] = header->acquisitionTime[5];
981 984
982 985 // SET PACKET ID
983 986 if ( (sid == SID_SBM1_CWF_F1) || (sid == SID_SBM2_CWF_F2) )
984 987 {
985 988 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2 >> 8);
986 989 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2);
987 990 }
988 991 else
989 992 {
990 993 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
991 994 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
992 995 }
993 996
994 997 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
995 998 if (status != RTEMS_SUCCESSFUL) {
996 999 ret = LFR_DEFAULT;
997 1000 }
998 1001 }
999 1002
1000 1003 return ret;
1001 1004 }
1002 1005
1003 1006 int spw_send_waveform_SWF( ring_node *ring_node_to_send,
1004 1007 Header_TM_LFR_SCIENCE_SWF_t *header )
1005 1008 {
1006 1009 /** This function sends SWF CCSDS packets (F2, F1 or F0).
1007 1010 *
1008 1011 * @param waveform points to the buffer containing the data that will be send.
1009 1012 * @param sid is the source identifier of the data that will be sent.
1010 1013 * @param headerSWF points to a table of headers that have been prepared for the data transmission.
1011 1014 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
1012 1015 * contain information to setup the transmission of the data packets.
1013 1016 *
1014 1017 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
1015 1018 *
1016 1019 */
1017 1020
1018 1021 unsigned int i;
1019 1022 int ret;
1020 1023 unsigned int coarseTime;
1021 1024 unsigned int fineTime;
1022 1025 rtems_status_code status;
1023 1026 spw_ioctl_pkt_send spw_ioctl_send_SWF;
1024 1027 int *dataPtr;
1025 1028 unsigned char sid;
1026 1029
1027 1030 spw_ioctl_send_SWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_SWF;
1028 1031 spw_ioctl_send_SWF.options = 0;
1029 1032
1030 1033 ret = LFR_DEFAULT;
1031 1034
1032 1035 coarseTime = ring_node_to_send->coarseTime;
1033 1036 fineTime = ring_node_to_send->fineTime;
1034 1037 dataPtr = (int*) ring_node_to_send->buffer_address;
1035 1038 sid = ring_node_to_send->sid;
1036 1039
1037 1040 header->hkBIA = pa_bia_status_info;
1038 1041 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1039 1042
1040 1043 for (i=0; i<7; i++) // send waveform
1041 1044 {
1042 1045 spw_ioctl_send_SWF.data = (char*) &dataPtr[ (i * BLK_NR_304 * NB_WORDS_SWF_BLK) ];
1043 1046 spw_ioctl_send_SWF.hdr = (char*) header;
1044 1047
1045 1048 // SET PACKET SEQUENCE CONTROL
1046 1049 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1047 1050
1048 1051 // SET PACKET LENGTH AND BLKNR
1049 1052 if (i == 6)
1050 1053 {
1051 1054 spw_ioctl_send_SWF.dlen = BLK_NR_224 * NB_BYTES_SWF_BLK;
1052 1055 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_224 >> 8);
1053 1056 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_224 );
1054 1057 header->blkNr[0] = (unsigned char) (BLK_NR_224 >> 8);
1055 1058 header->blkNr[1] = (unsigned char) (BLK_NR_224 );
1056 1059 }
1057 1060 else
1058 1061 {
1059 1062 spw_ioctl_send_SWF.dlen = BLK_NR_304 * NB_BYTES_SWF_BLK;
1060 1063 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_304 >> 8);
1061 1064 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_304 );
1062 1065 header->blkNr[0] = (unsigned char) (BLK_NR_304 >> 8);
1063 1066 header->blkNr[1] = (unsigned char) (BLK_NR_304 );
1064 1067 }
1065 1068
1066 1069 // SET PACKET TIME
1067 1070 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime );
1068 1071 //
1069 1072 header->time[0] = header->acquisitionTime[0];
1070 1073 header->time[1] = header->acquisitionTime[1];
1071 1074 header->time[2] = header->acquisitionTime[2];
1072 1075 header->time[3] = header->acquisitionTime[3];
1073 1076 header->time[4] = header->acquisitionTime[4];
1074 1077 header->time[5] = header->acquisitionTime[5];
1075 1078
1076 1079 // SET SID
1077 1080 header->sid = sid;
1078 1081
1079 1082 // SET PKTNR
1080 1083 header->pktNr = i+1; // PKT_NR
1081 1084
1082 1085 // SEND PACKET
1083 1086 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_SWF );
1084 1087 if (status != RTEMS_SUCCESSFUL) {
1085 1088 ret = LFR_DEFAULT;
1086 1089 }
1087 1090 }
1088 1091
1089 1092 return ret;
1090 1093 }
1091 1094
1092 1095 int spw_send_waveform_CWF3_light( ring_node *ring_node_to_send,
1093 1096 Header_TM_LFR_SCIENCE_CWF_t *header )
1094 1097 {
1095 1098 /** This function sends CWF_F3 CCSDS packets without the b1, b2 and b3 data.
1096 1099 *
1097 1100 * @param waveform points to the buffer containing the data that will be send.
1098 1101 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
1099 1102 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
1100 1103 * contain information to setup the transmission of the data packets.
1101 1104 *
1102 1105 * By default, CWF_F3 packet are send without the b1, b2 and b3 data. This function rebuilds a data buffer
1103 1106 * from the incoming data and sends it in 7 packets, 6 containing 340 blocks and 1 one containing 8 blocks.
1104 1107 *
1105 1108 */
1106 1109
1107 1110 unsigned int i;
1108 1111 int ret;
1109 1112 unsigned int coarseTime;
1110 1113 unsigned int fineTime;
1111 1114 rtems_status_code status;
1112 1115 spw_ioctl_pkt_send spw_ioctl_send_CWF;
1113 1116 char *dataPtr;
1114 1117 unsigned char sid;
1115 1118
1116 1119 spw_ioctl_send_CWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_CWF;
1117 1120 spw_ioctl_send_CWF.options = 0;
1118 1121
1119 1122 ret = LFR_DEFAULT;
1120 1123 sid = ring_node_to_send->sid;
1121 1124
1122 1125 coarseTime = ring_node_to_send->coarseTime;
1123 1126 fineTime = ring_node_to_send->fineTime;
1124 1127 dataPtr = (char*) ring_node_to_send->buffer_address;
1125 1128
1126 1129 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_672 >> 8);
1127 1130 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_672 );
1128 1131 header->hkBIA = pa_bia_status_info;
1129 1132 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1130 1133 header->blkNr[0] = (unsigned char) (BLK_NR_CWF_SHORT_F3 >> 8);
1131 1134 header->blkNr[1] = (unsigned char) (BLK_NR_CWF_SHORT_F3 );
1132 1135
1133 1136 //*********************
1134 1137 // SEND CWF3_light DATA
1135 1138 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF_LIGHT; i++) // send waveform
1136 1139 {
1137 1140 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK) ];
1138 1141 spw_ioctl_send_CWF.hdr = (char*) header;
1139 1142 // BUILD THE DATA
1140 1143 spw_ioctl_send_CWF.dlen = BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK;
1141 1144
1142 1145 // SET PACKET SEQUENCE COUNTER
1143 1146 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1144 1147
1145 1148 // SET SID
1146 1149 header->sid = sid;
1147 1150
1148 1151 // SET PACKET TIME
1149 1152 compute_acquisition_time( coarseTime, fineTime, SID_NORM_CWF_F3, i, header->acquisitionTime );
1150 1153 //
1151 1154 header->time[0] = header->acquisitionTime[0];
1152 1155 header->time[1] = header->acquisitionTime[1];
1153 1156 header->time[2] = header->acquisitionTime[2];
1154 1157 header->time[3] = header->acquisitionTime[3];
1155 1158 header->time[4] = header->acquisitionTime[4];
1156 1159 header->time[5] = header->acquisitionTime[5];
1157 1160
1158 1161 // SET PACKET ID
1159 1162 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1160 1163 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1161 1164
1162 1165 // SEND PACKET
1163 1166 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
1164 1167 if (status != RTEMS_SUCCESSFUL) {
1165 1168 ret = LFR_DEFAULT;
1166 1169 }
1167 1170 }
1168 1171
1169 1172 return ret;
1170 1173 }
1171 1174
1172 1175 void spw_send_asm_f0( ring_node *ring_node_to_send,
1173 1176 Header_TM_LFR_SCIENCE_ASM_t *header )
1174 1177 {
1175 1178 unsigned int i;
1176 1179 unsigned int length = 0;
1177 1180 rtems_status_code status;
1178 1181 unsigned int sid;
1179 1182 float *spectral_matrix;
1180 1183 int coarseTime;
1181 1184 int fineTime;
1182 1185 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1183 1186
1184 1187 sid = ring_node_to_send->sid;
1185 1188 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1186 1189 coarseTime = ring_node_to_send->coarseTime;
1187 1190 fineTime = ring_node_to_send->fineTime;
1188 1191
1189 1192 header->biaStatusInfo = pa_bia_status_info;
1190 1193 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1191 1194
1192 1195 for (i=0; i<3; i++)
1193 1196 {
1194 1197 if ((i==0) || (i==1))
1195 1198 {
1196 1199 spw_ioctl_send_ASM.dlen = DLEN_ASM_F0_PKT_1;
1197 1200 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1198 1201 ( (ASM_F0_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F0_1) ) * NB_VALUES_PER_SM )
1199 1202 ];
1200 1203 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0_1;
1201 1204 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1202 1205 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0_1) >> 8 ); // BLK_NR MSB
1203 1206 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0_1); // BLK_NR LSB
1204 1207 }
1205 1208 else
1206 1209 {
1207 1210 spw_ioctl_send_ASM.dlen = DLEN_ASM_F0_PKT_2;
1208 1211 spw_ioctl_send_ASM.data = (char*) &spectral_matrix[
1209 1212 ( (ASM_F0_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F0_1) ) * NB_VALUES_PER_SM )
1210 1213 ];
1211 1214 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0_2;
1212 1215 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1213 1216 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0_2) >> 8 ); // BLK_NR MSB
1214 1217 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0_2); // BLK_NR LSB
1215 1218 }
1216 1219
1217 1220 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1218 1221 spw_ioctl_send_ASM.hdr = (char *) header;
1219 1222 spw_ioctl_send_ASM.options = 0;
1220 1223
1221 1224 // (2) BUILD THE HEADER
1222 1225 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1223 1226 header->packetLength[0] = (unsigned char) (length>>8);
1224 1227 header->packetLength[1] = (unsigned char) (length);
1225 1228 header->sid = (unsigned char) sid; // SID
1226 1229 header->pa_lfr_pkt_cnt_asm = 3;
1227 1230 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1228 1231
1229 1232 // (3) SET PACKET TIME
1230 1233 header->time[0] = (unsigned char) (coarseTime>>24);
1231 1234 header->time[1] = (unsigned char) (coarseTime>>16);
1232 1235 header->time[2] = (unsigned char) (coarseTime>>8);
1233 1236 header->time[3] = (unsigned char) (coarseTime);
1234 1237 header->time[4] = (unsigned char) (fineTime>>8);
1235 1238 header->time[5] = (unsigned char) (fineTime);
1236 1239 //
1237 1240 header->acquisitionTime[0] = header->time[0];
1238 1241 header->acquisitionTime[1] = header->time[1];
1239 1242 header->acquisitionTime[2] = header->time[2];
1240 1243 header->acquisitionTime[3] = header->time[3];
1241 1244 header->acquisitionTime[4] = header->time[4];
1242 1245 header->acquisitionTime[5] = header->time[5];
1243 1246
1244 1247 // (4) SEND PACKET
1245 1248 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1246 1249 if (status != RTEMS_SUCCESSFUL) {
1247 1250 PRINTF1("in ASM_send *** ERR %d\n", (int) status)
1248 1251 }
1249 1252 }
1250 1253 }
1251 1254
1252 1255 void spw_send_asm_f1( ring_node *ring_node_to_send,
1253 1256 Header_TM_LFR_SCIENCE_ASM_t *header )
1254 1257 {
1255 1258 unsigned int i;
1256 1259 unsigned int length = 0;
1257 1260 rtems_status_code status;
1258 1261 unsigned int sid;
1259 1262 float *spectral_matrix;
1260 1263 int coarseTime;
1261 1264 int fineTime;
1262 1265 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1263 1266
1264 1267 sid = ring_node_to_send->sid;
1265 1268 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1266 1269 coarseTime = ring_node_to_send->coarseTime;
1267 1270 fineTime = ring_node_to_send->fineTime;
1268 1271
1269 1272 header->biaStatusInfo = pa_bia_status_info;
1270 1273 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1271 1274
1272 1275 for (i=0; i<3; i++)
1273 1276 {
1274 1277 if ((i==0) || (i==1))
1275 1278 {
1276 1279 spw_ioctl_send_ASM.dlen = DLEN_ASM_F1_PKT_1;
1277 1280 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1278 1281 ( (ASM_F1_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F1_1) ) * NB_VALUES_PER_SM )
1279 1282 ];
1280 1283 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F1_1;
1281 1284 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1282 1285 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F1_1) >> 8 ); // BLK_NR MSB
1283 1286 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F1_1); // BLK_NR LSB
1284 1287 }
1285 1288 else
1286 1289 {
1287 1290 spw_ioctl_send_ASM.dlen = DLEN_ASM_F1_PKT_2;
1288 1291 spw_ioctl_send_ASM.data = (char*) &spectral_matrix[
1289 1292 ( (ASM_F1_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F1_1) ) * NB_VALUES_PER_SM )
1290 1293 ];
1291 1294 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F1_2;
1292 1295 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1293 1296 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F1_2) >> 8 ); // BLK_NR MSB
1294 1297 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F1_2); // BLK_NR LSB
1295 1298 }
1296 1299
1297 1300 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1298 1301 spw_ioctl_send_ASM.hdr = (char *) header;
1299 1302 spw_ioctl_send_ASM.options = 0;
1300 1303
1301 1304 // (2) BUILD THE HEADER
1302 1305 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1303 1306 header->packetLength[0] = (unsigned char) (length>>8);
1304 1307 header->packetLength[1] = (unsigned char) (length);
1305 1308 header->sid = (unsigned char) sid; // SID
1306 1309 header->pa_lfr_pkt_cnt_asm = 3;
1307 1310 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1308 1311
1309 1312 // (3) SET PACKET TIME
1310 1313 header->time[0] = (unsigned char) (coarseTime>>24);
1311 1314 header->time[1] = (unsigned char) (coarseTime>>16);
1312 1315 header->time[2] = (unsigned char) (coarseTime>>8);
1313 1316 header->time[3] = (unsigned char) (coarseTime);
1314 1317 header->time[4] = (unsigned char) (fineTime>>8);
1315 1318 header->time[5] = (unsigned char) (fineTime);
1316 1319 //
1317 1320 header->acquisitionTime[0] = header->time[0];
1318 1321 header->acquisitionTime[1] = header->time[1];
1319 1322 header->acquisitionTime[2] = header->time[2];
1320 1323 header->acquisitionTime[3] = header->time[3];
1321 1324 header->acquisitionTime[4] = header->time[4];
1322 1325 header->acquisitionTime[5] = header->time[5];
1323 1326
1324 1327 // (4) SEND PACKET
1325 1328 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1326 1329 if (status != RTEMS_SUCCESSFUL) {
1327 1330 PRINTF1("in ASM_send *** ERR %d\n", (int) status)
1328 1331 }
1329 1332 }
1330 1333 }
1331 1334
1332 1335 void spw_send_asm_f2( ring_node *ring_node_to_send,
1333 1336 Header_TM_LFR_SCIENCE_ASM_t *header )
1334 1337 {
1335 1338 unsigned int i;
1336 1339 unsigned int length = 0;
1337 1340 rtems_status_code status;
1338 1341 unsigned int sid;
1339 1342 float *spectral_matrix;
1340 1343 int coarseTime;
1341 1344 int fineTime;
1342 1345 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1343 1346
1344 1347 sid = ring_node_to_send->sid;
1345 1348 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1346 1349 coarseTime = ring_node_to_send->coarseTime;
1347 1350 fineTime = ring_node_to_send->fineTime;
1348 1351
1349 1352 header->biaStatusInfo = pa_bia_status_info;
1350 1353 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1351 1354
1352 1355 for (i=0; i<3; i++)
1353 1356 {
1354 1357
1355 1358 spw_ioctl_send_ASM.dlen = DLEN_ASM_F2_PKT;
1356 1359 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1357 1360 ( (ASM_F2_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F2) ) * NB_VALUES_PER_SM )
1358 1361 ];
1359 1362 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F2;
1360 1363 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3;
1361 1364 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F2) >> 8 ); // BLK_NR MSB
1362 1365 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F2); // BLK_NR LSB
1363 1366
1364 1367 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1365 1368 spw_ioctl_send_ASM.hdr = (char *) header;
1366 1369 spw_ioctl_send_ASM.options = 0;
1367 1370
1368 1371 // (2) BUILD THE HEADER
1369 1372 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1370 1373 header->packetLength[0] = (unsigned char) (length>>8);
1371 1374 header->packetLength[1] = (unsigned char) (length);
1372 1375 header->sid = (unsigned char) sid; // SID
1373 1376 header->pa_lfr_pkt_cnt_asm = 3;
1374 1377 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1375 1378
1376 1379 // (3) SET PACKET TIME
1377 1380 header->time[0] = (unsigned char) (coarseTime>>24);
1378 1381 header->time[1] = (unsigned char) (coarseTime>>16);
1379 1382 header->time[2] = (unsigned char) (coarseTime>>8);
1380 1383 header->time[3] = (unsigned char) (coarseTime);
1381 1384 header->time[4] = (unsigned char) (fineTime>>8);
1382 1385 header->time[5] = (unsigned char) (fineTime);
1383 1386 //
1384 1387 header->acquisitionTime[0] = header->time[0];
1385 1388 header->acquisitionTime[1] = header->time[1];
1386 1389 header->acquisitionTime[2] = header->time[2];
1387 1390 header->acquisitionTime[3] = header->time[3];
1388 1391 header->acquisitionTime[4] = header->time[4];
1389 1392 header->acquisitionTime[5] = header->time[5];
1390 1393
1391 1394 // (4) SEND PACKET
1392 1395 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1393 1396 if (status != RTEMS_SUCCESSFUL) {
1394 1397 PRINTF1("in ASM_send *** ERR %d\n", (int) status)
1395 1398 }
1396 1399 }
1397 1400 }
1398 1401
1399 1402 void spw_send_k_dump( ring_node *ring_node_to_send )
1400 1403 {
1401 1404 rtems_status_code status;
1402 1405 Packet_TM_LFR_KCOEFFICIENTS_DUMP_t *kcoefficients_dump;
1403 1406 unsigned int packetLength;
1404 1407 unsigned int size;
1405 1408
1406 1409 PRINTF("spw_send_k_dump\n")
1407 1410
1408 1411 kcoefficients_dump = (Packet_TM_LFR_KCOEFFICIENTS_DUMP_t *) ring_node_to_send->buffer_address;
1409 1412
1410 1413 packetLength = kcoefficients_dump->packetLength[0] * 256 + kcoefficients_dump->packetLength[1];
1411 1414
1412 1415 size = packetLength + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
1413 1416
1414 1417 PRINTF2("packetLength %d, size %d\n", packetLength, size )
1415 1418
1416 1419 status = write( fdSPW, (char *) ring_node_to_send->buffer_address, size );
1417 1420
1418 1421 if (status == -1){
1419 1422 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
1420 1423 }
1421 1424
1422 1425 ring_node_to_send->status = 0x00;
1423 1426 }
@@ -1,1607 +1,1606
1 1 /** Functions and tasks related to TeleCommand handling.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * A group of functions to handle TeleCommands:\n
7 7 * action launching\n
8 8 * TC parsing\n
9 9 * ...
10 10 *
11 11 */
12 12
13 13 #include "tc_handler.h"
14 14 #include "math.h"
15 15
16 16 //***********
17 17 // RTEMS TASK
18 18
19 19 rtems_task actn_task( rtems_task_argument unused )
20 20 {
21 21 /** This RTEMS task is responsible for launching actions upton the reception of valid TeleCommands.
22 22 *
23 23 * @param unused is the starting argument of the RTEMS task
24 24 *
25 25 * The ACTN task waits for data coming from an RTEMS msesage queue. When data arrives, it launches specific actions depending
26 26 * on the incoming TeleCommand.
27 27 *
28 28 */
29 29
30 30 int result;
31 31 rtems_status_code status; // RTEMS status code
32 32 ccsdsTelecommandPacket_t TC; // TC sent to the ACTN task
33 33 size_t size; // size of the incoming TC packet
34 34 unsigned char subtype; // subtype of the current TC packet
35 35 unsigned char time[6];
36 36 rtems_id queue_rcv_id;
37 37 rtems_id queue_snd_id;
38 38
39 39 status = get_message_queue_id_recv( &queue_rcv_id );
40 40 if (status != RTEMS_SUCCESSFUL)
41 41 {
42 42 PRINTF1("in ACTN *** ERR get_message_queue_id_recv %d\n", status)
43 43 }
44 44
45 45 status = get_message_queue_id_send( &queue_snd_id );
46 46 if (status != RTEMS_SUCCESSFUL)
47 47 {
48 48 PRINTF1("in ACTN *** ERR get_message_queue_id_send %d\n", status)
49 49 }
50 50
51 51 result = LFR_SUCCESSFUL;
52 52 subtype = 0; // subtype of the current TC packet
53 53
54 54 BOOT_PRINTF("in ACTN *** \n")
55 55
56 56 while(1)
57 57 {
58 58 status = rtems_message_queue_receive( queue_rcv_id, (char*) &TC, &size,
59 59 RTEMS_WAIT, RTEMS_NO_TIMEOUT);
60 60 getTime( time ); // set time to the current time
61 61 if (status!=RTEMS_SUCCESSFUL)
62 62 {
63 63 PRINTF1("ERR *** in task ACTN *** error receiving a message, code %d \n", status)
64 64 }
65 65 else
66 66 {
67 67 subtype = TC.serviceSubType;
68 68 switch(subtype)
69 69 {
70 70 case TC_SUBTYPE_RESET:
71 71 result = action_reset( &TC, queue_snd_id, time );
72 72 close_action( &TC, result, queue_snd_id );
73 73 break;
74 74 case TC_SUBTYPE_LOAD_COMM:
75 75 result = action_load_common_par( &TC );
76 76 close_action( &TC, result, queue_snd_id );
77 77 break;
78 78 case TC_SUBTYPE_LOAD_NORM:
79 79 result = action_load_normal_par( &TC, queue_snd_id, time );
80 80 close_action( &TC, result, queue_snd_id );
81 81 break;
82 82 case TC_SUBTYPE_LOAD_BURST:
83 83 result = action_load_burst_par( &TC, queue_snd_id, time );
84 84 close_action( &TC, result, queue_snd_id );
85 85 break;
86 86 case TC_SUBTYPE_LOAD_SBM1:
87 87 result = action_load_sbm1_par( &TC, queue_snd_id, time );
88 88 close_action( &TC, result, queue_snd_id );
89 89 break;
90 90 case TC_SUBTYPE_LOAD_SBM2:
91 91 result = action_load_sbm2_par( &TC, queue_snd_id, time );
92 92 close_action( &TC, result, queue_snd_id );
93 93 break;
94 94 case TC_SUBTYPE_DUMP:
95 95 result = action_dump_par( &TC, queue_snd_id );
96 96 close_action( &TC, result, queue_snd_id );
97 97 break;
98 98 case TC_SUBTYPE_ENTER:
99 99 result = action_enter_mode( &TC, queue_snd_id );
100 100 close_action( &TC, result, queue_snd_id );
101 101 break;
102 102 case TC_SUBTYPE_UPDT_INFO:
103 103 result = action_update_info( &TC, queue_snd_id );
104 104 close_action( &TC, result, queue_snd_id );
105 105 break;
106 106 case TC_SUBTYPE_EN_CAL:
107 107 result = action_enable_calibration( &TC, queue_snd_id, time );
108 108 close_action( &TC, result, queue_snd_id );
109 109 break;
110 110 case TC_SUBTYPE_DIS_CAL:
111 111 result = action_disable_calibration( &TC, queue_snd_id, time );
112 112 close_action( &TC, result, queue_snd_id );
113 113 break;
114 114 case TC_SUBTYPE_LOAD_K:
115 115 result = action_load_kcoefficients( &TC, queue_snd_id, time );
116 116 close_action( &TC, result, queue_snd_id );
117 117 break;
118 118 case TC_SUBTYPE_DUMP_K:
119 119 result = action_dump_kcoefficients( &TC, queue_snd_id, time );
120 120 close_action( &TC, result, queue_snd_id );
121 121 break;
122 122 case TC_SUBTYPE_LOAD_FBINS:
123 123 result = action_load_fbins_mask( &TC, queue_snd_id, time );
124 124 close_action( &TC, result, queue_snd_id );
125 125 break;
126 126 case TC_SUBTYPE_UPDT_TIME:
127 127 result = action_update_time( &TC );
128 128 close_action( &TC, result, queue_snd_id );
129 129 break;
130 130 default:
131 131 break;
132 132 }
133 133 }
134 134 }
135 135 }
136 136
137 137 //***********
138 138 // TC ACTIONS
139 139
140 140 int action_reset(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
141 141 {
142 142 /** This function executes specific actions when a TC_LFR_RESET TeleCommand has been received.
143 143 *
144 144 * @param TC points to the TeleCommand packet that is being processed
145 145 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
146 146 *
147 147 */
148 148
149 149 PRINTF("this is the end!!!\n")
150 150 exit(0);
151 151 send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time );
152 152 return LFR_DEFAULT;
153 153 }
154 154
155 155 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
156 156 {
157 157 /** This function executes specific actions when a TC_LFR_ENTER_MODE TeleCommand has been received.
158 158 *
159 159 * @param TC points to the TeleCommand packet that is being processed
160 160 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
161 161 *
162 162 */
163 163
164 164 rtems_status_code status;
165 165 unsigned char requestedMode;
166 166 unsigned int *transitionCoarseTime_ptr;
167 167 unsigned int transitionCoarseTime;
168 168 unsigned char * bytePosPtr;
169 169
170 170 bytePosPtr = (unsigned char *) &TC->packetID;
171 171
172 172 requestedMode = bytePosPtr[ BYTE_POS_CP_MODE_LFR_SET ];
173 173 transitionCoarseTime_ptr = (unsigned int *) ( &bytePosPtr[ BYTE_POS_CP_LFR_ENTER_MODE_TIME ] );
174 174 transitionCoarseTime = (*transitionCoarseTime_ptr) & 0x7fffffff;
175 175
176 176 status = check_mode_value( requestedMode );
177 177
178 178 if ( status != LFR_SUCCESSFUL ) // the mode value is inconsistent
179 179 {
180 180 send_tm_lfr_tc_exe_inconsistent( TC, queue_id, BYTE_POS_CP_MODE_LFR_SET, requestedMode );
181 181 }
182 182
183 183 else // the mode value is valid, check the transition
184 184 {
185 185 status = check_mode_transition(requestedMode);
186 186 if (status != LFR_SUCCESSFUL)
187 187 {
188 188 PRINTF("ERR *** in action_enter_mode *** check_mode_transition\n")
189 189 send_tm_lfr_tc_exe_not_executable( TC, queue_id );
190 190 }
191 191 }
192 192
193 193 if ( status == LFR_SUCCESSFUL ) // the transition is valid, check the date
194 194 {
195 195 status = check_transition_date( transitionCoarseTime );
196 196 if (status != LFR_SUCCESSFUL)
197 197 {
198 PRINTF("ERR *** in action_enter_mode *** check_transition_date\n")
199 send_tm_lfr_tc_exe_inconsistent( TC, queue_id,
200 BYTE_POS_CP_LFR_ENTER_MODE_TIME,
201 bytePosPtr[ BYTE_POS_CP_LFR_ENTER_MODE_TIME + 3 ] );
198 PRINTF("ERR *** in action_enter_mode *** check_transition_date\n");
199 send_tm_lfr_tc_exe_not_executable(TC, queue_id );
202 200 }
203 201 }
204 202
205 203 if ( status == LFR_SUCCESSFUL ) // the date is valid, enter the mode
206 204 {
207 205 PRINTF1("OK *** in action_enter_mode *** enter mode %d\n", requestedMode);
208 206
209 207 update_last_valid_transition_date( transitionCoarseTime );
210 208
211 209 switch(requestedMode)
212 210 {
213 211 case LFR_MODE_STANDBY:
214 212 status = enter_mode_standby();
215 213 break;
216 214 case LFR_MODE_NORMAL:
217 215 status = enter_mode_normal( transitionCoarseTime );
218 216 break;
219 217 case LFR_MODE_BURST:
220 218 status = enter_mode_burst( transitionCoarseTime );
221 219 break;
222 220 case LFR_MODE_SBM1:
223 221 status = enter_mode_sbm1( transitionCoarseTime );
224 222 break;
225 223 case LFR_MODE_SBM2:
226 224 status = enter_mode_sbm2( transitionCoarseTime );
227 225 break;
228 226 default:
229 227 break;
230 228 }
231 229 }
232 230
233 231 return status;
234 232 }
235 233
236 234 int action_update_info(ccsdsTelecommandPacket_t *TC, rtems_id queue_id)
237 235 {
238 236 /** This function executes specific actions when a TC_LFR_UPDATE_INFO TeleCommand has been received.
239 237 *
240 238 * @param TC points to the TeleCommand packet that is being processed
241 239 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
242 240 *
243 241 * @return LFR directive status code:
244 242 * - LFR_DEFAULT
245 243 * - LFR_SUCCESSFUL
246 244 *
247 245 */
248 246
249 247 unsigned int val;
250 248 int result;
251 249 unsigned int status;
252 250 unsigned char mode;
253 251 unsigned char * bytePosPtr;
254 252
255 253 bytePosPtr = (unsigned char *) &TC->packetID;
256 254
257 255 // check LFR mode
258 256 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET5 ] & 0x1e) >> 1;
259 257 status = check_update_info_hk_lfr_mode( mode );
260 258 if (status == LFR_SUCCESSFUL) // check TDS mode
261 259 {
262 260 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & 0xf0) >> 4;
263 261 status = check_update_info_hk_tds_mode( mode );
264 262 }
265 263 if (status == LFR_SUCCESSFUL) // check THR mode
266 264 {
267 265 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & 0x0f);
268 266 status = check_update_info_hk_thr_mode( mode );
269 267 }
270 268 if (status == LFR_SUCCESSFUL) // if the parameter check is successful
271 269 {
272 270 val = housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * 256
273 271 + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
274 272 val++;
275 273 housekeeping_packet.hk_lfr_update_info_tc_cnt[0] = (unsigned char) (val >> 8);
276 274 housekeeping_packet.hk_lfr_update_info_tc_cnt[1] = (unsigned char) (val);
277 275 }
278 276
279 277 // pa_bia_status_info
280 278 // => pa_bia_mode_mux_set 3 bits
281 279 // => pa_bia_mode_hv_enabled 1 bit
282 280 // => pa_bia_mode_bias1_enabled 1 bit
283 281 // => pa_bia_mode_bias2_enabled 1 bit
284 282 // => pa_bia_mode_bias3_enabled 1 bit
285 283 // => pa_bia_on_off (cp_dpu_bias_on_off)
286 284 pa_bia_status_info = bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET2 ] & 0xfe; // [1111 1110]
287 285 pa_bia_status_info = pa_bia_status_info
288 286 | (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET1 ] & 0x1);
289 287
290 288 result = status;
291 289
292 290 return result;
293 291 }
294 292
295 293 int action_enable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
296 294 {
297 295 /** This function executes specific actions when a TC_LFR_ENABLE_CALIBRATION TeleCommand has been received.
298 296 *
299 297 * @param TC points to the TeleCommand packet that is being processed
300 298 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
301 299 *
302 300 */
303 301
304 302 int result;
305 303
306 304 result = LFR_DEFAULT;
307 305
308 306 setCalibration( true );
309 307
310 308 result = LFR_SUCCESSFUL;
311 309
312 310 return result;
313 311 }
314 312
315 313 int action_disable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
316 314 {
317 315 /** This function executes specific actions when a TC_LFR_DISABLE_CALIBRATION TeleCommand has been received.
318 316 *
319 317 * @param TC points to the TeleCommand packet that is being processed
320 318 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
321 319 *
322 320 */
323 321
324 322 int result;
325 323
326 324 result = LFR_DEFAULT;
327 325
328 326 setCalibration( false );
329 327
330 328 result = LFR_SUCCESSFUL;
331 329
332 330 return result;
333 331 }
334 332
335 333 int action_update_time(ccsdsTelecommandPacket_t *TC)
336 334 {
337 335 /** This function executes specific actions when a TC_LFR_UPDATE_TIME TeleCommand has been received.
338 336 *
339 337 * @param TC points to the TeleCommand packet that is being processed
340 338 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
341 339 *
342 340 * @return LFR_SUCCESSFUL
343 341 *
344 342 */
345 343
346 344 unsigned int val;
347 345
348 346 time_management_regs->coarse_time_load = (TC->dataAndCRC[0] << 24)
349 347 + (TC->dataAndCRC[1] << 16)
350 348 + (TC->dataAndCRC[2] << 8)
351 349 + TC->dataAndCRC[3];
352 350
353 351 val = housekeeping_packet.hk_lfr_update_time_tc_cnt[0] * 256
354 352 + housekeeping_packet.hk_lfr_update_time_tc_cnt[1];
355 353 val++;
356 354 housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char) (val >> 8);
357 355 housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char) (val);
358 356
359 357 return LFR_SUCCESSFUL;
360 358 }
361 359
362 360 //*******************
363 361 // ENTERING THE MODES
364 362 int check_mode_value( unsigned char requestedMode )
365 363 {
366 364 int status;
367 365
368 366 if ( (requestedMode != LFR_MODE_STANDBY)
369 367 && (requestedMode != LFR_MODE_NORMAL) && (requestedMode != LFR_MODE_BURST)
370 368 && (requestedMode != LFR_MODE_SBM1) && (requestedMode != LFR_MODE_SBM2) )
371 369 {
372 370 status = LFR_DEFAULT;
373 371 }
374 372 else
375 373 {
376 374 status = LFR_SUCCESSFUL;
377 375 }
378 376
379 377 return status;
380 378 }
381 379
382 380 int check_mode_transition( unsigned char requestedMode )
383 381 {
384 382 /** This function checks the validity of the transition requested by the TC_LFR_ENTER_MODE.
385 383 *
386 384 * @param requestedMode is the mode requested by the TC_LFR_ENTER_MODE
387 385 *
388 386 * @return LFR directive status codes:
389 387 * - LFR_SUCCESSFUL - the transition is authorized
390 388 * - LFR_DEFAULT - the transition is not authorized
391 389 *
392 390 */
393 391
394 392 int status;
395 393
396 394 switch (requestedMode)
397 395 {
398 396 case LFR_MODE_STANDBY:
399 397 if ( lfrCurrentMode == LFR_MODE_STANDBY ) {
400 398 status = LFR_DEFAULT;
401 399 }
402 400 else
403 401 {
404 402 status = LFR_SUCCESSFUL;
405 403 }
406 404 break;
407 405 case LFR_MODE_NORMAL:
408 406 if ( lfrCurrentMode == LFR_MODE_NORMAL ) {
409 407 status = LFR_DEFAULT;
410 408 }
411 409 else {
412 410 status = LFR_SUCCESSFUL;
413 411 }
414 412 break;
415 413 case LFR_MODE_BURST:
416 414 if ( lfrCurrentMode == LFR_MODE_BURST ) {
417 415 status = LFR_DEFAULT;
418 416 }
419 417 else {
420 418 status = LFR_SUCCESSFUL;
421 419 }
422 420 break;
423 421 case LFR_MODE_SBM1:
424 422 if ( lfrCurrentMode == LFR_MODE_SBM1 ) {
425 423 status = LFR_DEFAULT;
426 424 }
427 425 else {
428 426 status = LFR_SUCCESSFUL;
429 427 }
430 428 break;
431 429 case LFR_MODE_SBM2:
432 430 if ( lfrCurrentMode == LFR_MODE_SBM2 ) {
433 431 status = LFR_DEFAULT;
434 432 }
435 433 else {
436 434 status = LFR_SUCCESSFUL;
437 435 }
438 436 break;
439 437 default:
440 438 status = LFR_DEFAULT;
441 439 break;
442 440 }
443 441
444 442 return status;
445 443 }
446 444
447 445 void update_last_valid_transition_date( unsigned int transitionCoarseTime )
448 446 {
449 447 lastValidEnterModeTime = transitionCoarseTime;
450 448 PRINTF1("lastValidEnterModeTime = %x\n", transitionCoarseTime);
451 449 }
452 450
453 451 int check_transition_date( unsigned int transitionCoarseTime )
454 452 {
455 453 int status;
456 454 unsigned int localCoarseTime;
457 455 unsigned int deltaCoarseTime;
458 456
459 457 status = LFR_SUCCESSFUL;
460 458
461 459 if (transitionCoarseTime == 0) // transition time = 0 means an instant transition
462 460 {
463 461 status = LFR_SUCCESSFUL;
464 462 }
465 463 else
466 464 {
467 465 localCoarseTime = time_management_regs->coarse_time & 0x7fffffff;
468 466
469 467 PRINTF2("localTime = %x, transitionTime = %x\n", localCoarseTime, transitionCoarseTime);
470 468
471 469 if ( transitionCoarseTime <= localCoarseTime ) // SSS-CP-EQS-322
472 470 {
473 471 status = LFR_DEFAULT;
474 472 PRINTF("ERR *** in check_transition_date *** transitionCoarseTime <= localCoarseTime\n");
475 473 }
476 474
477 475 if (status == LFR_SUCCESSFUL)
478 476 {
479 477 deltaCoarseTime = transitionCoarseTime - localCoarseTime;
480 478 if ( deltaCoarseTime > 3 ) // SSS-CP-EQS-323
481 479 {
482 480 status = LFR_DEFAULT;
483 481 PRINTF1("ERR *** in check_transition_date *** deltaCoarseTime = %x\n", deltaCoarseTime)
484 482 }
485 483 }
486 484 }
487 485
488 486 return status;
489 487 }
490 488
491 489 int restart_asm_activities( unsigned char lfrRequestedMode )
492 490 {
493 491 rtems_status_code status;
494 492
495 493 status = stop_spectral_matrices();
496 494
497 495 status = restart_asm_tasks( lfrRequestedMode );
498 496
499 497 launch_spectral_matrix();
500 498
501 499 return status;
502 500 }
503 501
504 502 int stop_spectral_matrices( void )
505 503 {
506 504 /** This function stops and restarts the current mode average spectral matrices activities.
507 505 *
508 506 * @return RTEMS directive status codes:
509 507 * - RTEMS_SUCCESSFUL - task restarted successfully
510 508 * - RTEMS_INVALID_ID - task id invalid
511 509 * - RTEMS_ALREADY_SUSPENDED - task already suspended
512 510 *
513 511 */
514 512
515 513 rtems_status_code status;
516 514
517 515 status = RTEMS_SUCCESSFUL;
518 516
519 517 // (1) mask interruptions
520 518 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
521 519
522 520 // (2) reset spectral matrices registers
523 521 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
524 522 reset_sm_status();
525 523
526 524 // (3) clear interruptions
527 525 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
528 526
529 527 // suspend several tasks
530 528 if (lfrCurrentMode != LFR_MODE_STANDBY) {
531 529 status = suspend_asm_tasks();
532 530 }
533 531
534 532 if (status != RTEMS_SUCCESSFUL)
535 533 {
536 534 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
537 535 }
538 536
539 537 return status;
540 538 }
541 539
542 540 int stop_current_mode( void )
543 541 {
544 542 /** This function stops the current mode by masking interrupt lines and suspending science tasks.
545 543 *
546 544 * @return RTEMS directive status codes:
547 545 * - RTEMS_SUCCESSFUL - task restarted successfully
548 546 * - RTEMS_INVALID_ID - task id invalid
549 547 * - RTEMS_ALREADY_SUSPENDED - task already suspended
550 548 *
551 549 */
552 550
553 551 rtems_status_code status;
554 552
555 553 status = RTEMS_SUCCESSFUL;
556 554
557 555 // (1) mask interruptions
558 556 LEON_Mask_interrupt( IRQ_WAVEFORM_PICKER ); // mask waveform picker interrupt
559 557 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
560 558
561 559 // (2) reset waveform picker registers
562 560 reset_wfp_burst_enable(); // reset burst and enable bits
563 561 reset_wfp_status(); // reset all the status bits
564 562
565 563 // (3) reset spectral matrices registers
566 564 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
567 565 reset_sm_status();
568 566
569 567 // reset lfr VHDL module
570 568 reset_lfr();
571 569
572 570 reset_extractSWF(); // reset the extractSWF flag to false
573 571
574 572 // (4) clear interruptions
575 573 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER ); // clear waveform picker interrupt
576 574 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
577 575
578 576 // suspend several tasks
579 577 if (lfrCurrentMode != LFR_MODE_STANDBY) {
580 578 status = suspend_science_tasks();
581 579 }
582 580
583 581 if (status != RTEMS_SUCCESSFUL)
584 582 {
585 583 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
586 584 }
587 585
588 586 return status;
589 587 }
590 588
591 int enter_mode_standby()
589 int enter_mode_standby( void )
592 590 {
593 591 /** This function is used to put LFR in the STANDBY mode.
594 592 *
595 593 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
596 594 *
597 595 * @return RTEMS directive status codes:
598 596 * - RTEMS_SUCCESSFUL - task restarted successfully
599 597 * - RTEMS_INVALID_ID - task id invalid
600 598 * - RTEMS_INCORRECT_STATE - task never started
601 599 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
602 600 *
603 601 * The STANDBY mode does not depends on a specific transition date, the effect of the TC_LFR_ENTER_MODE
604 602 * is immediate.
605 603 *
606 604 */
607 605
608 606 int status;
609 607
610 608 status = stop_current_mode(); // STOP THE CURRENT MODE
611 609
612 610 #ifdef PRINT_TASK_STATISTICS
613 611 rtems_cpu_usage_report();
614 612 #endif
615 613
616 614 #ifdef PRINT_STACK_REPORT
617 615 PRINTF("stack report selected\n")
618 616 rtems_stack_checker_report_usage();
619 617 #endif
620 618
621 619 return status;
622 620 }
623 621
624 622 int enter_mode_normal( unsigned int transitionCoarseTime )
625 623 {
626 624 /** This function is used to start the NORMAL mode.
627 625 *
628 626 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
629 627 *
630 628 * @return RTEMS directive status codes:
631 629 * - RTEMS_SUCCESSFUL - task restarted successfully
632 630 * - RTEMS_INVALID_ID - task id invalid
633 631 * - RTEMS_INCORRECT_STATE - task never started
634 632 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
635 633 *
636 634 * The way the NORMAL mode is started depends on the LFR current mode. If LFR is in SBM1 or SBM2,
637 635 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected.
638 636 *
639 637 */
640 638
641 639 int status;
642 640
643 641 #ifdef PRINT_TASK_STATISTICS
644 642 rtems_cpu_usage_reset();
645 643 #endif
646 644
647 645 status = RTEMS_UNSATISFIED;
648 646
649 647 switch( lfrCurrentMode )
650 648 {
651 649 case LFR_MODE_STANDBY:
652 650 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart science tasks
653 651 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
654 652 {
655 653 launch_spectral_matrix( );
656 654 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
657 655 }
658 656 break;
659 657 case LFR_MODE_BURST:
660 658 status = stop_current_mode(); // stop the current mode
661 659 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart the science tasks
662 660 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
663 661 {
664 662 launch_spectral_matrix( );
665 663 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
666 664 }
667 665 break;
668 666 case LFR_MODE_SBM1:
669 667 restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
670 668 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
671 669 break;
672 670 case LFR_MODE_SBM2:
673 671 restart_asm_activities( LFR_MODE_NORMAL ); // this is necessary to restart ASM tasks to update the parameters
674 672 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
675 673 break;
676 674 default:
677 675 break;
678 676 }
679 677
680 678 if (status != RTEMS_SUCCESSFUL)
681 679 {
682 680 PRINTF1("ERR *** in enter_mode_normal *** status = %d\n", status)
683 681 status = RTEMS_UNSATISFIED;
684 682 }
685 683
686 684 return status;
687 685 }
688 686
689 687 int enter_mode_burst( unsigned int transitionCoarseTime )
690 688 {
691 689 /** This function is used to start the BURST mode.
692 690 *
693 691 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
694 692 *
695 693 * @return RTEMS directive status codes:
696 694 * - RTEMS_SUCCESSFUL - task restarted successfully
697 695 * - RTEMS_INVALID_ID - task id invalid
698 696 * - RTEMS_INCORRECT_STATE - task never started
699 697 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
700 698 *
701 699 * The way the BURST mode is started does not depend on the LFR current mode.
702 700 *
703 701 */
704 702
705 703
706 704 int status;
707 705
708 706 #ifdef PRINT_TASK_STATISTICS
709 707 rtems_cpu_usage_reset();
710 708 #endif
711 709
712 710 status = stop_current_mode(); // stop the current mode
713 711 status = restart_science_tasks( LFR_MODE_BURST ); // restart the science tasks
714 712 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
715 713 {
716 714 launch_spectral_matrix( );
717 715 launch_waveform_picker( LFR_MODE_BURST, transitionCoarseTime );
718 716 }
719 717
720 718 if (status != RTEMS_SUCCESSFUL)
721 719 {
722 720 PRINTF1("ERR *** in enter_mode_burst *** status = %d\n", status)
723 721 status = RTEMS_UNSATISFIED;
724 722 }
725 723
726 724 return status;
727 725 }
728 726
729 727 int enter_mode_sbm1( unsigned int transitionCoarseTime )
730 728 {
731 729 /** This function is used to start the SBM1 mode.
732 730 *
733 731 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
734 732 *
735 733 * @return RTEMS directive status codes:
736 734 * - RTEMS_SUCCESSFUL - task restarted successfully
737 735 * - RTEMS_INVALID_ID - task id invalid
738 736 * - RTEMS_INCORRECT_STATE - task never started
739 737 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
740 738 *
741 739 * The way the SBM1 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM2,
742 740 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
743 741 * cases, the acquisition is completely restarted.
744 742 *
745 743 */
746 744
747 745 int status;
748 746
749 747 #ifdef PRINT_TASK_STATISTICS
750 748 rtems_cpu_usage_reset();
751 749 #endif
752 750
753 751 status = RTEMS_UNSATISFIED;
754 752
755 753 switch( lfrCurrentMode )
756 754 {
757 755 case LFR_MODE_STANDBY:
758 756 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart science tasks
759 757 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
760 758 {
761 759 launch_spectral_matrix( );
762 760 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
763 761 }
764 762 break;
765 763 case LFR_MODE_NORMAL: // lfrCurrentMode will be updated after the execution of close_action
766 764 restart_asm_activities( LFR_MODE_SBM1 );
767 765 status = LFR_SUCCESSFUL;
768 766 break;
769 767 case LFR_MODE_BURST:
770 768 status = stop_current_mode(); // stop the current mode
771 769 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart the science tasks
772 770 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
773 771 {
774 772 launch_spectral_matrix( );
775 773 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
776 774 }
777 775 break;
778 776 case LFR_MODE_SBM2:
779 777 restart_asm_activities( LFR_MODE_SBM1 );
780 778 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
781 779 break;
782 780 default:
783 781 break;
784 782 }
785 783
786 784 if (status != RTEMS_SUCCESSFUL)
787 785 {
788 786 PRINTF1("ERR *** in enter_mode_sbm1 *** status = %d\n", status)
789 787 status = RTEMS_UNSATISFIED;
790 788 }
791 789
792 790 return status;
793 791 }
794 792
795 793 int enter_mode_sbm2( unsigned int transitionCoarseTime )
796 794 {
797 795 /** This function is used to start the SBM2 mode.
798 796 *
799 797 * @param transitionCoarseTime is the requested transition time contained in the TC_LFR_ENTER_MODE
800 798 *
801 799 * @return RTEMS directive status codes:
802 800 * - RTEMS_SUCCESSFUL - task restarted successfully
803 801 * - RTEMS_INVALID_ID - task id invalid
804 802 * - RTEMS_INCORRECT_STATE - task never started
805 803 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
806 804 *
807 805 * The way the SBM2 mode is started depends on the LFR current mode. If LFR is in NORMAL or SBM1,
808 806 * the snapshots are not restarted, only ASM, BP and CWF data generation are affected. In other
809 807 * cases, the acquisition is completely restarted.
810 808 *
811 809 */
812 810
813 811 int status;
814 812
815 813 #ifdef PRINT_TASK_STATISTICS
816 814 rtems_cpu_usage_reset();
817 815 #endif
818 816
819 817 status = RTEMS_UNSATISFIED;
820 818
821 819 switch( lfrCurrentMode )
822 820 {
823 821 case LFR_MODE_STANDBY:
824 822 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart science tasks
825 823 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
826 824 {
827 825 launch_spectral_matrix( );
828 826 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
829 827 }
830 828 break;
831 829 case LFR_MODE_NORMAL:
832 830 restart_asm_activities( LFR_MODE_SBM2 );
833 831 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
834 832 break;
835 833 case LFR_MODE_BURST:
836 834 status = stop_current_mode(); // stop the current mode
837 835 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart the science tasks
838 836 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
839 837 {
840 838 launch_spectral_matrix( );
841 839 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
842 840 }
843 841 break;
844 842 case LFR_MODE_SBM1:
845 843 restart_asm_activities( LFR_MODE_SBM2 );
846 844 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
847 845 break;
848 846 default:
849 847 break;
850 848 }
851 849
852 850 if (status != RTEMS_SUCCESSFUL)
853 851 {
854 852 PRINTF1("ERR *** in enter_mode_sbm2 *** status = %d\n", status)
855 853 status = RTEMS_UNSATISFIED;
856 854 }
857 855
858 856 return status;
859 857 }
860 858
861 859 int restart_science_tasks( unsigned char lfrRequestedMode )
862 860 {
863 861 /** This function is used to restart all science tasks.
864 862 *
865 863 * @return RTEMS directive status codes:
866 864 * - RTEMS_SUCCESSFUL - task restarted successfully
867 865 * - RTEMS_INVALID_ID - task id invalid
868 866 * - RTEMS_INCORRECT_STATE - task never started
869 867 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
870 868 *
871 869 * Science tasks are AVF0, PRC0, WFRM, CWF3, CW2, CWF1
872 870 *
873 871 */
874 872
875 873 rtems_status_code status[10];
876 874 rtems_status_code ret;
877 875
878 876 ret = RTEMS_SUCCESSFUL;
879 877
880 878 status[0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
881 879 if (status[0] != RTEMS_SUCCESSFUL)
882 880 {
883 881 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[0])
884 882 }
885 883
886 884 status[1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
887 885 if (status[1] != RTEMS_SUCCESSFUL)
888 886 {
889 887 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[1])
890 888 }
891 889
892 890 status[2] = rtems_task_restart( Task_id[TASKID_WFRM],1 );
893 891 if (status[2] != RTEMS_SUCCESSFUL)
894 892 {
895 893 PRINTF1("in restart_science_task *** WFRM ERR %d\n", status[2])
896 894 }
897 895
898 896 status[3] = rtems_task_restart( Task_id[TASKID_CWF3],1 );
899 897 if (status[3] != RTEMS_SUCCESSFUL)
900 898 {
901 899 PRINTF1("in restart_science_task *** CWF3 ERR %d\n", status[3])
902 900 }
903 901
904 902 status[4] = rtems_task_restart( Task_id[TASKID_CWF2],1 );
905 903 if (status[4] != RTEMS_SUCCESSFUL)
906 904 {
907 905 PRINTF1("in restart_science_task *** CWF2 ERR %d\n", status[4])
908 906 }
909 907
910 908 status[5] = rtems_task_restart( Task_id[TASKID_CWF1],1 );
911 909 if (status[5] != RTEMS_SUCCESSFUL)
912 910 {
913 911 PRINTF1("in restart_science_task *** CWF1 ERR %d\n", status[5])
914 912 }
915 913
916 914 status[6] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
917 915 if (status[6] != RTEMS_SUCCESSFUL)
918 916 {
919 917 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[6])
920 918 }
921 919
922 920 status[7] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
923 921 if (status[7] != RTEMS_SUCCESSFUL)
924 922 {
925 923 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[7])
926 924 }
927 925
928 926 status[8] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
929 927 if (status[8] != RTEMS_SUCCESSFUL)
930 928 {
931 929 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[8])
932 930 }
933 931
934 932 status[9] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
935 933 if (status[9] != RTEMS_SUCCESSFUL)
936 934 {
937 935 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[9])
938 936 }
939 937
940 938 if ( (status[0] != RTEMS_SUCCESSFUL) || (status[1] != RTEMS_SUCCESSFUL) ||
941 939 (status[2] != RTEMS_SUCCESSFUL) || (status[3] != RTEMS_SUCCESSFUL) ||
942 940 (status[4] != RTEMS_SUCCESSFUL) || (status[5] != RTEMS_SUCCESSFUL) ||
943 941 (status[6] != RTEMS_SUCCESSFUL) || (status[7] != RTEMS_SUCCESSFUL) ||
944 942 (status[8] != RTEMS_SUCCESSFUL) || (status[9] != RTEMS_SUCCESSFUL) )
945 943 {
946 944 ret = RTEMS_UNSATISFIED;
947 945 }
948 946
949 947 return ret;
950 948 }
951 949
952 950 int restart_asm_tasks( unsigned char lfrRequestedMode )
953 951 {
954 952 /** This function is used to restart average spectral matrices tasks.
955 953 *
956 954 * @return RTEMS directive status codes:
957 955 * - RTEMS_SUCCESSFUL - task restarted successfully
958 956 * - RTEMS_INVALID_ID - task id invalid
959 957 * - RTEMS_INCORRECT_STATE - task never started
960 958 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
961 959 *
962 960 * ASM tasks are AVF0, PRC0, AVF1, PRC1, AVF2 and PRC2
963 961 *
964 962 */
965 963
966 964 rtems_status_code status[6];
967 965 rtems_status_code ret;
968 966
969 967 ret = RTEMS_SUCCESSFUL;
970 968
971 969 status[0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
972 970 if (status[0] != RTEMS_SUCCESSFUL)
973 971 {
974 972 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[0])
975 973 }
976 974
977 975 status[1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
978 976 if (status[1] != RTEMS_SUCCESSFUL)
979 977 {
980 978 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[1])
981 979 }
982 980
983 981 status[2] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
984 982 if (status[2] != RTEMS_SUCCESSFUL)
985 983 {
986 984 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[2])
987 985 }
988 986
989 987 status[3] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
990 988 if (status[3] != RTEMS_SUCCESSFUL)
991 989 {
992 990 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[3])
993 991 }
994 992
995 993 status[4] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
996 994 if (status[4] != RTEMS_SUCCESSFUL)
997 995 {
998 996 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[4])
999 997 }
1000 998
1001 999 status[5] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
1002 1000 if (status[5] != RTEMS_SUCCESSFUL)
1003 1001 {
1004 1002 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[5])
1005 1003 }
1006 1004
1007 1005 if ( (status[0] != RTEMS_SUCCESSFUL) || (status[1] != RTEMS_SUCCESSFUL) ||
1008 1006 (status[2] != RTEMS_SUCCESSFUL) || (status[3] != RTEMS_SUCCESSFUL) ||
1009 1007 (status[4] != RTEMS_SUCCESSFUL) || (status[5] != RTEMS_SUCCESSFUL) )
1010 1008 {
1011 1009 ret = RTEMS_UNSATISFIED;
1012 1010 }
1013 1011
1014 1012 return ret;
1015 1013 }
1016 1014
1017 1015 int suspend_science_tasks( void )
1018 1016 {
1019 1017 /** This function suspends the science tasks.
1020 1018 *
1021 1019 * @return RTEMS directive status codes:
1022 1020 * - RTEMS_SUCCESSFUL - task restarted successfully
1023 1021 * - RTEMS_INVALID_ID - task id invalid
1024 1022 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1025 1023 *
1026 1024 */
1027 1025
1028 1026 rtems_status_code status;
1029 1027
1030 1028 PRINTF("in suspend_science_tasks\n")
1031 1029
1032 1030 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1033 1031 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1034 1032 {
1035 1033 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1036 1034 }
1037 1035 else
1038 1036 {
1039 1037 status = RTEMS_SUCCESSFUL;
1040 1038 }
1041 1039 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1042 1040 {
1043 1041 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1044 1042 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1045 1043 {
1046 1044 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1047 1045 }
1048 1046 else
1049 1047 {
1050 1048 status = RTEMS_SUCCESSFUL;
1051 1049 }
1052 1050 }
1053 1051 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1054 1052 {
1055 1053 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1056 1054 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1057 1055 {
1058 1056 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1059 1057 }
1060 1058 else
1061 1059 {
1062 1060 status = RTEMS_SUCCESSFUL;
1063 1061 }
1064 1062 }
1065 1063 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1066 1064 {
1067 1065 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1068 1066 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1069 1067 {
1070 1068 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1071 1069 }
1072 1070 else
1073 1071 {
1074 1072 status = RTEMS_SUCCESSFUL;
1075 1073 }
1076 1074 }
1077 1075 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1078 1076 {
1079 1077 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1080 1078 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1081 1079 {
1082 1080 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1083 1081 }
1084 1082 else
1085 1083 {
1086 1084 status = RTEMS_SUCCESSFUL;
1087 1085 }
1088 1086 }
1089 1087 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1090 1088 {
1091 1089 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1092 1090 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1093 1091 {
1094 1092 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1095 1093 }
1096 1094 else
1097 1095 {
1098 1096 status = RTEMS_SUCCESSFUL;
1099 1097 }
1100 1098 }
1101 1099 if (status == RTEMS_SUCCESSFUL) // suspend WFRM
1102 1100 {
1103 1101 status = rtems_task_suspend( Task_id[TASKID_WFRM] );
1104 1102 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1105 1103 {
1106 1104 PRINTF1("in suspend_science_task *** WFRM ERR %d\n", status)
1107 1105 }
1108 1106 else
1109 1107 {
1110 1108 status = RTEMS_SUCCESSFUL;
1111 1109 }
1112 1110 }
1113 1111 if (status == RTEMS_SUCCESSFUL) // suspend CWF3
1114 1112 {
1115 1113 status = rtems_task_suspend( Task_id[TASKID_CWF3] );
1116 1114 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1117 1115 {
1118 1116 PRINTF1("in suspend_science_task *** CWF3 ERR %d\n", status)
1119 1117 }
1120 1118 else
1121 1119 {
1122 1120 status = RTEMS_SUCCESSFUL;
1123 1121 }
1124 1122 }
1125 1123 if (status == RTEMS_SUCCESSFUL) // suspend CWF2
1126 1124 {
1127 1125 status = rtems_task_suspend( Task_id[TASKID_CWF2] );
1128 1126 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1129 1127 {
1130 1128 PRINTF1("in suspend_science_task *** CWF2 ERR %d\n", status)
1131 1129 }
1132 1130 else
1133 1131 {
1134 1132 status = RTEMS_SUCCESSFUL;
1135 1133 }
1136 1134 }
1137 1135 if (status == RTEMS_SUCCESSFUL) // suspend CWF1
1138 1136 {
1139 1137 status = rtems_task_suspend( Task_id[TASKID_CWF1] );
1140 1138 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1141 1139 {
1142 1140 PRINTF1("in suspend_science_task *** CWF1 ERR %d\n", status)
1143 1141 }
1144 1142 else
1145 1143 {
1146 1144 status = RTEMS_SUCCESSFUL;
1147 1145 }
1148 1146 }
1149 1147
1150 1148 return status;
1151 1149 }
1152 1150
1153 1151 int suspend_asm_tasks( void )
1154 1152 {
1155 1153 /** This function suspends the science tasks.
1156 1154 *
1157 1155 * @return RTEMS directive status codes:
1158 1156 * - RTEMS_SUCCESSFUL - task restarted successfully
1159 1157 * - RTEMS_INVALID_ID - task id invalid
1160 1158 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1161 1159 *
1162 1160 */
1163 1161
1164 1162 rtems_status_code status;
1165 1163
1166 1164 PRINTF("in suspend_science_tasks\n")
1167 1165
1168 1166 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1169 1167 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1170 1168 {
1171 1169 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1172 1170 }
1173 1171 else
1174 1172 {
1175 1173 status = RTEMS_SUCCESSFUL;
1176 1174 }
1177 1175
1178 1176 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1179 1177 {
1180 1178 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1181 1179 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1182 1180 {
1183 1181 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1184 1182 }
1185 1183 else
1186 1184 {
1187 1185 status = RTEMS_SUCCESSFUL;
1188 1186 }
1189 1187 }
1190 1188
1191 1189 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1192 1190 {
1193 1191 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1194 1192 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1195 1193 {
1196 1194 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1197 1195 }
1198 1196 else
1199 1197 {
1200 1198 status = RTEMS_SUCCESSFUL;
1201 1199 }
1202 1200 }
1203 1201
1204 1202 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1205 1203 {
1206 1204 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1207 1205 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1208 1206 {
1209 1207 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1210 1208 }
1211 1209 else
1212 1210 {
1213 1211 status = RTEMS_SUCCESSFUL;
1214 1212 }
1215 1213 }
1216 1214
1217 1215 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1218 1216 {
1219 1217 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1220 1218 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1221 1219 {
1222 1220 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1223 1221 }
1224 1222 else
1225 1223 {
1226 1224 status = RTEMS_SUCCESSFUL;
1227 1225 }
1228 1226 }
1229 1227
1230 1228 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1231 1229 {
1232 1230 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1233 1231 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1234 1232 {
1235 1233 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1236 1234 }
1237 1235 else
1238 1236 {
1239 1237 status = RTEMS_SUCCESSFUL;
1240 1238 }
1241 1239 }
1242 1240
1243 1241 return status;
1244 1242 }
1245 1243
1246 1244 void launch_waveform_picker( unsigned char mode, unsigned int transitionCoarseTime )
1247 1245 {
1248 1246 WFP_reset_current_ring_nodes();
1249 1247
1250 1248 reset_waveform_picker_regs();
1251 1249
1252 1250 set_wfp_burst_enable_register( mode );
1253 1251
1254 1252 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER );
1255 1253 LEON_Unmask_interrupt( IRQ_WAVEFORM_PICKER );
1256 1254
1257 1255 if (transitionCoarseTime == 0)
1258 1256 {
1259 1257 // instant transition means transition on the next valid date
1260 1258 // this is mandatory to have a good snapshot period a a good correction of the snapshot period
1261 1259 waveform_picker_regs->start_date = time_management_regs->coarse_time + 1;
1262 1260 }
1263 1261 else
1264 1262 {
1265 1263 waveform_picker_regs->start_date = transitionCoarseTime;
1266 1264 }
1267 1265
1268 1266 }
1269 1267
1270 1268 void launch_spectral_matrix( void )
1271 1269 {
1272 1270 SM_reset_current_ring_nodes();
1273 1271
1274 1272 reset_spectral_matrix_regs();
1275 1273
1276 1274 reset_nb_sm();
1277 1275
1278 1276 set_sm_irq_onNewMatrix( 1 );
1279 1277
1280 1278 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX );
1281 1279 LEON_Unmask_interrupt( IRQ_SPECTRAL_MATRIX );
1282 1280
1283 1281 }
1284 1282
1285 1283 void set_sm_irq_onNewMatrix( unsigned char value )
1286 1284 {
1287 1285 if (value == 1)
1288 1286 {
1289 1287 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x01;
1290 1288 }
1291 1289 else
1292 1290 {
1293 1291 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffe; // 1110
1294 1292 }
1295 1293 }
1296 1294
1297 1295 void set_sm_irq_onError( unsigned char value )
1298 1296 {
1299 1297 if (value == 1)
1300 1298 {
1301 1299 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x02;
1302 1300 }
1303 1301 else
1304 1302 {
1305 1303 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffd; // 1101
1306 1304 }
1307 1305 }
1308 1306
1309 1307 //*****************************
1310 1308 // CONFIGURE CALIBRATION SIGNAL
1311 1309 void setCalibrationPrescaler( unsigned int prescaler )
1312 1310 {
1313 1311 // prescaling of the master clock (25 MHz)
1314 1312 // master clock is divided by 2^prescaler
1315 1313 time_management_regs->calPrescaler = prescaler;
1316 1314 }
1317 1315
1318 1316 void setCalibrationDivisor( unsigned int divisionFactor )
1319 1317 {
1320 1318 // division of the prescaled clock by the division factor
1321 1319 time_management_regs->calDivisor = divisionFactor;
1322 1320 }
1323 1321
1324 1322 void setCalibrationData( void ){
1325 1323 unsigned int k;
1326 1324 unsigned short data;
1327 1325 float val;
1328 1326 float f0;
1329 1327 float f1;
1330 1328 float fs;
1331 1329 float Ts;
1332 1330 float scaleFactor;
1333 1331
1334 1332 f0 = 625;
1335 1333 f1 = 10000;
1336 1334 fs = 160256.410;
1337 1335 Ts = 1. / fs;
1338 1336 scaleFactor = 0.250 / 0.000654; // 191, 500 mVpp, 2 sinus waves => 500 mVpp each, amplitude = 250 mV
1339 1337
1340 1338 time_management_regs->calDataPtr = 0x00;
1341 1339
1342 1340 // build the signal for the SCM calibration
1343 1341 for (k=0; k<256; k++)
1344 1342 {
1345 1343 val = sin( 2 * pi * f0 * k * Ts )
1346 1344 + sin( 2 * pi * f1 * k * Ts );
1347 1345 data = (unsigned short) ((val * scaleFactor) + 2048);
1348 1346 time_management_regs->calData = data & 0xfff;
1349 1347 }
1350 1348 }
1351 1349
1352 1350 void setCalibrationDataInterleaved( void ){
1353 1351 unsigned int k;
1354 1352 float val;
1355 1353 float f0;
1356 1354 float f1;
1357 1355 float fs;
1358 1356 float Ts;
1359 1357 unsigned short data[384];
1360 1358 unsigned char *dataPtr;
1361 1359
1362 1360 f0 = 625;
1363 1361 f1 = 10000;
1364 1362 fs = 240384.615;
1365 1363 Ts = 1. / fs;
1366 1364
1367 1365 time_management_regs->calDataPtr = 0x00;
1368 1366
1369 1367 // build the signal for the SCM calibration
1370 1368 for (k=0; k<384; k++)
1371 1369 {
1372 1370 val = sin( 2 * pi * f0 * k * Ts )
1373 1371 + sin( 2 * pi * f1 * k * Ts );
1374 1372 data[k] = (unsigned short) (val * 512 + 2048);
1375 1373 }
1376 1374
1377 1375 // write the signal in interleaved mode
1378 1376 for (k=0; k<128; k++)
1379 1377 {
1380 1378 dataPtr = (unsigned char*) &data[k*3 + 2];
1381 1379 time_management_regs->calData = (data[k*3] & 0xfff)
1382 1380 + ( (dataPtr[0] & 0x3f) << 12);
1383 1381 time_management_regs->calData = (data[k*3 + 1] & 0xfff)
1384 1382 + ( (dataPtr[1] & 0x3f) << 12);
1385 1383 }
1386 1384 }
1387 1385
1388 1386 void setCalibrationReload( bool state)
1389 1387 {
1390 1388 if (state == true)
1391 1389 {
1392 1390 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000010; // [0001 0000]
1393 1391 }
1394 1392 else
1395 1393 {
1396 1394 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffef; // [1110 1111]
1397 1395 }
1398 1396 }
1399 1397
1400 1398 void setCalibrationEnable( bool state )
1401 1399 {
1402 1400 // this bit drives the multiplexer
1403 1401 if (state == true)
1404 1402 {
1405 1403 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000040; // [0100 0000]
1406 1404 }
1407 1405 else
1408 1406 {
1409 1407 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffbf; // [1011 1111]
1410 1408 }
1411 1409 }
1412 1410
1413 1411 void setCalibrationInterleaved( bool state )
1414 1412 {
1415 1413 // this bit drives the multiplexer
1416 1414 if (state == true)
1417 1415 {
1418 1416 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000020; // [0010 0000]
1419 1417 }
1420 1418 else
1421 1419 {
1422 1420 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffdf; // [1101 1111]
1423 1421 }
1424 1422 }
1425 1423
1426 1424 void setCalibration( bool state )
1427 1425 {
1428 1426 if (state == true)
1429 1427 {
1430 1428 setCalibrationEnable( true );
1431 1429 setCalibrationReload( false );
1432 1430 set_hk_lfr_calib_enable( true );
1433 1431 }
1434 1432 else
1435 1433 {
1436 1434 setCalibrationEnable( false );
1437 1435 setCalibrationReload( true );
1438 1436 set_hk_lfr_calib_enable( false );
1439 1437 }
1440 1438 }
1441 1439
1442 1440 void configureCalibration( bool interleaved )
1443 1441 {
1444 1442 setCalibration( false );
1445 1443 if ( interleaved == true )
1446 1444 {
1447 1445 setCalibrationInterleaved( true );
1448 1446 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1449 1447 setCalibrationDivisor( 26 ); // => 240 384
1450 1448 setCalibrationDataInterleaved();
1451 1449 }
1452 1450 else
1453 1451 {
1454 1452 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1455 1453 setCalibrationDivisor( 38 ); // => 160 256 (39 - 1)
1456 1454 setCalibrationData();
1457 1455 }
1458 1456 }
1459 1457
1460 1458 //****************
1461 1459 // CLOSING ACTIONS
1462 1460 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC, unsigned char * time )
1463 1461 {
1464 1462 /** This function is used to update the HK packets statistics after a successful TC execution.
1465 1463 *
1466 1464 * @param TC points to the TC being processed
1467 1465 * @param time is the time used to date the TC execution
1468 1466 *
1469 1467 */
1470 1468
1471 1469 unsigned int val;
1472 1470
1473 1471 housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
1474 1472 housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
1475 1473 housekeeping_packet.hk_lfr_last_exe_tc_type[0] = 0x00;
1476 1474 housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
1477 1475 housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = 0x00;
1478 1476 housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
1479 1477 housekeeping_packet.hk_lfr_last_exe_tc_time[0] = time[0];
1480 1478 housekeeping_packet.hk_lfr_last_exe_tc_time[1] = time[1];
1481 1479 housekeeping_packet.hk_lfr_last_exe_tc_time[2] = time[2];
1482 1480 housekeeping_packet.hk_lfr_last_exe_tc_time[3] = time[3];
1483 1481 housekeeping_packet.hk_lfr_last_exe_tc_time[4] = time[4];
1484 1482 housekeeping_packet.hk_lfr_last_exe_tc_time[5] = time[5];
1485 1483
1486 1484 val = housekeeping_packet.hk_lfr_exe_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
1487 1485 val++;
1488 1486 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> 8);
1489 1487 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
1490 1488 }
1491 1489
1492 1490 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC, unsigned char * time )
1493 1491 {
1494 1492 /** This function is used to update the HK packets statistics after a TC rejection.
1495 1493 *
1496 1494 * @param TC points to the TC being processed
1497 1495 * @param time is the time used to date the TC rejection
1498 1496 *
1499 1497 */
1500 1498
1501 1499 unsigned int val;
1502 1500
1503 1501 housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
1504 1502 housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
1505 1503 housekeeping_packet.hk_lfr_last_rej_tc_type[0] = 0x00;
1506 1504 housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
1507 1505 housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = 0x00;
1508 1506 housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
1509 1507 housekeeping_packet.hk_lfr_last_rej_tc_time[0] = time[0];
1510 1508 housekeeping_packet.hk_lfr_last_rej_tc_time[1] = time[1];
1511 1509 housekeeping_packet.hk_lfr_last_rej_tc_time[2] = time[2];
1512 1510 housekeeping_packet.hk_lfr_last_rej_tc_time[3] = time[3];
1513 1511 housekeeping_packet.hk_lfr_last_rej_tc_time[4] = time[4];
1514 1512 housekeeping_packet.hk_lfr_last_rej_tc_time[5] = time[5];
1515 1513
1516 1514 val = housekeeping_packet.hk_lfr_rej_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
1517 1515 val++;
1518 1516 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> 8);
1519 1517 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
1520 1518 }
1521 1519
1522 1520 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id )
1523 1521 {
1524 1522 /** This function is the last step of the TC execution workflow.
1525 1523 *
1526 1524 * @param TC points to the TC being processed
1527 1525 * @param result is the result of the TC execution (LFR_SUCCESSFUL / LFR_DEFAULT)
1528 1526 * @param queue_id is the id of the RTEMS message queue used to send TM packets
1529 1527 * @param time is the time used to date the TC execution
1530 1528 *
1531 1529 */
1532 1530
1533 1531 unsigned char requestedMode;
1534 1532
1535 1533 if (result == LFR_SUCCESSFUL)
1536 1534 {
1537 1535 if ( !( (TC->serviceType==TC_TYPE_TIME) & (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
1538 1536 &
1539 1537 !( (TC->serviceType==TC_TYPE_GEN) & (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
1540 1538 )
1541 1539 {
1542 1540 send_tm_lfr_tc_exe_success( TC, queue_id );
1543 1541 }
1544 1542 if ( (TC->serviceType == TC_TYPE_GEN) & (TC->serviceSubType == TC_SUBTYPE_ENTER) )
1545 1543 {
1546 1544 //**********************************
1547 1545 // UPDATE THE LFRMODE LOCAL VARIABLE
1548 1546 requestedMode = TC->dataAndCRC[1];
1549 housekeeping_packet.lfr_status_word[0] = (unsigned char) ((requestedMode << 4) + 0x0d);
1550 updateLFRCurrentMode();
1547 updateLFRCurrentMode( requestedMode );
1551 1548 }
1552 1549 }
1553 1550 else if (result == LFR_EXE_ERROR)
1554 1551 {
1555 1552 send_tm_lfr_tc_exe_error( TC, queue_id );
1556 1553 }
1557 1554 }
1558 1555
1559 1556 //***************************
1560 1557 // Interrupt Service Routines
1561 1558 rtems_isr commutation_isr1( rtems_vector_number vector )
1562 1559 {
1563 1560 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1564 1561 PRINTF("In commutation_isr1 *** Error sending event to DUMB\n")
1565 1562 }
1566 1563 }
1567 1564
1568 1565 rtems_isr commutation_isr2( rtems_vector_number vector )
1569 1566 {
1570 1567 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1571 1568 PRINTF("In commutation_isr2 *** Error sending event to DUMB\n")
1572 1569 }
1573 1570 }
1574 1571
1575 1572 //****************
1576 1573 // OTHER FUNCTIONS
1577 void updateLFRCurrentMode()
1574 void updateLFRCurrentMode( unsigned char requestedMode )
1578 1575 {
1579 1576 /** This function updates the value of the global variable lfrCurrentMode.
1580 1577 *
1581 1578 * lfrCurrentMode is a parameter used by several functions to know in which mode LFR is running.
1582 1579 *
1583 1580 */
1581
1584 1582 // update the local value of lfrCurrentMode with the value contained in the housekeeping_packet structure
1585 lfrCurrentMode = (housekeeping_packet.lfr_status_word[0] & 0xf0) >> 4;
1583 housekeeping_packet.lfr_status_word[0] = (unsigned char) ((requestedMode << 4) + 0x0d);
1584 lfrCurrentMode = requestedMode;
1586 1585 }
1587 1586
1588 1587 void set_lfr_soft_reset( unsigned char value )
1589 1588 {
1590 1589 if (value == 1)
1591 1590 {
1592 1591 time_management_regs->ctrl = time_management_regs->ctrl | 0x00000004; // [0100]
1593 1592 }
1594 1593 else
1595 1594 {
1596 1595 time_management_regs->ctrl = time_management_regs->ctrl & 0xfffffffb; // [1011]
1597 1596 }
1598 1597 }
1599 1598
1600 1599 void reset_lfr( void )
1601 1600 {
1602 1601 set_lfr_soft_reset( 1 );
1603 1602
1604 1603 set_lfr_soft_reset( 0 );
1605 1604
1606 1605 set_hk_lfr_sc_potential_flag( true );
1607 1606 }
General Comments 0
You need to be logged in to leave comments. Login now