##// END OF EJS Templates
sync before modifying the snapshot resynchronization
paul -
r246:9f992c214f6f R3a
parent child
Show More
@@ -1,112 +1,116
1 1 TEMPLATE = app
2 2 # CONFIG += console v8 sim
3 3 # CONFIG options = verbose *** boot_messages *** debug_messages *** cpu_usage_report *** stack_report *** vhdl_dev *** debug_tch
4 4 # lpp_dpu_destid
5 CONFIG += console verbose lpp_dpu_destid cpu_usage_report stack_report
5 CONFIG += console verbose lpp_dpu_destid
6 6 CONFIG -= qt
7 7
8 8 include(./sparc.pri)
9 9
10 10 # flight software version
11 11 SWVERSION=-1-0
12 12 DEFINES += SW_VERSION_N1=3 # major
13 13 DEFINES += SW_VERSION_N2=0 # minor
14 14 DEFINES += SW_VERSION_N3=0 # patch
15 15 DEFINES += SW_VERSION_N4=13 # internal
16 16
17 17 # <GCOV>
18 18 #QMAKE_CFLAGS_RELEASE += -fprofile-arcs -ftest-coverage
19 19 #LIBS += -lgcov /opt/GCOV/01A/lib/overload.o -lc
20 20 # </GCOV>
21 21
22 22 # <CHANGE BEFORE FLIGHT>
23 23 contains( CONFIG, lpp_dpu_destid ) {
24 24 DEFINES += LPP_DPU_DESTID
25 25 }
26 26 # </CHANGE BEFORE FLIGHT>
27 27
28 28 contains( CONFIG, debug_tch ) {
29 29 DEFINES += DEBUG_TCH
30 30 }
31 31 DEFINES += MSB_FIRST_TCH
32 32
33 33 contains( CONFIG, vhdl_dev ) {
34 34 DEFINES += VHDL_DEV
35 35 }
36 36
37 37 contains( CONFIG, verbose ) {
38 38 DEFINES += PRINT_MESSAGES_ON_CONSOLE
39 39 }
40 40
41 41 contains( CONFIG, debug_messages ) {
42 42 DEFINES += DEBUG_MESSAGES
43 43 }
44 44
45 45 contains( CONFIG, cpu_usage_report ) {
46 46 DEFINES += PRINT_TASK_STATISTICS
47 47 }
48 48
49 49 contains( CONFIG, stack_report ) {
50 50 DEFINES += PRINT_STACK_REPORT
51 51 }
52 52
53 53 contains( CONFIG, boot_messages ) {
54 54 DEFINES += BOOT_MESSAGES
55 55 }
56 56
57 contains( CONFIG, debug_watchdog ) {
58 DEFINES += DEBUG_WATCHDOG
59 }
60
57 61 #doxygen.target = doxygen
58 62 #doxygen.commands = doxygen ../doc/Doxyfile
59 63 #QMAKE_EXTRA_TARGETS += doxygen
60 64
61 65 TARGET = fsw
62 66
63 67 INCLUDEPATH += \
64 68 $${PWD}/../src \
65 69 $${PWD}/../header \
66 70 $${PWD}/../header/lfr_common_headers \
67 71 $${PWD}/../header/processing \
68 72 $${PWD}/../LFR_basic-parameters
69 73
70 74 SOURCES += \
71 75 ../src/wf_handler.c \
72 76 ../src/tc_handler.c \
73 77 ../src/fsw_misc.c \
74 78 ../src/fsw_init.c \
75 79 ../src/fsw_globals.c \
76 80 ../src/fsw_spacewire.c \
77 81 ../src/tc_load_dump_parameters.c \
78 82 ../src/tm_lfr_tc_exe.c \
79 83 ../src/tc_acceptance.c \
80 84 ../src/processing/fsw_processing.c \
81 85 ../src/processing/avf0_prc0.c \
82 86 ../src/processing/avf1_prc1.c \
83 87 ../src/processing/avf2_prc2.c \
84 88 ../src/lfr_cpu_usage_report.c \
85 89 ../LFR_basic-parameters/basic_parameters.c
86 90
87 91 HEADERS += \
88 92 ../header/wf_handler.h \
89 93 ../header/tc_handler.h \
90 94 ../header/grlib_regs.h \
91 95 ../header/fsw_misc.h \
92 96 ../header/fsw_init.h \
93 97 ../header/fsw_spacewire.h \
94 98 ../header/tc_load_dump_parameters.h \
95 99 ../header/tm_lfr_tc_exe.h \
96 100 ../header/tc_acceptance.h \
97 101 ../header/processing/fsw_processing.h \
98 102 ../header/processing/avf0_prc0.h \
99 103 ../header/processing/avf1_prc1.h \
100 104 ../header/processing/avf2_prc2.h \
101 105 ../header/fsw_params_wf_handler.h \
102 106 ../header/lfr_cpu_usage_report.h \
103 107 ../header/lfr_common_headers/ccsds_types.h \
104 108 ../header/lfr_common_headers/fsw_params.h \
105 109 ../header/lfr_common_headers/fsw_params_nb_bytes.h \
106 110 ../header/lfr_common_headers/fsw_params_processing.h \
107 111 ../header/lfr_common_headers/TC_types.h \
108 112 ../header/lfr_common_headers/tm_byte_positions.h \
109 113 ../LFR_basic-parameters/basic_parameters.h \
110 114 ../LFR_basic-parameters/basic_parameters_params.h \
111 115 ../header/GscMemoryLPP.hpp
112 116
@@ -1,698 +1,700
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 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 36 timer_set_clock_divider( timer, clock_divider);
37 37 }
38 38
39 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 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 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 82 // WATCHDOG
83 83
84 84 rtems_isr watchdog_isr( rtems_vector_number vector )
85 85 {
86 86 rtems_status_code status_code;
87 87
88 88 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_12 );
89 89 }
90 90
91 91 void watchdog_configure(void)
92 92 {
93 93 /** This function configure the watchdog.
94 94 *
95 95 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
96 96 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
97 97 *
98 98 * The watchdog is a timer provided by the GPTIMER IP core of the GRLIB.
99 99 *
100 100 */
101 101
102 102 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt during configuration
103 103
104 104 timer_configure( TIMER_WATCHDOG, CLKDIV_WATCHDOG, IRQ_SPARC_GPTIMER_WATCHDOG, watchdog_isr );
105 105
106 106 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
107 107 }
108 108
109 109 void watchdog_stop(void)
110 110 {
111 111 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt line
112 112 timer_stop( TIMER_WATCHDOG );
113 113 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
114 114 }
115 115
116 116 void watchdog_reload(void)
117 117 {
118 118 /** This function reloads the watchdog timer counter with the timer reload value.
119 119 *
120 120 *
121 121 */
122 122
123 123 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000004; // LD load value from the reload register
124 124 }
125 125
126 126 void watchdog_start(void)
127 127 {
128 128 /** This function starts the watchdog timer.
129 129 *
130 130 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
131 131 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
132 132 *
133 133 */
134 134
135 135 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG );
136 136
137 137 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000010; // clear pending IRQ if any
138 138 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000004; // LD load value from the reload register
139 139 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000001; // EN enable the timer
140 140 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000008; // IE interrupt enable
141 141
142 142 LEON_Unmask_interrupt( IRQ_GPTIMER_WATCHDOG );
143 143
144 144 }
145 145
146 146 int send_console_outputs_on_apbuart_port( void ) // Send the console outputs on the apbuart port
147 147 {
148 148 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
149 149
150 150 apbuart_regs->ctrl = APBUART_CTRL_REG_MASK_TE;
151 151
152 152 return 0;
153 153 }
154 154
155 155 int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register
156 156 {
157 157 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
158 158
159 159 apbuart_regs->ctrl = apbuart_regs->ctrl | APBUART_CTRL_REG_MASK_TE;
160 160
161 161 return 0;
162 162 }
163 163
164 164 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value)
165 165 {
166 166 /** This function sets the scaler reload register of the apbuart module
167 167 *
168 168 * @param regs is the address of the apbuart registers in memory
169 169 * @param value is the value that will be stored in the scaler register
170 170 *
171 171 * The value shall be set by the software to get data on the serial interface.
172 172 *
173 173 */
174 174
175 175 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs;
176 176
177 177 apbuart_regs->scaler = value;
178 178 BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value)
179 179 }
180 180
181 181 //************
182 182 // RTEMS TASKS
183 183
184 184 rtems_task load_task(rtems_task_argument argument)
185 185 {
186 186 BOOT_PRINTF("in LOAD *** \n")
187 187
188 188 rtems_status_code status;
189 189 unsigned int i;
190 190 unsigned int j;
191 191 rtems_name name_watchdog_rate_monotonic; // name of the watchdog rate monotonic
192 192 rtems_id watchdog_period_id; // id of the watchdog rate monotonic period
193 193
194 194 name_watchdog_rate_monotonic = rtems_build_name( 'L', 'O', 'A', 'D' );
195 195
196 196 status = rtems_rate_monotonic_create( name_watchdog_rate_monotonic, &watchdog_period_id );
197 197 if( status != RTEMS_SUCCESSFUL ) {
198 198 PRINTF1( "in LOAD *** rtems_rate_monotonic_create failed with status of %d\n", status )
199 199 }
200 200
201 201 i = 0;
202 202 j = 0;
203 203
204 204 watchdog_configure();
205 205
206 206 watchdog_start();
207 207
208 208 while(1){
209 209 status = rtems_rate_monotonic_period( watchdog_period_id, WATCHDOG_PERIOD );
210 210 watchdog_reload();
211 211 i = i + 1;
212 212 if ( i == 10 )
213 213 {
214 214 i = 0;
215 215 j = j + 1;
216 216 PRINTF1("%d\n", j)
217 217 }
218 #ifdef DEBUG_WATCHDOG
218 219 if (j == 3 )
219 220 {
220 221 status = rtems_task_delete(RTEMS_SELF);
221 222 }
223 #endif
222 224 }
223 225 }
224 226
225 227 rtems_task hous_task(rtems_task_argument argument)
226 228 {
227 229 rtems_status_code status;
228 230 rtems_status_code spare_status;
229 231 rtems_id queue_id;
230 232 rtems_rate_monotonic_period_status period_status;
231 233
232 234 status = get_message_queue_id_send( &queue_id );
233 235 if (status != RTEMS_SUCCESSFUL)
234 236 {
235 237 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
236 238 }
237 239
238 240 BOOT_PRINTF("in HOUS ***\n")
239 241
240 242 if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
241 243 status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id );
242 244 if( status != RTEMS_SUCCESSFUL ) {
243 245 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status )
244 246 }
245 247 }
246 248
247 249 status = rtems_rate_monotonic_cancel(HK_id);
248 250 if( status != RTEMS_SUCCESSFUL ) {
249 251 PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status )
250 252 }
251 253 else {
252 254 DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n")
253 255 }
254 256
255 257 // startup phase
256 258 status = rtems_rate_monotonic_period( HK_id, SY_LFR_TIME_SYN_TIMEOUT_in_ticks );
257 259 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
258 260 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
259 261 while(period_status.state != RATE_MONOTONIC_EXPIRED ) // after SY_LFR_TIME_SYN_TIMEOUT ms, starts HK anyway
260 262 {
261 263 if ((time_management_regs->coarse_time & 0x80000000) == 0x00000000) // check time synchronization
262 264 {
263 265 break; // break if LFR is synchronized
264 266 }
265 267 else
266 268 {
267 269 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
268 270 // sched_yield();
269 271 status = rtems_task_wake_after( 10 ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 100 ms = 10 * 10 ms
270 272 }
271 273 }
272 274 status = rtems_rate_monotonic_cancel(HK_id);
273 275 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
274 276
275 277 set_hk_lfr_reset_cause( POWER_ON );
276 278
277 279 while(1){ // launch the rate monotonic task
278 280 status = rtems_rate_monotonic_period( HK_id, HK_PERIOD );
279 281 if ( status != RTEMS_SUCCESSFUL ) {
280 282 PRINTF1( "in HOUS *** ERR period: %d\n", status);
281 283 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 );
282 284 }
283 285 else {
284 286 housekeeping_packet.packetSequenceControl[0] = (unsigned char) (sequenceCounterHK >> 8);
285 287 housekeeping_packet.packetSequenceControl[1] = (unsigned char) (sequenceCounterHK );
286 288 increment_seq_counter( &sequenceCounterHK );
287 289
288 290 housekeeping_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
289 291 housekeeping_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
290 292 housekeeping_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
291 293 housekeeping_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
292 294 housekeeping_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
293 295 housekeeping_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
294 296
295 297 spacewire_update_statistics();
296 298
297 299 hk_lfr_le_me_he_update();
298 300
299 301 housekeeping_packet.hk_lfr_q_sd_fifo_size_max = hk_lfr_q_sd_fifo_size_max;
300 302 housekeeping_packet.hk_lfr_q_rv_fifo_size_max = hk_lfr_q_rv_fifo_size_max;
301 303 housekeeping_packet.hk_lfr_q_p0_fifo_size_max = hk_lfr_q_p0_fifo_size_max;
302 304 housekeeping_packet.hk_lfr_q_p1_fifo_size_max = hk_lfr_q_p1_fifo_size_max;
303 305 housekeeping_packet.hk_lfr_q_p2_fifo_size_max = hk_lfr_q_p2_fifo_size_max;
304 306
305 307 housekeeping_packet.sy_lfr_common_parameters_spare = parameter_dump_packet.sy_lfr_common_parameters_spare;
306 308 housekeeping_packet.sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
307 309 get_temperatures( housekeeping_packet.hk_lfr_temp_scm );
308 310 get_v_e1_e2_f3( housekeeping_packet.hk_lfr_sc_v_f3 );
309 311 get_cpu_load( (unsigned char *) &housekeeping_packet.hk_lfr_cpu_load );
310 312
311 313 // SEND PACKET
312 314 status = rtems_message_queue_send( queue_id, &housekeeping_packet,
313 315 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
314 316 if (status != RTEMS_SUCCESSFUL) {
315 317 PRINTF1("in HOUS *** ERR send: %d\n", status)
316 318 }
317 319 }
318 320 }
319 321
320 322 PRINTF("in HOUS *** deleting task\n")
321 323
322 324 status = rtems_task_delete( RTEMS_SELF ); // should not return
323 325
324 326 return;
325 327 }
326 328
327 329 rtems_task dumb_task( rtems_task_argument unused )
328 330 {
329 331 /** This RTEMS taks is used to print messages without affecting the general behaviour of the software.
330 332 *
331 333 * @param unused is the starting argument of the RTEMS task
332 334 *
333 335 * The DUMB taks waits for RTEMS events and print messages depending on the incoming events.
334 336 *
335 337 */
336 338
337 339 unsigned int i;
338 340 unsigned int intEventOut;
339 341 unsigned int coarse_time = 0;
340 342 unsigned int fine_time = 0;
341 343 rtems_event_set event_out;
342 344
343 345 char *DumbMessages[13] = {"in DUMB *** default", // RTEMS_EVENT_0
344 346 "in DUMB *** timecode_irq_handler", // RTEMS_EVENT_1
345 347 "in DUMB *** f3 buffer changed", // RTEMS_EVENT_2
346 348 "in DUMB *** in SMIQ *** Error sending event to AVF0", // RTEMS_EVENT_3
347 349 "in DUMB *** spectral_matrices_isr *** Error sending event to SMIQ", // RTEMS_EVENT_4
348 350 "in DUMB *** waveforms_simulator_isr", // RTEMS_EVENT_5
349 351 "VHDL SM *** two buffers f0 ready", // RTEMS_EVENT_6
350 352 "ready for dump", // RTEMS_EVENT_7
351 353 "VHDL ERR *** spectral matrix", // RTEMS_EVENT_8
352 354 "tick", // RTEMS_EVENT_9
353 355 "VHDL ERR *** waveform picker", // RTEMS_EVENT_10
354 356 "VHDL ERR *** unexpected ready matrix values", // RTEMS_EVENT_11
355 357 "WATCHDOG timer" // RTEMS_EVENT_12
356 358 };
357 359
358 360 BOOT_PRINTF("in DUMB *** \n")
359 361
360 362 while(1){
361 363 rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3
362 364 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7
363 365 | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12,
364 366 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT
365 367 intEventOut = (unsigned int) event_out;
366 368 for ( i=0; i<32; i++)
367 369 {
368 370 if ( ((intEventOut >> i) & 0x0001) != 0)
369 371 {
370 372 coarse_time = time_management_regs->coarse_time;
371 373 fine_time = time_management_regs->fine_time;
372 374 if (i==12)
373 375 {
374 376 PRINTF1("%s\n", DumbMessages[12])
375 377 }
376 378 }
377 379 }
378 380 }
379 381 }
380 382
381 383 //*****************************
382 384 // init housekeeping parameters
383 385
384 386 void init_housekeeping_parameters( void )
385 387 {
386 388 /** This function initialize the housekeeping_packet global variable with default values.
387 389 *
388 390 */
389 391
390 392 unsigned int i = 0;
391 393 unsigned char *parameters;
392 394 unsigned char sizeOfHK;
393 395
394 396 sizeOfHK = sizeof( Packet_TM_LFR_HK_t );
395 397
396 398 parameters = (unsigned char*) &housekeeping_packet;
397 399
398 400 for(i = 0; i< sizeOfHK; i++)
399 401 {
400 402 parameters[i] = 0x00;
401 403 }
402 404
403 405 housekeeping_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
404 406 housekeeping_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
405 407 housekeeping_packet.reserved = DEFAULT_RESERVED;
406 408 housekeeping_packet.userApplication = CCSDS_USER_APP;
407 409 housekeeping_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
408 410 housekeeping_packet.packetID[1] = (unsigned char) (APID_TM_HK);
409 411 housekeeping_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
410 412 housekeeping_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
411 413 housekeeping_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
412 414 housekeeping_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
413 415 housekeeping_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
414 416 housekeeping_packet.serviceType = TM_TYPE_HK;
415 417 housekeeping_packet.serviceSubType = TM_SUBTYPE_HK;
416 418 housekeeping_packet.destinationID = TM_DESTINATION_ID_GROUND;
417 419 housekeeping_packet.sid = SID_HK;
418 420
419 421 // init status word
420 422 housekeeping_packet.lfr_status_word[0] = DEFAULT_STATUS_WORD_BYTE0;
421 423 housekeeping_packet.lfr_status_word[1] = DEFAULT_STATUS_WORD_BYTE1;
422 424 // init software version
423 425 housekeeping_packet.lfr_sw_version[0] = SW_VERSION_N1;
424 426 housekeeping_packet.lfr_sw_version[1] = SW_VERSION_N2;
425 427 housekeeping_packet.lfr_sw_version[2] = SW_VERSION_N3;
426 428 housekeeping_packet.lfr_sw_version[3] = SW_VERSION_N4;
427 429 // init fpga version
428 430 parameters = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
429 431 housekeeping_packet.lfr_fpga_version[0] = parameters[1]; // n1
430 432 housekeeping_packet.lfr_fpga_version[1] = parameters[2]; // n2
431 433 housekeeping_packet.lfr_fpga_version[2] = parameters[3]; // n3
432 434
433 435 housekeeping_packet.hk_lfr_q_sd_fifo_size = MSG_QUEUE_COUNT_SEND;
434 436 housekeeping_packet.hk_lfr_q_rv_fifo_size = MSG_QUEUE_COUNT_RECV;
435 437 housekeeping_packet.hk_lfr_q_p0_fifo_size = MSG_QUEUE_COUNT_PRC0;
436 438 housekeeping_packet.hk_lfr_q_p1_fifo_size = MSG_QUEUE_COUNT_PRC1;
437 439 housekeeping_packet.hk_lfr_q_p2_fifo_size = MSG_QUEUE_COUNT_PRC2;
438 440 }
439 441
440 442 void increment_seq_counter( unsigned short *packetSequenceControl )
441 443 {
442 444 /** This function increment the sequence counter passes in argument.
443 445 *
444 446 * The increment does not affect the grouping flag. In case of an overflow, the counter is reset to 0.
445 447 *
446 448 */
447 449
448 450 unsigned short segmentation_grouping_flag;
449 451 unsigned short sequence_cnt;
450 452
451 453 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << 8; // keep bits 7 downto 6
452 454 sequence_cnt = (*packetSequenceControl) & 0x3fff; // [0011 1111 1111 1111]
453 455
454 456 if ( sequence_cnt < SEQ_CNT_MAX)
455 457 {
456 458 sequence_cnt = sequence_cnt + 1;
457 459 }
458 460 else
459 461 {
460 462 sequence_cnt = 0;
461 463 }
462 464
463 465 *packetSequenceControl = segmentation_grouping_flag | sequence_cnt ;
464 466 }
465 467
466 468 void getTime( unsigned char *time)
467 469 {
468 470 /** This function write the current local time in the time buffer passed in argument.
469 471 *
470 472 */
471 473
472 474 time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
473 475 time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
474 476 time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
475 477 time[3] = (unsigned char) (time_management_regs->coarse_time);
476 478 time[4] = (unsigned char) (time_management_regs->fine_time>>8);
477 479 time[5] = (unsigned char) (time_management_regs->fine_time);
478 480 }
479 481
480 482 unsigned long long int getTimeAsUnsignedLongLongInt( )
481 483 {
482 484 /** This function write the current local time in the time buffer passed in argument.
483 485 *
484 486 */
485 487 unsigned long long int time;
486 488
487 489 time = ( (unsigned long long int) (time_management_regs->coarse_time & 0x7fffffff) << 16 )
488 490 + time_management_regs->fine_time;
489 491
490 492 return time;
491 493 }
492 494
493 495 void send_dumb_hk( void )
494 496 {
495 497 Packet_TM_LFR_HK_t dummy_hk_packet;
496 498 unsigned char *parameters;
497 499 unsigned int i;
498 500 rtems_id queue_id;
499 501
500 502 dummy_hk_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
501 503 dummy_hk_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
502 504 dummy_hk_packet.reserved = DEFAULT_RESERVED;
503 505 dummy_hk_packet.userApplication = CCSDS_USER_APP;
504 506 dummy_hk_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
505 507 dummy_hk_packet.packetID[1] = (unsigned char) (APID_TM_HK);
506 508 dummy_hk_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
507 509 dummy_hk_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
508 510 dummy_hk_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
509 511 dummy_hk_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
510 512 dummy_hk_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
511 513 dummy_hk_packet.serviceType = TM_TYPE_HK;
512 514 dummy_hk_packet.serviceSubType = TM_SUBTYPE_HK;
513 515 dummy_hk_packet.destinationID = TM_DESTINATION_ID_GROUND;
514 516 dummy_hk_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
515 517 dummy_hk_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
516 518 dummy_hk_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
517 519 dummy_hk_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
518 520 dummy_hk_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
519 521 dummy_hk_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
520 522 dummy_hk_packet.sid = SID_HK;
521 523
522 524 // init status word
523 525 dummy_hk_packet.lfr_status_word[0] = 0xff;
524 526 dummy_hk_packet.lfr_status_word[1] = 0xff;
525 527 // init software version
526 528 dummy_hk_packet.lfr_sw_version[0] = SW_VERSION_N1;
527 529 dummy_hk_packet.lfr_sw_version[1] = SW_VERSION_N2;
528 530 dummy_hk_packet.lfr_sw_version[2] = SW_VERSION_N3;
529 531 dummy_hk_packet.lfr_sw_version[3] = SW_VERSION_N4;
530 532 // init fpga version
531 533 parameters = (unsigned char *) (REGS_ADDR_WAVEFORM_PICKER + 0xb0);
532 534 dummy_hk_packet.lfr_fpga_version[0] = parameters[1]; // n1
533 535 dummy_hk_packet.lfr_fpga_version[1] = parameters[2]; // n2
534 536 dummy_hk_packet.lfr_fpga_version[2] = parameters[3]; // n3
535 537
536 538 parameters = (unsigned char *) &dummy_hk_packet.hk_lfr_cpu_load;
537 539
538 540 for (i=0; i<100; i++)
539 541 {
540 542 parameters[i] = 0xff;
541 543 }
542 544
543 545 get_message_queue_id_send( &queue_id );
544 546
545 547 rtems_message_queue_send( queue_id, &dummy_hk_packet,
546 548 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
547 549 }
548 550
549 551 void get_temperatures( unsigned char *temperatures )
550 552 {
551 553 unsigned char* temp_scm_ptr;
552 554 unsigned char* temp_pcb_ptr;
553 555 unsigned char* temp_fpga_ptr;
554 556
555 557 // SEL1 SEL0
556 558 // 0 0 => PCB
557 559 // 0 1 => FPGA
558 560 // 1 0 => SCM
559 561
560 562 temp_scm_ptr = (unsigned char *) &time_management_regs->temp_scm;
561 563 temp_pcb_ptr = (unsigned char *) &time_management_regs->temp_pcb;
562 564 temp_fpga_ptr = (unsigned char *) &time_management_regs->temp_fpga;
563 565
564 566 temperatures[0] = temp_scm_ptr[2];
565 567 temperatures[1] = temp_scm_ptr[3];
566 568 temperatures[2] = temp_pcb_ptr[2];
567 569 temperatures[3] = temp_pcb_ptr[3];
568 570 temperatures[4] = temp_fpga_ptr[2];
569 571 temperatures[5] = temp_fpga_ptr[3];
570 572 }
571 573
572 574 void get_v_e1_e2_f3( unsigned char *spacecraft_potential )
573 575 {
574 576 unsigned char* v_ptr;
575 577 unsigned char* e1_ptr;
576 578 unsigned char* e2_ptr;
577 579
578 580 v_ptr = (unsigned char *) &waveform_picker_regs->v;
579 581 e1_ptr = (unsigned char *) &waveform_picker_regs->e1;
580 582 e2_ptr = (unsigned char *) &waveform_picker_regs->e2;
581 583
582 584 spacecraft_potential[0] = v_ptr[2];
583 585 spacecraft_potential[1] = v_ptr[3];
584 586 spacecraft_potential[2] = e1_ptr[2];
585 587 spacecraft_potential[3] = e1_ptr[3];
586 588 spacecraft_potential[4] = e2_ptr[2];
587 589 spacecraft_potential[5] = e2_ptr[3];
588 590 }
589 591
590 592 void get_cpu_load( unsigned char *resource_statistics )
591 593 {
592 594 unsigned char cpu_load;
593 595
594 596 cpu_load = lfr_rtems_cpu_usage_report();
595 597
596 598 // HK_LFR_CPU_LOAD
597 599 resource_statistics[0] = cpu_load;
598 600
599 601 // HK_LFR_CPU_LOAD_MAX
600 602 if (cpu_load > resource_statistics[1])
601 603 {
602 604 resource_statistics[1] = cpu_load;
603 605 }
604 606
605 607 // CPU_LOAD_AVE
606 608 resource_statistics[2] = 0;
607 609
608 610 #ifndef PRINT_TASK_STATISTICS
609 611 rtems_cpu_usage_reset();
610 612 #endif
611 613
612 614 }
613 615
614 616 void set_hk_lfr_sc_potential_flag( bool state )
615 617 {
616 618 if (state == true)
617 619 {
618 620 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x40; // [0100 0000]
619 621 }
620 622 else
621 623 {
622 624 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xbf; // [1011 1111]
623 625 }
624 626 }
625 627
626 628 void set_hk_lfr_mag_fields_flag( bool state )
627 629 {
628 630 if (state == true)
629 631 {
630 632 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x20; // [0010 0000]
631 633 }
632 634 else
633 635 {
634 636 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xd7; // [1101 1111]
635 637 }
636 638 }
637 639
638 640 void set_hk_lfr_calib_enable( bool state )
639 641 {
640 642 if (state == true)
641 643 {
642 644 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x08; // [0000 1000]
643 645 }
644 646 else
645 647 {
646 648 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xf7; // [1111 0111]
647 649 }
648 650 }
649 651
650 652 void set_hk_lfr_reset_cause( enum lfr_reset_cause_t lfr_reset_cause )
651 653 {
652 654 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1]
653 655 | (lfr_reset_cause & 0x07 ); // [0000 0111]
654 656 }
655 657
656 658 void hk_lfr_le_me_he_update()
657 659 {
658 660 unsigned int hk_lfr_le_cnt;
659 661 unsigned int hk_lfr_me_cnt;
660 662 unsigned int hk_lfr_he_cnt;
661 663
662 664 hk_lfr_le_cnt = 0;
663 665 hk_lfr_me_cnt = 0;
664 666 hk_lfr_he_cnt = 0;
665 667
666 668 //update the low severity error counter
667 669 hk_lfr_le_cnt =
668 670 housekeeping_packet.hk_lfr_dpu_spw_parity
669 671 + housekeeping_packet.hk_lfr_dpu_spw_disconnect
670 672 + housekeeping_packet.hk_lfr_dpu_spw_escape
671 673 + housekeeping_packet.hk_lfr_dpu_spw_credit
672 674 + housekeeping_packet.hk_lfr_dpu_spw_write_sync
673 675 + housekeeping_packet.hk_lfr_dpu_spw_rx_ahb
674 676 + housekeeping_packet.hk_lfr_dpu_spw_tx_ahb
675 677 + housekeeping_packet.hk_lfr_time_timecode_ctr;
676 678
677 679 //update the medium severity error counter
678 680 hk_lfr_me_cnt =
679 681 housekeeping_packet.hk_lfr_dpu_spw_early_eop
680 682 + housekeeping_packet.hk_lfr_dpu_spw_invalid_addr
681 683 + housekeeping_packet.hk_lfr_dpu_spw_eep
682 684 + housekeeping_packet.hk_lfr_dpu_spw_rx_too_big;
683 685
684 686 //update the high severity error counter
685 687 hk_lfr_he_cnt = 0;
686 688
687 689 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
688 690 // LE
689 691 housekeeping_packet.hk_lfr_le_cnt[0] = (unsigned char) ((hk_lfr_le_cnt & 0xff00) >> 8);
690 692 housekeeping_packet.hk_lfr_le_cnt[1] = (unsigned char) (hk_lfr_le_cnt & 0x00ff);
691 693 // ME
692 694 housekeeping_packet.hk_lfr_me_cnt[0] = (unsigned char) ((hk_lfr_me_cnt & 0xff00) >> 8);
693 695 housekeeping_packet.hk_lfr_me_cnt[1] = (unsigned char) (hk_lfr_me_cnt & 0x00ff);
694 696 // HE
695 697 housekeeping_packet.hk_lfr_he_cnt[0] = (unsigned char) ((hk_lfr_he_cnt & 0xff00) >> 8);
696 698 housekeeping_packet.hk_lfr_he_cnt[1] = (unsigned char) (hk_lfr_he_cnt & 0x00ff);
697 699
698 700 }
@@ -1,1205 +1,1208
1 1 /** Functions and tasks related to waveform packet generation.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * A group of functions to handle waveforms, in snapshot or continuous format.\n
7 7 *
8 8 */
9 9
10 10 #include "wf_handler.h"
11 11
12 12 //***************
13 13 // waveform rings
14 14 // F0
15 15 ring_node waveform_ring_f0[NB_RING_NODES_F0];
16 16 ring_node *current_ring_node_f0;
17 17 ring_node *ring_node_to_send_swf_f0;
18 18 // F1
19 19 ring_node waveform_ring_f1[NB_RING_NODES_F1];
20 20 ring_node *current_ring_node_f1;
21 21 ring_node *ring_node_to_send_swf_f1;
22 22 ring_node *ring_node_to_send_cwf_f1;
23 23 // F2
24 24 ring_node waveform_ring_f2[NB_RING_NODES_F2];
25 25 ring_node *current_ring_node_f2;
26 26 ring_node *ring_node_to_send_swf_f2;
27 27 ring_node *ring_node_to_send_cwf_f2;
28 28 // F3
29 29 ring_node waveform_ring_f3[NB_RING_NODES_F3];
30 30 ring_node *current_ring_node_f3;
31 31 ring_node *ring_node_to_send_cwf_f3;
32 32 char wf_cont_f3_light[ (NB_SAMPLES_PER_SNAPSHOT) * NB_BYTES_CWF3_LIGHT_BLK ];
33 33
34 34 bool extractSWF1 = false;
35 35 bool extractSWF2 = false;
36 36 bool swf0_ready_flag_f1 = false;
37 37 bool swf0_ready_flag_f2 = false;
38 38 bool swf1_ready = false;
39 39 bool swf2_ready = false;
40 40
41 41 int swf1_extracted[ (NB_SAMPLES_PER_SNAPSHOT * NB_WORDS_SWF_BLK) ];
42 42 int swf2_extracted[ (NB_SAMPLES_PER_SNAPSHOT * NB_WORDS_SWF_BLK) ];
43 43 ring_node ring_node_swf1_extracted;
44 44 ring_node ring_node_swf2_extracted;
45 45
46 46 //*********************
47 47 // Interrupt SubRoutine
48 48
49 49 ring_node * getRingNodeToSendCWF( unsigned char frequencyChannel)
50 50 {
51 51 ring_node *node;
52 52
53 53 node = NULL;
54 54 switch ( frequencyChannel ) {
55 55 case 1:
56 56 node = ring_node_to_send_cwf_f1;
57 57 break;
58 58 case 2:
59 59 node = ring_node_to_send_cwf_f2;
60 60 break;
61 61 case 3:
62 62 node = ring_node_to_send_cwf_f3;
63 63 break;
64 64 default:
65 65 break;
66 66 }
67 67
68 68 return node;
69 69 }
70 70
71 71 ring_node * getRingNodeToSendSWF( unsigned char frequencyChannel)
72 72 {
73 73 ring_node *node;
74 74
75 75 node = NULL;
76 76 switch ( frequencyChannel ) {
77 77 case 0:
78 78 node = ring_node_to_send_swf_f0;
79 79 break;
80 80 case 1:
81 81 node = ring_node_to_send_swf_f1;
82 82 break;
83 83 case 2:
84 84 node = ring_node_to_send_swf_f2;
85 85 break;
86 86 default:
87 87 break;
88 88 }
89 89
90 90 return node;
91 91 }
92 92
93 93 void reset_extractSWF( void )
94 94 {
95 95 extractSWF1 = false;
96 96 extractSWF2 = false;
97 97 swf0_ready_flag_f1 = false;
98 98 swf0_ready_flag_f2 = false;
99 99 swf1_ready = false;
100 100 swf2_ready = false;
101 101 }
102 102
103 103 inline void waveforms_isr_f3( void )
104 104 {
105 105 rtems_status_code spare_status;
106 106
107 107 if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_BURST) // in BURST the data are used to place v, e1 and e2 in the HK packet
108 108 || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) )
109 109 { // in modes other than STANDBY and BURST, send the CWF_F3 data
110 110 //***
111 111 // F3
112 112 if ( (waveform_picker_regs->status & 0xc0) != 0x00 ) { // [1100 0000] check the f3 full bits
113 113 ring_node_to_send_cwf_f3 = current_ring_node_f3->previous;
114 114 current_ring_node_f3 = current_ring_node_f3->next;
115 115 if ((waveform_picker_regs->status & 0x40) == 0x40){ // [0100 0000] f3 buffer 0 is full
116 116 ring_node_to_send_cwf_f3->coarseTime = waveform_picker_regs->f3_0_coarse_time;
117 117 ring_node_to_send_cwf_f3->fineTime = waveform_picker_regs->f3_0_fine_time;
118 118 waveform_picker_regs->addr_data_f3_0 = current_ring_node_f3->buffer_address;
119 119 waveform_picker_regs->status = waveform_picker_regs->status & 0x00008840; // [1000 1000 0100 0000]
120 120 }
121 121 else if ((waveform_picker_regs->status & 0x80) == 0x80){ // [1000 0000] f3 buffer 1 is full
122 122 ring_node_to_send_cwf_f3->coarseTime = waveform_picker_regs->f3_1_coarse_time;
123 123 ring_node_to_send_cwf_f3->fineTime = waveform_picker_regs->f3_1_fine_time;
124 124 waveform_picker_regs->addr_data_f3_1 = current_ring_node_f3->buffer_address;
125 125 waveform_picker_regs->status = waveform_picker_regs->status & 0x00008880; // [1000 1000 1000 0000]
126 126 }
127 127 if (rtems_event_send( Task_id[TASKID_CWF3], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
128 128 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
129 129 }
130 130 }
131 131 }
132 132 }
133 133
134 134 inline void waveforms_isr_burst( void )
135 135 {
136 136 unsigned char status;
137 137 rtems_status_code spare_status;
138 138
139 139 status = (waveform_picker_regs->status & 0x30) >> 4; // [0011 0000] get the status bits for f2
140 140
141 141
142 142 switch(status)
143 143 {
144 144 case 1:
145 145 ring_node_to_send_cwf_f2 = current_ring_node_f2->previous;
146 146 ring_node_to_send_cwf_f2->sid = SID_BURST_CWF_F2;
147 147 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_0_coarse_time;
148 148 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_0_fine_time;
149 149 current_ring_node_f2 = current_ring_node_f2->next;
150 150 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->buffer_address;
151 151 if (rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_BURST ) != RTEMS_SUCCESSFUL) {
152 152 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
153 153 }
154 154 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004410; // [0100 0100 0001 0000]
155 155 break;
156 156 case 2:
157 157 ring_node_to_send_cwf_f2 = current_ring_node_f2->previous;
158 158 ring_node_to_send_cwf_f2->sid = SID_BURST_CWF_F2;
159 159 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_1_coarse_time;
160 160 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_1_fine_time;
161 161 current_ring_node_f2 = current_ring_node_f2->next;
162 162 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address;
163 163 if (rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_BURST ) != RTEMS_SUCCESSFUL) {
164 164 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
165 165 }
166 166 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004420; // [0100 0100 0010 0000]
167 167 break;
168 168 default:
169 169 break;
170 170 }
171 171 }
172 172
173 173 inline void waveform_isr_normal_sbm1_sbm2( void )
174 174 {
175 175 rtems_status_code status;
176 176
177 177 //***
178 178 // F0
179 179 if ( (waveform_picker_regs->status & 0x03) != 0x00 ) // [0000 0011] check the f0 full bits
180 180 {
181 181 swf0_ready_flag_f1 = true;
182 182 swf0_ready_flag_f2 = true;
183 183 ring_node_to_send_swf_f0 = current_ring_node_f0->previous;
184 184 current_ring_node_f0 = current_ring_node_f0->next;
185 185 if ( (waveform_picker_regs->status & 0x01) == 0x01)
186 186 {
187 187
188 188 ring_node_to_send_swf_f0->coarseTime = waveform_picker_regs->f0_0_coarse_time;
189 189 ring_node_to_send_swf_f0->fineTime = waveform_picker_regs->f0_0_fine_time;
190 190 waveform_picker_regs->addr_data_f0_0 = current_ring_node_f0->buffer_address;
191 191 waveform_picker_regs->status = waveform_picker_regs->status & 0x00001101; // [0001 0001 0000 0001]
192 192 }
193 193 else if ( (waveform_picker_regs->status & 0x02) == 0x02)
194 194 {
195 195 ring_node_to_send_swf_f0->coarseTime = waveform_picker_regs->f0_1_coarse_time;
196 196 ring_node_to_send_swf_f0->fineTime = waveform_picker_regs->f0_1_fine_time;
197 197 waveform_picker_regs->addr_data_f0_1 = current_ring_node_f0->buffer_address;
198 198 waveform_picker_regs->status = waveform_picker_regs->status & 0x00001102; // [0001 0001 0000 0010]
199 199 }
200 200 }
201 201
202 202 //***
203 203 // F1
204 204 if ( (waveform_picker_regs->status & 0x0c) != 0x00 ) { // [0000 1100] check the f1 full bits
205 205 // (1) change the receiving buffer for the waveform picker
206 206 ring_node_to_send_cwf_f1 = current_ring_node_f1->previous;
207 207 current_ring_node_f1 = current_ring_node_f1->next;
208 208 if ( (waveform_picker_regs->status & 0x04) == 0x04)
209 209 {
210 210 ring_node_to_send_cwf_f1->coarseTime = waveform_picker_regs->f1_0_coarse_time;
211 211 ring_node_to_send_cwf_f1->fineTime = waveform_picker_regs->f1_0_fine_time;
212 212 waveform_picker_regs->addr_data_f1_0 = current_ring_node_f1->buffer_address;
213 213 waveform_picker_regs->status = waveform_picker_regs->status & 0x00002204; // [0010 0010 0000 0100] f1 bits = 0
214 214 }
215 215 else if ( (waveform_picker_regs->status & 0x08) == 0x08)
216 216 {
217 217 ring_node_to_send_cwf_f1->coarseTime = waveform_picker_regs->f1_1_coarse_time;
218 218 ring_node_to_send_cwf_f1->fineTime = waveform_picker_regs->f1_1_fine_time;
219 219 waveform_picker_regs->addr_data_f1_1 = current_ring_node_f1->buffer_address;
220 220 waveform_picker_regs->status = waveform_picker_regs->status & 0x00002208; // [0010 0010 0000 1000] f1 bits = 0
221 221 }
222 222 // (2) send an event for the the CWF1 task for transmission (and snapshot extraction if needed)
223 223 status = rtems_event_send( Task_id[TASKID_CWF1], RTEMS_EVENT_MODE_NORM_S1_S2 );
224 224 }
225 225
226 226 //***
227 227 // F2
228 228 if ( (waveform_picker_regs->status & 0x30) != 0x00 ) { // [0011 0000] check the f2 full bit
229 229 // (1) change the receiving buffer for the waveform picker
230 230 ring_node_to_send_cwf_f2 = current_ring_node_f2->previous;
231 231 ring_node_to_send_cwf_f2->sid = SID_SBM2_CWF_F2;
232 232 current_ring_node_f2 = current_ring_node_f2->next;
233 233 if ( (waveform_picker_regs->status & 0x10) == 0x10)
234 234 {
235 235 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_0_coarse_time;
236 236 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_0_fine_time;
237 237 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->buffer_address;
238 238 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004410; // [0100 0100 0001 0000]
239 239 }
240 240 else if ( (waveform_picker_regs->status & 0x20) == 0x20)
241 241 {
242 242 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_1_coarse_time;
243 243 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_1_fine_time;
244 244 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address;
245 245 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004420; // [0100 0100 0010 0000]
246 246 }
247 247 // (2) send an event for the waveforms transmission
248 248 status = rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_NORM_S1_S2 );
249 249 }
250 250 }
251 251
252 252 rtems_isr waveforms_isr( rtems_vector_number vector )
253 253 {
254 254 /** This is the interrupt sub routine called by the waveform picker core.
255 255 *
256 256 * This ISR launch different actions depending mainly on two pieces of information:
257 257 * 1. the values read in the registers of the waveform picker.
258 258 * 2. the current LFR mode.
259 259 *
260 260 */
261 261
262 262 // STATUS
263 263 // new error error buffer full
264 264 // 15 14 13 12 11 10 9 8
265 265 // f3 f2 f1 f0 f3 f2 f1 f0
266 266 //
267 267 // ready buffer
268 268 // 7 6 5 4 3 2 1 0
269 269 // f3_1 f3_0 f2_1 f2_0 f1_1 f1_0 f0_1 f0_0
270 270
271 271 rtems_status_code spare_status;
272 272
273 273 waveforms_isr_f3();
274 274
275 275 if ( (waveform_picker_regs->status & 0xff00) != 0x00) // [1111 1111 0000 0000] check the error bits
276 276 {
277 277 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_10 );
278 278 }
279 279
280 280 switch(lfrCurrentMode)
281 281 {
282 282 //********
283 283 // STANDBY
284 284 case LFR_MODE_STANDBY:
285 285 break;
286 286 //**************************
287 287 // LFR NORMAL, SBM1 and SBM2
288 288 case LFR_MODE_NORMAL:
289 289 case LFR_MODE_SBM1:
290 290 case LFR_MODE_SBM2:
291 291 waveform_isr_normal_sbm1_sbm2();
292 292 break;
293 293 //******
294 294 // BURST
295 295 case LFR_MODE_BURST:
296 296 waveforms_isr_burst();
297 297 break;
298 298 //********
299 299 // DEFAULT
300 300 default:
301 301 break;
302 302 }
303 303 }
304 304
305 305 //************
306 306 // RTEMS TASKS
307 307
308 308 rtems_task wfrm_task(rtems_task_argument argument) //used with the waveform picker VHDL IP
309 309 {
310 310 /** This RTEMS task is dedicated to the transmission of snapshots of the NORMAL mode.
311 311 *
312 312 * @param unused is the starting argument of the RTEMS task
313 313 *
314 314 * The following data packets are sent by this task:
315 315 * - TM_LFR_SCIENCE_NORMAL_SWF_F0
316 316 * - TM_LFR_SCIENCE_NORMAL_SWF_F1
317 317 * - TM_LFR_SCIENCE_NORMAL_SWF_F2
318 318 *
319 319 */
320 320
321 321 rtems_event_set event_out;
322 322 rtems_id queue_id;
323 323 rtems_status_code status;
324 324 bool resynchronisationEngaged;
325 325 ring_node *ring_node_swf1_extracted_ptr;
326 326 ring_node *ring_node_swf2_extracted_ptr;
327 327
328 328 ring_node_swf1_extracted_ptr = (ring_node *) &ring_node_swf1_extracted;
329 329 ring_node_swf2_extracted_ptr = (ring_node *) &ring_node_swf2_extracted;
330 330
331 331 resynchronisationEngaged = false;
332 332
333 333 status = get_message_queue_id_send( &queue_id );
334 334 if (status != RTEMS_SUCCESSFUL)
335 335 {
336 PRINTF1("in WFRM *** ERR get_message_queue_id_send %d\n", status)
336 PRINTF1("in WFRM *** ERR get_message_queue_id_send %d\n", status);
337 337 }
338 338
339 BOOT_PRINTF("in WFRM ***\n")
339 BOOT_PRINTF("in WFRM ***\n");
340 340
341 341 while(1){
342 342 // wait for an RTEMS_EVENT
343 343 rtems_event_receive(RTEMS_EVENT_MODE_NORMAL,
344 344 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
345 345 if(resynchronisationEngaged == false)
346 346 { // engage resynchronisation
347 347 snapshot_resynchronization( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
348 348 resynchronisationEngaged = true;
349 349 }
350 350 else
351 351 { // reset delta_snapshot to the nominal value
352 PRINTF("no resynchronisation, reset delta_snapshot to the nominal value\n")
352 PRINTF("no resynchronisation, reset delta_snapshot to the nominal value\n");
353 353 set_wfp_delta_snapshot();
354 354 resynchronisationEngaged = false;
355 355 }
356 356 //
357 357 if (event_out == RTEMS_EVENT_MODE_NORMAL)
358 358 {
359 DEBUG_PRINTF("WFRM received RTEMS_EVENT_MODE_SBM2\n")
359 DEBUG_PRINTF("WFRM received RTEMS_EVENT_MODE_SBM2\n");
360 360 ring_node_to_send_swf_f0->sid = SID_NORM_SWF_F0;
361 361 ring_node_swf1_extracted_ptr->sid = SID_NORM_SWF_F1;
362 362 ring_node_swf2_extracted_ptr->sid = SID_NORM_SWF_F2;
363 363 status = rtems_message_queue_send( queue_id, &ring_node_to_send_swf_f0, sizeof( ring_node* ) );
364 364 status = rtems_message_queue_send( queue_id, &ring_node_swf1_extracted_ptr, sizeof( ring_node* ) );
365 365 status = rtems_message_queue_send( queue_id, &ring_node_swf2_extracted_ptr, sizeof( ring_node* ) );
366 366 }
367 367 }
368 368 }
369 369
370 370 rtems_task cwf3_task(rtems_task_argument argument) //used with the waveform picker VHDL IP
371 371 {
372 372 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f3.
373 373 *
374 374 * @param unused is the starting argument of the RTEMS task
375 375 *
376 376 * The following data packet is sent by this task:
377 377 * - TM_LFR_SCIENCE_NORMAL_CWF_F3
378 378 *
379 379 */
380 380
381 381 rtems_event_set event_out;
382 382 rtems_id queue_id;
383 383 rtems_status_code status;
384 384 ring_node ring_node_cwf3_light;
385 385 ring_node *ring_node_to_send_cwf;
386 386
387 387 status = get_message_queue_id_send( &queue_id );
388 388 if (status != RTEMS_SUCCESSFUL)
389 389 {
390 390 PRINTF1("in CWF3 *** ERR get_message_queue_id_send %d\n", status)
391 391 }
392 392
393 393 ring_node_to_send_cwf_f3->sid = SID_NORM_CWF_LONG_F3;
394 394
395 395 // init the ring_node_cwf3_light structure
396 396 ring_node_cwf3_light.buffer_address = (int) wf_cont_f3_light;
397 397 ring_node_cwf3_light.coarseTime = 0x00;
398 398 ring_node_cwf3_light.fineTime = 0x00;
399 399 ring_node_cwf3_light.next = NULL;
400 400 ring_node_cwf3_light.previous = NULL;
401 401 ring_node_cwf3_light.sid = SID_NORM_CWF_F3;
402 402 ring_node_cwf3_light.status = 0x00;
403 403
404 404 BOOT_PRINTF("in CWF3 ***\n")
405 405
406 406 while(1){
407 407 // wait for an RTEMS_EVENT
408 408 rtems_event_receive( RTEMS_EVENT_0,
409 409 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
410 410 if ( (lfrCurrentMode == LFR_MODE_NORMAL)
411 411 || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode==LFR_MODE_SBM2) )
412 412 {
413 413 ring_node_to_send_cwf = getRingNodeToSendCWF( 3 );
414 414 if ( (parameter_dump_packet.sy_lfr_n_cwf_long_f3 & 0x01) == 0x01)
415 415 {
416 416 PRINTF("send CWF_LONG_F3\n")
417 417 ring_node_to_send_cwf_f3->sid = SID_NORM_CWF_LONG_F3;
418 418 status = rtems_message_queue_send( queue_id, &ring_node_to_send_cwf, sizeof( ring_node* ) );
419 419 }
420 420 else
421 421 {
422 422 PRINTF("send CWF_F3 (light)\n")
423 423 send_waveform_CWF3_light( ring_node_to_send_cwf, &ring_node_cwf3_light, queue_id );
424 424 }
425 425
426 426 }
427 427 else
428 428 {
429 429 PRINTF1("in CWF3 *** lfrCurrentMode is %d, no data will be sent\n", lfrCurrentMode)
430 430 }
431 431 }
432 432 }
433 433
434 434 rtems_task cwf2_task(rtems_task_argument argument) // ONLY USED IN BURST AND SBM2
435 435 {
436 436 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f2.
437 437 *
438 438 * @param unused is the starting argument of the RTEMS task
439 439 *
440 440 * The following data packet is sent by this function:
441 441 * - TM_LFR_SCIENCE_BURST_CWF_F2
442 442 * - TM_LFR_SCIENCE_SBM2_CWF_F2
443 443 *
444 444 */
445 445
446 446 rtems_event_set event_out;
447 447 rtems_id queue_id;
448 448 rtems_status_code status;
449 449 ring_node *ring_node_to_send;
450 450 unsigned long long int acquisitionTimeF0_asLong;
451 451
452 452 acquisitionTimeF0_asLong = 0x00;
453 453
454 454 status = get_message_queue_id_send( &queue_id );
455 455 if (status != RTEMS_SUCCESSFUL)
456 456 {
457 457 PRINTF1("in CWF2 *** ERR get_message_queue_id_send %d\n", status)
458 458 }
459 459
460 460 BOOT_PRINTF("in CWF2 ***\n")
461 461
462 462 while(1){
463 463 // wait for an RTEMS_EVENT
464 464 rtems_event_receive( RTEMS_EVENT_MODE_NORM_S1_S2 | RTEMS_EVENT_MODE_BURST,
465 465 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
466 466 ring_node_to_send = getRingNodeToSendCWF( 2 );
467 467 if (event_out == RTEMS_EVENT_MODE_BURST)
468 468 {
469 469 status = rtems_message_queue_send( queue_id, &ring_node_to_send, sizeof( ring_node* ) );
470 470 }
471 471 else if (event_out == RTEMS_EVENT_MODE_NORM_S1_S2)
472 472 {
473 473 if ( lfrCurrentMode == LFR_MODE_SBM2 )
474 474 {
475 475 status = rtems_message_queue_send( queue_id, &ring_node_to_send, sizeof( ring_node* ) );
476 476 }
477 477 // launch snapshot extraction if needed
478 478 if (extractSWF2 == true)
479 479 {
480 480 ring_node_to_send_swf_f2 = ring_node_to_send_cwf_f2;
481 481 // extract the snapshot
482 482 build_snapshot_from_ring( ring_node_to_send_swf_f2, 2, acquisitionTimeF0_asLong,
483 483 &ring_node_swf2_extracted, swf2_extracted );
484 484 // send the snapshot when built
485 485 status = rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_SBM2 );
486 486 extractSWF2 = false;
487 487 swf2_ready = true;
488 488 }
489 489 if (swf0_ready_flag_f2 == true)
490 490 {
491 491 extractSWF2 = true;
492 492 // record the acquition time of the f0 snapshot to use to build the snapshot at f2
493 493 acquisitionTimeF0_asLong = get_acquisition_time( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
494 494 swf0_ready_flag_f2 = false;
495 495 }
496 496 }
497 497 }
498 498 }
499 499
500 500 rtems_task cwf1_task(rtems_task_argument argument) // ONLY USED IN SBM1
501 501 {
502 502 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f1.
503 503 *
504 504 * @param unused is the starting argument of the RTEMS task
505 505 *
506 506 * The following data packet is sent by this function:
507 507 * - TM_LFR_SCIENCE_SBM1_CWF_F1
508 508 *
509 509 */
510 510
511 511 rtems_event_set event_out;
512 512 rtems_id queue_id;
513 513 rtems_status_code status;
514 514
515 515 ring_node *ring_node_to_send_cwf;
516 516
517 517 status = get_message_queue_id_send( &queue_id );
518 518 if (status != RTEMS_SUCCESSFUL)
519 519 {
520 520 PRINTF1("in CWF1 *** ERR get_message_queue_id_send %d\n", status)
521 521 }
522 522
523 523 BOOT_PRINTF("in CWF1 ***\n")
524 524
525 525 while(1){
526 526 // wait for an RTEMS_EVENT
527 527 rtems_event_receive( RTEMS_EVENT_MODE_NORM_S1_S2,
528 528 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
529 529 ring_node_to_send_cwf = getRingNodeToSendCWF( 1 );
530 530 ring_node_to_send_cwf_f1->sid = SID_SBM1_CWF_F1;
531 531 if (lfrCurrentMode == LFR_MODE_SBM1)
532 532 {
533 533 status = rtems_message_queue_send( queue_id, &ring_node_to_send_cwf, sizeof( ring_node* ) );
534 534 if (status != 0)
535 535 {
536 536 PRINTF("cwf sending failed\n")
537 537 }
538 538 }
539 539 // launch snapshot extraction if needed
540 540 if (extractSWF1 == true)
541 541 {
542 542 ring_node_to_send_swf_f1 = ring_node_to_send_cwf;
543 543 // launch the snapshot extraction
544 544 status = rtems_event_send( Task_id[TASKID_SWBD], RTEMS_EVENT_MODE_NORM_S1_S2 );
545 545 extractSWF1 = false;
546 546 }
547 547 if (swf0_ready_flag_f1 == true)
548 548 {
549 549 extractSWF1 = true;
550 550 swf0_ready_flag_f1 = false; // this step shall be executed only one time
551 551 }
552 552 if ((swf1_ready == true) && (swf2_ready == true)) // swf_f1 is ready after the extraction
553 553 {
554 554 status = rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_NORMAL );
555 555 swf1_ready = false;
556 556 swf2_ready = false;
557 557 }
558 558 }
559 559 }
560 560
561 561 rtems_task swbd_task(rtems_task_argument argument)
562 562 {
563 563 /** This RTEMS task is dedicated to the building of snapshots from different continuous waveforms buffers.
564 564 *
565 565 * @param unused is the starting argument of the RTEMS task
566 566 *
567 567 */
568 568
569 569 rtems_event_set event_out;
570 570 unsigned long long int acquisitionTimeF0_asLong;
571 571
572 572 acquisitionTimeF0_asLong = 0x00;
573 573
574 574 BOOT_PRINTF("in SWBD ***\n")
575 575
576 576 while(1){
577 577 // wait for an RTEMS_EVENT
578 578 rtems_event_receive( RTEMS_EVENT_MODE_NORM_S1_S2,
579 579 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
580 580 if (event_out == RTEMS_EVENT_MODE_NORM_S1_S2)
581 581 {
582 582 acquisitionTimeF0_asLong = get_acquisition_time( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
583 583 build_snapshot_from_ring( ring_node_to_send_swf_f1, 1, acquisitionTimeF0_asLong,
584 584 &ring_node_swf1_extracted, swf1_extracted );
585 585 swf1_ready = true; // the snapshot has been extracted and is ready to be sent
586 586 }
587 587 else
588 588 {
589 589 PRINTF1("in SWBD *** unexpected rtems event received %x\n", (int) event_out)
590 590 }
591 591 }
592 592 }
593 593
594 594 //******************
595 595 // general functions
596 596
597 597 void WFP_init_rings( void )
598 598 {
599 599 // F0 RING
600 600 init_ring( waveform_ring_f0, NB_RING_NODES_F0, wf_buffer_f0, WFRM_BUFFER );
601 601 // F1 RING
602 602 init_ring( waveform_ring_f1, NB_RING_NODES_F1, wf_buffer_f1, WFRM_BUFFER );
603 603 // F2 RING
604 604 init_ring( waveform_ring_f2, NB_RING_NODES_F2, wf_buffer_f2, WFRM_BUFFER );
605 605 // F3 RING
606 606 init_ring( waveform_ring_f3, NB_RING_NODES_F3, wf_buffer_f3, WFRM_BUFFER );
607 607
608 608 ring_node_swf1_extracted.buffer_address = (int) swf1_extracted;
609 609 ring_node_swf2_extracted.buffer_address = (int) swf2_extracted;
610 610
611 611 DEBUG_PRINTF1("waveform_ring_f0 @%x\n", (unsigned int) waveform_ring_f0)
612 612 DEBUG_PRINTF1("waveform_ring_f1 @%x\n", (unsigned int) waveform_ring_f1)
613 613 DEBUG_PRINTF1("waveform_ring_f2 @%x\n", (unsigned int) waveform_ring_f2)
614 614 DEBUG_PRINTF1("waveform_ring_f3 @%x\n", (unsigned int) waveform_ring_f3)
615 615 DEBUG_PRINTF1("wf_buffer_f0 @%x\n", (unsigned int) wf_buffer_f0)
616 616 DEBUG_PRINTF1("wf_buffer_f1 @%x\n", (unsigned int) wf_buffer_f1)
617 617 DEBUG_PRINTF1("wf_buffer_f2 @%x\n", (unsigned int) wf_buffer_f2)
618 618 DEBUG_PRINTF1("wf_buffer_f3 @%x\n", (unsigned int) wf_buffer_f3)
619 619
620 620 }
621 621
622 622 void WFP_reset_current_ring_nodes( void )
623 623 {
624 624 current_ring_node_f0 = waveform_ring_f0[0].next;
625 625 current_ring_node_f1 = waveform_ring_f1[0].next;
626 626 current_ring_node_f2 = waveform_ring_f2[0].next;
627 627 current_ring_node_f3 = waveform_ring_f3[0].next;
628 628
629 629 ring_node_to_send_swf_f0 = waveform_ring_f0;
630 630 ring_node_to_send_swf_f1 = waveform_ring_f1;
631 631 ring_node_to_send_swf_f2 = waveform_ring_f2;
632 632
633 633 ring_node_to_send_cwf_f1 = waveform_ring_f1;
634 634 ring_node_to_send_cwf_f2 = waveform_ring_f2;
635 635 ring_node_to_send_cwf_f3 = waveform_ring_f3;
636 636 }
637 637
638 638 int send_waveform_CWF3_light( ring_node *ring_node_to_send, ring_node *ring_node_cwf3_light, rtems_id queue_id )
639 639 {
640 640 /** This function sends CWF_F3 CCSDS packets without the b1, b2 and b3 data.
641 641 *
642 642 * @param waveform points to the buffer containing the data that will be send.
643 643 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
644 644 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
645 645 * contain information to setup the transmission of the data packets.
646 646 *
647 647 * By default, CWF_F3 packet are send without the b1, b2 and b3 data. This function rebuilds a data buffer
648 648 * from the incoming data and sends it in 7 packets, 6 containing 340 blocks and 1 one containing 8 blocks.
649 649 *
650 650 */
651 651
652 652 unsigned int i;
653 653 int ret;
654 654 rtems_status_code status;
655 655
656 656 char *sample;
657 657 int *dataPtr;
658 658
659 659 ret = LFR_DEFAULT;
660 660
661 661 dataPtr = (int*) ring_node_to_send->buffer_address;
662 662
663 663 ring_node_cwf3_light->coarseTime = ring_node_to_send->coarseTime;
664 664 ring_node_cwf3_light->fineTime = ring_node_to_send->fineTime;
665 665
666 666 //**********************
667 667 // BUILD CWF3_light DATA
668 668 for ( i=0; i< NB_SAMPLES_PER_SNAPSHOT; i++)
669 669 {
670 670 sample = (char*) &dataPtr[ (i * NB_WORDS_SWF_BLK) ];
671 671 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) ] = sample[ 0 ];
672 672 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 1 ] = sample[ 1 ];
673 673 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 2 ] = sample[ 2 ];
674 674 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 3 ] = sample[ 3 ];
675 675 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 4 ] = sample[ 4 ];
676 676 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 5 ] = sample[ 5 ];
677 677 }
678 678
679 679 // SEND PACKET
680 680 status = rtems_message_queue_send( queue_id, &ring_node_cwf3_light, sizeof( ring_node* ) );
681 681 if (status != RTEMS_SUCCESSFUL) {
682 682 ret = LFR_DEFAULT;
683 683 }
684 684
685 685 return ret;
686 686 }
687 687
688 688 void compute_acquisition_time( unsigned int coarseTime, unsigned int fineTime,
689 689 unsigned int sid, unsigned char pa_lfr_pkt_nr, unsigned char * acquisitionTime )
690 690 {
691 691 unsigned long long int acquisitionTimeAsLong;
692 692 unsigned char localAcquisitionTime[6];
693 693 double deltaT;
694 694
695 695 deltaT = 0.;
696 696
697 697 localAcquisitionTime[0] = (unsigned char) ( coarseTime >> 24 );
698 698 localAcquisitionTime[1] = (unsigned char) ( coarseTime >> 16 );
699 699 localAcquisitionTime[2] = (unsigned char) ( coarseTime >> 8 );
700 700 localAcquisitionTime[3] = (unsigned char) ( coarseTime );
701 701 localAcquisitionTime[4] = (unsigned char) ( fineTime >> 8 );
702 702 localAcquisitionTime[5] = (unsigned char) ( fineTime );
703 703
704 704 acquisitionTimeAsLong = ( (unsigned long long int) localAcquisitionTime[0] << 40 )
705 705 + ( (unsigned long long int) localAcquisitionTime[1] << 32 )
706 706 + ( (unsigned long long int) localAcquisitionTime[2] << 24 )
707 707 + ( (unsigned long long int) localAcquisitionTime[3] << 16 )
708 708 + ( (unsigned long long int) localAcquisitionTime[4] << 8 )
709 709 + ( (unsigned long long int) localAcquisitionTime[5] );
710 710
711 711 switch( sid )
712 712 {
713 713 case SID_NORM_SWF_F0:
714 714 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 24576. ;
715 715 break;
716 716
717 717 case SID_NORM_SWF_F1:
718 718 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 4096. ;
719 719 break;
720 720
721 721 case SID_NORM_SWF_F2:
722 722 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 256. ;
723 723 break;
724 724
725 725 case SID_SBM1_CWF_F1:
726 726 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 4096. ;
727 727 break;
728 728
729 729 case SID_SBM2_CWF_F2:
730 730 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 256. ;
731 731 break;
732 732
733 733 case SID_BURST_CWF_F2:
734 734 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 256. ;
735 735 break;
736 736
737 737 case SID_NORM_CWF_F3:
738 738 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF_SHORT_F3 * 65536. / 16. ;
739 739 break;
740 740
741 741 case SID_NORM_CWF_LONG_F3:
742 742 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 16. ;
743 743 break;
744 744
745 745 default:
746 746 PRINTF1("in compute_acquisition_time *** ERR unexpected sid %d\n", sid)
747 747 deltaT = 0.;
748 748 break;
749 749 }
750 750
751 751 acquisitionTimeAsLong = acquisitionTimeAsLong + (unsigned long long int) deltaT;
752 752 //
753 753 acquisitionTime[0] = (unsigned char) (acquisitionTimeAsLong >> 40);
754 754 acquisitionTime[1] = (unsigned char) (acquisitionTimeAsLong >> 32);
755 755 acquisitionTime[2] = (unsigned char) (acquisitionTimeAsLong >> 24);
756 756 acquisitionTime[3] = (unsigned char) (acquisitionTimeAsLong >> 16);
757 757 acquisitionTime[4] = (unsigned char) (acquisitionTimeAsLong >> 8 );
758 758 acquisitionTime[5] = (unsigned char) (acquisitionTimeAsLong );
759 759
760 760 }
761 761
762 762 void build_snapshot_from_ring( ring_node *ring_node_to_send,
763 763 unsigned char frequencyChannel,
764 764 unsigned long long int acquisitionTimeF0_asLong,
765 765 ring_node *ring_node_swf_extracted,
766 766 int *swf_extracted)
767 767 {
768 768 unsigned int i;
769 769 unsigned long long int centerTime_asLong;
770 770 unsigned long long int acquisitionTime_asLong;
771 771 unsigned long long int bufferAcquisitionTime_asLong;
772 772 unsigned char *ptr1;
773 773 unsigned char *ptr2;
774 774 unsigned char *timeCharPtr;
775 775 unsigned char nb_ring_nodes;
776 776 unsigned long long int frequency_asLong;
777 777 unsigned long long int nbTicksPerSample_asLong;
778 778 unsigned long long int nbSamplesPart1_asLong;
779 779 unsigned long long int sampleOffset_asLong;
780 780
781 781 unsigned int deltaT_F0;
782 782 unsigned int deltaT_F1;
783 783 unsigned long long int deltaT_F2;
784 784
785 785 deltaT_F0 = 2731; // (2048. / 24576. / 2.) * 65536. = 2730.667;
786 786 deltaT_F1 = 16384; // (2048. / 4096. / 2.) * 65536. = 16384;
787 787 deltaT_F2 = 262144; // (2048. / 256. / 2.) * 65536. = 262144;
788 788 sampleOffset_asLong = 0x00;
789 789
790 790 // (1) get the f0 acquisition time => the value is passed in argument
791 791
792 792 // (2) compute the central reference time
793 793 centerTime_asLong = acquisitionTimeF0_asLong + deltaT_F0;
794 794
795 795 // (3) compute the acquisition time of the current snapshot
796 796 switch(frequencyChannel)
797 797 {
798 798 case 1: // 1 is for F1 = 4096 Hz
799 799 acquisitionTime_asLong = centerTime_asLong - deltaT_F1;
800 800 nb_ring_nodes = NB_RING_NODES_F1;
801 801 frequency_asLong = 4096;
802 802 nbTicksPerSample_asLong = 16; // 65536 / 4096;
803 803 break;
804 804 case 2: // 2 is for F2 = 256 Hz
805 805 acquisitionTime_asLong = centerTime_asLong - deltaT_F2;
806 806 nb_ring_nodes = NB_RING_NODES_F2;
807 807 frequency_asLong = 256;
808 808 nbTicksPerSample_asLong = 256; // 65536 / 256;
809 809 break;
810 810 default:
811 811 acquisitionTime_asLong = centerTime_asLong;
812 812 frequency_asLong = 256;
813 813 nbTicksPerSample_asLong = 256;
814 814 break;
815 815 }
816 816
817 817 //****************************************************************************
818 818 // (4) search the ring_node with the acquisition time <= acquisitionTime_asLong
819 819 for (i=0; i<nb_ring_nodes; i++)
820 820 {
821 PRINTF1("%d ... ", i)
821 //PRINTF1("%d ... ", i);
822 822 bufferAcquisitionTime_asLong = get_acquisition_time( (unsigned char *) &ring_node_to_send->coarseTime );
823 823 if (bufferAcquisitionTime_asLong <= acquisitionTime_asLong)
824 824 {
825 PRINTF1("buffer found with acquisition time = %llx\n", bufferAcquisitionTime_asLong)
825 //PRINTF1("buffer found with acquisition time = %llx\n", bufferAcquisitionTime_asLong);
826 826 break;
827 827 }
828 828 ring_node_to_send = ring_node_to_send->previous;
829 829 }
830 830
831 831 // (5) compute the number of samples to take in the current buffer
832 832 sampleOffset_asLong = ((acquisitionTime_asLong - bufferAcquisitionTime_asLong) * frequency_asLong ) >> 16;
833 833 nbSamplesPart1_asLong = NB_SAMPLES_PER_SNAPSHOT - sampleOffset_asLong;
834 PRINTF2("sampleOffset_asLong = %lld, nbSamplesPart1_asLong = %lld\n", sampleOffset_asLong, nbSamplesPart1_asLong)
834 //PRINTF2("sampleOffset_asLong = %lld, nbSamplesPart1_asLong = %lld\n", sampleOffset_asLong, nbSamplesPart1_asLong);
835 835
836 836 // (6) compute the final acquisition time
837 837 acquisitionTime_asLong = bufferAcquisitionTime_asLong +
838 838 sampleOffset_asLong * nbTicksPerSample_asLong;
839 839
840 840 // (7) copy the acquisition time at the beginning of the extrated snapshot
841 841 ptr1 = (unsigned char*) &acquisitionTime_asLong;
842 842 // fine time
843 843 ptr2 = (unsigned char*) &ring_node_swf_extracted->fineTime;
844 844 ptr2[2] = ptr1[ 4 + 2 ];
845 845 ptr2[3] = ptr1[ 5 + 2 ];
846 846 // coarse time
847 847 ptr2 = (unsigned char*) &ring_node_swf_extracted->coarseTime;
848 848 ptr2[0] = ptr1[ 0 + 2 ];
849 849 ptr2[1] = ptr1[ 1 + 2 ];
850 850 ptr2[2] = ptr1[ 2 + 2 ];
851 851 ptr2[3] = ptr1[ 3 + 2 ];
852 852
853 853 // re set the synchronization bit
854 854 timeCharPtr = (unsigned char*) &ring_node_to_send->coarseTime;
855 855 ptr2[0] = ptr2[0] | (timeCharPtr[0] & 0x80); // [1000 0000]
856 856
857 857 if ( (nbSamplesPart1_asLong >= NB_SAMPLES_PER_SNAPSHOT) | (nbSamplesPart1_asLong < 0) )
858 858 {
859 859 nbSamplesPart1_asLong = 0;
860 860 }
861 861 // copy the part 1 of the snapshot in the extracted buffer
862 862 for ( i = 0; i < (nbSamplesPart1_asLong * NB_WORDS_SWF_BLK); i++ )
863 863 {
864 864 swf_extracted[i] =
865 865 ((int*) ring_node_to_send->buffer_address)[ i + (sampleOffset_asLong * NB_WORDS_SWF_BLK) ];
866 866 }
867 867 // copy the part 2 of the snapshot in the extracted buffer
868 868 ring_node_to_send = ring_node_to_send->next;
869 869 for ( i = (nbSamplesPart1_asLong * NB_WORDS_SWF_BLK); i < (NB_SAMPLES_PER_SNAPSHOT * NB_WORDS_SWF_BLK); i++ )
870 870 {
871 871 swf_extracted[i] =
872 872 ((int*) ring_node_to_send->buffer_address)[ (i-(nbSamplesPart1_asLong * NB_WORDS_SWF_BLK)) ];
873 873 }
874 874 }
875 875
876 876 void snapshot_resynchronization( unsigned char *timePtr )
877 877 {
878 878 unsigned long long int acquisitionTime;
879 879 unsigned long long int centerTime;
880 880 unsigned long long int previousTick;
881 881 unsigned long long int nextTick;
882 882 unsigned long long int deltaPreviousTick;
883 883 unsigned long long int deltaNextTick;
884 884 unsigned int deltaTickInF2;
885 double deltaPrevious;
886 double deltaNext;
885 double deltaPrevious_ms;
886 double deltaNext_ms;
887 887
888 // get acquisition time in fine time ticks
888 889 acquisitionTime = get_acquisition_time( timePtr );
889 890
890 891 // compute center time
891 892 centerTime = acquisitionTime + 2731; // (2048. / 24576. / 2.) * 65536. = 2730.667;
892 893 previousTick = centerTime - (centerTime & 0xffff);
893 894 nextTick = previousTick + 65536;
894 895
895 896 deltaPreviousTick = centerTime - previousTick;
896 897 deltaNextTick = nextTick - centerTime;
897 898
898 deltaPrevious = ((double) deltaPreviousTick) / 65536. * 1000.;
899 deltaNext = ((double) deltaNextTick) / 65536. * 1000.;
899 deltaPrevious_ms = ((double) deltaPreviousTick) / 65536. * 1000.;
900 deltaNext_ms = ((double) deltaNextTick) / 65536. * 1000.;
900 901
901 PRINTF2("delta previous = %f ms, delta next = %f ms\n", deltaPrevious, deltaNext)
902 PRINTF2("delta previous = %llu, delta next = %llu\n", deltaPreviousTick, deltaNextTick)
902 PRINTF2("delta previous = %f ms, delta next = %f ms\n", deltaPrevious_ms, deltaNext_ms);
903 PRINTF2("delta previous = %llu fine time ticks, delta next = %llu fine time ticks\n", deltaPreviousTick, deltaNextTick);
903 904
904 905 // which tick is the closest
905 906 if (deltaPreviousTick > deltaNextTick)
906 907 {
907 deltaTickInF2 = floor( (deltaNext * 256. / 1000.) ); // the division by 2 is important here
908 waveform_picker_regs->delta_snapshot = waveform_picker_regs->delta_snapshot + deltaTickInF2;
909 PRINTF1("correction of = + %u\n", deltaTickInF2)
908 // deltaNext is in [ms]
909 deltaTickInF2 = floor( (deltaNext_ms * 256. / 1000.) );
910 waveform_picker_regs->delta_snapshot = waveform_picker_regs->delta_snapshot + 1 * deltaTickInF2;
911 PRINTF2("correction of = + %u, delta_snapshot = %d\n", deltaTickInF2, waveform_picker_regs->delta_snapshot);
910 912 }
911 913 else
912 914 {
913 deltaTickInF2 = floor( (deltaPrevious * 256. / 1000.) ); // the division by 2 is important here
914 waveform_picker_regs->delta_snapshot = waveform_picker_regs->delta_snapshot - deltaTickInF2;
915 PRINTF1("correction of = - %u\n", deltaTickInF2)
915 // deltaPrevious is in [ms]
916 deltaTickInF2 = floor( (deltaPrevious_ms * 256. / 1000.) );
917 waveform_picker_regs->delta_snapshot = waveform_picker_regs->delta_snapshot - 1 * deltaTickInF2;
918 PRINTF2("correction of = - %u, delta_snapshot = %d\n", deltaTickInF2, waveform_picker_regs->delta_snapshot);
916 919 }
917 920 }
918 921
919 922 //**************
920 923 // wfp registers
921 924 void reset_wfp_burst_enable( void )
922 925 {
923 926 /** This function resets the waveform picker burst_enable register.
924 927 *
925 928 * The burst bits [f2 f1 f0] and the enable bits [f3 f2 f1 f0] are set to 0.
926 929 *
927 930 */
928 931
929 932 // [1000 000] burst f2, f1, f0 enable f3, f2, f1, f0
930 933 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable & 0x80;
931 934 }
932 935
933 936 void reset_wfp_status( void )
934 937 {
935 938 /** This function resets the waveform picker status register.
936 939 *
937 940 * All status bits are set to 0 [new_err full_err full].
938 941 *
939 942 */
940 943
941 944 waveform_picker_regs->status = 0xffff;
942 945 }
943 946
944 947 void reset_wfp_buffer_addresses( void )
945 948 {
946 949 // F0
947 950 waveform_picker_regs->addr_data_f0_0 = current_ring_node_f0->previous->buffer_address; // 0x08
948 951 waveform_picker_regs->addr_data_f0_1 = current_ring_node_f0->buffer_address; // 0x0c
949 952 // F1
950 953 waveform_picker_regs->addr_data_f1_0 = current_ring_node_f1->previous->buffer_address; // 0x10
951 954 waveform_picker_regs->addr_data_f1_1 = current_ring_node_f1->buffer_address; // 0x14
952 955 // F2
953 956 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->previous->buffer_address; // 0x18
954 957 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address; // 0x1c
955 958 // F3
956 959 waveform_picker_regs->addr_data_f3_0 = current_ring_node_f3->previous->buffer_address; // 0x20
957 960 waveform_picker_regs->addr_data_f3_1 = current_ring_node_f3->buffer_address; // 0x24
958 961 }
959 962
960 963 void reset_waveform_picker_regs( void )
961 964 {
962 965 /** This function resets the waveform picker module registers.
963 966 *
964 967 * The registers affected by this function are located at the following offset addresses:
965 968 * - 0x00 data_shaping
966 969 * - 0x04 run_burst_enable
967 970 * - 0x08 addr_data_f0
968 971 * - 0x0C addr_data_f1
969 972 * - 0x10 addr_data_f2
970 973 * - 0x14 addr_data_f3
971 974 * - 0x18 status
972 975 * - 0x1C delta_snapshot
973 976 * - 0x20 delta_f0
974 977 * - 0x24 delta_f0_2
975 978 * - 0x28 delta_f1
976 979 * - 0x2c delta_f2
977 980 * - 0x30 nb_data_by_buffer
978 981 * - 0x34 nb_snapshot_param
979 982 * - 0x38 start_date
980 983 * - 0x3c nb_word_in_buffer
981 984 *
982 985 */
983 986
984 987 set_wfp_data_shaping(); // 0x00 *** R1 R0 SP1 SP0 BW
985 988
986 989 reset_wfp_burst_enable(); // 0x04 *** [run *** burst f2, f1, f0 *** enable f3, f2, f1, f0 ]
987 990
988 991 reset_wfp_buffer_addresses();
989 992
990 993 reset_wfp_status(); // 0x18
991 994
992 995 set_wfp_delta_snapshot(); // 0x1c *** 300 s => 0x12bff
993 996
994 997 set_wfp_delta_f0_f0_2(); // 0x20, 0x24
995 998
996 999 set_wfp_delta_f1(); // 0x28
997 1000
998 1001 set_wfp_delta_f2(); // 0x2c
999 1002
1000 1003 DEBUG_PRINTF1("delta_snapshot %x\n", waveform_picker_regs->delta_snapshot)
1001 1004 DEBUG_PRINTF1("delta_f0 %x\n", waveform_picker_regs->delta_f0)
1002 1005 DEBUG_PRINTF1("delta_f0_2 %x\n", waveform_picker_regs->delta_f0_2)
1003 1006 DEBUG_PRINTF1("delta_f1 %x\n", waveform_picker_regs->delta_f1)
1004 1007 DEBUG_PRINTF1("delta_f2 %x\n", waveform_picker_regs->delta_f2)
1005 1008 // 2688 = 8 * 336
1006 1009 waveform_picker_regs->nb_data_by_buffer = 0xa7f; // 0x30 *** 2688 - 1 => nb samples -1
1007 1010 waveform_picker_regs->snapshot_param = 0xa80; // 0x34 *** 2688 => nb samples
1008 1011 waveform_picker_regs->start_date = 0x7fffffff; // 0x38
1009 1012 //
1010 1013 // coarse time and fine time registers are not initialized, they are volatile
1011 1014 //
1012 1015 waveform_picker_regs->buffer_length = 0x1f8;// buffer length in burst = 3 * 2688 / 16 = 504 = 0x1f8
1013 1016 }
1014 1017
1015 1018 void set_wfp_data_shaping( void )
1016 1019 {
1017 1020 /** This function sets the data_shaping register of the waveform picker module.
1018 1021 *
1019 1022 * The value is read from one field of the parameter_dump_packet structure:\n
1020 1023 * bw_sp0_sp1_r0_r1
1021 1024 *
1022 1025 */
1023 1026
1024 1027 unsigned char data_shaping;
1025 1028
1026 1029 // get the parameters for the data shaping [BW SP0 SP1 R0 R1] in sy_lfr_common1 and configure the register
1027 1030 // waveform picker : [R1 R0 SP1 SP0 BW]
1028 1031
1029 1032 data_shaping = parameter_dump_packet.sy_lfr_common_parameters;
1030 1033
1031 1034 waveform_picker_regs->data_shaping =
1032 1035 ( (data_shaping & 0x20) >> 5 ) // BW
1033 1036 + ( (data_shaping & 0x10) >> 3 ) // SP0
1034 1037 + ( (data_shaping & 0x08) >> 1 ) // SP1
1035 1038 + ( (data_shaping & 0x04) << 1 ) // R0
1036 1039 + ( (data_shaping & 0x02) << 3 ) // R1
1037 1040 + ( (data_shaping & 0x01) << 5 ); // R2
1038 1041 }
1039 1042
1040 1043 void set_wfp_burst_enable_register( unsigned char mode )
1041 1044 {
1042 1045 /** This function sets the waveform picker burst_enable register depending on the mode.
1043 1046 *
1044 1047 * @param mode is the LFR mode to launch.
1045 1048 *
1046 1049 * The burst bits shall be before the enable bits.
1047 1050 *
1048 1051 */
1049 1052
1050 1053 // [0000 0000] burst f2, f1, f0 enable f3 f2 f1 f0
1051 1054 // the burst bits shall be set first, before the enable bits
1052 1055 switch(mode) {
1053 1056 case LFR_MODE_NORMAL:
1054 1057 case LFR_MODE_SBM1:
1055 1058 case LFR_MODE_SBM2:
1056 1059 waveform_picker_regs->run_burst_enable = 0x60; // [0110 0000] enable f2 and f1 burst
1057 1060 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x0f; // [1111] enable f3 f2 f1 f0
1058 1061 break;
1059 1062 case LFR_MODE_BURST:
1060 1063 waveform_picker_regs->run_burst_enable = 0x40; // [0100 0000] f2 burst enabled
1061 1064 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x0c; // [1100] enable f3 and f2
1062 1065 break;
1063 1066 default:
1064 1067 waveform_picker_regs->run_burst_enable = 0x00; // [0000 0000] no burst enabled, no waveform enabled
1065 1068 break;
1066 1069 }
1067 1070 }
1068 1071
1069 1072 void set_wfp_delta_snapshot( void )
1070 1073 {
1071 1074 /** This function sets the delta_snapshot register of the waveform picker module.
1072 1075 *
1073 1076 * The value is read from two (unsigned char) of the parameter_dump_packet structure:
1074 1077 * - sy_lfr_n_swf_p[0]
1075 1078 * - sy_lfr_n_swf_p[1]
1076 1079 *
1077 1080 */
1078 1081
1079 1082 unsigned int delta_snapshot;
1080 1083 unsigned int delta_snapshot_in_T2;
1081 1084
1082 1085 delta_snapshot = parameter_dump_packet.sy_lfr_n_swf_p[0]*256
1083 1086 + parameter_dump_packet.sy_lfr_n_swf_p[1];
1084 1087
1085 1088 delta_snapshot_in_T2 = delta_snapshot * 256;
1086 1089 waveform_picker_regs->delta_snapshot = delta_snapshot_in_T2 - 1; // max 4 bytes
1087 1090 }
1088 1091
1089 1092 void set_wfp_delta_f0_f0_2( void )
1090 1093 {
1091 1094 unsigned int delta_snapshot;
1092 1095 unsigned int nb_samples_per_snapshot;
1093 1096 float delta_f0_in_float;
1094 1097
1095 1098 delta_snapshot = waveform_picker_regs->delta_snapshot;
1096 1099 nb_samples_per_snapshot = parameter_dump_packet.sy_lfr_n_swf_l[0] * 256 + parameter_dump_packet.sy_lfr_n_swf_l[1];
1097 1100 delta_f0_in_float =nb_samples_per_snapshot / 2. * ( 1. / 256. - 1. / 24576.) * 256.;
1098 1101
1099 1102 waveform_picker_regs->delta_f0 = delta_snapshot - floor( delta_f0_in_float );
1100 1103 waveform_picker_regs->delta_f0_2 = 0x30; // 48 = 11 0000, max 7 bits
1101 1104 }
1102 1105
1103 1106 void set_wfp_delta_f1( void )
1104 1107 {
1105 1108 unsigned int delta_snapshot;
1106 1109 unsigned int nb_samples_per_snapshot;
1107 1110 float delta_f1_in_float;
1108 1111
1109 1112 delta_snapshot = waveform_picker_regs->delta_snapshot;
1110 1113 nb_samples_per_snapshot = parameter_dump_packet.sy_lfr_n_swf_l[0] * 256 + parameter_dump_packet.sy_lfr_n_swf_l[1];
1111 1114 delta_f1_in_float = nb_samples_per_snapshot / 2. * ( 1. / 256. - 1. / 4096.) * 256.;
1112 1115
1113 1116 waveform_picker_regs->delta_f1 = delta_snapshot - floor( delta_f1_in_float );
1114 1117 }
1115 1118
1116 1119 void set_wfp_delta_f2()
1117 1120 {
1118 1121 unsigned int delta_snapshot;
1119 1122 unsigned int nb_samples_per_snapshot;
1120 1123
1121 1124 delta_snapshot = waveform_picker_regs->delta_snapshot;
1122 1125 nb_samples_per_snapshot = parameter_dump_packet.sy_lfr_n_swf_l[0] * 256 + parameter_dump_packet.sy_lfr_n_swf_l[1];
1123 1126
1124 1127 waveform_picker_regs->delta_f2 = delta_snapshot - nb_samples_per_snapshot / 2;
1125 1128 }
1126 1129
1127 1130 //*****************
1128 1131 // local parameters
1129 1132
1130 1133 void increment_seq_counter_source_id( unsigned char *packet_sequence_control, unsigned int sid )
1131 1134 {
1132 1135 /** This function increments the parameter "sequence_cnt" depending on the sid passed in argument.
1133 1136 *
1134 1137 * @param packet_sequence_control is a pointer toward the parameter sequence_cnt to update.
1135 1138 * @param sid is the source identifier of the packet being updated.
1136 1139 *
1137 1140 * REQ-LFR-SRS-5240 / SSS-CP-FS-590
1138 1141 * The sequence counters shall wrap around from 2^14 to zero.
1139 1142 * The sequence counter shall start at zero at startup.
1140 1143 *
1141 1144 * REQ-LFR-SRS-5239 / SSS-CP-FS-580
1142 1145 * All TM_LFR_SCIENCE_ packets are sent to ground, i.e. destination id = 0
1143 1146 *
1144 1147 */
1145 1148
1146 1149 unsigned short *sequence_cnt;
1147 1150 unsigned short segmentation_grouping_flag;
1148 1151 unsigned short new_packet_sequence_control;
1149 1152 rtems_mode initial_mode_set;
1150 1153 rtems_mode current_mode_set;
1151 1154 rtems_status_code status;
1152 1155
1153 1156 //******************************************
1154 1157 // CHANGE THE MODE OF THE CALLING RTEMS TASK
1155 1158 status = rtems_task_mode( RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &initial_mode_set );
1156 1159
1157 1160 if ( (sid == SID_NORM_SWF_F0) || (sid == SID_NORM_SWF_F1) || (sid == SID_NORM_SWF_F2)
1158 1161 || (sid == SID_NORM_CWF_F3) || (sid == SID_NORM_CWF_LONG_F3)
1159 1162 || (sid == SID_BURST_CWF_F2)
1160 1163 || (sid == SID_NORM_ASM_F0) || (sid == SID_NORM_ASM_F1) || (sid == SID_NORM_ASM_F2)
1161 1164 || (sid == SID_NORM_BP1_F0) || (sid == SID_NORM_BP1_F1) || (sid == SID_NORM_BP1_F2)
1162 1165 || (sid == SID_NORM_BP2_F0) || (sid == SID_NORM_BP2_F1) || (sid == SID_NORM_BP2_F2)
1163 1166 || (sid == SID_BURST_BP1_F0) || (sid == SID_BURST_BP2_F0)
1164 1167 || (sid == SID_BURST_BP1_F1) || (sid == SID_BURST_BP2_F1) )
1165 1168 {
1166 1169 sequence_cnt = (unsigned short *) &sequenceCounters_SCIENCE_NORMAL_BURST;
1167 1170 }
1168 1171 else if ( (sid ==SID_SBM1_CWF_F1) || (sid ==SID_SBM2_CWF_F2)
1169 1172 || (sid == SID_SBM1_BP1_F0) || (sid == SID_SBM1_BP2_F0)
1170 1173 || (sid == SID_SBM2_BP1_F0) || (sid == SID_SBM2_BP2_F0)
1171 1174 || (sid == SID_SBM2_BP1_F1) || (sid == SID_SBM2_BP2_F1) )
1172 1175 {
1173 1176 sequence_cnt = (unsigned short *) &sequenceCounters_SCIENCE_SBM1_SBM2;
1174 1177 }
1175 1178 else
1176 1179 {
1177 1180 sequence_cnt = (unsigned short *) NULL;
1178 1181 PRINTF1("in increment_seq_counter_source_id *** ERR apid_destid %d not known\n", sid)
1179 1182 }
1180 1183
1181 1184 if (sequence_cnt != NULL)
1182 1185 {
1183 1186 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << 8;
1184 1187 *sequence_cnt = (*sequence_cnt) & 0x3fff;
1185 1188
1186 1189 new_packet_sequence_control = segmentation_grouping_flag | (*sequence_cnt) ;
1187 1190
1188 1191 packet_sequence_control[0] = (unsigned char) (new_packet_sequence_control >> 8);
1189 1192 packet_sequence_control[1] = (unsigned char) (new_packet_sequence_control );
1190 1193
1191 1194 // increment the sequence counter
1192 1195 if ( *sequence_cnt < SEQ_CNT_MAX)
1193 1196 {
1194 1197 *sequence_cnt = *sequence_cnt + 1;
1195 1198 }
1196 1199 else
1197 1200 {
1198 1201 *sequence_cnt = 0;
1199 1202 }
1200 1203 }
1201 1204
1202 1205 //*************************************
1203 1206 // RESTORE THE MODE OF THE CALLING TASK
1204 1207 status = rtems_task_mode( initial_mode_set, RTEMS_PREEMPT_MASK, &current_mode_set );
1205 1208 }
General Comments 0
You need to be logged in to leave comments. Login now