##// END OF EJS Templates
STAT task removec...
paul -
r239:1c5814170464 R3
parent child
Show More
@@ -1,2 +1,2
1 1 3081d1f9bb20b2b64a192585337a292a9804e0c5 LFR_basic-parameters
2 e1bf35e31e3c8c1d1448d2e485c71f5f1259615c header/lfr_common_headers
2 721463c11a484e6a3439e16c99f8bd27720b9265 header/lfr_common_headers
@@ -1,69 +1,77
1 1 #ifndef FSW_MISC_H_INCLUDED
2 2 #define FSW_MISC_H_INCLUDED
3 3
4 4 #include <rtems.h>
5 5 #include <stdio.h>
6 6 #include <grspw.h>
7 7 #include <grlib_regs.h>
8 8
9 9 #include "fsw_params.h"
10 10 #include "fsw_spacewire.h"
11 11 #include "lfr_cpu_usage_report.h"
12 12
13 13 enum lfr_reset_cause_t{
14 14 UNKNOWN_CAUSE,
15 15 POWER_ON,
16 16 TC_RESET,
17 17 WATCHDOG,
18 18 ERROR_RESET,
19 19 UNEXP_RESET
20 20 };
21 21
22 extern gptimer_regs_t *gptimer_regs;
23
22 24 #define LFR_RESET_CAUSE_UNKNOWN_CAUSE 0
23 25
24 rtems_name name_hk_rate_monotonic; // name of the HK rate monotonic
25 rtems_id HK_id; // id of the HK rate monotonic period
26 rtems_name name_hk_rate_monotonic; // name of the HK rate monotonic
27 rtems_id HK_id; // id of the HK rate monotonic period
26 28
27 void configure_timer(gptimer_regs_t *gptimer_regs, unsigned char timer, unsigned int clock_divider,
29 void timer_configure( unsigned char timer, unsigned int clock_divider,
28 30 unsigned char interrupt_level, rtems_isr (*timer_isr)() );
29 void timer_start( gptimer_regs_t *gptimer_regs, unsigned char timer );
30 void timer_stop( gptimer_regs_t *gptimer_regs, unsigned char timer );
31 void timer_set_clock_divider(gptimer_regs_t *gptimer_regs, unsigned char timer, unsigned int clock_divider);
31 void timer_start( unsigned char timer );
32 void timer_stop( unsigned char timer );
33 void timer_set_clock_divider(unsigned char timer, unsigned int clock_divider);
34
35 // WATCHDOG
36 rtems_isr watchdog_isr( rtems_vector_number vector );
37 void watchdog_configure(void);
38 void watchdog_stop(void);
39 void watchdog_start(void);
32 40
33 41 // SERIAL LINK
34 42 int send_console_outputs_on_apbuart_port( void );
35 43 int enable_apbuart_transmitter( void );
36 44 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value);
37 45
38 46 // RTEMS TASKS
39 rtems_task stat_task( rtems_task_argument argument );
47 rtems_task load_task( rtems_task_argument argument );
40 48 rtems_task hous_task( rtems_task_argument argument );
41 49 rtems_task dumb_task( rtems_task_argument unused );
42 50
43 51 void init_housekeeping_parameters( void );
44 52 void increment_seq_counter(unsigned short *packetSequenceControl);
45 53 void getTime( unsigned char *time);
46 54 unsigned long long int getTimeAsUnsignedLongLongInt( );
47 55 void send_dumb_hk( void );
48 56 void get_temperatures( unsigned char *temperatures );
49 57 void get_v_e1_e2_f3( unsigned char *spacecraft_potential );
50 58 void get_cpu_load( unsigned char *resource_statistics );
51 59 void set_hk_lfr_sc_potential_flag( bool state );
52 60 void set_hk_lfr_mag_fields_flag( bool state );
53 61 void set_hk_lfr_calib_enable( bool state );
54 62 void set_hk_lfr_reset_cause( enum lfr_reset_cause_t lfr_reset_cause );
55 63
56 64 extern int sched_yield( void );
57 65 extern void rtems_cpu_usage_reset();
58 66 extern ring_node *current_ring_node_f3;
59 67 extern ring_node *ring_node_to_send_cwf_f3;
60 68 extern ring_node waveform_ring_f3[];
61 69 extern unsigned short sequenceCounterHK;
62 70
63 71 extern unsigned char hk_lfr_q_sd_fifo_size_max;
64 72 extern unsigned char hk_lfr_q_rv_fifo_size_max;
65 73 extern unsigned char hk_lfr_q_p0_fifo_size_max;
66 74 extern unsigned char hk_lfr_q_p1_fifo_size_max;
67 75 extern unsigned char hk_lfr_q_p2_fifo_size_max;
68 76
69 77 #endif // FSW_MISC_H_INCLUDED
@@ -1,329 +1,327
1 1 #ifndef FSW_PROCESSING_H_INCLUDED
2 2 #define FSW_PROCESSING_H_INCLUDED
3 3
4 4 #include <rtems.h>
5 5 #include <grspw.h>
6 6 #include <math.h>
7 7 #include <stdlib.h> // abs() is in the stdlib
8 8 #include <stdio.h>
9 9 #include <math.h>
10 10 #include <grlib_regs.h>
11 11
12 12 #include "fsw_params.h"
13 13
14 14 typedef struct ring_node_asm
15 15 {
16 16 struct ring_node_asm *next;
17 17 float matrix[ TOTAL_SIZE_SM ];
18 18 unsigned int status;
19 19 } ring_node_asm;
20 20
21 21 typedef struct
22 22 {
23 23 unsigned char targetLogicalAddress;
24 24 unsigned char protocolIdentifier;
25 25 unsigned char reserved;
26 26 unsigned char userApplication;
27 27 unsigned char packetID[2];
28 28 unsigned char packetSequenceControl[2];
29 29 unsigned char packetLength[2];
30 30 // DATA FIELD HEADER
31 31 unsigned char spare1_pusVersion_spare2;
32 32 unsigned char serviceType;
33 33 unsigned char serviceSubType;
34 34 unsigned char destinationID;
35 35 unsigned char time[6];
36 36 // AUXILIARY HEADER
37 37 unsigned char sid;
38 38 unsigned char biaStatusInfo;
39 39 unsigned char sy_lfr_common_parameters_spare;
40 40 unsigned char sy_lfr_common_parameters;
41 41 unsigned char acquisitionTime[6];
42 42 unsigned char pa_lfr_bp_blk_nr[2];
43 43 // SOURCE DATA
44 44 unsigned char data[ 780 ]; // MAX size is 26 bins * 30 Bytes [TM_LFR_SCIENCE_BURST_BP2_F1]
45 45 } bp_packet;
46 46
47 47 typedef struct
48 48 {
49 49 unsigned char targetLogicalAddress;
50 50 unsigned char protocolIdentifier;
51 51 unsigned char reserved;
52 52 unsigned char userApplication;
53 53 unsigned char packetID[2];
54 54 unsigned char packetSequenceControl[2];
55 55 unsigned char packetLength[2];
56 56 // DATA FIELD HEADER
57 57 unsigned char spare1_pusVersion_spare2;
58 58 unsigned char serviceType;
59 59 unsigned char serviceSubType;
60 60 unsigned char destinationID;
61 61 unsigned char time[6];
62 62 // AUXILIARY HEADER
63 63 unsigned char sid;
64 64 unsigned char biaStatusInfo;
65 65 unsigned char sy_lfr_common_parameters_spare;
66 66 unsigned char sy_lfr_common_parameters;
67 67 unsigned char acquisitionTime[6];
68 68 unsigned char source_data_spare;
69 69 unsigned char pa_lfr_bp_blk_nr[2];
70 70 // SOURCE DATA
71 71 unsigned char data[ 143 ]; // 13 bins * 11 Bytes
72 72 } bp_packet_with_spare; // only for TM_LFR_SCIENCE_NORMAL_BP1_F0 and F1
73 73
74 74 typedef struct asm_msg
75 75 {
76 76 ring_node_asm *norm;
77 77 ring_node_asm *burst_sbm;
78 78 rtems_event_set event;
79 79 unsigned int coarseTimeNORM;
80 80 unsigned int fineTimeNORM;
81 81 unsigned int coarseTimeSBM;
82 82 unsigned int fineTimeSBM;
83 83 } asm_msg;
84 84
85 85 extern volatile int sm_f0[ ];
86 86 extern volatile int sm_f1[ ];
87 87 extern volatile int sm_f2[ ];
88 88
89 89 // parameters
90 90 extern struct param_local_str param_local;
91 91 extern Packet_TM_LFR_PARAMETER_DUMP_t parameter_dump_packet;
92 92
93 93 // registers
94 94 extern time_management_regs_t *time_management_regs;
95 95 extern volatile spectral_matrix_regs_t *spectral_matrix_regs;
96 96
97 97 extern rtems_name misc_name[5];
98 98 extern rtems_id Task_id[20]; /* array of task ids */
99 99
100 //
101 100 ring_node * getRingNodeForAveraging( unsigned char frequencyChannel);
102 101 // ISR
103 102 rtems_isr spectral_matrices_isr( rtems_vector_number vector );
104 rtems_isr spectral_matrices_isr_simu( rtems_vector_number vector );
105 103
106 104 //******************
107 105 // Spectral Matrices
108 106 void reset_nb_sm( void );
109 107 // SM
110 108 void SM_init_rings( void );
111 109 void SM_reset_current_ring_nodes( void );
112 110 // ASM
113 111 void ASM_generic_init_ring(ring_node_asm *ring, unsigned char nbNodes );
114 112
115 113 //*****************
116 114 // Basic Parameters
117 115
118 116 void BP_reset_current_ring_nodes( void );
119 117 void BP_init_header(bp_packet *packet,
120 118 unsigned int apid, unsigned char sid,
121 119 unsigned int packetLength , unsigned char blkNr);
122 120 void BP_init_header_with_spare(bp_packet_with_spare *packet,
123 121 unsigned int apid, unsigned char sid,
124 122 unsigned int packetLength, unsigned char blkNr );
125 123 void BP_send( char *data,
126 124 rtems_id queue_id ,
127 125 unsigned int nbBytesToSend , unsigned int sid );
128 126
129 127 //******************
130 128 // general functions
131 129 void reset_sm_status( void );
132 130 void reset_spectral_matrix_regs( void );
133 131 void set_time(unsigned char *time, unsigned char *timeInBuffer );
134 132 unsigned long long int get_acquisition_time( unsigned char *timePtr );
135 133 unsigned char getSID( rtems_event_set event );
136 134
137 135 extern rtems_status_code get_message_queue_id_prc1( rtems_id *queue_id );
138 136 extern rtems_status_code get_message_queue_id_prc2( rtems_id *queue_id );
139 137
140 138 //***************************************
141 139 // DEFINITIONS OF STATIC INLINE FUNCTIONS
142 140 static inline void SM_average(float *averaged_spec_mat_NORM, float *averaged_spec_mat_SBM,
143 141 ring_node *ring_node_tab[],
144 142 unsigned int nbAverageNORM, unsigned int nbAverageSBM,
145 143 asm_msg *msgForMATR );
146 144
147 145 static inline void SM_average_debug(float *averaged_spec_mat_NORM, float *averaged_spec_mat_SBM,
148 146 ring_node *ring_node_tab[],
149 147 unsigned int nbAverageNORM, unsigned int nbAverageSBM,
150 148 asm_msg *msgForMATR );
151 149
152 150 void ASM_patch( float *inputASM, float *outputASM );
153 151
154 152 void extractReImVectors(float *inputASM, float *outputASM, unsigned int asmComponent );
155 153
156 154 static inline void ASM_reorganize_and_divide(float *averaged_spec_mat, float *averaged_spec_mat_reorganized,
157 155 float divider );
158 156
159 157 static inline void ASM_compress_reorganize_and_divide(float *averaged_spec_mat, float *compressed_spec_mat,
160 158 float divider,
161 159 unsigned char nbBinsCompressedMatrix, unsigned char nbBinsToAverage , unsigned char ASMIndexStart);
162 160
163 161 static inline void ASM_convert(volatile float *input_matrix, char *output_matrix);
164 162
165 163 void SM_average( float *averaged_spec_mat_NORM, float *averaged_spec_mat_SBM,
166 164 ring_node *ring_node_tab[],
167 165 unsigned int nbAverageNORM, unsigned int nbAverageSBM,
168 166 asm_msg *msgForMATR )
169 167 {
170 168 float sum;
171 169 unsigned int i;
172 170
173 171 for(i=0; i<TOTAL_SIZE_SM; i++)
174 172 {
175 173 sum = ( (int *) (ring_node_tab[0]->buffer_address) ) [ i ]
176 174 + ( (int *) (ring_node_tab[1]->buffer_address) ) [ i ]
177 175 + ( (int *) (ring_node_tab[2]->buffer_address) ) [ i ]
178 176 + ( (int *) (ring_node_tab[3]->buffer_address) ) [ i ]
179 177 + ( (int *) (ring_node_tab[4]->buffer_address) ) [ i ]
180 178 + ( (int *) (ring_node_tab[5]->buffer_address) ) [ i ]
181 179 + ( (int *) (ring_node_tab[6]->buffer_address) ) [ i ]
182 180 + ( (int *) (ring_node_tab[7]->buffer_address) ) [ i ];
183 181
184 182 if ( (nbAverageNORM == 0) && (nbAverageSBM == 0) )
185 183 {
186 184 averaged_spec_mat_NORM[ i ] = sum;
187 185 averaged_spec_mat_SBM[ i ] = sum;
188 186 msgForMATR->coarseTimeNORM = ring_node_tab[0]->coarseTime;
189 187 msgForMATR->fineTimeNORM = ring_node_tab[0]->fineTime;
190 188 msgForMATR->coarseTimeSBM = ring_node_tab[0]->coarseTime;
191 189 msgForMATR->fineTimeSBM = ring_node_tab[0]->fineTime;
192 190 }
193 191 else if ( (nbAverageNORM != 0) && (nbAverageSBM != 0) )
194 192 {
195 193 averaged_spec_mat_NORM[ i ] = ( averaged_spec_mat_NORM[ i ] + sum );
196 194 averaged_spec_mat_SBM[ i ] = ( averaged_spec_mat_SBM[ i ] + sum );
197 195 }
198 196 else if ( (nbAverageNORM != 0) && (nbAverageSBM == 0) )
199 197 {
200 198 averaged_spec_mat_NORM[ i ] = ( averaged_spec_mat_NORM[ i ] + sum );
201 199 averaged_spec_mat_SBM[ i ] = sum;
202 200 msgForMATR->coarseTimeSBM = ring_node_tab[0]->coarseTime;
203 201 msgForMATR->fineTimeSBM = ring_node_tab[0]->fineTime;
204 202 }
205 203 else
206 204 {
207 205 averaged_spec_mat_NORM[ i ] = sum;
208 206 averaged_spec_mat_SBM[ i ] = ( averaged_spec_mat_SBM[ i ] + sum );
209 207 msgForMATR->coarseTimeNORM = ring_node_tab[0]->coarseTime;
210 208 msgForMATR->fineTimeNORM = ring_node_tab[0]->fineTime;
211 209 // PRINTF2("ERR *** in SM_average *** unexpected parameters %d %d\n", nbAverageNORM, nbAverageSBM)
212 210 }
213 211 }
214 212 }
215 213
216 214 void SM_average_debug( float *averaged_spec_mat_NORM, float *averaged_spec_mat_SBM,
217 215 ring_node *ring_node_tab[],
218 216 unsigned int nbAverageNORM, unsigned int nbAverageSBM,
219 217 asm_msg *msgForMATR )
220 218 {
221 219 float sum;
222 220 unsigned int i;
223 221
224 222 for(i=0; i<TOTAL_SIZE_SM; i++)
225 223 {
226 224 sum = ( (int *) (ring_node_tab[0]->buffer_address) ) [ i ];
227 225 averaged_spec_mat_NORM[ i ] = sum;
228 226 averaged_spec_mat_SBM[ i ] = sum;
229 227 msgForMATR->coarseTimeNORM = ring_node_tab[0]->coarseTime;
230 228 msgForMATR->fineTimeNORM = ring_node_tab[0]->fineTime;
231 229 msgForMATR->coarseTimeSBM = ring_node_tab[0]->coarseTime;
232 230 msgForMATR->fineTimeSBM = ring_node_tab[0]->fineTime;
233 231 }
234 232 }
235 233
236 234 void ASM_reorganize_and_divide( float *averaged_spec_mat, float *averaged_spec_mat_reorganized, float divider )
237 235 {
238 236 int frequencyBin;
239 237 int asmComponent;
240 238 unsigned int offsetASM;
241 239 unsigned int offsetASMReorganized;
242 240
243 241 // BUILD DATA
244 242 for (asmComponent = 0; asmComponent < NB_VALUES_PER_SM; asmComponent++)
245 243 {
246 244 for( frequencyBin = 0; frequencyBin < NB_BINS_PER_SM; frequencyBin++ )
247 245 {
248 246 offsetASMReorganized =
249 247 frequencyBin * NB_VALUES_PER_SM
250 248 + asmComponent;
251 249 offsetASM =
252 250 asmComponent * NB_BINS_PER_SM
253 251 + frequencyBin;
254 252 averaged_spec_mat_reorganized[offsetASMReorganized ] =
255 253 averaged_spec_mat[ offsetASM ] / divider;
256 254 }
257 255 }
258 256 }
259 257
260 258 void ASM_compress_reorganize_and_divide(float *averaged_spec_mat, float *compressed_spec_mat , float divider,
261 259 unsigned char nbBinsCompressedMatrix, unsigned char nbBinsToAverage, unsigned char ASMIndexStart )
262 260 {
263 261 int frequencyBin;
264 262 int asmComponent;
265 263 int offsetASM;
266 264 int offsetCompressed;
267 265 int k;
268 266
269 267 // BUILD DATA
270 268 for (asmComponent = 0; asmComponent < NB_VALUES_PER_SM; asmComponent++)
271 269 {
272 270 for( frequencyBin = 0; frequencyBin < nbBinsCompressedMatrix; frequencyBin++ )
273 271 {
274 272 offsetCompressed = // NO TIME OFFSET
275 273 frequencyBin * NB_VALUES_PER_SM
276 274 + asmComponent;
277 275 offsetASM = // NO TIME OFFSET
278 276 asmComponent * NB_BINS_PER_SM
279 277 + ASMIndexStart
280 278 + frequencyBin * nbBinsToAverage;
281 279 compressed_spec_mat[ offsetCompressed ] = 0;
282 280 for ( k = 0; k < nbBinsToAverage; k++ )
283 281 {
284 282 compressed_spec_mat[offsetCompressed ] =
285 283 ( compressed_spec_mat[ offsetCompressed ]
286 284 + averaged_spec_mat[ offsetASM + k ] );
287 285 }
288 286 compressed_spec_mat[ offsetCompressed ] =
289 287 compressed_spec_mat[ offsetCompressed ] / (divider * nbBinsToAverage);
290 288 }
291 289 }
292 290 }
293 291
294 292 void ASM_convert( volatile float *input_matrix, char *output_matrix)
295 293 {
296 294 unsigned int frequencyBin;
297 295 unsigned int asmComponent;
298 296 char * pt_char_input;
299 297 char * pt_char_output;
300 298 unsigned int offsetInput;
301 299 unsigned int offsetOutput;
302 300
303 301 pt_char_input = (char*) &input_matrix;
304 302 pt_char_output = (char*) &output_matrix;
305 303
306 304 // convert all other data
307 305 for( frequencyBin=0; frequencyBin<NB_BINS_PER_SM; frequencyBin++)
308 306 {
309 307 for ( asmComponent=0; asmComponent<NB_VALUES_PER_SM; asmComponent++)
310 308 {
311 309 offsetInput = (frequencyBin*NB_VALUES_PER_SM) + asmComponent ;
312 310 offsetOutput = 2 * ( (frequencyBin*NB_VALUES_PER_SM) + asmComponent ) ;
313 311 pt_char_input = (char*) &input_matrix [ offsetInput ];
314 312 pt_char_output = (char*) &output_matrix[ offsetOutput ];
315 313 pt_char_output[0] = pt_char_input[0]; // bits 31 downto 24 of the float
316 314 pt_char_output[1] = pt_char_input[1]; // bits 23 downto 16 of the float
317 315 }
318 316 }
319 317 }
320 318
321 319 void ASM_compress_reorganize_and_divide_mask(float *averaged_spec_mat, float *compressed_spec_mat,
322 320 float divider,
323 321 unsigned char nbBinsCompressedMatrix, unsigned char nbBinsToAverage , unsigned char ASMIndexStart, unsigned char channel);
324 322
325 323 int getFBinMask(int k, unsigned char channel);
326 324
327 325 void init_kcoeff_sbm_from_kcoeff_norm( float *input_kcoeff, float *output_kcoeff, unsigned char nb_bins_norm);
328 326
329 327 #endif // FSW_PROCESSING_H_INCLUDED
@@ -1,872 +1,864
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 38 #define CONFIGURE_MAXIMUM_TIMERS 5 // STAT (1s), send SWF (0.3s), send CWF3 (1s)
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 unsigned int cacheControlRegister;
68 68
69 69 cacheControlRegister = getCacheControlRegister();
70 70 PRINTF1("(0) cacheControlRegister = %x\n", cacheControlRegister)
71 71
72 72 resetCacheControlRegister();
73 73
74 74 enableInstructionCache();
75 75 enableDataCache();
76 76 enableInstructionBurstFetch();
77 77
78 78 cacheControlRegister = getCacheControlRegister();
79 79 PRINTF1("(1) cacheControlRegister = %x\n", cacheControlRegister)
80 80 }
81 81
82 82 rtems_task Init( rtems_task_argument ignored )
83 83 {
84 84 /** This is the RTEMS INIT taks, it is the first task launched by the system.
85 85 *
86 86 * @param unused is the starting argument of the RTEMS task
87 87 *
88 88 * The INIT task create and run all other RTEMS tasks.
89 89 *
90 90 */
91 91
92 92 //***********
93 93 // INIT CACHE
94 94
95 95 unsigned char *vhdlVersion;
96 96
97 97 reset_lfr();
98 98
99 99 reset_local_time();
100 100
101 101 rtems_cpu_usage_reset();
102 102
103 103 rtems_status_code status;
104 104 rtems_status_code status_spw;
105 105 rtems_isr_entry old_isr_handler;
106 106
107 107 // UART settings
108 108 send_console_outputs_on_apbuart_port();
109 109 set_apbuart_scaler_reload_register(REGS_ADDR_APBUART, APBUART_SCALER_RELOAD_VALUE);
110 110 enable_apbuart_transmitter();
111 111
112 112 DEBUG_PRINTF("\n\n\n\n\nIn INIT *** Now the console is on port COM1\n")
113 113
114 114
115 115 PRINTF("\n\n\n\n\n")
116 116
117 117 initCache();
118 118
119 119 PRINTF("*************************\n")
120 120 PRINTF("** LFR Flight Software **\n")
121 121 PRINTF1("** %d.", SW_VERSION_N1)
122 122 PRINTF1("%d." , SW_VERSION_N2)
123 123 PRINTF1("%d." , SW_VERSION_N3)
124 124 PRINTF1("%d **\n", SW_VERSION_N4)
125 125
126 126 vhdlVersion = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
127 127 PRINTF("** VHDL **\n")
128 128 PRINTF1("** %d.", vhdlVersion[1])
129 129 PRINTF1("%d." , vhdlVersion[2])
130 130 PRINTF1("%d **\n", vhdlVersion[3])
131 131 PRINTF("*************************\n")
132 132 PRINTF("\n\n")
133 133
134 134 init_parameter_dump();
135 135 init_kcoefficients_dump();
136 136 init_local_mode_parameters();
137 137 init_housekeeping_parameters();
138 138 init_k_coefficients_prc0();
139 139 init_k_coefficients_prc1();
140 140 init_k_coefficients_prc2();
141 141 pa_bia_status_info = 0x00;
142 142
143 143 // waveform picker initialization
144 WFP_init_rings(); // initialize the waveform rings
144 WFP_init_rings(); LEON_Clear_interrupt( IRQ_SPARC_GPTIMER_WATCHDOG ); // initialize the waveform rings
145 145 WFP_reset_current_ring_nodes();
146 146 reset_waveform_picker_regs();
147 147
148 148 // spectral matrices initialization
149 149 SM_init_rings(); // initialize spectral matrices rings
150 150 SM_reset_current_ring_nodes();
151 151 reset_spectral_matrix_regs();
152 152
153 153 // configure calibration
154 154 configureCalibration( false ); // true means interleaved mode, false is for normal mode
155 155
156 156 updateLFRCurrentMode();
157 157
158 158 BOOT_PRINTF1("in INIT *** lfrCurrentMode is %d\n", lfrCurrentMode)
159 159
160 160 create_names(); // create all names
161 161
162 162 status = create_message_queues(); // create message queues
163 163 if (status != RTEMS_SUCCESSFUL)
164 164 {
165 165 PRINTF1("in INIT *** ERR in create_message_queues, code %d", status)
166 166 }
167 167
168 168 status = create_all_tasks(); // create all tasks
169 169 if (status != RTEMS_SUCCESSFUL)
170 170 {
171 171 PRINTF1("in INIT *** ERR in create_all_tasks, code %d\n", status)
172 172 }
173 173
174 174 // **************************
175 175 // <SPACEWIRE INITIALIZATION>
176 176 grspw_timecode_callback = &timecode_irq_handler;
177 177
178 178 status_spw = spacewire_open_link(); // (1) open the link
179 179 if ( status_spw != RTEMS_SUCCESSFUL )
180 180 {
181 181 PRINTF1("in INIT *** ERR spacewire_open_link code %d\n", status_spw )
182 182 }
183 183
184 184 if ( status_spw == RTEMS_SUCCESSFUL ) // (2) configure the link
185 185 {
186 186 status_spw = spacewire_configure_link( fdSPW );
187 187 if ( status_spw != RTEMS_SUCCESSFUL )
188 188 {
189 189 PRINTF1("in INIT *** ERR spacewire_configure_link code %d\n", status_spw )
190 190 }
191 191 }
192 192
193 193 if ( status_spw == RTEMS_SUCCESSFUL) // (3) start the link
194 194 {
195 195 status_spw = spacewire_start_link( fdSPW );
196 196 if ( status_spw != RTEMS_SUCCESSFUL )
197 197 {
198 198 PRINTF1("in INIT *** ERR spacewire_start_link code %d\n", status_spw )
199 199 }
200 200 }
201 201 // </SPACEWIRE INITIALIZATION>
202 202 // ***************************
203 203
204 204 status = start_all_tasks(); // start all tasks
205 205 if (status != RTEMS_SUCCESSFUL)
206 206 {
207 207 PRINTF1("in INIT *** ERR in start_all_tasks, code %d", status)
208 208 }
209 209
210 210 // start RECV and SEND *AFTER* SpaceWire Initialization, due to the timeout of the start call during the initialization
211 211 status = start_recv_send_tasks();
212 212 if ( status != RTEMS_SUCCESSFUL )
213 213 {
214 214 PRINTF1("in INIT *** ERR start_recv_send_tasks code %d\n", status )
215 215 }
216 216
217 217 // suspend science tasks, they will be restarted later depending on the mode
218 218 status = suspend_science_tasks(); // suspend science tasks (not done in stop_current_mode if current mode = STANDBY)
219 219 if (status != RTEMS_SUCCESSFUL)
220 220 {
221 221 PRINTF1("in INIT *** in suspend_science_tasks *** ERR code: %d\n", status)
222 222 }
223 223
224 //******************************
225 // <SPECTRAL MATRICES SIMULATOR>
226 LEON_Mask_interrupt( IRQ_SM_SIMULATOR );
227 configure_timer((gptimer_regs_t*) REGS_ADDR_GPTIMER, TIMER_SM_SIMULATOR, CLKDIV_SM_SIMULATOR,
228 IRQ_SPARC_SM_SIMULATOR, spectral_matrices_isr_simu );
229 // </SPECTRAL MATRICES SIMULATOR>
230 //*******************************
231
232 224 // configure IRQ handling for the waveform picker unit
233 225 status = rtems_interrupt_catch( waveforms_isr,
234 226 IRQ_SPARC_WAVEFORM_PICKER,
235 227 &old_isr_handler) ;
236 228 // configure IRQ handling for the spectral matrices unit
237 229 status = rtems_interrupt_catch( spectral_matrices_isr,
238 230 IRQ_SPARC_SPECTRAL_MATRIX,
239 231 &old_isr_handler) ;
240 232
241 233 // if the spacewire link is not up then send an event to the SPIQ task for link recovery
242 234 if ( status_spw != RTEMS_SUCCESSFUL )
243 235 {
244 236 status = rtems_event_send( Task_id[TASKID_SPIQ], SPW_LINKERR_EVENT );
245 237 if ( status != RTEMS_SUCCESSFUL ) {
246 238 PRINTF1("in INIT *** ERR rtems_event_send to SPIQ code %d\n", status )
247 239 }
248 240 }
249 241
250 242 BOOT_PRINTF("delete INIT\n")
251 243
252 244 set_hk_lfr_sc_potential_flag( true );
253 245
254 246 status = rtems_task_delete(RTEMS_SELF);
255 247
256 248 }
257 249
258 250 void init_local_mode_parameters( void )
259 251 {
260 252 /** This function initialize the param_local global variable with default values.
261 253 *
262 254 */
263 255
264 256 unsigned int i;
265 257
266 258 // LOCAL PARAMETERS
267 259
268 260 BOOT_PRINTF1("local_sbm1_nb_cwf_max %d \n", param_local.local_sbm1_nb_cwf_max)
269 261 BOOT_PRINTF1("local_sbm2_nb_cwf_max %d \n", param_local.local_sbm2_nb_cwf_max)
270 262 BOOT_PRINTF1("nb_interrupt_f0_MAX = %d\n", param_local.local_nb_interrupt_f0_MAX)
271 263
272 264 // init sequence counters
273 265
274 266 for(i = 0; i<SEQ_CNT_NB_DEST_ID; i++)
275 267 {
276 268 sequenceCounters_TC_EXE[i] = 0x00;
277 269 sequenceCounters_TM_DUMP[i] = 0x00;
278 270 }
279 271 sequenceCounters_SCIENCE_NORMAL_BURST = 0x00;
280 272 sequenceCounters_SCIENCE_SBM1_SBM2 = 0x00;
281 273 sequenceCounterHK = TM_PACKET_SEQ_CTRL_STANDALONE << 8;
282 274 }
283 275
284 276 void reset_local_time( void )
285 277 {
286 278 time_management_regs->ctrl = time_management_regs->ctrl | 0x02; // [0010] software reset, coarse time = 0x80000000
287 279 }
288 280
289 281 void create_names( void ) // create all names for tasks and queues
290 282 {
291 283 /** This function creates all RTEMS names used in the software for tasks and queues.
292 284 *
293 285 * @return RTEMS directive status codes:
294 286 * - RTEMS_SUCCESSFUL - successful completion
295 287 *
296 288 */
297 289
298 290 // task names
299 291 Task_name[TASKID_RECV] = rtems_build_name( 'R', 'E', 'C', 'V' );
300 292 Task_name[TASKID_ACTN] = rtems_build_name( 'A', 'C', 'T', 'N' );
301 293 Task_name[TASKID_SPIQ] = rtems_build_name( 'S', 'P', 'I', 'Q' );
302 Task_name[TASKID_STAT] = rtems_build_name( 'S', 'T', 'A', 'T' );
294 Task_name[TASKID_LOAD] = rtems_build_name( 'L', 'O', 'A', 'D' );
303 295 Task_name[TASKID_AVF0] = rtems_build_name( 'A', 'V', 'F', '0' );
304 296 Task_name[TASKID_SWBD] = rtems_build_name( 'S', 'W', 'B', 'D' );
305 297 Task_name[TASKID_WFRM] = rtems_build_name( 'W', 'F', 'R', 'M' );
306 298 Task_name[TASKID_DUMB] = rtems_build_name( 'D', 'U', 'M', 'B' );
307 299 Task_name[TASKID_HOUS] = rtems_build_name( 'H', 'O', 'U', 'S' );
308 300 Task_name[TASKID_PRC0] = rtems_build_name( 'P', 'R', 'C', '0' );
309 301 Task_name[TASKID_CWF3] = rtems_build_name( 'C', 'W', 'F', '3' );
310 302 Task_name[TASKID_CWF2] = rtems_build_name( 'C', 'W', 'F', '2' );
311 303 Task_name[TASKID_CWF1] = rtems_build_name( 'C', 'W', 'F', '1' );
312 304 Task_name[TASKID_SEND] = rtems_build_name( 'S', 'E', 'N', 'D' );
313 305 Task_name[TASKID_WTDG] = rtems_build_name( 'W', 'T', 'D', 'G' );
314 306 Task_name[TASKID_AVF1] = rtems_build_name( 'A', 'V', 'F', '1' );
315 307 Task_name[TASKID_PRC1] = rtems_build_name( 'P', 'R', 'C', '1' );
316 308 Task_name[TASKID_AVF2] = rtems_build_name( 'A', 'V', 'F', '2' );
317 309 Task_name[TASKID_PRC2] = rtems_build_name( 'P', 'R', 'C', '2' );
318 310
319 311 // rate monotonic period names
320 312 name_hk_rate_monotonic = rtems_build_name( 'H', 'O', 'U', 'S' );
321 313
322 314 misc_name[QUEUE_RECV] = rtems_build_name( 'Q', '_', 'R', 'V' );
323 315 misc_name[QUEUE_SEND] = rtems_build_name( 'Q', '_', 'S', 'D' );
324 316 misc_name[QUEUE_PRC0] = rtems_build_name( 'Q', '_', 'P', '0' );
325 317 misc_name[QUEUE_PRC1] = rtems_build_name( 'Q', '_', 'P', '1' );
326 318 misc_name[QUEUE_PRC2] = rtems_build_name( 'Q', '_', 'P', '2' );
327 319 }
328 320
329 321 int create_all_tasks( void ) // create all tasks which run in the software
330 322 {
331 323 /** This function creates all RTEMS tasks used in the software.
332 324 *
333 325 * @return RTEMS directive status codes:
334 326 * - RTEMS_SUCCESSFUL - task created successfully
335 327 * - RTEMS_INVALID_ADDRESS - id is NULL
336 328 * - RTEMS_INVALID_NAME - invalid task name
337 329 * - RTEMS_INVALID_PRIORITY - invalid task priority
338 330 * - RTEMS_MP_NOT_CONFIGURED - multiprocessing not configured
339 331 * - RTEMS_TOO_MANY - too many tasks created
340 332 * - RTEMS_UNSATISFIED - not enough memory for stack/FP context
341 333 * - RTEMS_TOO_MANY - too many global objects
342 334 *
343 335 */
344 336
345 337 rtems_status_code status;
346 338
347 339 //**********
348 340 // SPACEWIRE
349 341 // RECV
350 342 status = rtems_task_create(
351 343 Task_name[TASKID_RECV], TASK_PRIORITY_RECV, RTEMS_MINIMUM_STACK_SIZE,
352 344 RTEMS_DEFAULT_MODES,
353 345 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_RECV]
354 346 );
355 347 if (status == RTEMS_SUCCESSFUL) // SEND
356 348 {
357 349 status = rtems_task_create(
358 350 Task_name[TASKID_SEND], TASK_PRIORITY_SEND, RTEMS_MINIMUM_STACK_SIZE * 2,
359 351 RTEMS_DEFAULT_MODES,
360 352 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SEND]
361 353 );
362 354 }
363 355 if (status == RTEMS_SUCCESSFUL) // WTDG
364 356 {
365 357 status = rtems_task_create(
366 358 Task_name[TASKID_WTDG], TASK_PRIORITY_WTDG, RTEMS_MINIMUM_STACK_SIZE,
367 359 RTEMS_DEFAULT_MODES,
368 360 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_WTDG]
369 361 );
370 362 }
371 363 if (status == RTEMS_SUCCESSFUL) // ACTN
372 364 {
373 365 status = rtems_task_create(
374 366 Task_name[TASKID_ACTN], TASK_PRIORITY_ACTN, RTEMS_MINIMUM_STACK_SIZE,
375 367 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
376 368 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_ACTN]
377 369 );
378 370 }
379 371 if (status == RTEMS_SUCCESSFUL) // SPIQ
380 372 {
381 373 status = rtems_task_create(
382 374 Task_name[TASKID_SPIQ], TASK_PRIORITY_SPIQ, RTEMS_MINIMUM_STACK_SIZE,
383 375 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
384 376 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SPIQ]
385 377 );
386 378 }
387 379
388 380 //******************
389 381 // SPECTRAL MATRICES
390 382 if (status == RTEMS_SUCCESSFUL) // AVF0
391 383 {
392 384 status = rtems_task_create(
393 385 Task_name[TASKID_AVF0], TASK_PRIORITY_AVF0, RTEMS_MINIMUM_STACK_SIZE,
394 386 RTEMS_DEFAULT_MODES,
395 387 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF0]
396 388 );
397 389 }
398 390 if (status == RTEMS_SUCCESSFUL) // PRC0
399 391 {
400 392 status = rtems_task_create(
401 393 Task_name[TASKID_PRC0], TASK_PRIORITY_PRC0, RTEMS_MINIMUM_STACK_SIZE * 2,
402 394 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
403 395 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC0]
404 396 );
405 397 }
406 398 if (status == RTEMS_SUCCESSFUL) // AVF1
407 399 {
408 400 status = rtems_task_create(
409 401 Task_name[TASKID_AVF1], TASK_PRIORITY_AVF1, RTEMS_MINIMUM_STACK_SIZE,
410 402 RTEMS_DEFAULT_MODES,
411 403 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF1]
412 404 );
413 405 }
414 406 if (status == RTEMS_SUCCESSFUL) // PRC1
415 407 {
416 408 status = rtems_task_create(
417 409 Task_name[TASKID_PRC1], TASK_PRIORITY_PRC1, RTEMS_MINIMUM_STACK_SIZE * 2,
418 410 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
419 411 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC1]
420 412 );
421 413 }
422 414 if (status == RTEMS_SUCCESSFUL) // AVF2
423 415 {
424 416 status = rtems_task_create(
425 417 Task_name[TASKID_AVF2], TASK_PRIORITY_AVF2, RTEMS_MINIMUM_STACK_SIZE,
426 418 RTEMS_DEFAULT_MODES,
427 419 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF2]
428 420 );
429 421 }
430 422 if (status == RTEMS_SUCCESSFUL) // PRC2
431 423 {
432 424 status = rtems_task_create(
433 425 Task_name[TASKID_PRC2], TASK_PRIORITY_PRC2, RTEMS_MINIMUM_STACK_SIZE * 2,
434 426 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
435 427 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC2]
436 428 );
437 429 }
438 430
439 431 //****************
440 432 // WAVEFORM PICKER
441 433 if (status == RTEMS_SUCCESSFUL) // WFRM
442 434 {
443 435 status = rtems_task_create(
444 436 Task_name[TASKID_WFRM], TASK_PRIORITY_WFRM, RTEMS_MINIMUM_STACK_SIZE,
445 437 RTEMS_DEFAULT_MODES,
446 438 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_WFRM]
447 439 );
448 440 }
449 441 if (status == RTEMS_SUCCESSFUL) // CWF3
450 442 {
451 443 status = rtems_task_create(
452 444 Task_name[TASKID_CWF3], TASK_PRIORITY_CWF3, RTEMS_MINIMUM_STACK_SIZE,
453 445 RTEMS_DEFAULT_MODES,
454 446 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF3]
455 447 );
456 448 }
457 449 if (status == RTEMS_SUCCESSFUL) // CWF2
458 450 {
459 451 status = rtems_task_create(
460 452 Task_name[TASKID_CWF2], TASK_PRIORITY_CWF2, RTEMS_MINIMUM_STACK_SIZE,
461 453 RTEMS_DEFAULT_MODES,
462 454 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF2]
463 455 );
464 456 }
465 457 if (status == RTEMS_SUCCESSFUL) // CWF1
466 458 {
467 459 status = rtems_task_create(
468 460 Task_name[TASKID_CWF1], TASK_PRIORITY_CWF1, RTEMS_MINIMUM_STACK_SIZE,
469 461 RTEMS_DEFAULT_MODES,
470 462 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF1]
471 463 );
472 464 }
473 465 if (status == RTEMS_SUCCESSFUL) // SWBD
474 466 {
475 467 status = rtems_task_create(
476 468 Task_name[TASKID_SWBD], TASK_PRIORITY_SWBD, RTEMS_MINIMUM_STACK_SIZE,
477 469 RTEMS_DEFAULT_MODES,
478 470 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SWBD]
479 471 );
480 472 }
481 473
482 474 //*****
483 475 // MISC
484 if (status == RTEMS_SUCCESSFUL) // STAT
476 if (status == RTEMS_SUCCESSFUL) // LOAD
485 477 {
486 478 status = rtems_task_create(
487 Task_name[TASKID_STAT], TASK_PRIORITY_STAT, RTEMS_MINIMUM_STACK_SIZE,
479 Task_name[TASKID_LOAD], TASK_PRIORITY_LOAD, RTEMS_MINIMUM_STACK_SIZE,
488 480 RTEMS_DEFAULT_MODES,
489 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_STAT]
481 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_LOAD]
490 482 );
491 483 }
492 484 if (status == RTEMS_SUCCESSFUL) // DUMB
493 485 {
494 486 status = rtems_task_create(
495 487 Task_name[TASKID_DUMB], TASK_PRIORITY_DUMB, RTEMS_MINIMUM_STACK_SIZE,
496 488 RTEMS_DEFAULT_MODES,
497 489 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_DUMB]
498 490 );
499 491 }
500 492 if (status == RTEMS_SUCCESSFUL) // HOUS
501 493 {
502 494 status = rtems_task_create(
503 495 Task_name[TASKID_HOUS], TASK_PRIORITY_HOUS, RTEMS_MINIMUM_STACK_SIZE,
504 496 RTEMS_DEFAULT_MODES,
505 497 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_HOUS]
506 498 );
507 499 }
508 500
509 501 return status;
510 502 }
511 503
512 504 int start_recv_send_tasks( void )
513 505 {
514 506 rtems_status_code status;
515 507
516 508 status = rtems_task_start( Task_id[TASKID_RECV], recv_task, 1 );
517 509 if (status!=RTEMS_SUCCESSFUL) {
518 510 BOOT_PRINTF("in INIT *** Error starting TASK_RECV\n")
519 511 }
520 512
521 513 if (status == RTEMS_SUCCESSFUL) // SEND
522 514 {
523 515 status = rtems_task_start( Task_id[TASKID_SEND], send_task, 1 );
524 516 if (status!=RTEMS_SUCCESSFUL) {
525 517 BOOT_PRINTF("in INIT *** Error starting TASK_SEND\n")
526 518 }
527 519 }
528 520
529 521 return status;
530 522 }
531 523
532 524 int start_all_tasks( void ) // start all tasks except SEND RECV and HOUS
533 525 {
534 526 /** This function starts all RTEMS tasks used in the software.
535 527 *
536 528 * @return RTEMS directive status codes:
537 529 * - RTEMS_SUCCESSFUL - ask started successfully
538 530 * - RTEMS_INVALID_ADDRESS - invalid task entry point
539 531 * - RTEMS_INVALID_ID - invalid task id
540 532 * - RTEMS_INCORRECT_STATE - task not in the dormant state
541 533 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot start remote task
542 534 *
543 535 */
544 536 // starts all the tasks fot eh flight software
545 537
546 538 rtems_status_code status;
547 539
548 540 //**********
549 541 // SPACEWIRE
550 542 status = rtems_task_start( Task_id[TASKID_SPIQ], spiq_task, 1 );
551 543 if (status!=RTEMS_SUCCESSFUL) {
552 544 BOOT_PRINTF("in INIT *** Error starting TASK_SPIQ\n")
553 545 }
554 546
555 547 if (status == RTEMS_SUCCESSFUL) // WTDG
556 548 {
557 549 status = rtems_task_start( Task_id[TASKID_WTDG], wtdg_task, 1 );
558 550 if (status!=RTEMS_SUCCESSFUL) {
559 551 BOOT_PRINTF("in INIT *** Error starting TASK_WTDG\n")
560 552 }
561 553 }
562 554
563 555 if (status == RTEMS_SUCCESSFUL) // ACTN
564 556 {
565 557 status = rtems_task_start( Task_id[TASKID_ACTN], actn_task, 1 );
566 558 if (status!=RTEMS_SUCCESSFUL) {
567 559 BOOT_PRINTF("in INIT *** Error starting TASK_ACTN\n")
568 560 }
569 561 }
570 562
571 563 //******************
572 564 // SPECTRAL MATRICES
573 565 if (status == RTEMS_SUCCESSFUL) // AVF0
574 566 {
575 567 status = rtems_task_start( Task_id[TASKID_AVF0], avf0_task, LFR_MODE_STANDBY );
576 568 if (status!=RTEMS_SUCCESSFUL) {
577 569 BOOT_PRINTF("in INIT *** Error starting TASK_AVF0\n")
578 570 }
579 571 }
580 572 if (status == RTEMS_SUCCESSFUL) // PRC0
581 573 {
582 574 status = rtems_task_start( Task_id[TASKID_PRC0], prc0_task, LFR_MODE_STANDBY );
583 575 if (status!=RTEMS_SUCCESSFUL) {
584 576 BOOT_PRINTF("in INIT *** Error starting TASK_PRC0\n")
585 577 }
586 578 }
587 579 if (status == RTEMS_SUCCESSFUL) // AVF1
588 580 {
589 581 status = rtems_task_start( Task_id[TASKID_AVF1], avf1_task, LFR_MODE_STANDBY );
590 582 if (status!=RTEMS_SUCCESSFUL) {
591 583 BOOT_PRINTF("in INIT *** Error starting TASK_AVF1\n")
592 584 }
593 585 }
594 586 if (status == RTEMS_SUCCESSFUL) // PRC1
595 587 {
596 588 status = rtems_task_start( Task_id[TASKID_PRC1], prc1_task, LFR_MODE_STANDBY );
597 589 if (status!=RTEMS_SUCCESSFUL) {
598 590 BOOT_PRINTF("in INIT *** Error starting TASK_PRC1\n")
599 591 }
600 592 }
601 593 if (status == RTEMS_SUCCESSFUL) // AVF2
602 594 {
603 595 status = rtems_task_start( Task_id[TASKID_AVF2], avf2_task, 1 );
604 596 if (status!=RTEMS_SUCCESSFUL) {
605 597 BOOT_PRINTF("in INIT *** Error starting TASK_AVF2\n")
606 598 }
607 599 }
608 600 if (status == RTEMS_SUCCESSFUL) // PRC2
609 601 {
610 602 status = rtems_task_start( Task_id[TASKID_PRC2], prc2_task, 1 );
611 603 if (status!=RTEMS_SUCCESSFUL) {
612 604 BOOT_PRINTF("in INIT *** Error starting TASK_PRC2\n")
613 605 }
614 606 }
615 607
616 608 //****************
617 609 // WAVEFORM PICKER
618 610 if (status == RTEMS_SUCCESSFUL) // WFRM
619 611 {
620 612 status = rtems_task_start( Task_id[TASKID_WFRM], wfrm_task, 1 );
621 613 if (status!=RTEMS_SUCCESSFUL) {
622 614 BOOT_PRINTF("in INIT *** Error starting TASK_WFRM\n")
623 615 }
624 616 }
625 617 if (status == RTEMS_SUCCESSFUL) // CWF3
626 618 {
627 619 status = rtems_task_start( Task_id[TASKID_CWF3], cwf3_task, 1 );
628 620 if (status!=RTEMS_SUCCESSFUL) {
629 621 BOOT_PRINTF("in INIT *** Error starting TASK_CWF3\n")
630 622 }
631 623 }
632 624 if (status == RTEMS_SUCCESSFUL) // CWF2
633 625 {
634 626 status = rtems_task_start( Task_id[TASKID_CWF2], cwf2_task, 1 );
635 627 if (status!=RTEMS_SUCCESSFUL) {
636 628 BOOT_PRINTF("in INIT *** Error starting TASK_CWF2\n")
637 629 }
638 630 }
639 631 if (status == RTEMS_SUCCESSFUL) // CWF1
640 632 {
641 633 status = rtems_task_start( Task_id[TASKID_CWF1], cwf1_task, 1 );
642 634 if (status!=RTEMS_SUCCESSFUL) {
643 635 BOOT_PRINTF("in INIT *** Error starting TASK_CWF1\n")
644 636 }
645 637 }
646 638 if (status == RTEMS_SUCCESSFUL) // SWBD
647 639 {
648 640 status = rtems_task_start( Task_id[TASKID_SWBD], swbd_task, 1 );
649 641 if (status!=RTEMS_SUCCESSFUL) {
650 642 BOOT_PRINTF("in INIT *** Error starting TASK_SWBD\n")
651 643 }
652 644 }
653 645
654 646 //*****
655 647 // MISC
656 648 if (status == RTEMS_SUCCESSFUL) // HOUS
657 649 {
658 650 status = rtems_task_start( Task_id[TASKID_HOUS], hous_task, 1 );
659 651 if (status!=RTEMS_SUCCESSFUL) {
660 652 BOOT_PRINTF("in INIT *** Error starting TASK_HOUS\n")
661 653 }
662 654 }
663 655 if (status == RTEMS_SUCCESSFUL) // DUMB
664 656 {
665 657 status = rtems_task_start( Task_id[TASKID_DUMB], dumb_task, 1 );
666 658 if (status!=RTEMS_SUCCESSFUL) {
667 659 BOOT_PRINTF("in INIT *** Error starting TASK_DUMB\n")
668 660 }
669 661 }
670 if (status == RTEMS_SUCCESSFUL) // STAT
662 if (status == RTEMS_SUCCESSFUL) // LOAD
671 663 {
672 status = rtems_task_start( Task_id[TASKID_STAT], stat_task, 1 );
664 status = rtems_task_start( Task_id[TASKID_LOAD], load_task, 1 );
673 665 if (status!=RTEMS_SUCCESSFUL) {
674 BOOT_PRINTF("in INIT *** Error starting TASK_STAT\n")
666 BOOT_PRINTF("in INIT *** Error starting TASK_LOAD\n")
675 667 }
676 668 }
677 669
678 670 return status;
679 671 }
680 672
681 673 rtems_status_code create_message_queues( void ) // create the two message queues used in the software
682 674 {
683 675 rtems_status_code status_recv;
684 676 rtems_status_code status_send;
685 677 rtems_status_code status_q_p0;
686 678 rtems_status_code status_q_p1;
687 679 rtems_status_code status_q_p2;
688 680 rtems_status_code ret;
689 681 rtems_id queue_id;
690 682
691 683 //****************************************
692 684 // create the queue for handling valid TCs
693 685 status_recv = rtems_message_queue_create( misc_name[QUEUE_RECV],
694 686 MSG_QUEUE_COUNT_RECV, CCSDS_TC_PKT_MAX_SIZE,
695 687 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
696 688 if ( status_recv != RTEMS_SUCCESSFUL ) {
697 689 PRINTF1("in create_message_queues *** ERR creating QUEU queue, %d\n", status_recv)
698 690 }
699 691
700 692 //************************************************
701 693 // create the queue for handling TM packet sending
702 694 status_send = rtems_message_queue_create( misc_name[QUEUE_SEND],
703 695 MSG_QUEUE_COUNT_SEND, MSG_QUEUE_SIZE_SEND,
704 696 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
705 697 if ( status_send != RTEMS_SUCCESSFUL ) {
706 698 PRINTF1("in create_message_queues *** ERR creating PKTS queue, %d\n", status_send)
707 699 }
708 700
709 701 //*****************************************************************************
710 702 // create the queue for handling averaged spectral matrices for processing @ f0
711 703 status_q_p0 = rtems_message_queue_create( misc_name[QUEUE_PRC0],
712 704 MSG_QUEUE_COUNT_PRC0, MSG_QUEUE_SIZE_PRC0,
713 705 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
714 706 if ( status_q_p0 != RTEMS_SUCCESSFUL ) {
715 707 PRINTF1("in create_message_queues *** ERR creating Q_P0 queue, %d\n", status_q_p0)
716 708 }
717 709
718 710 //*****************************************************************************
719 711 // create the queue for handling averaged spectral matrices for processing @ f1
720 712 status_q_p1 = rtems_message_queue_create( misc_name[QUEUE_PRC1],
721 713 MSG_QUEUE_COUNT_PRC1, MSG_QUEUE_SIZE_PRC1,
722 714 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
723 715 if ( status_q_p1 != RTEMS_SUCCESSFUL ) {
724 716 PRINTF1("in create_message_queues *** ERR creating Q_P1 queue, %d\n", status_q_p1)
725 717 }
726 718
727 719 //*****************************************************************************
728 720 // create the queue for handling averaged spectral matrices for processing @ f2
729 721 status_q_p2 = rtems_message_queue_create( misc_name[QUEUE_PRC2],
730 722 MSG_QUEUE_COUNT_PRC2, MSG_QUEUE_SIZE_PRC2,
731 723 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
732 724 if ( status_q_p2 != RTEMS_SUCCESSFUL ) {
733 725 PRINTF1("in create_message_queues *** ERR creating Q_P2 queue, %d\n", status_q_p2)
734 726 }
735 727
736 728 if ( status_recv != RTEMS_SUCCESSFUL )
737 729 {
738 730 ret = status_recv;
739 731 }
740 732 else if( status_send != RTEMS_SUCCESSFUL )
741 733 {
742 734 ret = status_send;
743 735 }
744 736 else if( status_q_p0 != RTEMS_SUCCESSFUL )
745 737 {
746 738 ret = status_q_p0;
747 739 }
748 740 else if( status_q_p1 != RTEMS_SUCCESSFUL )
749 741 {
750 742 ret = status_q_p1;
751 743 }
752 744 else
753 745 {
754 746 ret = status_q_p2;
755 747 }
756 748
757 749 return ret;
758 750 }
759 751
760 752 rtems_status_code get_message_queue_id_send( rtems_id *queue_id )
761 753 {
762 754 rtems_status_code status;
763 755 rtems_name queue_name;
764 756
765 757 queue_name = rtems_build_name( 'Q', '_', 'S', 'D' );
766 758
767 759 status = rtems_message_queue_ident( queue_name, 0, queue_id );
768 760
769 761 return status;
770 762 }
771 763
772 764 rtems_status_code get_message_queue_id_recv( rtems_id *queue_id )
773 765 {
774 766 rtems_status_code status;
775 767 rtems_name queue_name;
776 768
777 769 queue_name = rtems_build_name( 'Q', '_', 'R', 'V' );
778 770
779 771 status = rtems_message_queue_ident( queue_name, 0, queue_id );
780 772
781 773 return status;
782 774 }
783 775
784 776 rtems_status_code get_message_queue_id_prc0( rtems_id *queue_id )
785 777 {
786 778 rtems_status_code status;
787 779 rtems_name queue_name;
788 780
789 781 queue_name = rtems_build_name( 'Q', '_', 'P', '0' );
790 782
791 783 status = rtems_message_queue_ident( queue_name, 0, queue_id );
792 784
793 785 return status;
794 786 }
795 787
796 788 rtems_status_code get_message_queue_id_prc1( rtems_id *queue_id )
797 789 {
798 790 rtems_status_code status;
799 791 rtems_name queue_name;
800 792
801 793 queue_name = rtems_build_name( 'Q', '_', 'P', '1' );
802 794
803 795 status = rtems_message_queue_ident( queue_name, 0, queue_id );
804 796
805 797 return status;
806 798 }
807 799
808 800 rtems_status_code get_message_queue_id_prc2( rtems_id *queue_id )
809 801 {
810 802 rtems_status_code status;
811 803 rtems_name queue_name;
812 804
813 805 queue_name = rtems_build_name( 'Q', '_', 'P', '2' );
814 806
815 807 status = rtems_message_queue_ident( queue_name, 0, queue_id );
816 808
817 809 return status;
818 810 }
819 811
820 812 void update_queue_max_count( rtems_id queue_id, unsigned char*fifo_size_max )
821 813 {
822 814 u_int32_t count;
823 815 rtems_status_code status;
824 816
825 817 status = rtems_message_queue_get_number_pending( queue_id, &count );
826 818
827 819 count = count + 1;
828 820
829 821 if (status != RTEMS_SUCCESSFUL)
830 822 {
831 823 PRINTF1("in update_queue_max_count *** ERR = %d\n", status)
832 824 }
833 825 else
834 826 {
835 827 if (count > *fifo_size_max)
836 828 {
837 829 *fifo_size_max = count;
838 830 }
839 831 }
840 832 }
841 833
842 834 void init_ring(ring_node ring[], unsigned char nbNodes, volatile int buffer[], unsigned int bufferSize )
843 835 {
844 836 unsigned char i;
845 837
846 838 //***************
847 839 // BUFFER ADDRESS
848 840 for(i=0; i<nbNodes; i++)
849 841 {
850 842 ring[i].coarseTime = 0xffffffff;
851 843 ring[i].fineTime = 0xffffffff;
852 844 ring[i].sid = 0x00;
853 845 ring[i].status = 0x00;
854 846 ring[i].buffer_address = (int) &buffer[ i * bufferSize ];
855 847 }
856 848
857 849 //*****
858 850 // NEXT
859 851 ring[ nbNodes - 1 ].next = (ring_node*) &ring[ 0 ];
860 852 for(i=0; i<nbNodes-1; i++)
861 853 {
862 854 ring[i].next = (ring_node*) &ring[ i + 1 ];
863 855 }
864 856
865 857 //*********
866 858 // PREVIOUS
867 859 ring[ 0 ].previous = (ring_node*) &ring[ nbNodes - 1 ];
868 860 for(i=1; i<nbNodes; i++)
869 861 {
870 862 ring[i].previous = (ring_node*) &ring[ i - 1 ];
871 863 }
872 864 }
@@ -1,570 +1,652
1 1 /** General usage functions and RTEMS tasks.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 */
7 7
8 8 #include "fsw_misc.h"
9 9
10 void configure_timer(gptimer_regs_t *gptimer_regs, unsigned char timer, unsigned int clock_divider,
10 void timer_configure(unsigned char timer, unsigned int clock_divider,
11 11 unsigned char interrupt_level, rtems_isr (*timer_isr)() )
12 12 {
13 13 /** This function configures a GPTIMER timer instantiated in the VHDL design.
14 14 *
15 15 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
16 16 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
17 17 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
18 18 * @param interrupt_level is the interrupt level that the timer drives.
19 19 * @param timer_isr is the interrupt subroutine that will be attached to the IRQ driven by the timer.
20 20 *
21 21 * Interrupt levels are described in the SPARC documentation sparcv8.pdf p.76
22 22 *
23 23 */
24 24
25 25 rtems_status_code status;
26 26 rtems_isr_entry old_isr_handler;
27 27
28 28 gptimer_regs->timer[timer].ctrl = 0x00; // reset the control register
29 29
30 30 status = rtems_interrupt_catch( timer_isr, interrupt_level, &old_isr_handler) ; // see sparcv8.pdf p.76 for interrupt levels
31 31 if (status!=RTEMS_SUCCESSFUL)
32 32 {
33 33 PRINTF("in configure_timer *** ERR rtems_interrupt_catch\n")
34 34 }
35 35
36 timer_set_clock_divider( gptimer_regs, timer, clock_divider);
36 timer_set_clock_divider( timer, clock_divider);
37 37 }
38 38
39 void timer_start(gptimer_regs_t *gptimer_regs, unsigned char timer)
39 void timer_start(unsigned char timer)
40 40 {
41 41 /** This function starts a GPTIMER timer.
42 42 *
43 43 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
44 44 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
45 45 *
46 46 */
47 47
48 48 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
49 49 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000004; // LD load value from the reload register
50 50 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000001; // EN enable the timer
51 51 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000002; // RS restart
52 52 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000008; // IE interrupt enable
53 53 }
54 54
55 void timer_stop(gptimer_regs_t *gptimer_regs, unsigned char timer)
55 void timer_stop(unsigned char timer)
56 56 {
57 57 /** This function stops a GPTIMER timer.
58 58 *
59 59 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
60 60 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
61 61 *
62 62 */
63 63
64 64 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xfffffffe; // EN enable the timer
65 65 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xffffffef; // IE interrupt enable
66 66 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
67 67 }
68 68
69 void timer_set_clock_divider(gptimer_regs_t *gptimer_regs, unsigned char timer, unsigned int clock_divider)
69 void timer_set_clock_divider(unsigned char timer, unsigned int clock_divider)
70 70 {
71 71 /** This function sets the clock divider of a GPTIMER timer.
72 72 *
73 73 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
74 74 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
75 75 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
76 76 *
77 77 */
78 78
79 79 gptimer_regs->timer[timer].reload = clock_divider; // base clock frequency is 1 MHz
80 80 }
81 81
82 // WATCHDOG
83
84 rtems_isr watchdog_isr( rtems_vector_number vector )
85 {
86 rtems_status_code status_code;
87
88 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_12 );
89 }
90
91 void watchdog_configure(void)
92 {
93 /** This function configure the watchdog.
94 *
95 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
96 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
97 *
98 * The watchdog is a timer provided by the GPTIMER IP core of the GRLIB.
99 *
100 */
101
102 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt during configuration
103
104 timer_configure( TIMER_WATCHDOG, CLKDIV_WATCHDOG, IRQ_SPARC_GPTIMER_WATCHDOG, watchdog_isr );
105
106 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
107 }
108
109 void watchdog_stop(void)
110 {
111 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt line
112 timer_stop( TIMER_WATCHDOG );
113 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
114 }
115
116 void watchdog_reload(void)
117 {
118 /** This function reloads the watchdog timer counter with the timer reload value.
119 *
120 *
121 */
122
123 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000004; // LD load value from the reload register
124 }
125
126 void watchdog_start(void)
127 {
128 /** This function starts the watchdog timer.
129 *
130 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
131 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
132 *
133 */
134
135 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG );
136
137 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000010; // clear pending IRQ if any
138 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000004; // LD load value from the reload register
139 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000001; // EN enable the timer
140 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000008; // IE interrupt enable
141
142 LEON_Unmask_interrupt( IRQ_GPTIMER_WATCHDOG );
143
144 }
145
82 146 int send_console_outputs_on_apbuart_port( void ) // Send the console outputs on the apbuart port
83 147 {
84 148 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
85 149
86 150 apbuart_regs->ctrl = APBUART_CTRL_REG_MASK_TE;
87 151
88 152 return 0;
89 153 }
90 154
91 155 int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register
92 156 {
93 157 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
94 158
95 159 apbuart_regs->ctrl = apbuart_regs->ctrl | APBUART_CTRL_REG_MASK_TE;
96 160
97 161 return 0;
98 162 }
99 163
100 164 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value)
101 165 {
102 166 /** This function sets the scaler reload register of the apbuart module
103 167 *
104 168 * @param regs is the address of the apbuart registers in memory
105 169 * @param value is the value that will be stored in the scaler register
106 170 *
107 171 * The value shall be set by the software to get data on the serial interface.
108 172 *
109 173 */
110 174
111 175 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs;
112 176
113 177 apbuart_regs->scaler = value;
114 178 BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value)
115 179 }
116 180
117 181 //************
118 182 // RTEMS TASKS
119 183
120 rtems_task stat_task(rtems_task_argument argument)
184 rtems_task load_task(rtems_task_argument argument)
121 185 {
122 int i;
123 int j;
186 BOOT_PRINTF("in LOAD *** \n")
187
188 rtems_status_code status;
189 unsigned int i;
190 unsigned int j;
191 rtems_name name_watchdog_rate_monotonic; // name of the watchdog rate monotonic
192 rtems_id watchdog_period_id; // id of the watchdog rate monotonic period
193
194 name_watchdog_rate_monotonic = rtems_build_name( 'L', 'O', 'A', 'D' );
195
196 status = rtems_rate_monotonic_create( name_watchdog_rate_monotonic, &watchdog_period_id );
197 if( status != RTEMS_SUCCESSFUL ) {
198 PRINTF1( "in LOAD *** rtems_rate_monotonic_create failed with status of %d\n", status )
199 }
200
124 201 i = 0;
125 202 j = 0;
126 BOOT_PRINTF("in STAT *** \n")
203
204 watchdog_configure();
205
206 watchdog_start();
207
127 208 while(1){
128 rtems_task_wake_after(1000);
129 PRINTF1("%d\n", j)
130 if (i == CPU_USAGE_REPORT_PERIOD) {
131 // #ifdef PRINT_TASK_STATISTICS
132 // rtems_cpu_usage_report();
133 // rtems_cpu_usage_reset();
134 // #endif
209 status = rtems_rate_monotonic_period( watchdog_period_id, WATCHDOG_PERIOD );
210 watchdog_reload();
211 i = i + 1;
212 if ( i == 10 )
213 {
135 214 i = 0;
215 j = j + 1;
216 PRINTF1("%d\n", j)
136 217 }
137 else i++;
138 j++;
218 if (j == 3 )
219 {
220 status = rtems_task_delete(RTEMS_SELF);
221 }
139 222 }
140 223 }
141 224
142 225 rtems_task hous_task(rtems_task_argument argument)
143 226 {
144 227 rtems_status_code status;
145 228 rtems_status_code spare_status;
146 229 rtems_id queue_id;
147 230 rtems_rate_monotonic_period_status period_status;
148 231
149 232 status = get_message_queue_id_send( &queue_id );
150 233 if (status != RTEMS_SUCCESSFUL)
151 234 {
152 235 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
153 236 }
154 237
155 238 BOOT_PRINTF("in HOUS ***\n")
156 239
157 240 if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
158 241 status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id );
159 242 if( status != RTEMS_SUCCESSFUL ) {
160 243 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status )
161 244 }
162 245 }
163 246
164 247 status = rtems_rate_monotonic_cancel(HK_id);
165 248 if( status != RTEMS_SUCCESSFUL ) {
166 249 PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status )
167 250 }
168 251 else {
169 252 DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n")
170 253 }
171 254
172 255 // startup phase
173 256 status = rtems_rate_monotonic_period( HK_id, SY_LFR_TIME_SYN_TIMEOUT_in_ticks );
174 257 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
175 258 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
176 259 while(period_status.state != RATE_MONOTONIC_EXPIRED ) // after SY_LFR_TIME_SYN_TIMEOUT ms, starts HK anyway
177 260 {
178 261 if ((time_management_regs->coarse_time & 0x80000000) == 0x00000000) // check time synchronization
179 262 {
180 263 break; // break if LFR is synchronized
181 264 }
182 265 else
183 266 {
184 267 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
185 268 // sched_yield();
186 269 status = rtems_task_wake_after( 10 ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 100 ms = 10 * 10 ms
187 270 }
188 271 }
189 272 status = rtems_rate_monotonic_cancel(HK_id);
190 273 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
191 274
192 275 set_hk_lfr_reset_cause( POWER_ON );
193 276
194 277 while(1){ // launch the rate monotonic task
195 278 status = rtems_rate_monotonic_period( HK_id, HK_PERIOD );
196 279 if ( status != RTEMS_SUCCESSFUL ) {
197 280 PRINTF1( "in HOUS *** ERR period: %d\n", status);
198 281 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 );
199 282 }
200 283 else {
201 284 housekeeping_packet.packetSequenceControl[0] = (unsigned char) (sequenceCounterHK >> 8);
202 285 housekeeping_packet.packetSequenceControl[1] = (unsigned char) (sequenceCounterHK );
203 286 increment_seq_counter( &sequenceCounterHK );
204 287
205 288 housekeeping_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
206 289 housekeeping_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
207 290 housekeeping_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
208 291 housekeeping_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
209 292 housekeeping_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
210 293 housekeeping_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
211 294
212 295 spacewire_update_statistics();
213 296
214 297 housekeeping_packet.hk_lfr_q_sd_fifo_size_max = hk_lfr_q_sd_fifo_size_max;
215 298 housekeeping_packet.hk_lfr_q_rv_fifo_size_max = hk_lfr_q_rv_fifo_size_max;
216 299 housekeeping_packet.hk_lfr_q_p0_fifo_size_max = hk_lfr_q_p0_fifo_size_max;
217 300 housekeeping_packet.hk_lfr_q_p1_fifo_size_max = hk_lfr_q_p1_fifo_size_max;
218 301 housekeeping_packet.hk_lfr_q_p2_fifo_size_max = hk_lfr_q_p2_fifo_size_max;
219 302
220 303 housekeeping_packet.sy_lfr_common_parameters_spare = parameter_dump_packet.sy_lfr_common_parameters_spare;
221 304 housekeeping_packet.sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
222 305 get_temperatures( housekeeping_packet.hk_lfr_temp_scm );
223 306 get_v_e1_e2_f3( housekeeping_packet.hk_lfr_sc_v_f3 );
224 307 get_cpu_load( (unsigned char *) &housekeeping_packet.hk_lfr_cpu_load );
225 308
226 309 // SEND PACKET
227 310 status = rtems_message_queue_send( queue_id, &housekeeping_packet,
228 311 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
229 312 if (status != RTEMS_SUCCESSFUL) {
230 313 PRINTF1("in HOUS *** ERR send: %d\n", status)
231 314 }
232 315 }
233 316 }
234 317
235 318 PRINTF("in HOUS *** deleting task\n")
236 319
237 320 status = rtems_task_delete( RTEMS_SELF ); // should not return
238 321
239 322 return;
240 323 }
241 324
242 325 rtems_task dumb_task( rtems_task_argument unused )
243 326 {
244 327 /** This RTEMS taks is used to print messages without affecting the general behaviour of the software.
245 328 *
246 329 * @param unused is the starting argument of the RTEMS task
247 330 *
248 331 * The DUMB taks waits for RTEMS events and print messages depending on the incoming events.
249 332 *
250 333 */
251 334
252 335 unsigned int i;
253 336 unsigned int intEventOut;
254 337 unsigned int coarse_time = 0;
255 338 unsigned int fine_time = 0;
256 339 rtems_event_set event_out;
257 340
258 char *DumbMessages[12] = {"in DUMB *** default", // RTEMS_EVENT_0
341 char *DumbMessages[13] = {"in DUMB *** default", // RTEMS_EVENT_0
259 342 "in DUMB *** timecode_irq_handler", // RTEMS_EVENT_1
260 343 "in DUMB *** f3 buffer changed", // RTEMS_EVENT_2
261 344 "in DUMB *** in SMIQ *** Error sending event to AVF0", // RTEMS_EVENT_3
262 345 "in DUMB *** spectral_matrices_isr *** Error sending event to SMIQ", // RTEMS_EVENT_4
263 346 "in DUMB *** waveforms_simulator_isr", // RTEMS_EVENT_5
264 347 "VHDL SM *** two buffers f0 ready", // RTEMS_EVENT_6
265 348 "ready for dump", // RTEMS_EVENT_7
266 349 "VHDL ERR *** spectral matrix", // RTEMS_EVENT_8
267 350 "tick", // RTEMS_EVENT_9
268 351 "VHDL ERR *** waveform picker", // RTEMS_EVENT_10
269 "VHDL ERR *** unexpected ready matrix values" // RTEMS_EVENT_11
352 "VHDL ERR *** unexpected ready matrix values", // RTEMS_EVENT_11
353 "WATCHDOG timer" // RTEMS_EVENT_12
270 354 };
271 355
272 356 BOOT_PRINTF("in DUMB *** \n")
273 357
274 358 while(1){
275 359 rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3
276 360 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7
277 | RTEMS_EVENT_8 | RTEMS_EVENT_9,
361 | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12,
278 362 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT
279 363 intEventOut = (unsigned int) event_out;
280 364 for ( i=0; i<32; i++)
281 365 {
282 366 if ( ((intEventOut >> i) & 0x0001) != 0)
283 367 {
284 368 coarse_time = time_management_regs->coarse_time;
285 369 fine_time = time_management_regs->fine_time;
286 if (i==8)
370 if (i==12)
287 371 {
288 }
289 if (i==10)
290 {
372 PRINTF1("%s\n", DumbMessages[12])
291 373 }
292 374 }
293 375 }
294 376 }
295 377 }
296 378
297 379 //*****************************
298 380 // init housekeeping parameters
299 381
300 382 void init_housekeeping_parameters( void )
301 383 {
302 384 /** This function initialize the housekeeping_packet global variable with default values.
303 385 *
304 386 */
305 387
306 388 unsigned int i = 0;
307 389 unsigned char *parameters;
308 390 unsigned char sizeOfHK;
309 391
310 392 sizeOfHK = sizeof( Packet_TM_LFR_HK_t );
311 393
312 394 parameters = (unsigned char*) &housekeeping_packet;
313 395
314 396 for(i = 0; i< sizeOfHK; i++)
315 397 {
316 398 parameters[i] = 0x00;
317 399 }
318 400
319 401 housekeeping_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
320 402 housekeeping_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
321 403 housekeeping_packet.reserved = DEFAULT_RESERVED;
322 404 housekeeping_packet.userApplication = CCSDS_USER_APP;
323 405 housekeeping_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
324 406 housekeeping_packet.packetID[1] = (unsigned char) (APID_TM_HK);
325 407 housekeeping_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
326 408 housekeeping_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
327 409 housekeeping_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
328 410 housekeeping_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
329 411 housekeeping_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
330 412 housekeeping_packet.serviceType = TM_TYPE_HK;
331 413 housekeeping_packet.serviceSubType = TM_SUBTYPE_HK;
332 414 housekeeping_packet.destinationID = TM_DESTINATION_ID_GROUND;
333 415 housekeeping_packet.sid = SID_HK;
334 416
335 417 // init status word
336 418 housekeeping_packet.lfr_status_word[0] = DEFAULT_STATUS_WORD_BYTE0;
337 419 housekeeping_packet.lfr_status_word[1] = DEFAULT_STATUS_WORD_BYTE1;
338 420 // init software version
339 421 housekeeping_packet.lfr_sw_version[0] = SW_VERSION_N1;
340 422 housekeeping_packet.lfr_sw_version[1] = SW_VERSION_N2;
341 423 housekeeping_packet.lfr_sw_version[2] = SW_VERSION_N3;
342 424 housekeeping_packet.lfr_sw_version[3] = SW_VERSION_N4;
343 425 // init fpga version
344 426 parameters = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
345 427 housekeeping_packet.lfr_fpga_version[0] = parameters[1]; // n1
346 428 housekeeping_packet.lfr_fpga_version[1] = parameters[2]; // n2
347 429 housekeeping_packet.lfr_fpga_version[2] = parameters[3]; // n3
348 430
349 431 housekeeping_packet.hk_lfr_q_sd_fifo_size = MSG_QUEUE_COUNT_SEND;
350 432 housekeeping_packet.hk_lfr_q_rv_fifo_size = MSG_QUEUE_COUNT_RECV;
351 433 housekeeping_packet.hk_lfr_q_p0_fifo_size = MSG_QUEUE_COUNT_PRC0;
352 434 housekeeping_packet.hk_lfr_q_p1_fifo_size = MSG_QUEUE_COUNT_PRC1;
353 435 housekeeping_packet.hk_lfr_q_p2_fifo_size = MSG_QUEUE_COUNT_PRC2;
354 436 }
355 437
356 438 void increment_seq_counter( unsigned short *packetSequenceControl )
357 439 {
358 440 /** This function increment the sequence counter passes in argument.
359 441 *
360 442 * The increment does not affect the grouping flag. In case of an overflow, the counter is reset to 0.
361 443 *
362 444 */
363 445
364 446 unsigned short segmentation_grouping_flag;
365 447 unsigned short sequence_cnt;
366 448
367 449 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << 8; // keep bits 7 downto 6
368 450 sequence_cnt = (*packetSequenceControl) & 0x3fff; // [0011 1111 1111 1111]
369 451
370 452 if ( sequence_cnt < SEQ_CNT_MAX)
371 453 {
372 454 sequence_cnt = sequence_cnt + 1;
373 455 }
374 456 else
375 457 {
376 458 sequence_cnt = 0;
377 459 }
378 460
379 461 *packetSequenceControl = segmentation_grouping_flag | sequence_cnt ;
380 462 }
381 463
382 464 void getTime( unsigned char *time)
383 465 {
384 466 /** This function write the current local time in the time buffer passed in argument.
385 467 *
386 468 */
387 469
388 470 time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
389 471 time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
390 472 time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
391 473 time[3] = (unsigned char) (time_management_regs->coarse_time);
392 474 time[4] = (unsigned char) (time_management_regs->fine_time>>8);
393 475 time[5] = (unsigned char) (time_management_regs->fine_time);
394 476 }
395 477
396 478 unsigned long long int getTimeAsUnsignedLongLongInt( )
397 479 {
398 480 /** This function write the current local time in the time buffer passed in argument.
399 481 *
400 482 */
401 483 unsigned long long int time;
402 484
403 485 time = ( (unsigned long long int) (time_management_regs->coarse_time & 0x7fffffff) << 16 )
404 486 + time_management_regs->fine_time;
405 487
406 488 return time;
407 489 }
408 490
409 491 void send_dumb_hk( void )
410 492 {
411 493 Packet_TM_LFR_HK_t dummy_hk_packet;
412 494 unsigned char *parameters;
413 495 unsigned int i;
414 496 rtems_id queue_id;
415 497
416 498 dummy_hk_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
417 499 dummy_hk_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
418 500 dummy_hk_packet.reserved = DEFAULT_RESERVED;
419 501 dummy_hk_packet.userApplication = CCSDS_USER_APP;
420 502 dummy_hk_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
421 503 dummy_hk_packet.packetID[1] = (unsigned char) (APID_TM_HK);
422 504 dummy_hk_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
423 505 dummy_hk_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
424 506 dummy_hk_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
425 507 dummy_hk_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
426 508 dummy_hk_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
427 509 dummy_hk_packet.serviceType = TM_TYPE_HK;
428 510 dummy_hk_packet.serviceSubType = TM_SUBTYPE_HK;
429 511 dummy_hk_packet.destinationID = TM_DESTINATION_ID_GROUND;
430 512 dummy_hk_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
431 513 dummy_hk_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
432 514 dummy_hk_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
433 515 dummy_hk_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
434 516 dummy_hk_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
435 517 dummy_hk_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
436 518 dummy_hk_packet.sid = SID_HK;
437 519
438 520 // init status word
439 521 dummy_hk_packet.lfr_status_word[0] = 0xff;
440 522 dummy_hk_packet.lfr_status_word[1] = 0xff;
441 523 // init software version
442 524 dummy_hk_packet.lfr_sw_version[0] = SW_VERSION_N1;
443 525 dummy_hk_packet.lfr_sw_version[1] = SW_VERSION_N2;
444 526 dummy_hk_packet.lfr_sw_version[2] = SW_VERSION_N3;
445 527 dummy_hk_packet.lfr_sw_version[3] = SW_VERSION_N4;
446 528 // init fpga version
447 529 parameters = (unsigned char *) (REGS_ADDR_WAVEFORM_PICKER + 0xb0);
448 530 dummy_hk_packet.lfr_fpga_version[0] = parameters[1]; // n1
449 531 dummy_hk_packet.lfr_fpga_version[1] = parameters[2]; // n2
450 532 dummy_hk_packet.lfr_fpga_version[2] = parameters[3]; // n3
451 533
452 534 parameters = (unsigned char *) &dummy_hk_packet.hk_lfr_cpu_load;
453 535
454 536 for (i=0; i<100; i++)
455 537 {
456 538 parameters[i] = 0xff;
457 539 }
458 540
459 541 get_message_queue_id_send( &queue_id );
460 542
461 543 rtems_message_queue_send( queue_id, &dummy_hk_packet,
462 544 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
463 545 }
464 546
465 547 void get_temperatures( unsigned char *temperatures )
466 548 {
467 549 unsigned char* temp_scm_ptr;
468 550 unsigned char* temp_pcb_ptr;
469 551 unsigned char* temp_fpga_ptr;
470 552
471 553 // SEL1 SEL0
472 554 // 0 0 => PCB
473 555 // 0 1 => FPGA
474 556 // 1 0 => SCM
475 557
476 558 temp_scm_ptr = (unsigned char *) &time_management_regs->temp_scm;
477 559 temp_pcb_ptr = (unsigned char *) &time_management_regs->temp_pcb;
478 560 temp_fpga_ptr = (unsigned char *) &time_management_regs->temp_fpga;
479 561
480 562 temperatures[0] = temp_scm_ptr[2];
481 563 temperatures[1] = temp_scm_ptr[3];
482 564 temperatures[2] = temp_pcb_ptr[2];
483 565 temperatures[3] = temp_pcb_ptr[3];
484 566 temperatures[4] = temp_fpga_ptr[2];
485 567 temperatures[5] = temp_fpga_ptr[3];
486 568 }
487 569
488 570 void get_v_e1_e2_f3( unsigned char *spacecraft_potential )
489 571 {
490 572 unsigned char* v_ptr;
491 573 unsigned char* e1_ptr;
492 574 unsigned char* e2_ptr;
493 575
494 576 v_ptr = (unsigned char *) &waveform_picker_regs->v;
495 577 e1_ptr = (unsigned char *) &waveform_picker_regs->e1;
496 578 e2_ptr = (unsigned char *) &waveform_picker_regs->e2;
497 579
498 580 spacecraft_potential[0] = v_ptr[2];
499 581 spacecraft_potential[1] = v_ptr[3];
500 582 spacecraft_potential[2] = e1_ptr[2];
501 583 spacecraft_potential[3] = e1_ptr[3];
502 584 spacecraft_potential[4] = e2_ptr[2];
503 585 spacecraft_potential[5] = e2_ptr[3];
504 586 }
505 587
506 588 void get_cpu_load( unsigned char *resource_statistics )
507 589 {
508 590 unsigned char cpu_load;
509 591
510 592 cpu_load = lfr_rtems_cpu_usage_report();
511 593
512 594 // HK_LFR_CPU_LOAD
513 595 resource_statistics[0] = cpu_load;
514 596
515 597 // HK_LFR_CPU_LOAD_MAX
516 598 if (cpu_load > resource_statistics[1])
517 599 {
518 600 resource_statistics[1] = cpu_load;
519 601 }
520 602
521 603 // CPU_LOAD_AVE
522 604 resource_statistics[2] = 0;
523 605
524 606 #ifndef PRINT_TASK_STATISTICS
525 607 rtems_cpu_usage_reset();
526 608 #endif
527 609
528 610 }
529 611
530 612 void set_hk_lfr_sc_potential_flag( bool state )
531 613 {
532 614 if (state == true)
533 615 {
534 616 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x40; // [0100 0000]
535 617 }
536 618 else
537 619 {
538 620 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xbf; // [1011 1111]
539 621 }
540 622 }
541 623
542 624 void set_hk_lfr_mag_fields_flag( bool state )
543 625 {
544 626 if (state == true)
545 627 {
546 628 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x20; // [0010 0000]
547 629 }
548 630 else
549 631 {
550 632 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xd7; // [1101 1111]
551 633 }
552 634 }
553 635
554 636 void set_hk_lfr_calib_enable( bool state )
555 637 {
556 638 if (state == true)
557 639 {
558 640 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x08; // [0000 1000]
559 641 }
560 642 else
561 643 {
562 644 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xf7; // [1111 0111]
563 645 }
564 646 }
565 647
566 648 void set_hk_lfr_reset_cause( enum lfr_reset_cause_t lfr_reset_cause )
567 649 {
568 650 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1]
569 651 | (lfr_reset_cause & 0x07 ); // [0000 0111]
570 652 }
@@ -1,689 +1,640
1 1 /** Functions related to data processing.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * These function are related to data processing, i.e. spectral matrices averaging and basic parameters computation.
7 7 *
8 8 */
9 9
10 10 #include "fsw_processing.h"
11 11 #include "fsw_processing_globals.c"
12 12 #include "fsw_init.h"
13 13
14 14 unsigned int nb_sm_f0;
15 15 unsigned int nb_sm_f0_aux_f1;
16 16 unsigned int nb_sm_f1;
17 17 unsigned int nb_sm_f0_aux_f2;
18 18
19 19 //************************
20 20 // spectral matrices rings
21 21 ring_node sm_ring_f0[ NB_RING_NODES_SM_F0 ];
22 22 ring_node sm_ring_f1[ NB_RING_NODES_SM_F1 ];
23 23 ring_node sm_ring_f2[ NB_RING_NODES_SM_F2 ];
24 24 ring_node *current_ring_node_sm_f0;
25 25 ring_node *current_ring_node_sm_f1;
26 26 ring_node *current_ring_node_sm_f2;
27 27 ring_node *ring_node_for_averaging_sm_f0;
28 28 ring_node *ring_node_for_averaging_sm_f1;
29 29 ring_node *ring_node_for_averaging_sm_f2;
30 30
31 31 //
32 32 ring_node * getRingNodeForAveraging( unsigned char frequencyChannel)
33 33 {
34 34 ring_node *node;
35 35
36 36 node = NULL;
37 37 switch ( frequencyChannel ) {
38 38 case 0:
39 39 node = ring_node_for_averaging_sm_f0;
40 40 break;
41 41 case 1:
42 42 node = ring_node_for_averaging_sm_f1;
43 43 break;
44 44 case 2:
45 45 node = ring_node_for_averaging_sm_f2;
46 46 break;
47 47 default:
48 48 break;
49 49 }
50 50
51 51 return node;
52 52 }
53 53
54 54 //***********************************************************
55 55 // Interrupt Service Routine for spectral matrices processing
56 56
57 57 void spectral_matrices_isr_f0( unsigned char statusReg )
58 58 {
59 59 unsigned char status;
60 60 rtems_status_code status_code;
61 61 ring_node *full_ring_node;
62 62
63 63 status = statusReg & 0x03; // [0011] get the status_ready_matrix_f0_x bits
64 64
65 65 switch(status)
66 66 {
67 67 case 0:
68 68 break;
69 69 case 3:
70 70 // UNEXPECTED VALUE
71 71 spectral_matrix_regs->status = 0x03; // [0011]
72 72 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_11 );
73 73 break;
74 74 case 1:
75 75 full_ring_node = current_ring_node_sm_f0->previous;
76 76 full_ring_node->coarseTime = spectral_matrix_regs->f0_0_coarse_time;
77 77 full_ring_node->fineTime = spectral_matrix_regs->f0_0_fine_time;
78 78 current_ring_node_sm_f0 = current_ring_node_sm_f0->next;
79 79 spectral_matrix_regs->f0_0_address = current_ring_node_sm_f0->buffer_address;
80 80 // if there are enough ring nodes ready, wake up an AVFx task
81 81 nb_sm_f0 = nb_sm_f0 + 1;
82 82 if (nb_sm_f0 == NB_SM_BEFORE_AVF0)
83 83 {
84 84 ring_node_for_averaging_sm_f0 = full_ring_node;
85 85 if (rtems_event_send( Task_id[TASKID_AVF0], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL)
86 86 {
87 87 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_3 );
88 88 }
89 89 nb_sm_f0 = 0;
90 90 }
91 91 spectral_matrix_regs->status = 0x01; // [0000 0001]
92 92 break;
93 93 case 2:
94 94 full_ring_node = current_ring_node_sm_f0->previous;
95 95 full_ring_node->coarseTime = spectral_matrix_regs->f0_1_coarse_time;
96 96 full_ring_node->fineTime = spectral_matrix_regs->f0_1_fine_time;
97 97 current_ring_node_sm_f0 = current_ring_node_sm_f0->next;
98 98 spectral_matrix_regs->f0_1_address = current_ring_node_sm_f0->buffer_address;
99 99 // if there are enough ring nodes ready, wake up an AVFx task
100 100 nb_sm_f0 = nb_sm_f0 + 1;
101 101 if (nb_sm_f0 == NB_SM_BEFORE_AVF0)
102 102 {
103 103 ring_node_for_averaging_sm_f0 = full_ring_node;
104 104 if (rtems_event_send( Task_id[TASKID_AVF0], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL)
105 105 {
106 106 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_3 );
107 107 }
108 108 nb_sm_f0 = 0;
109 109 }
110 110 spectral_matrix_regs->status = 0x02; // [0000 0010]
111 111 break;
112 112 }
113 113 }
114 114
115 115 void spectral_matrices_isr_f1( unsigned char statusReg )
116 116 {
117 117 rtems_status_code status_code;
118 118 unsigned char status;
119 119 ring_node *full_ring_node;
120 120
121 121 status = (statusReg & 0x0c) >> 2; // [1100] get the status_ready_matrix_f0_x bits
122 122
123 123 switch(status)
124 124 {
125 125 case 0:
126 126 break;
127 127 case 3:
128 128 // UNEXPECTED VALUE
129 129 spectral_matrix_regs->status = 0xc0; // [1100]
130 130 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_11 );
131 131 break;
132 132 case 1:
133 133 full_ring_node = current_ring_node_sm_f1->previous;
134 134 full_ring_node->coarseTime = spectral_matrix_regs->f1_0_coarse_time;
135 135 full_ring_node->fineTime = spectral_matrix_regs->f1_0_fine_time;
136 136 current_ring_node_sm_f1 = current_ring_node_sm_f1->next;
137 137 spectral_matrix_regs->f1_0_address = current_ring_node_sm_f1->buffer_address;
138 138 // if there are enough ring nodes ready, wake up an AVFx task
139 139 nb_sm_f1 = nb_sm_f1 + 1;
140 140 if (nb_sm_f1 == NB_SM_BEFORE_AVF1)
141 141 {
142 142 ring_node_for_averaging_sm_f1 = full_ring_node;
143 143 if (rtems_event_send( Task_id[TASKID_AVF1], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL)
144 144 {
145 145 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_3 );
146 146 }
147 147 nb_sm_f1 = 0;
148 148 }
149 149 spectral_matrix_regs->status = 0x04; // [0000 0100]
150 150 break;
151 151 case 2:
152 152 full_ring_node = current_ring_node_sm_f1->previous;
153 153 full_ring_node->coarseTime = spectral_matrix_regs->f1_1_coarse_time;
154 154 full_ring_node->fineTime = spectral_matrix_regs->f1_1_fine_time;
155 155 current_ring_node_sm_f1 = current_ring_node_sm_f1->next;
156 156 spectral_matrix_regs->f1_1_address = current_ring_node_sm_f1->buffer_address;
157 157 // if there are enough ring nodes ready, wake up an AVFx task
158 158 nb_sm_f1 = nb_sm_f1 + 1;
159 159 if (nb_sm_f1 == NB_SM_BEFORE_AVF1)
160 160 {
161 161 ring_node_for_averaging_sm_f1 = full_ring_node;
162 162 if (rtems_event_send( Task_id[TASKID_AVF1], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL)
163 163 {
164 164 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_3 );
165 165 }
166 166 nb_sm_f1 = 0;
167 167 }
168 168 spectral_matrix_regs->status = 0x08; // [1000 0000]
169 169 break;
170 170 }
171 171 }
172 172
173 173 void spectral_matrices_isr_f2( unsigned char statusReg )
174 174 {
175 175 unsigned char status;
176 176 rtems_status_code status_code;
177 177
178 178 status = (statusReg & 0x30) >> 4; // [0011 0000] get the status_ready_matrix_f0_x bits
179 179
180 180 switch(status)
181 181 {
182 182 case 0:
183 183 break;
184 184 case 3:
185 185 // UNEXPECTED VALUE
186 186 spectral_matrix_regs->status = 0x30; // [0011 0000]
187 187 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_11 );
188 188 break;
189 189 case 1:
190 190 ring_node_for_averaging_sm_f2 = current_ring_node_sm_f2->previous;
191 191 current_ring_node_sm_f2 = current_ring_node_sm_f2->next;
192 192 ring_node_for_averaging_sm_f2->coarseTime = spectral_matrix_regs->f2_0_coarse_time;
193 193 ring_node_for_averaging_sm_f2->fineTime = spectral_matrix_regs->f2_0_fine_time;
194 194 spectral_matrix_regs->f2_0_address = current_ring_node_sm_f2->buffer_address;
195 195 spectral_matrix_regs->status = 0x10; // [0001 0000]
196 196 if (rtems_event_send( Task_id[TASKID_AVF2], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL)
197 197 {
198 198 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_3 );
199 199 }
200 200 break;
201 201 case 2:
202 202 ring_node_for_averaging_sm_f2 = current_ring_node_sm_f2->previous;
203 203 current_ring_node_sm_f2 = current_ring_node_sm_f2->next;
204 204 ring_node_for_averaging_sm_f2->coarseTime = spectral_matrix_regs->f2_1_coarse_time;
205 205 ring_node_for_averaging_sm_f2->fineTime = spectral_matrix_regs->f2_1_fine_time;
206 206 spectral_matrix_regs->f2_1_address = current_ring_node_sm_f2->buffer_address;
207 207 spectral_matrix_regs->status = 0x20; // [0010 0000]
208 208 if (rtems_event_send( Task_id[TASKID_AVF2], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL)
209 209 {
210 210 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_3 );
211 211 }
212 212 break;
213 213 }
214 214 }
215 215
216 216 void spectral_matrix_isr_error_handler( unsigned char statusReg )
217 217 {
218 218 rtems_status_code status_code;
219 219
220 220 if (statusReg & 0x7c0) // [0111 1100 0000]
221 221 {
222 222 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_8 );
223 223 }
224 224
225 225 spectral_matrix_regs->status = spectral_matrix_regs->status & 0x7c0;
226 226 }
227 227
228 228 rtems_isr spectral_matrices_isr( rtems_vector_number vector )
229 229 {
230 230 // STATUS REGISTER
231 231 // input_fifo_write(2) *** input_fifo_write(1) *** input_fifo_write(0)
232 232 // 10 9 8
233 233 // buffer_full ** bad_component_err ** f2_1 ** f2_0 ** f1_1 ** f1_0 ** f0_1 ** f0_0
234 234 // 7 6 5 4 3 2 1 0
235 235
236 236 unsigned char statusReg;
237 237
238 238 statusReg = spectral_matrix_regs->status;
239 239
240 240 spectral_matrices_isr_f0( statusReg );
241 241
242 242 spectral_matrices_isr_f1( statusReg );
243 243
244 244 spectral_matrices_isr_f2( statusReg );
245 245
246 246 spectral_matrix_isr_error_handler( statusReg );
247 247 }
248 248
249 rtems_isr spectral_matrices_isr_simu( rtems_vector_number vector )
250 {
251 rtems_status_code status_code;
252
253 //***
254 // F0
255 nb_sm_f0 = nb_sm_f0 + 1;
256 if (nb_sm_f0 == NB_SM_BEFORE_AVF0 )
257 {
258 ring_node_for_averaging_sm_f0 = current_ring_node_sm_f0;
259 if (rtems_event_send( Task_id[TASKID_AVF0], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL)
260 {
261 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_3 );
262 }
263 nb_sm_f0 = 0;
264 }
265
266 //***
267 // F1
268 nb_sm_f0_aux_f1 = nb_sm_f0_aux_f1 + 1;
269 if (nb_sm_f0_aux_f1 == 6)
270 {
271 nb_sm_f0_aux_f1 = 0;
272 nb_sm_f1 = nb_sm_f1 + 1;
273 }
274 if (nb_sm_f1 == NB_SM_BEFORE_AVF1 )
275 {
276 ring_node_for_averaging_sm_f1 = current_ring_node_sm_f1;
277 if (rtems_event_send( Task_id[TASKID_AVF1], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL)
278 {
279 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_3 );
280 }
281 nb_sm_f1 = 0;
282 }
283
284 //***
285 // F2
286 nb_sm_f0_aux_f2 = nb_sm_f0_aux_f2 + 1;
287 if (nb_sm_f0_aux_f2 == 96)
288 {
289 nb_sm_f0_aux_f2 = 0;
290 ring_node_for_averaging_sm_f2 = current_ring_node_sm_f2;
291 if (rtems_event_send( Task_id[TASKID_AVF2], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL)
292 {
293 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_3 );
294 }
295 }
296 }
297
298 249 //******************
299 250 // Spectral Matrices
300 251
301 252 void reset_nb_sm( void )
302 253 {
303 254 nb_sm_f0 = 0;
304 255 nb_sm_f0_aux_f1 = 0;
305 256 nb_sm_f0_aux_f2 = 0;
306 257
307 258 nb_sm_f1 = 0;
308 259 }
309 260
310 261 void SM_init_rings( void )
311 262 {
312 263 init_ring( sm_ring_f0, NB_RING_NODES_SM_F0, sm_f0, TOTAL_SIZE_SM );
313 264 init_ring( sm_ring_f1, NB_RING_NODES_SM_F1, sm_f1, TOTAL_SIZE_SM );
314 265 init_ring( sm_ring_f2, NB_RING_NODES_SM_F2, sm_f2, TOTAL_SIZE_SM );
315 266
316 267 DEBUG_PRINTF1("sm_ring_f0 @%x\n", (unsigned int) sm_ring_f0)
317 268 DEBUG_PRINTF1("sm_ring_f1 @%x\n", (unsigned int) sm_ring_f1)
318 269 DEBUG_PRINTF1("sm_ring_f2 @%x\n", (unsigned int) sm_ring_f2)
319 270 DEBUG_PRINTF1("sm_f0 @%x\n", (unsigned int) sm_f0)
320 271 DEBUG_PRINTF1("sm_f1 @%x\n", (unsigned int) sm_f1)
321 272 DEBUG_PRINTF1("sm_f2 @%x\n", (unsigned int) sm_f2)
322 273 }
323 274
324 275 void ASM_generic_init_ring( ring_node_asm *ring, unsigned char nbNodes )
325 276 {
326 277 unsigned char i;
327 278
328 279 ring[ nbNodes - 1 ].next
329 280 = (ring_node_asm*) &ring[ 0 ];
330 281
331 282 for(i=0; i<nbNodes-1; i++)
332 283 {
333 284 ring[ i ].next = (ring_node_asm*) &ring[ i + 1 ];
334 285 }
335 286 }
336 287
337 288 void SM_reset_current_ring_nodes( void )
338 289 {
339 290 current_ring_node_sm_f0 = sm_ring_f0[0].next;
340 291 current_ring_node_sm_f1 = sm_ring_f1[0].next;
341 292 current_ring_node_sm_f2 = sm_ring_f2[0].next;
342 293
343 294 ring_node_for_averaging_sm_f0 = NULL;
344 295 ring_node_for_averaging_sm_f1 = NULL;
345 296 ring_node_for_averaging_sm_f2 = NULL;
346 297 }
347 298
348 299 //*****************
349 300 // Basic Parameters
350 301
351 302 void BP_init_header( bp_packet *packet,
352 303 unsigned int apid, unsigned char sid,
353 304 unsigned int packetLength, unsigned char blkNr )
354 305 {
355 306 packet->targetLogicalAddress = CCSDS_DESTINATION_ID;
356 307 packet->protocolIdentifier = CCSDS_PROTOCOLE_ID;
357 308 packet->reserved = 0x00;
358 309 packet->userApplication = CCSDS_USER_APP;
359 310 packet->packetID[0] = (unsigned char) (apid >> 8);
360 311 packet->packetID[1] = (unsigned char) (apid);
361 312 packet->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
362 313 packet->packetSequenceControl[1] = 0x00;
363 314 packet->packetLength[0] = (unsigned char) (packetLength >> 8);
364 315 packet->packetLength[1] = (unsigned char) (packetLength);
365 316 // DATA FIELD HEADER
366 317 packet->spare1_pusVersion_spare2 = 0x10;
367 318 packet->serviceType = TM_TYPE_LFR_SCIENCE; // service type
368 319 packet->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3; // service subtype
369 320 packet->destinationID = TM_DESTINATION_ID_GROUND;
370 321 packet->time[0] = 0x00;
371 322 packet->time[1] = 0x00;
372 323 packet->time[2] = 0x00;
373 324 packet->time[3] = 0x00;
374 325 packet->time[4] = 0x00;
375 326 packet->time[5] = 0x00;
376 327 // AUXILIARY DATA HEADER
377 328 packet->sid = sid;
378 329 packet->biaStatusInfo = 0x00;
379 330 packet->sy_lfr_common_parameters_spare = 0x00;
380 331 packet->sy_lfr_common_parameters = 0x00;
381 332 packet->acquisitionTime[0] = 0x00;
382 333 packet->acquisitionTime[1] = 0x00;
383 334 packet->acquisitionTime[2] = 0x00;
384 335 packet->acquisitionTime[3] = 0x00;
385 336 packet->acquisitionTime[4] = 0x00;
386 337 packet->acquisitionTime[5] = 0x00;
387 338 packet->pa_lfr_bp_blk_nr[0] = 0x00; // BLK_NR MSB
388 339 packet->pa_lfr_bp_blk_nr[1] = blkNr; // BLK_NR LSB
389 340 }
390 341
391 342 void BP_init_header_with_spare( bp_packet_with_spare *packet,
392 343 unsigned int apid, unsigned char sid,
393 344 unsigned int packetLength , unsigned char blkNr)
394 345 {
395 346 packet->targetLogicalAddress = CCSDS_DESTINATION_ID;
396 347 packet->protocolIdentifier = CCSDS_PROTOCOLE_ID;
397 348 packet->reserved = 0x00;
398 349 packet->userApplication = CCSDS_USER_APP;
399 350 packet->packetID[0] = (unsigned char) (apid >> 8);
400 351 packet->packetID[1] = (unsigned char) (apid);
401 352 packet->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
402 353 packet->packetSequenceControl[1] = 0x00;
403 354 packet->packetLength[0] = (unsigned char) (packetLength >> 8);
404 355 packet->packetLength[1] = (unsigned char) (packetLength);
405 356 // DATA FIELD HEADER
406 357 packet->spare1_pusVersion_spare2 = 0x10;
407 358 packet->serviceType = TM_TYPE_LFR_SCIENCE; // service type
408 359 packet->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3; // service subtype
409 360 packet->destinationID = TM_DESTINATION_ID_GROUND;
410 361 // AUXILIARY DATA HEADER
411 362 packet->sid = sid;
412 363 packet->biaStatusInfo = 0x00;
413 364 packet->sy_lfr_common_parameters_spare = 0x00;
414 365 packet->sy_lfr_common_parameters = 0x00;
415 366 packet->time[0] = 0x00;
416 367 packet->time[0] = 0x00;
417 368 packet->time[0] = 0x00;
418 369 packet->time[0] = 0x00;
419 370 packet->time[0] = 0x00;
420 371 packet->time[0] = 0x00;
421 372 packet->source_data_spare = 0x00;
422 373 packet->pa_lfr_bp_blk_nr[0] = 0x00; // BLK_NR MSB
423 374 packet->pa_lfr_bp_blk_nr[1] = blkNr; // BLK_NR LSB
424 375 }
425 376
426 377 void BP_send(char *data, rtems_id queue_id, unsigned int nbBytesToSend, unsigned int sid )
427 378 {
428 379 rtems_status_code status;
429 380
430 381 // SEND PACKET
431 382 status = rtems_message_queue_send( queue_id, data, nbBytesToSend);
432 383 if (status != RTEMS_SUCCESSFUL)
433 384 {
434 385 PRINTF1("ERR *** in BP_send *** ERR %d\n", (int) status)
435 386 }
436 387 }
437 388
438 389 //******************
439 390 // general functions
440 391
441 392 void reset_sm_status( void )
442 393 {
443 394 // error
444 395 // 10 --------------- 9 ---------------- 8 ---------------- 7 ---------
445 396 // input_fif0_write_2 input_fifo_write_1 input_fifo_write_0 buffer_full
446 397 // ---------- 5 -- 4 -- 3 -- 2 -- 1 -- 0 --
447 398 // ready bits f2_1 f2_0 f1_1 f1_1 f0_1 f0_0
448 399
449 400 spectral_matrix_regs->status = 0x7ff; // [0111 1111 1111]
450 401 }
451 402
452 403 void reset_spectral_matrix_regs( void )
453 404 {
454 405 /** This function resets the spectral matrices module registers.
455 406 *
456 407 * The registers affected by this function are located at the following offset addresses:
457 408 *
458 409 * - 0x00 config
459 410 * - 0x04 status
460 411 * - 0x08 matrixF0_Address0
461 412 * - 0x10 matrixFO_Address1
462 413 * - 0x14 matrixF1_Address
463 414 * - 0x18 matrixF2_Address
464 415 *
465 416 */
466 417
467 418 set_sm_irq_onError( 0 );
468 419
469 420 set_sm_irq_onNewMatrix( 0 );
470 421
471 422 reset_sm_status();
472 423
473 424 // F1
474 425 spectral_matrix_regs->f0_0_address = current_ring_node_sm_f0->previous->buffer_address;
475 426 spectral_matrix_regs->f0_1_address = current_ring_node_sm_f0->buffer_address;
476 427 // F2
477 428 spectral_matrix_regs->f1_0_address = current_ring_node_sm_f1->previous->buffer_address;
478 429 spectral_matrix_regs->f1_1_address = current_ring_node_sm_f1->buffer_address;
479 430 // F3
480 431 spectral_matrix_regs->f2_0_address = current_ring_node_sm_f2->previous->buffer_address;
481 432 spectral_matrix_regs->f2_1_address = current_ring_node_sm_f2->buffer_address;
482 433
483 434 spectral_matrix_regs->matrix_length = 0xc8; // 25 * 128 / 16 = 200 = 0xc8
484 435 }
485 436
486 437 void set_time( unsigned char *time, unsigned char * timeInBuffer )
487 438 {
488 439 time[0] = timeInBuffer[0];
489 440 time[1] = timeInBuffer[1];
490 441 time[2] = timeInBuffer[2];
491 442 time[3] = timeInBuffer[3];
492 443 time[4] = timeInBuffer[6];
493 444 time[5] = timeInBuffer[7];
494 445 }
495 446
496 447 unsigned long long int get_acquisition_time( unsigned char *timePtr )
497 448 {
498 449 unsigned long long int acquisitionTimeAslong;
499 450 acquisitionTimeAslong = 0x00;
500 451 acquisitionTimeAslong = ( (unsigned long long int) (timePtr[0] & 0x7f) << 40 ) // [0111 1111] mask the synchronization bit
501 452 + ( (unsigned long long int) timePtr[1] << 32 )
502 453 + ( (unsigned long long int) timePtr[2] << 24 )
503 454 + ( (unsigned long long int) timePtr[3] << 16 )
504 455 + ( (unsigned long long int) timePtr[6] << 8 )
505 456 + ( (unsigned long long int) timePtr[7] );
506 457 return acquisitionTimeAslong;
507 458 }
508 459
509 460 unsigned char getSID( rtems_event_set event )
510 461 {
511 462 unsigned char sid;
512 463
513 464 rtems_event_set eventSetBURST;
514 465 rtems_event_set eventSetSBM;
515 466
516 467 //******
517 468 // BURST
518 469 eventSetBURST = RTEMS_EVENT_BURST_BP1_F0
519 470 | RTEMS_EVENT_BURST_BP1_F1
520 471 | RTEMS_EVENT_BURST_BP2_F0
521 472 | RTEMS_EVENT_BURST_BP2_F1;
522 473
523 474 //****
524 475 // SBM
525 476 eventSetSBM = RTEMS_EVENT_SBM_BP1_F0
526 477 | RTEMS_EVENT_SBM_BP1_F1
527 478 | RTEMS_EVENT_SBM_BP2_F0
528 479 | RTEMS_EVENT_SBM_BP2_F1;
529 480
530 481 if (event & eventSetBURST)
531 482 {
532 483 sid = SID_BURST_BP1_F0;
533 484 }
534 485 else if (event & eventSetSBM)
535 486 {
536 487 sid = SID_SBM1_BP1_F0;
537 488 }
538 489 else
539 490 {
540 491 sid = 0;
541 492 }
542 493
543 494 return sid;
544 495 }
545 496
546 497 void extractReImVectors( float *inputASM, float *outputASM, unsigned int asmComponent )
547 498 {
548 499 unsigned int i;
549 500 float re;
550 501 float im;
551 502
552 503 for (i=0; i<NB_BINS_PER_SM; i++){
553 504 re = inputASM[ (asmComponent*NB_BINS_PER_SM) + i * 2 ];
554 505 im = inputASM[ (asmComponent*NB_BINS_PER_SM) + i * 2 + 1];
555 506 outputASM[ (asmComponent *NB_BINS_PER_SM) + i] = re;
556 507 outputASM[ (asmComponent+1)*NB_BINS_PER_SM + i] = im;
557 508 }
558 509 }
559 510
560 511 void copyReVectors( float *inputASM, float *outputASM, unsigned int asmComponent )
561 512 {
562 513 unsigned int i;
563 514 float re;
564 515
565 516 for (i=0; i<NB_BINS_PER_SM; i++){
566 517 re = inputASM[ (asmComponent*NB_BINS_PER_SM) + i];
567 518 outputASM[ (asmComponent*NB_BINS_PER_SM) + i] = re;
568 519 }
569 520 }
570 521
571 522 void ASM_patch( float *inputASM, float *outputASM )
572 523 {
573 524 extractReImVectors( inputASM, outputASM, 1); // b1b2
574 525 extractReImVectors( inputASM, outputASM, 3 ); // b1b3
575 526 extractReImVectors( inputASM, outputASM, 5 ); // b1e1
576 527 extractReImVectors( inputASM, outputASM, 7 ); // b1e2
577 528 extractReImVectors( inputASM, outputASM, 10 ); // b2b3
578 529 extractReImVectors( inputASM, outputASM, 12 ); // b2e1
579 530 extractReImVectors( inputASM, outputASM, 14 ); // b2e2
580 531 extractReImVectors( inputASM, outputASM, 17 ); // b3e1
581 532 extractReImVectors( inputASM, outputASM, 19 ); // b3e2
582 533 extractReImVectors( inputASM, outputASM, 22 ); // e1e2
583 534
584 535 copyReVectors(inputASM, outputASM, 0 ); // b1b1
585 536 copyReVectors(inputASM, outputASM, 9 ); // b2b2
586 537 copyReVectors(inputASM, outputASM, 16); // b3b3
587 538 copyReVectors(inputASM, outputASM, 21); // e1e1
588 539 copyReVectors(inputASM, outputASM, 24); // e2e2
589 540 }
590 541
591 542 void ASM_compress_reorganize_and_divide_mask(float *averaged_spec_mat, float *compressed_spec_mat , float divider,
592 543 unsigned char nbBinsCompressedMatrix, unsigned char nbBinsToAverage,
593 544 unsigned char ASMIndexStart,
594 545 unsigned char channel )
595 546 {
596 547 //*************
597 548 // input format
598 549 // component0[0 .. 127] component1[0 .. 127] .. component24[0 .. 127]
599 550 //**************
600 551 // output format
601 552 // matr0[0 .. 24] matr1[0 .. 24] .. matr127[0 .. 24]
602 553 //************
603 554 // compression
604 555 // matr0[0 .. 24] matr1[0 .. 24] .. matr11[0 .. 24] => f0 NORM
605 556 // matr0[0 .. 24] matr1[0 .. 24] .. matr22[0 .. 24] => f0 BURST, SBM
606 557
607 558 int frequencyBin;
608 559 int asmComponent;
609 560 int offsetASM;
610 561 int offsetCompressed;
611 562 int offsetFBin;
612 563 int fBinMask;
613 564 int k;
614 565
615 566 // BUILD DATA
616 567 for (asmComponent = 0; asmComponent < NB_VALUES_PER_SM; asmComponent++)
617 568 {
618 569 for( frequencyBin = 0; frequencyBin < nbBinsCompressedMatrix; frequencyBin++ )
619 570 {
620 571 offsetCompressed = // NO TIME OFFSET
621 572 frequencyBin * NB_VALUES_PER_SM
622 573 + asmComponent;
623 574 offsetASM = // NO TIME OFFSET
624 575 asmComponent * NB_BINS_PER_SM
625 576 + ASMIndexStart
626 577 + frequencyBin * nbBinsToAverage;
627 578 offsetFBin = ASMIndexStart
628 579 + frequencyBin * nbBinsToAverage;
629 580 compressed_spec_mat[ offsetCompressed ] = 0;
630 581 for ( k = 0; k < nbBinsToAverage; k++ )
631 582 {
632 583 fBinMask = getFBinMask( offsetFBin + k, channel );
633 584 compressed_spec_mat[offsetCompressed ] =
634 585 ( compressed_spec_mat[ offsetCompressed ]
635 586 + averaged_spec_mat[ offsetASM + k ] * fBinMask );
636 587 }
637 588 compressed_spec_mat[ offsetCompressed ] =
638 589 compressed_spec_mat[ offsetCompressed ] / (divider * nbBinsToAverage);
639 590 }
640 591 }
641 592
642 593 }
643 594
644 595 int getFBinMask( int index, unsigned char channel )
645 596 {
646 597 unsigned int indexInChar;
647 598 unsigned int indexInTheChar;
648 599 int fbin;
649 600 unsigned char *sy_lfr_fbins_fx_word1;
650 601
651 602 sy_lfr_fbins_fx_word1 = parameter_dump_packet.sy_lfr_fbins_f0_word1;
652 603
653 604 switch(channel)
654 605 {
655 606 case 0:
656 607 sy_lfr_fbins_fx_word1 = parameter_dump_packet.sy_lfr_fbins_f0_word1;
657 608 break;
658 609 case 1:
659 610 sy_lfr_fbins_fx_word1 = parameter_dump_packet.sy_lfr_fbins_f1_word1;
660 611 break;
661 612 case 2:
662 613 sy_lfr_fbins_fx_word1 = parameter_dump_packet.sy_lfr_fbins_f2_word1;
663 614 break;
664 615 default:
665 616 PRINTF("ERR *** in getFBinMask, wrong frequency channel")
666 617 }
667 618
668 619 indexInChar = index >> 3;
669 620 indexInTheChar = index - indexInChar * 8;
670 621
671 622 fbin = (int) ((sy_lfr_fbins_fx_word1[ NB_BYTES_PER_FREQ_MASK - 1 - indexInChar] >> indexInTheChar) & 0x1);
672 623
673 624 return fbin;
674 625 }
675 626
676 627 void init_kcoeff_sbm_from_kcoeff_norm(float *input_kcoeff, float *output_kcoeff, unsigned char nb_bins_norm)
677 628 {
678 629 unsigned char bin;
679 630 unsigned char kcoeff;
680 631
681 632 for (bin=0; bin<nb_bins_norm; bin++)
682 633 {
683 634 for (kcoeff=0; kcoeff<NB_K_COEFF_PER_BIN; kcoeff++)
684 635 {
685 636 output_kcoeff[ (bin*NB_K_COEFF_PER_BIN + kcoeff)*2 ] = input_kcoeff[ bin*NB_K_COEFF_PER_BIN + kcoeff ];
686 637 output_kcoeff[ (bin*NB_K_COEFF_PER_BIN + kcoeff)*2 + 1 ] = input_kcoeff[ bin*NB_K_COEFF_PER_BIN + kcoeff ];
687 638 }
688 639 }
689 640 }
@@ -1,1525 +1,1519
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 else // the mode value is valid, check the transition
183 183 {
184 184 status = check_mode_transition(requestedMode);
185 185 if (status != LFR_SUCCESSFUL)
186 186 {
187 187 PRINTF("ERR *** in action_enter_mode *** check_mode_transition\n")
188 188 send_tm_lfr_tc_exe_not_executable( TC, queue_id );
189 189 }
190 190 }
191 191
192 192 if ( status == LFR_SUCCESSFUL ) // the transition is valid, check the date
193 193 {
194 194 status = check_transition_date( transitionCoarseTime );
195 195 if (status != LFR_SUCCESSFUL)
196 196 {
197 197 PRINTF("ERR *** in action_enter_mode *** check_transition_date\n")
198 198 send_tm_lfr_tc_exe_inconsistent( TC, queue_id,
199 199 BYTE_POS_CP_LFR_ENTER_MODE_TIME,
200 200 bytePosPtr[ BYTE_POS_CP_LFR_ENTER_MODE_TIME + 3 ] );
201 201 }
202 202 }
203 203
204 204 if ( status == LFR_SUCCESSFUL ) // the date is valid, enter the mode
205 205 {
206 206 PRINTF1("OK *** in action_enter_mode *** enter mode %d\n", requestedMode);
207 207
208 208 switch(requestedMode)
209 209 {
210 210 case LFR_MODE_STANDBY:
211 211 status = enter_mode_standby();
212 212 break;
213 213 case LFR_MODE_NORMAL:
214 214 status = enter_mode_normal( transitionCoarseTime );
215 215 break;
216 216 case LFR_MODE_BURST:
217 217 status = enter_mode_burst( transitionCoarseTime );
218 218 break;
219 219 case LFR_MODE_SBM1:
220 220 status = enter_mode_sbm1( transitionCoarseTime );
221 221 break;
222 222 case LFR_MODE_SBM2:
223 223 status = enter_mode_sbm2( transitionCoarseTime );
224 224 break;
225 225 default:
226 226 break;
227 227 }
228 228 }
229 229
230 230 return status;
231 231 }
232 232
233 233 int action_update_info(ccsdsTelecommandPacket_t *TC, rtems_id queue_id)
234 234 {
235 235 /** This function executes specific actions when a TC_LFR_UPDATE_INFO TeleCommand has been received.
236 236 *
237 237 * @param TC points to the TeleCommand packet that is being processed
238 238 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
239 239 *
240 240 * @return LFR directive status code:
241 241 * - LFR_DEFAULT
242 242 * - LFR_SUCCESSFUL
243 243 *
244 244 */
245 245
246 246 unsigned int val;
247 247 int result;
248 248 unsigned int status;
249 249 unsigned char mode;
250 250 unsigned char * bytePosPtr;
251 251
252 252 bytePosPtr = (unsigned char *) &TC->packetID;
253 253
254 254 // check LFR mode
255 255 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET5 ] & 0x1e) >> 1;
256 256 status = check_update_info_hk_lfr_mode( mode );
257 257 if (status == LFR_SUCCESSFUL) // check TDS mode
258 258 {
259 259 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & 0xf0) >> 4;
260 260 status = check_update_info_hk_tds_mode( mode );
261 261 }
262 262 if (status == LFR_SUCCESSFUL) // check THR mode
263 263 {
264 264 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & 0x0f);
265 265 status = check_update_info_hk_thr_mode( mode );
266 266 }
267 267 if (status == LFR_SUCCESSFUL) // if the parameter check is successful
268 268 {
269 269 val = housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * 256
270 270 + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
271 271 val++;
272 272 housekeeping_packet.hk_lfr_update_info_tc_cnt[0] = (unsigned char) (val >> 8);
273 273 housekeeping_packet.hk_lfr_update_info_tc_cnt[1] = (unsigned char) (val);
274 274 }
275 275
276 276 // pa_bia_status_info
277 277 // => pa_bia_mode_mux_set 3 bits
278 278 // => pa_bia_mode_hv_enabled 1 bit
279 279 // => pa_bia_mode_bias1_enabled 1 bit
280 280 // => pa_bia_mode_bias2_enabled 1 bit
281 281 // => pa_bia_mode_bias3_enabled 1 bit
282 282 // => pa_bia_on_off (cp_dpu_bias_on_off)
283 283 pa_bia_status_info = bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET2 ] & 0xfe; // [1111 1110]
284 284 pa_bia_status_info = pa_bia_status_info
285 285 | (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET1 ] & 0x1);
286 286
287 287 result = status;
288 288
289 289 return result;
290 290 }
291 291
292 292 int action_enable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
293 293 {
294 294 /** This function executes specific actions when a TC_LFR_ENABLE_CALIBRATION TeleCommand has been received.
295 295 *
296 296 * @param TC points to the TeleCommand packet that is being processed
297 297 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
298 298 *
299 299 */
300 300
301 301 int result;
302 302
303 303 result = LFR_DEFAULT;
304 304
305 305 setCalibration( true );
306 306
307 307 result = LFR_SUCCESSFUL;
308 308
309 309 return result;
310 310 }
311 311
312 312 int action_disable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
313 313 {
314 314 /** This function executes specific actions when a TC_LFR_DISABLE_CALIBRATION TeleCommand has been received.
315 315 *
316 316 * @param TC points to the TeleCommand packet that is being processed
317 317 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
318 318 *
319 319 */
320 320
321 321 int result;
322 322
323 323 result = LFR_DEFAULT;
324 324
325 325 setCalibration( false );
326 326
327 327 result = LFR_SUCCESSFUL;
328 328
329 329 return result;
330 330 }
331 331
332 332 int action_update_time(ccsdsTelecommandPacket_t *TC)
333 333 {
334 334 /** This function executes specific actions when a TC_LFR_UPDATE_TIME TeleCommand has been received.
335 335 *
336 336 * @param TC points to the TeleCommand packet that is being processed
337 337 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
338 338 *
339 339 * @return LFR_SUCCESSFUL
340 340 *
341 341 */
342 342
343 343 unsigned int val;
344 344
345 345 time_management_regs->coarse_time_load = (TC->dataAndCRC[0] << 24)
346 346 + (TC->dataAndCRC[1] << 16)
347 347 + (TC->dataAndCRC[2] << 8)
348 348 + TC->dataAndCRC[3];
349 349
350 350 val = housekeeping_packet.hk_lfr_update_time_tc_cnt[0] * 256
351 351 + housekeeping_packet.hk_lfr_update_time_tc_cnt[1];
352 352 val++;
353 353 housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char) (val >> 8);
354 354 housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char) (val);
355 355
356 356 return LFR_SUCCESSFUL;
357 357 }
358 358
359 359 //*******************
360 360 // ENTERING THE MODES
361 361 int check_mode_value( unsigned char requestedMode )
362 362 {
363 363 int status;
364 364
365 365 if ( (requestedMode != LFR_MODE_STANDBY)
366 366 && (requestedMode != LFR_MODE_NORMAL) && (requestedMode != LFR_MODE_BURST)
367 367 && (requestedMode != LFR_MODE_SBM1) && (requestedMode != LFR_MODE_SBM2) )
368 368 {
369 369 status = LFR_DEFAULT;
370 370 }
371 371 else
372 372 {
373 373 status = LFR_SUCCESSFUL;
374 374 }
375 375
376 376 return status;
377 377 }
378 378
379 379 int check_mode_transition( unsigned char requestedMode )
380 380 {
381 381 /** This function checks the validity of the transition requested by the TC_LFR_ENTER_MODE.
382 382 *
383 383 * @param requestedMode is the mode requested by the TC_LFR_ENTER_MODE
384 384 *
385 385 * @return LFR directive status codes:
386 386 * - LFR_SUCCESSFUL - the transition is authorized
387 387 * - LFR_DEFAULT - the transition is not authorized
388 388 *
389 389 */
390 390
391 391 int status;
392 392
393 393 switch (requestedMode)
394 394 {
395 395 case LFR_MODE_STANDBY:
396 396 if ( lfrCurrentMode == LFR_MODE_STANDBY ) {
397 397 status = LFR_DEFAULT;
398 398 }
399 399 else
400 400 {
401 401 status = LFR_SUCCESSFUL;
402 402 }
403 403 break;
404 404 case LFR_MODE_NORMAL:
405 405 if ( lfrCurrentMode == LFR_MODE_NORMAL ) {
406 406 status = LFR_DEFAULT;
407 407 }
408 408 else {
409 409 status = LFR_SUCCESSFUL;
410 410 }
411 411 break;
412 412 case LFR_MODE_BURST:
413 413 if ( lfrCurrentMode == LFR_MODE_BURST ) {
414 414 status = LFR_DEFAULT;
415 415 }
416 416 else {
417 417 status = LFR_SUCCESSFUL;
418 418 }
419 419 break;
420 420 case LFR_MODE_SBM1:
421 421 if ( lfrCurrentMode == LFR_MODE_SBM1 ) {
422 422 status = LFR_DEFAULT;
423 423 }
424 424 else {
425 425 status = LFR_SUCCESSFUL;
426 426 }
427 427 break;
428 428 case LFR_MODE_SBM2:
429 429 if ( lfrCurrentMode == LFR_MODE_SBM2 ) {
430 430 status = LFR_DEFAULT;
431 431 }
432 432 else {
433 433 status = LFR_SUCCESSFUL;
434 434 }
435 435 break;
436 436 default:
437 437 status = LFR_DEFAULT;
438 438 break;
439 439 }
440 440
441 441 return status;
442 442 }
443 443
444 444 int check_transition_date( unsigned int transitionCoarseTime )
445 445 {
446 446 int status;
447 447 unsigned int localCoarseTime;
448 448 unsigned int deltaCoarseTime;
449 449
450 450 status = LFR_SUCCESSFUL;
451 451
452 452 if (transitionCoarseTime == 0) // transition time = 0 means an instant transition
453 453 {
454 454 status = LFR_SUCCESSFUL;
455 455 }
456 456 else
457 457 {
458 458 localCoarseTime = time_management_regs->coarse_time & 0x7fffffff;
459 459
460 460 PRINTF2("localTime = %x, transitionTime = %x\n", localCoarseTime, transitionCoarseTime)
461 461
462 462 if ( transitionCoarseTime <= localCoarseTime ) // SSS-CP-EQS-322
463 463 {
464 464 status = LFR_DEFAULT;
465 465 PRINTF("ERR *** in check_transition_date *** transitionCoarseTime <= localCoarseTime\n")
466 466 }
467 467
468 468 if (status == LFR_SUCCESSFUL)
469 469 {
470 470 deltaCoarseTime = transitionCoarseTime - localCoarseTime;
471 471 if ( deltaCoarseTime > 3 ) // SSS-CP-EQS-323
472 472 {
473 473 status = LFR_DEFAULT;
474 474 PRINTF1("ERR *** in check_transition_date *** deltaCoarseTime = %x\n", deltaCoarseTime)
475 475 }
476 476 }
477 477 }
478 478
479 479 return status;
480 480 }
481 481
482 482 int restart_asm_activities( unsigned char lfrRequestedMode )
483 483 {
484 484 rtems_status_code status;
485 485
486 486 status = stop_spectral_matrices();
487 487
488 488 status = restart_asm_tasks( lfrRequestedMode );
489 489
490 490 launch_spectral_matrix();
491 491
492 492 return status;
493 493 }
494 494
495 495 int stop_spectral_matrices( void )
496 496 {
497 497 /** This function stops and restarts the current mode average spectral matrices activities.
498 498 *
499 499 * @return RTEMS directive status codes:
500 500 * - RTEMS_SUCCESSFUL - task restarted successfully
501 501 * - RTEMS_INVALID_ID - task id invalid
502 502 * - RTEMS_ALREADY_SUSPENDED - task already suspended
503 503 *
504 504 */
505 505
506 506 rtems_status_code status;
507 507
508 508 status = RTEMS_SUCCESSFUL;
509 509
510 510 // (1) mask interruptions
511 511 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
512 512
513 513 // (2) reset spectral matrices registers
514 514 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
515 515 reset_sm_status();
516 516
517 517 // (3) clear interruptions
518 518 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
519 519
520 520 // suspend several tasks
521 521 if (lfrCurrentMode != LFR_MODE_STANDBY) {
522 522 status = suspend_asm_tasks();
523 523 }
524 524
525 525 if (status != RTEMS_SUCCESSFUL)
526 526 {
527 527 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
528 528 }
529 529
530 530 return status;
531 531 }
532 532
533 533 int stop_current_mode( void )
534 534 {
535 535 /** This function stops the current mode by masking interrupt lines and suspending science tasks.
536 536 *
537 537 * @return RTEMS directive status codes:
538 538 * - RTEMS_SUCCESSFUL - task restarted successfully
539 539 * - RTEMS_INVALID_ID - task id invalid
540 540 * - RTEMS_ALREADY_SUSPENDED - task already suspended
541 541 *
542 542 */
543 543
544 544 rtems_status_code status;
545 545
546 546 status = RTEMS_SUCCESSFUL;
547 547
548 548 // (1) mask interruptions
549 549 LEON_Mask_interrupt( IRQ_WAVEFORM_PICKER ); // mask waveform picker interrupt
550 550 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
551 551
552 552 // (2) reset waveform picker registers
553 553 reset_wfp_burst_enable(); // reset burst and enable bits
554 554 reset_wfp_status(); // reset all the status bits
555 555
556 556 // (3) reset spectral matrices registers
557 557 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
558 558 reset_sm_status();
559 559
560 560 // reset lfr VHDL module
561 561 reset_lfr();
562 562
563 563 reset_extractSWF(); // reset the extractSWF flag to false
564 564
565 565 // (4) clear interruptions
566 566 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER ); // clear waveform picker interrupt
567 567 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
568 568
569 // <Spectral Matrices simulator>
570 LEON_Mask_interrupt( IRQ_SM_SIMULATOR ); // mask spectral matrix interrupt simulator
571 timer_stop( (gptimer_regs_t*) REGS_ADDR_GPTIMER, TIMER_SM_SIMULATOR );
572 LEON_Clear_interrupt( IRQ_SM_SIMULATOR ); // clear spectral matrix interrupt simulator
573 // </Spectral Matrices simulator>
574
575 569 // suspend several tasks
576 570 if (lfrCurrentMode != LFR_MODE_STANDBY) {
577 571 status = suspend_science_tasks();
578 572 }
579 573
580 574 if (status != RTEMS_SUCCESSFUL)
581 575 {
582 576 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
583 577 }
584 578
585 579 return status;
586 580 }
587 581
588 582 int enter_mode_standby()
589 583 {
590 584 int status;
591 585
592 586 status = stop_current_mode(); // STOP THE CURRENT MODE
593 587
594 588 #ifdef PRINT_TASK_STATISTICS
595 589 rtems_cpu_usage_report();
596 590 #endif
597 591
598 592 #ifdef PRINT_STACK_REPORT
599 593 PRINTF("stack report selected\n")
600 594 rtems_stack_checker_report_usage();
601 595 #endif
602 596
603 597 return status;
604 598 }
605 599
606 600 int enter_mode_normal( unsigned int transitionCoarseTime )
607 601 {
608 602 int status;
609 603
610 604 #ifdef PRINT_TASK_STATISTICS
611 605 rtems_cpu_usage_reset();
612 606 #endif
613 607
614 608 status = RTEMS_UNSATISFIED;
615 609
616 610 switch( lfrCurrentMode )
617 611 {
618 612 case LFR_MODE_STANDBY:
619 613 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart science tasks
620 614 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
621 615 {
622 616 launch_spectral_matrix( );
623 617 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
624 618 }
625 619 break;
626 620 case LFR_MODE_BURST:
627 621 status = stop_current_mode(); // stop the current mode
628 622 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart the science tasks
629 623 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
630 624 {
631 625 launch_spectral_matrix( );
632 626 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
633 627 }
634 628 break;
635 629 case LFR_MODE_SBM1:
636 630 restart_asm_activities( LFR_MODE_NORMAL );
637 631 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
638 632 break;
639 633 case LFR_MODE_SBM2:
640 634 restart_asm_activities( LFR_MODE_NORMAL );
641 635 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
642 636 break;
643 637 default:
644 638 break;
645 639 }
646 640
647 641 if (status != RTEMS_SUCCESSFUL)
648 642 {
649 643 PRINTF1("ERR *** in enter_mode_normal *** status = %d\n", status)
650 644 status = RTEMS_UNSATISFIED;
651 645 }
652 646
653 647 return status;
654 648 }
655 649
656 650 int enter_mode_burst( unsigned int transitionCoarseTime )
657 651 {
658 652 int status;
659 653
660 654 #ifdef PRINT_TASK_STATISTICS
661 655 rtems_cpu_usage_reset();
662 656 #endif
663 657
664 658 status = stop_current_mode(); // stop the current mode
665 659 status = restart_science_tasks( LFR_MODE_BURST ); // restart the science tasks
666 660 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
667 661 {
668 662 launch_spectral_matrix( );
669 663 launch_waveform_picker( LFR_MODE_BURST, transitionCoarseTime );
670 664 }
671 665
672 666 if (status != RTEMS_SUCCESSFUL)
673 667 {
674 668 PRINTF1("ERR *** in enter_mode_burst *** status = %d\n", status)
675 669 status = RTEMS_UNSATISFIED;
676 670 }
677 671
678 672 return status;
679 673 }
680 674
681 675 int enter_mode_sbm1( unsigned int transitionCoarseTime )
682 676 {
683 677 int status;
684 678
685 679 #ifdef PRINT_TASK_STATISTICS
686 680 rtems_cpu_usage_reset();
687 681 #endif
688 682
689 683 status = RTEMS_UNSATISFIED;
690 684
691 685 switch( lfrCurrentMode )
692 686 {
693 687 case LFR_MODE_STANDBY:
694 688 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart science tasks
695 689 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
696 690 {
697 691 launch_spectral_matrix( );
698 692 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
699 693 }
700 694 break;
701 695 case LFR_MODE_NORMAL: // lfrCurrentMode will be updated after the execution of close_action
702 696 restart_asm_activities( LFR_MODE_SBM1 );
703 697 status = LFR_SUCCESSFUL;
704 698 break;
705 699 case LFR_MODE_BURST:
706 700 status = stop_current_mode(); // stop the current mode
707 701 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart the science tasks
708 702 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
709 703 {
710 704 launch_spectral_matrix( );
711 705 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
712 706 }
713 707 break;
714 708 case LFR_MODE_SBM2:
715 709 restart_asm_activities( LFR_MODE_SBM1 );
716 710 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
717 711 break;
718 712 default:
719 713 break;
720 714 }
721 715
722 716 if (status != RTEMS_SUCCESSFUL)
723 717 {
724 718 PRINTF1("ERR *** in enter_mode_sbm1 *** status = %d\n", status)
725 719 status = RTEMS_UNSATISFIED;
726 720 }
727 721
728 722 return status;
729 723 }
730 724
731 725 int enter_mode_sbm2( unsigned int transitionCoarseTime )
732 726 {
733 727 int status;
734 728
735 729 #ifdef PRINT_TASK_STATISTICS
736 730 rtems_cpu_usage_reset();
737 731 #endif
738 732
739 733 status = RTEMS_UNSATISFIED;
740 734
741 735 switch( lfrCurrentMode )
742 736 {
743 737 case LFR_MODE_STANDBY:
744 738 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart science tasks
745 739 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
746 740 {
747 741 launch_spectral_matrix( );
748 742 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
749 743 }
750 744 break;
751 745 case LFR_MODE_NORMAL:
752 746 restart_asm_activities( LFR_MODE_SBM2 );
753 747 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
754 748 break;
755 749 case LFR_MODE_BURST:
756 750 status = stop_current_mode(); // stop the current mode
757 751 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart the science tasks
758 752 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
759 753 {
760 754 launch_spectral_matrix( );
761 755 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
762 756 }
763 757 break;
764 758 case LFR_MODE_SBM1:
765 759 restart_asm_activities( LFR_MODE_SBM2 );
766 760 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
767 761 break;
768 762 default:
769 763 break;
770 764 }
771 765
772 766 if (status != RTEMS_SUCCESSFUL)
773 767 {
774 768 PRINTF1("ERR *** in enter_mode_sbm2 *** status = %d\n", status)
775 769 status = RTEMS_UNSATISFIED;
776 770 }
777 771
778 772 return status;
779 773 }
780 774
781 775 int restart_science_tasks( unsigned char lfrRequestedMode )
782 776 {
783 777 /** This function is used to restart all science tasks.
784 778 *
785 779 * @return RTEMS directive status codes:
786 780 * - RTEMS_SUCCESSFUL - task restarted successfully
787 781 * - RTEMS_INVALID_ID - task id invalid
788 782 * - RTEMS_INCORRECT_STATE - task never started
789 783 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
790 784 *
791 785 * Science tasks are AVF0, PRC0, WFRM, CWF3, CW2, CWF1
792 786 *
793 787 */
794 788
795 789 rtems_status_code status[10];
796 790 rtems_status_code ret;
797 791
798 792 ret = RTEMS_SUCCESSFUL;
799 793
800 794 status[0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
801 795 if (status[0] != RTEMS_SUCCESSFUL)
802 796 {
803 797 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[0])
804 798 }
805 799
806 800 status[1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
807 801 if (status[1] != RTEMS_SUCCESSFUL)
808 802 {
809 803 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[1])
810 804 }
811 805
812 806 status[2] = rtems_task_restart( Task_id[TASKID_WFRM],1 );
813 807 if (status[2] != RTEMS_SUCCESSFUL)
814 808 {
815 809 PRINTF1("in restart_science_task *** WFRM ERR %d\n", status[2])
816 810 }
817 811
818 812 status[3] = rtems_task_restart( Task_id[TASKID_CWF3],1 );
819 813 if (status[3] != RTEMS_SUCCESSFUL)
820 814 {
821 815 PRINTF1("in restart_science_task *** CWF3 ERR %d\n", status[3])
822 816 }
823 817
824 818 status[4] = rtems_task_restart( Task_id[TASKID_CWF2],1 );
825 819 if (status[4] != RTEMS_SUCCESSFUL)
826 820 {
827 821 PRINTF1("in restart_science_task *** CWF2 ERR %d\n", status[4])
828 822 }
829 823
830 824 status[5] = rtems_task_restart( Task_id[TASKID_CWF1],1 );
831 825 if (status[5] != RTEMS_SUCCESSFUL)
832 826 {
833 827 PRINTF1("in restart_science_task *** CWF1 ERR %d\n", status[5])
834 828 }
835 829
836 830 status[6] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
837 831 if (status[6] != RTEMS_SUCCESSFUL)
838 832 {
839 833 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[6])
840 834 }
841 835
842 836 status[7] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
843 837 if (status[7] != RTEMS_SUCCESSFUL)
844 838 {
845 839 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[7])
846 840 }
847 841
848 842 status[8] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
849 843 if (status[8] != RTEMS_SUCCESSFUL)
850 844 {
851 845 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[8])
852 846 }
853 847
854 848 status[9] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
855 849 if (status[9] != RTEMS_SUCCESSFUL)
856 850 {
857 851 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[9])
858 852 }
859 853
860 854 if ( (status[0] != RTEMS_SUCCESSFUL) || (status[1] != RTEMS_SUCCESSFUL) ||
861 855 (status[2] != RTEMS_SUCCESSFUL) || (status[3] != RTEMS_SUCCESSFUL) ||
862 856 (status[4] != RTEMS_SUCCESSFUL) || (status[5] != RTEMS_SUCCESSFUL) ||
863 857 (status[6] != RTEMS_SUCCESSFUL) || (status[7] != RTEMS_SUCCESSFUL) ||
864 858 (status[8] != RTEMS_SUCCESSFUL) || (status[9] != RTEMS_SUCCESSFUL) )
865 859 {
866 860 ret = RTEMS_UNSATISFIED;
867 861 }
868 862
869 863 return ret;
870 864 }
871 865
872 866 int restart_asm_tasks( unsigned char lfrRequestedMode )
873 867 {
874 868 /** This function is used to restart average spectral matrices tasks.
875 869 *
876 870 * @return RTEMS directive status codes:
877 871 * - RTEMS_SUCCESSFUL - task restarted successfully
878 872 * - RTEMS_INVALID_ID - task id invalid
879 873 * - RTEMS_INCORRECT_STATE - task never started
880 874 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
881 875 *
882 876 * ASM tasks are AVF0, PRC0, AVF1, PRC1, AVF2 and PRC2
883 877 *
884 878 */
885 879
886 880 rtems_status_code status[6];
887 881 rtems_status_code ret;
888 882
889 883 ret = RTEMS_SUCCESSFUL;
890 884
891 885 status[0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
892 886 if (status[0] != RTEMS_SUCCESSFUL)
893 887 {
894 888 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[0])
895 889 }
896 890
897 891 status[1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
898 892 if (status[1] != RTEMS_SUCCESSFUL)
899 893 {
900 894 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[1])
901 895 }
902 896
903 897 status[2] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
904 898 if (status[2] != RTEMS_SUCCESSFUL)
905 899 {
906 900 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[2])
907 901 }
908 902
909 903 status[3] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
910 904 if (status[3] != RTEMS_SUCCESSFUL)
911 905 {
912 906 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[3])
913 907 }
914 908
915 909 status[4] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
916 910 if (status[4] != RTEMS_SUCCESSFUL)
917 911 {
918 912 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[4])
919 913 }
920 914
921 915 status[5] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
922 916 if (status[5] != RTEMS_SUCCESSFUL)
923 917 {
924 918 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[5])
925 919 }
926 920
927 921 if ( (status[0] != RTEMS_SUCCESSFUL) || (status[1] != RTEMS_SUCCESSFUL) ||
928 922 (status[2] != RTEMS_SUCCESSFUL) || (status[3] != RTEMS_SUCCESSFUL) ||
929 923 (status[4] != RTEMS_SUCCESSFUL) || (status[5] != RTEMS_SUCCESSFUL) )
930 924 {
931 925 ret = RTEMS_UNSATISFIED;
932 926 }
933 927
934 928 return ret;
935 929 }
936 930
937 931 int suspend_science_tasks( void )
938 932 {
939 933 /** This function suspends the science tasks.
940 934 *
941 935 * @return RTEMS directive status codes:
942 936 * - RTEMS_SUCCESSFUL - task restarted successfully
943 937 * - RTEMS_INVALID_ID - task id invalid
944 938 * - RTEMS_ALREADY_SUSPENDED - task already suspended
945 939 *
946 940 */
947 941
948 942 rtems_status_code status;
949 943
950 944 PRINTF("in suspend_science_tasks\n")
951 945
952 946 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
953 947 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
954 948 {
955 949 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
956 950 }
957 951 else
958 952 {
959 953 status = RTEMS_SUCCESSFUL;
960 954 }
961 955 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
962 956 {
963 957 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
964 958 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
965 959 {
966 960 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
967 961 }
968 962 else
969 963 {
970 964 status = RTEMS_SUCCESSFUL;
971 965 }
972 966 }
973 967 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
974 968 {
975 969 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
976 970 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
977 971 {
978 972 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
979 973 }
980 974 else
981 975 {
982 976 status = RTEMS_SUCCESSFUL;
983 977 }
984 978 }
985 979 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
986 980 {
987 981 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
988 982 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
989 983 {
990 984 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
991 985 }
992 986 else
993 987 {
994 988 status = RTEMS_SUCCESSFUL;
995 989 }
996 990 }
997 991 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
998 992 {
999 993 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1000 994 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1001 995 {
1002 996 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1003 997 }
1004 998 else
1005 999 {
1006 1000 status = RTEMS_SUCCESSFUL;
1007 1001 }
1008 1002 }
1009 1003 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1010 1004 {
1011 1005 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1012 1006 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1013 1007 {
1014 1008 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1015 1009 }
1016 1010 else
1017 1011 {
1018 1012 status = RTEMS_SUCCESSFUL;
1019 1013 }
1020 1014 }
1021 1015 if (status == RTEMS_SUCCESSFUL) // suspend WFRM
1022 1016 {
1023 1017 status = rtems_task_suspend( Task_id[TASKID_WFRM] );
1024 1018 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1025 1019 {
1026 1020 PRINTF1("in suspend_science_task *** WFRM ERR %d\n", status)
1027 1021 }
1028 1022 else
1029 1023 {
1030 1024 status = RTEMS_SUCCESSFUL;
1031 1025 }
1032 1026 }
1033 1027 if (status == RTEMS_SUCCESSFUL) // suspend CWF3
1034 1028 {
1035 1029 status = rtems_task_suspend( Task_id[TASKID_CWF3] );
1036 1030 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1037 1031 {
1038 1032 PRINTF1("in suspend_science_task *** CWF3 ERR %d\n", status)
1039 1033 }
1040 1034 else
1041 1035 {
1042 1036 status = RTEMS_SUCCESSFUL;
1043 1037 }
1044 1038 }
1045 1039 if (status == RTEMS_SUCCESSFUL) // suspend CWF2
1046 1040 {
1047 1041 status = rtems_task_suspend( Task_id[TASKID_CWF2] );
1048 1042 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1049 1043 {
1050 1044 PRINTF1("in suspend_science_task *** CWF2 ERR %d\n", status)
1051 1045 }
1052 1046 else
1053 1047 {
1054 1048 status = RTEMS_SUCCESSFUL;
1055 1049 }
1056 1050 }
1057 1051 if (status == RTEMS_SUCCESSFUL) // suspend CWF1
1058 1052 {
1059 1053 status = rtems_task_suspend( Task_id[TASKID_CWF1] );
1060 1054 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1061 1055 {
1062 1056 PRINTF1("in suspend_science_task *** CWF1 ERR %d\n", status)
1063 1057 }
1064 1058 else
1065 1059 {
1066 1060 status = RTEMS_SUCCESSFUL;
1067 1061 }
1068 1062 }
1069 1063
1070 1064 return status;
1071 1065 }
1072 1066
1073 1067 int suspend_asm_tasks( void )
1074 1068 {
1075 1069 /** This function suspends the science tasks.
1076 1070 *
1077 1071 * @return RTEMS directive status codes:
1078 1072 * - RTEMS_SUCCESSFUL - task restarted successfully
1079 1073 * - RTEMS_INVALID_ID - task id invalid
1080 1074 * - RTEMS_ALREADY_SUSPENDED - task already suspended
1081 1075 *
1082 1076 */
1083 1077
1084 1078 rtems_status_code status;
1085 1079
1086 1080 PRINTF("in suspend_science_tasks\n")
1087 1081
1088 1082 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
1089 1083 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1090 1084 {
1091 1085 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
1092 1086 }
1093 1087 else
1094 1088 {
1095 1089 status = RTEMS_SUCCESSFUL;
1096 1090 }
1097 1091
1098 1092 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
1099 1093 {
1100 1094 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
1101 1095 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1102 1096 {
1103 1097 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
1104 1098 }
1105 1099 else
1106 1100 {
1107 1101 status = RTEMS_SUCCESSFUL;
1108 1102 }
1109 1103 }
1110 1104
1111 1105 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
1112 1106 {
1113 1107 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
1114 1108 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1115 1109 {
1116 1110 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
1117 1111 }
1118 1112 else
1119 1113 {
1120 1114 status = RTEMS_SUCCESSFUL;
1121 1115 }
1122 1116 }
1123 1117
1124 1118 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
1125 1119 {
1126 1120 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
1127 1121 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1128 1122 {
1129 1123 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
1130 1124 }
1131 1125 else
1132 1126 {
1133 1127 status = RTEMS_SUCCESSFUL;
1134 1128 }
1135 1129 }
1136 1130
1137 1131 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
1138 1132 {
1139 1133 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
1140 1134 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1141 1135 {
1142 1136 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
1143 1137 }
1144 1138 else
1145 1139 {
1146 1140 status = RTEMS_SUCCESSFUL;
1147 1141 }
1148 1142 }
1149 1143
1150 1144 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
1151 1145 {
1152 1146 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
1153 1147 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
1154 1148 {
1155 1149 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
1156 1150 }
1157 1151 else
1158 1152 {
1159 1153 status = RTEMS_SUCCESSFUL;
1160 1154 }
1161 1155 }
1162 1156
1163 1157 return status;
1164 1158 }
1165 1159
1166 1160 void launch_waveform_picker( unsigned char mode, unsigned int transitionCoarseTime )
1167 1161 {
1168 1162 WFP_reset_current_ring_nodes();
1169 1163
1170 1164 reset_waveform_picker_regs();
1171 1165
1172 1166 set_wfp_burst_enable_register( mode );
1173 1167
1174 1168 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER );
1175 1169 LEON_Unmask_interrupt( IRQ_WAVEFORM_PICKER );
1176 1170
1177 1171 if (transitionCoarseTime == 0)
1178 1172 {
1179 1173 waveform_picker_regs->start_date = time_management_regs->coarse_time;
1180 1174 }
1181 1175 else
1182 1176 {
1183 1177 waveform_picker_regs->start_date = transitionCoarseTime;
1184 1178 }
1185 1179
1186 1180 }
1187 1181
1188 1182 void launch_spectral_matrix( void )
1189 1183 {
1190 1184 SM_reset_current_ring_nodes();
1191 1185
1192 1186 reset_spectral_matrix_regs();
1193 1187
1194 1188 reset_nb_sm();
1195 1189
1196 1190 set_sm_irq_onNewMatrix( 1 );
1197 1191
1198 1192 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX );
1199 1193 LEON_Unmask_interrupt( IRQ_SPECTRAL_MATRIX );
1200 1194
1201 1195 }
1202 1196
1203 1197 void set_sm_irq_onNewMatrix( unsigned char value )
1204 1198 {
1205 1199 if (value == 1)
1206 1200 {
1207 1201 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x01;
1208 1202 }
1209 1203 else
1210 1204 {
1211 1205 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffe; // 1110
1212 1206 }
1213 1207 }
1214 1208
1215 1209 void set_sm_irq_onError( unsigned char value )
1216 1210 {
1217 1211 if (value == 1)
1218 1212 {
1219 1213 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x02;
1220 1214 }
1221 1215 else
1222 1216 {
1223 1217 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffd; // 1101
1224 1218 }
1225 1219 }
1226 1220
1227 1221 //*****************************
1228 1222 // CONFIGURE CALIBRATION SIGNAL
1229 1223 void setCalibrationPrescaler( unsigned int prescaler )
1230 1224 {
1231 1225 // prescaling of the master clock (25 MHz)
1232 1226 // master clock is divided by 2^prescaler
1233 1227 time_management_regs->calPrescaler = prescaler;
1234 1228 }
1235 1229
1236 1230 void setCalibrationDivisor( unsigned int divisionFactor )
1237 1231 {
1238 1232 // division of the prescaled clock by the division factor
1239 1233 time_management_regs->calDivisor = divisionFactor;
1240 1234 }
1241 1235
1242 1236 void setCalibrationData( void ){
1243 1237 unsigned int k;
1244 1238 unsigned short data;
1245 1239 float val;
1246 1240 float f0;
1247 1241 float f1;
1248 1242 float fs;
1249 1243 float Ts;
1250 1244 float scaleFactor;
1251 1245
1252 1246 f0 = 625;
1253 1247 f1 = 10000;
1254 1248 fs = 160256.410;
1255 1249 Ts = 1. / fs;
1256 1250 scaleFactor = 0.250 / 0.000654; // 191, 500 mVpp, 2 sinus waves => 500 mVpp each, amplitude = 250 mV
1257 1251
1258 1252 time_management_regs->calDataPtr = 0x00;
1259 1253
1260 1254 // build the signal for the SCM calibration
1261 1255 for (k=0; k<256; k++)
1262 1256 {
1263 1257 val = sin( 2 * pi * f0 * k * Ts )
1264 1258 + sin( 2 * pi * f1 * k * Ts );
1265 1259 data = (unsigned short) ((val * scaleFactor) + 2048);
1266 1260 time_management_regs->calData = data & 0xfff;
1267 1261 }
1268 1262 }
1269 1263
1270 1264 void setCalibrationDataInterleaved( void ){
1271 1265 unsigned int k;
1272 1266 float val;
1273 1267 float f0;
1274 1268 float f1;
1275 1269 float fs;
1276 1270 float Ts;
1277 1271 unsigned short data[384];
1278 1272 unsigned char *dataPtr;
1279 1273
1280 1274 f0 = 625;
1281 1275 f1 = 10000;
1282 1276 fs = 240384.615;
1283 1277 Ts = 1. / fs;
1284 1278
1285 1279 time_management_regs->calDataPtr = 0x00;
1286 1280
1287 1281 // build the signal for the SCM calibration
1288 1282 for (k=0; k<384; k++)
1289 1283 {
1290 1284 val = sin( 2 * pi * f0 * k * Ts )
1291 1285 + sin( 2 * pi * f1 * k * Ts );
1292 1286 data[k] = (unsigned short) (val * 512 + 2048);
1293 1287 }
1294 1288
1295 1289 // write the signal in interleaved mode
1296 1290 for (k=0; k<128; k++)
1297 1291 {
1298 1292 dataPtr = (unsigned char*) &data[k*3 + 2];
1299 1293 time_management_regs->calData = (data[k*3] & 0xfff)
1300 1294 + ( (dataPtr[0] & 0x3f) << 12);
1301 1295 time_management_regs->calData = (data[k*3 + 1] & 0xfff)
1302 1296 + ( (dataPtr[1] & 0x3f) << 12);
1303 1297 }
1304 1298 }
1305 1299
1306 1300 void setCalibrationReload( bool state)
1307 1301 {
1308 1302 if (state == true)
1309 1303 {
1310 1304 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000010; // [0001 0000]
1311 1305 }
1312 1306 else
1313 1307 {
1314 1308 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffef; // [1110 1111]
1315 1309 }
1316 1310 }
1317 1311
1318 1312 void setCalibrationEnable( bool state )
1319 1313 {
1320 1314 // this bit drives the multiplexer
1321 1315 if (state == true)
1322 1316 {
1323 1317 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000040; // [0100 0000]
1324 1318 }
1325 1319 else
1326 1320 {
1327 1321 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffbf; // [1011 1111]
1328 1322 }
1329 1323 }
1330 1324
1331 1325 void setCalibrationInterleaved( bool state )
1332 1326 {
1333 1327 // this bit drives the multiplexer
1334 1328 if (state == true)
1335 1329 {
1336 1330 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000020; // [0010 0000]
1337 1331 }
1338 1332 else
1339 1333 {
1340 1334 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffdf; // [1101 1111]
1341 1335 }
1342 1336 }
1343 1337
1344 1338 void setCalibration( bool state )
1345 1339 {
1346 1340 if (state == true)
1347 1341 {
1348 1342 setCalibrationEnable( true );
1349 1343 setCalibrationReload( false );
1350 1344 set_hk_lfr_calib_enable( true );
1351 1345 }
1352 1346 else
1353 1347 {
1354 1348 setCalibrationEnable( false );
1355 1349 setCalibrationReload( true );
1356 1350 set_hk_lfr_calib_enable( false );
1357 1351 }
1358 1352 }
1359 1353
1360 1354 void configureCalibration( bool interleaved )
1361 1355 {
1362 1356 setCalibration( false );
1363 1357 if ( interleaved == true )
1364 1358 {
1365 1359 setCalibrationInterleaved( true );
1366 1360 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1367 1361 setCalibrationDivisor( 26 ); // => 240 384
1368 1362 setCalibrationDataInterleaved();
1369 1363 }
1370 1364 else
1371 1365 {
1372 1366 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1373 1367 setCalibrationDivisor( 38 ); // => 160 256 (39 - 1)
1374 1368 setCalibrationData();
1375 1369 }
1376 1370 }
1377 1371
1378 1372 //****************
1379 1373 // CLOSING ACTIONS
1380 1374 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC, unsigned char * time )
1381 1375 {
1382 1376 /** This function is used to update the HK packets statistics after a successful TC execution.
1383 1377 *
1384 1378 * @param TC points to the TC being processed
1385 1379 * @param time is the time used to date the TC execution
1386 1380 *
1387 1381 */
1388 1382
1389 1383 unsigned int val;
1390 1384
1391 1385 housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
1392 1386 housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
1393 1387 housekeeping_packet.hk_lfr_last_exe_tc_type[0] = 0x00;
1394 1388 housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
1395 1389 housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = 0x00;
1396 1390 housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
1397 1391 housekeeping_packet.hk_lfr_last_exe_tc_time[0] = time[0];
1398 1392 housekeeping_packet.hk_lfr_last_exe_tc_time[1] = time[1];
1399 1393 housekeeping_packet.hk_lfr_last_exe_tc_time[2] = time[2];
1400 1394 housekeeping_packet.hk_lfr_last_exe_tc_time[3] = time[3];
1401 1395 housekeeping_packet.hk_lfr_last_exe_tc_time[4] = time[4];
1402 1396 housekeeping_packet.hk_lfr_last_exe_tc_time[5] = time[5];
1403 1397
1404 1398 val = housekeeping_packet.hk_lfr_exe_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
1405 1399 val++;
1406 1400 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> 8);
1407 1401 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
1408 1402 }
1409 1403
1410 1404 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC, unsigned char * time )
1411 1405 {
1412 1406 /** This function is used to update the HK packets statistics after a TC rejection.
1413 1407 *
1414 1408 * @param TC points to the TC being processed
1415 1409 * @param time is the time used to date the TC rejection
1416 1410 *
1417 1411 */
1418 1412
1419 1413 unsigned int val;
1420 1414
1421 1415 housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
1422 1416 housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
1423 1417 housekeeping_packet.hk_lfr_last_rej_tc_type[0] = 0x00;
1424 1418 housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
1425 1419 housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = 0x00;
1426 1420 housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
1427 1421 housekeeping_packet.hk_lfr_last_rej_tc_time[0] = time[0];
1428 1422 housekeeping_packet.hk_lfr_last_rej_tc_time[1] = time[1];
1429 1423 housekeeping_packet.hk_lfr_last_rej_tc_time[2] = time[2];
1430 1424 housekeeping_packet.hk_lfr_last_rej_tc_time[3] = time[3];
1431 1425 housekeeping_packet.hk_lfr_last_rej_tc_time[4] = time[4];
1432 1426 housekeeping_packet.hk_lfr_last_rej_tc_time[5] = time[5];
1433 1427
1434 1428 val = housekeeping_packet.hk_lfr_rej_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
1435 1429 val++;
1436 1430 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> 8);
1437 1431 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
1438 1432 }
1439 1433
1440 1434 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id )
1441 1435 {
1442 1436 /** This function is the last step of the TC execution workflow.
1443 1437 *
1444 1438 * @param TC points to the TC being processed
1445 1439 * @param result is the result of the TC execution (LFR_SUCCESSFUL / LFR_DEFAULT)
1446 1440 * @param queue_id is the id of the RTEMS message queue used to send TM packets
1447 1441 * @param time is the time used to date the TC execution
1448 1442 *
1449 1443 */
1450 1444
1451 1445 unsigned char requestedMode;
1452 1446
1453 1447 if (result == LFR_SUCCESSFUL)
1454 1448 {
1455 1449 if ( !( (TC->serviceType==TC_TYPE_TIME) & (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
1456 1450 &
1457 1451 !( (TC->serviceType==TC_TYPE_GEN) & (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
1458 1452 )
1459 1453 {
1460 1454 send_tm_lfr_tc_exe_success( TC, queue_id );
1461 1455 }
1462 1456 if ( (TC->serviceType == TC_TYPE_GEN) & (TC->serviceSubType == TC_SUBTYPE_ENTER) )
1463 1457 {
1464 1458 //**********************************
1465 1459 // UPDATE THE LFRMODE LOCAL VARIABLE
1466 1460 requestedMode = TC->dataAndCRC[1];
1467 1461 housekeeping_packet.lfr_status_word[0] = (unsigned char) ((requestedMode << 4) + 0x0d);
1468 1462 updateLFRCurrentMode();
1469 1463 }
1470 1464 }
1471 1465 else if (result == LFR_EXE_ERROR)
1472 1466 {
1473 1467 send_tm_lfr_tc_exe_error( TC, queue_id );
1474 1468 }
1475 1469 }
1476 1470
1477 1471 //***************************
1478 1472 // Interrupt Service Routines
1479 1473 rtems_isr commutation_isr1( rtems_vector_number vector )
1480 1474 {
1481 1475 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1482 1476 PRINTF("In commutation_isr1 *** Error sending event to DUMB\n")
1483 1477 }
1484 1478 }
1485 1479
1486 1480 rtems_isr commutation_isr2( rtems_vector_number vector )
1487 1481 {
1488 1482 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1489 1483 PRINTF("In commutation_isr2 *** Error sending event to DUMB\n")
1490 1484 }
1491 1485 }
1492 1486
1493 1487 //****************
1494 1488 // OTHER FUNCTIONS
1495 1489 void updateLFRCurrentMode()
1496 1490 {
1497 1491 /** This function updates the value of the global variable lfrCurrentMode.
1498 1492 *
1499 1493 * lfrCurrentMode is a parameter used by several functions to know in which mode LFR is running.
1500 1494 *
1501 1495 */
1502 1496 // update the local value of lfrCurrentMode with the value contained in the housekeeping_packet structure
1503 1497 lfrCurrentMode = (housekeeping_packet.lfr_status_word[0] & 0xf0) >> 4;
1504 1498 }
1505 1499
1506 1500 void set_lfr_soft_reset( unsigned char value )
1507 1501 {
1508 1502 if (value == 1)
1509 1503 {
1510 1504 time_management_regs->ctrl = time_management_regs->ctrl | 0x00000004; // [0100]
1511 1505 }
1512 1506 else
1513 1507 {
1514 1508 time_management_regs->ctrl = time_management_regs->ctrl & 0xfffffffb; // [1011]
1515 1509 }
1516 1510 }
1517 1511
1518 1512 void reset_lfr( void )
1519 1513 {
1520 1514 set_lfr_soft_reset( 1 );
1521 1515
1522 1516 set_lfr_soft_reset( 0 );
1523 1517
1524 1518 set_hk_lfr_sc_potential_flag( true );
1525 1519 }
General Comments 0
You need to be logged in to leave comments. Login now