##// END OF EJS Templates
Snapshot resynchro modified
paul -
r267:3616e7d285c0 R3a
parent child
Show More
@@ -1,2 +1,2
1 1 3081d1f9bb20b2b64a192585337a292a9804e0c5 LFR_basic-parameters
2 b0e42058c39c77fc42a5bd3bf529e4547497c4c3 header/lfr_common_headers
2 449d1ebc41af2e62571508883dab8043a33f16df header/lfr_common_headers
@@ -1,124 +1,124
1 1 TEMPLATE = app
2 2 # CONFIG += console v8 sim
3 3 # CONFIG options =
4 4 # verbose
5 5 # boot_messages
6 6 # debug_messages
7 7 # cpu_usage_report
8 8 # stack_report
9 9 # vhdl_dev
10 10 # debug_tch
11 11 # lpp_dpu_destid /!\ REMOVE BEFORE DELIVERY TO LESIA /!\
12 12 # debug_watchdog
13 13 CONFIG += console verbose lpp_dpu_destid
14 14 CONFIG -= qt
15 15
16 16 include(./sparc.pri)
17 17
18 18 # flight software version
19 19 SWVERSION=-1-0
20 20 DEFINES += SW_VERSION_N1=3 # major
21 21 DEFINES += SW_VERSION_N2=0 # minor
22 22 DEFINES += SW_VERSION_N3=0 # patch
23 DEFINES += SW_VERSION_N4=16 # internal
23 DEFINES += SW_VERSION_N4=17 # internal
24 24
25 25 # <GCOV>
26 26 #QMAKE_CFLAGS_RELEASE += -fprofile-arcs -ftest-coverage
27 27 #LIBS += -lgcov /opt/GCOV/01A/lib/overload.o -lc
28 28 # </GCOV>
29 29
30 30 # <CHANGE BEFORE FLIGHT>
31 31 contains( CONFIG, lpp_dpu_destid ) {
32 32 DEFINES += LPP_DPU_DESTID
33 33 }
34 34 # </CHANGE BEFORE FLIGHT>
35 35
36 36 contains( CONFIG, debug_tch ) {
37 37 DEFINES += DEBUG_TCH
38 38 }
39 39 DEFINES += MSB_FIRST_TCH
40 40
41 41 contains( CONFIG, vhdl_dev ) {
42 42 DEFINES += VHDL_DEV
43 43 }
44 44
45 45 contains( CONFIG, verbose ) {
46 46 DEFINES += PRINT_MESSAGES_ON_CONSOLE
47 47 }
48 48
49 49 contains( CONFIG, debug_messages ) {
50 50 DEFINES += DEBUG_MESSAGES
51 51 }
52 52
53 53 contains( CONFIG, cpu_usage_report ) {
54 54 DEFINES += PRINT_TASK_STATISTICS
55 55 }
56 56
57 57 contains( CONFIG, stack_report ) {
58 58 DEFINES += PRINT_STACK_REPORT
59 59 }
60 60
61 61 contains( CONFIG, boot_messages ) {
62 62 DEFINES += BOOT_MESSAGES
63 63 }
64 64
65 65 contains( CONFIG, debug_watchdog ) {
66 66 DEFINES += DEBUG_WATCHDOG
67 67 }
68 68
69 69 #doxygen.target = doxygen
70 70 #doxygen.commands = doxygen ../doc/Doxyfile
71 71 #QMAKE_EXTRA_TARGETS += doxygen
72 72
73 73 TARGET = fsw
74 74
75 75 INCLUDEPATH += \
76 76 $${PWD}/../src \
77 77 $${PWD}/../header \
78 78 $${PWD}/../header/lfr_common_headers \
79 79 $${PWD}/../header/processing \
80 80 $${PWD}/../LFR_basic-parameters
81 81
82 82 SOURCES += \
83 83 ../src/wf_handler.c \
84 84 ../src/tc_handler.c \
85 85 ../src/fsw_misc.c \
86 86 ../src/fsw_init.c \
87 87 ../src/fsw_globals.c \
88 88 ../src/fsw_spacewire.c \
89 89 ../src/tc_load_dump_parameters.c \
90 90 ../src/tm_lfr_tc_exe.c \
91 91 ../src/tc_acceptance.c \
92 92 ../src/processing/fsw_processing.c \
93 93 ../src/processing/avf0_prc0.c \
94 94 ../src/processing/avf1_prc1.c \
95 95 ../src/processing/avf2_prc2.c \
96 96 ../src/lfr_cpu_usage_report.c \
97 97 ../LFR_basic-parameters/basic_parameters.c
98 98
99 99 HEADERS += \
100 100 ../header/wf_handler.h \
101 101 ../header/tc_handler.h \
102 102 ../header/grlib_regs.h \
103 103 ../header/fsw_misc.h \
104 104 ../header/fsw_init.h \
105 105 ../header/fsw_spacewire.h \
106 106 ../header/tc_load_dump_parameters.h \
107 107 ../header/tm_lfr_tc_exe.h \
108 108 ../header/tc_acceptance.h \
109 109 ../header/processing/fsw_processing.h \
110 110 ../header/processing/avf0_prc0.h \
111 111 ../header/processing/avf1_prc1.h \
112 112 ../header/processing/avf2_prc2.h \
113 113 ../header/fsw_params_wf_handler.h \
114 114 ../header/lfr_cpu_usage_report.h \
115 115 ../header/lfr_common_headers/ccsds_types.h \
116 116 ../header/lfr_common_headers/fsw_params.h \
117 117 ../header/lfr_common_headers/fsw_params_nb_bytes.h \
118 118 ../header/lfr_common_headers/fsw_params_processing.h \
119 119 ../header/lfr_common_headers/TC_types.h \
120 120 ../header/lfr_common_headers/tm_byte_positions.h \
121 121 ../LFR_basic-parameters/basic_parameters.h \
122 122 ../LFR_basic-parameters/basic_parameters_params.h \
123 123 ../header/GscMemoryLPP.hpp
124 124
@@ -1,138 +1,138
1 1 #ifndef GRLIB_REGS_H_INCLUDED
2 2 #define GRLIB_REGS_H_INCLUDED
3 3
4 4 #define NB_GPTIMER 3
5 5
6 6 struct apbuart_regs_str{
7 7 volatile unsigned int data;
8 8 volatile unsigned int status;
9 9 volatile unsigned int ctrl;
10 10 volatile unsigned int scaler;
11 11 volatile unsigned int fifoDebug;
12 12 };
13 13
14 14 struct grgpio_regs_str{
15 15 volatile int io_port_data_register;
16 16 int io_port_output_register;
17 17 int io_port_direction_register;
18 18 int interrupt_mak_register;
19 19 int interrupt_polarity_register;
20 20 int interrupt_edge_register;
21 21 int bypass_register;
22 22 int reserved;
23 23 // 0x20-0x3c interrupt map register(s)
24 24 };
25 25
26 26 typedef struct {
27 27 volatile unsigned int counter;
28 28 volatile unsigned int reload;
29 29 volatile unsigned int ctrl;
30 30 volatile unsigned int unused;
31 31 } timer_regs_t;
32 32
33 33 typedef struct {
34 34 volatile unsigned int scaler_value;
35 35 volatile unsigned int scaler_reload;
36 36 volatile unsigned int conf;
37 37 volatile unsigned int unused0;
38 38 timer_regs_t timer[NB_GPTIMER];
39 39 } gptimer_regs_t;
40 40
41 41 typedef struct {
42 42 volatile int ctrl; // bit 0 forces the load of the coarse_time_load value and resets the fine_time
43 43 // bit 1 is the soft reset for the time management module
44 44 // bit 2 is the soft reset for the waveform picker and the spectral matrix modules, set to 1 after HW reset
45 45 volatile int coarse_time_load;
46 46 volatile int coarse_time;
47 47 volatile int fine_time;
48 48 // TEMPERATURES
49 49 volatile int temp_pcb; // SEL1 = 0 SEL0 = 0
50 50 volatile int temp_fpga; // SEL1 = 0 SEL0 = 1
51 51 volatile int temp_scm; // SEL1 = 1 SEL0 = 0
52 52 // CALIBRATION
53 53 volatile unsigned int calDACCtrl;
54 54 volatile unsigned int calPrescaler;
55 55 volatile unsigned int calDivisor;
56 56 volatile unsigned int calDataPtr;
57 57 volatile unsigned int calData;
58 58 } time_management_regs_t;
59 59
60 60 // PDB >= 0.1.28, 0x80000f54
61 61 typedef struct{
62 62 int data_shaping; // 0x00 00 *** R1 R0 SP1 SP0 BW
63 63 int run_burst_enable; // 0x04 01 *** [run *** burst f2, f1, f0 *** enable f3, f2, f1, f0 ]
64 64 int addr_data_f0_0; // 0x08
65 65 int addr_data_f0_1; // 0x0c
66 66 int addr_data_f1_0; // 0x10
67 67 int addr_data_f1_1; // 0x14
68 68 int addr_data_f2_0; // 0x18
69 69 int addr_data_f2_1; // 0x1c
70 70 int addr_data_f3_0; // 0x20
71 71 int addr_data_f3_1; // 0x24
72 72 volatile int status; // 0x28
73 int delta_snapshot; // 0x2c
73 volatile int delta_snapshot; // 0x2c
74 74 int delta_f0; // 0x30
75 75 int delta_f0_2; // 0x34
76 76 int delta_f1; // 0x38
77 77 int delta_f2; // 0x3c
78 78 int nb_data_by_buffer; // 0x40 number of samples in a buffer = 2688
79 79 int snapshot_param; // 0x44
80 80 int start_date; // 0x48
81 81 //
82 82 volatile unsigned int f0_0_coarse_time; // 0x4c
83 83 volatile unsigned int f0_0_fine_time; // 0x50
84 84 volatile unsigned int f0_1_coarse_time; // 0x54
85 85 volatile unsigned int f0_1_fine_time; // 0x58
86 86 //
87 87 volatile unsigned int f1_0_coarse_time; // 0x5c
88 88 volatile unsigned int f1_0_fine_time; // 0x60
89 89 volatile unsigned int f1_1_coarse_time; // 0x64
90 90 volatile unsigned int f1_1_fine_time; // 0x68
91 91 //
92 92 volatile unsigned int f2_0_coarse_time; // 0x6c
93 93 volatile unsigned int f2_0_fine_time; // 0x70
94 94 volatile unsigned int f2_1_coarse_time; // 0x74
95 95 volatile unsigned int f2_1_fine_time; // 0x78
96 96 //
97 97 volatile unsigned int f3_0_coarse_time; // 0x7c => 0x7c + 0xf54 = 0xd0
98 98 volatile unsigned int f3_0_fine_time; // 0x80
99 99 volatile unsigned int f3_1_coarse_time; // 0x84
100 100 volatile unsigned int f3_1_fine_time; // 0x88
101 101 //
102 102 unsigned int buffer_length; // 0x8c = buffer length in burst 2688 / 16 = 168
103 103 //
104 104 volatile unsigned int v; // 0x90
105 105 volatile unsigned int e1; // 0x94
106 106 volatile unsigned int e2; // 0x98
107 107 } waveform_picker_regs_0_1_18_t;
108 108
109 109 typedef struct {
110 110 volatile int config; // 0x00
111 111 volatile int status; // 0x04
112 112 volatile int f0_0_address; // 0x08
113 113 volatile int f0_1_address; // 0x0C
114 114 //
115 115 volatile int f1_0_address; // 0x10
116 116 volatile int f1_1_address; // 0x14
117 117 volatile int f2_0_address; // 0x18
118 118 volatile int f2_1_address; // 0x1C
119 119 //
120 120 volatile unsigned int f0_0_coarse_time; // 0x20
121 121 volatile unsigned int f0_0_fine_time; // 0x24
122 122 volatile unsigned int f0_1_coarse_time; // 0x28
123 123 volatile unsigned int f0_1_fine_time; // 0x2C
124 124 //
125 125 volatile unsigned int f1_0_coarse_time; // 0x30
126 126 volatile unsigned int f1_0_fine_time; // 0x34
127 127 volatile unsigned int f1_1_coarse_time; // 0x38
128 128 volatile unsigned int f1_1_fine_time; // 0x3C
129 129 //
130 130 volatile unsigned int f2_0_coarse_time; // 0x40
131 131 volatile unsigned int f2_0_fine_time; // 0x44
132 132 volatile unsigned int f2_1_coarse_time; // 0x48
133 133 volatile unsigned int f2_1_fine_time; // 0x4C
134 134 //
135 135 unsigned int matrix_length; // 0x50, length of a spectral matrix in burst 3200 / 16 = 200 = 0xc8
136 136 } spectral_matrix_regs_t;
137 137
138 138 #endif // GRLIB_REGS_H_INCLUDED
@@ -1,916 +1,917
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 // [spiq] [link] [spacewire_reset_link]
39 39 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 5
40 40 #ifdef PRINT_STACK_REPORT
41 41 #define CONFIGURE_STACK_CHECKER_ENABLED
42 42 #endif
43 43
44 44 #include <rtems/confdefs.h>
45 45
46 46 /* If --drvmgr was enabled during the configuration of the RTEMS kernel */
47 47 #ifdef RTEMS_DRVMGR_STARTUP
48 48 #ifdef LEON3
49 49 /* Add Timer and UART Driver */
50 50 #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
51 51 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GPTIMER
52 52 #endif
53 53 #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
54 54 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_APBUART
55 55 #endif
56 56 #endif
57 57 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GRSPW /* GRSPW Driver */
58 58 #include <drvmgr/drvmgr_confdefs.h>
59 59 #endif
60 60
61 61 #include "fsw_init.h"
62 62 #include "fsw_config.c"
63 63 #include "GscMemoryLPP.hpp"
64 64
65 65 void initCache()
66 66 {
67 67 // ASI 2 contains a few control registers that have not been assigned as ancillary state registers.
68 68 // These should only be read and written using 32-bit LDA/STA instructions.
69 69 // All cache registers are accessed through load/store operations to the alternate address space (LDA/STA), using ASI = 2.
70 70 // The table below shows the register addresses:
71 71 // 0x00 Cache control register
72 72 // 0x04 Reserved
73 73 // 0x08 Instruction cache configuration register
74 74 // 0x0C Data cache configuration register
75 75
76 76 // Cache Control Register Leon3 / Leon3FT
77 77 // 31..30 29 28 27..24 23 22 21 20..19 18 17 16
78 78 // RFT PS TB DS FD FI FT ST IB
79 79 // 15 14 13..12 11..10 9..8 7..6 5 4 3..2 1..0
80 80 // IP DP ITE IDE DTE DDE DF IF DCS ICS
81 81
82 82 unsigned int cacheControlRegister;
83 83
84 84 CCR_resetCacheControlRegister();
85 85 ASR16_resetRegisterProtectionControlRegister();
86 86
87 87 cacheControlRegister = CCR_getValue();
88 88 PRINTF1("(0) CCR - Cache Control Register = %x\n", cacheControlRegister);
89 89 PRINTF1("(0) ASR16 = %x\n", *asr16Ptr);
90 90
91 91 CCR_enableInstructionCache(); // ICS bits
92 92 CCR_enableDataCache(); // DCS bits
93 93 CCR_enableInstructionBurstFetch(); // IB bit
94 94
95 95 faultTolerantScheme();
96 96
97 97 cacheControlRegister = CCR_getValue();
98 98 PRINTF1("(1) CCR - Cache Control Register = %x\n", cacheControlRegister);
99 99 PRINTF1("(1) ASR16 Register protection control register = %x\n", *asr16Ptr);
100 100
101 101 PRINTF("\n");
102 102 }
103 103
104 104 rtems_task Init( rtems_task_argument ignored )
105 105 {
106 106 /** This is the RTEMS INIT taks, it is the first task launched by the system.
107 107 *
108 108 * @param unused is the starting argument of the RTEMS task
109 109 *
110 110 * The INIT task create and run all other RTEMS tasks.
111 111 *
112 112 */
113 113
114 114 //***********
115 115 // INIT CACHE
116 116
117 117 unsigned char *vhdlVersion;
118 118
119 119 reset_lfr();
120 120
121 121 reset_local_time();
122 122
123 123 rtems_cpu_usage_reset();
124 124
125 125 rtems_status_code status;
126 126 rtems_status_code status_spw;
127 127 rtems_isr_entry old_isr_handler;
128 128
129 129 // UART settings
130 130 enable_apbuart_transmitter();
131 131 set_apbuart_scaler_reload_register(REGS_ADDR_APBUART, APBUART_SCALER_RELOAD_VALUE);
132 132
133 133 DEBUG_PRINTF("\n\n\n\n\nIn INIT *** Now the console is on port COM1\n")
134 134
135 135
136 136 PRINTF("\n\n\n\n\n")
137 137
138 138 initCache();
139 139
140 140 PRINTF("*************************\n")
141 141 PRINTF("** LFR Flight Software **\n")
142 142 PRINTF1("** %d.", SW_VERSION_N1)
143 143 PRINTF1("%d." , SW_VERSION_N2)
144 144 PRINTF1("%d." , SW_VERSION_N3)
145 145 PRINTF1("%d **\n", SW_VERSION_N4)
146 146
147 147 vhdlVersion = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
148 148 PRINTF("** VHDL **\n")
149 149 PRINTF1("** %d.", vhdlVersion[1])
150 150 PRINTF1("%d." , vhdlVersion[2])
151 151 PRINTF1("%d **\n", vhdlVersion[3])
152 152 PRINTF("*************************\n")
153 153 PRINTF("\n\n")
154 154
155 155 init_parameter_dump();
156 156 init_kcoefficients_dump();
157 157 init_local_mode_parameters();
158 158 init_housekeeping_parameters();
159 159 init_k_coefficients_prc0();
160 160 init_k_coefficients_prc1();
161 161 init_k_coefficients_prc2();
162 162 pa_bia_status_info = 0x00;
163 163 update_last_valid_transition_date( DEFAULT_LAST_VALID_TRANSITION_DATE );
164 164
165 165 // waveform picker initialization
166 166 WFP_init_rings(); LEON_Clear_interrupt( IRQ_SPARC_GPTIMER_WATCHDOG ); // initialize the waveform rings
167 167 WFP_reset_current_ring_nodes();
168 168 reset_waveform_picker_regs();
169 169
170 170 // spectral matrices initialization
171 171 SM_init_rings(); // initialize spectral matrices rings
172 172 SM_reset_current_ring_nodes();
173 173 reset_spectral_matrix_regs();
174 174
175 175 // configure calibration
176 176 configureCalibration( false ); // true means interleaved mode, false is for normal mode
177 177
178 178 updateLFRCurrentMode( LFR_MODE_STANDBY );
179 179
180 180 BOOT_PRINTF1("in INIT *** lfrCurrentMode is %d\n", lfrCurrentMode)
181 181
182 182 create_names(); // create all names
183 183
184 184 status = create_timecode_timer(); // create the timer used by timecode_irq_handler
185 185 if (status != RTEMS_SUCCESSFUL)
186 186 {
187 187 PRINTF1("in INIT *** ERR in create_timer_timecode, code %d", status)
188 188 }
189 189
190 190 status = create_message_queues(); // create message queues
191 191 if (status != RTEMS_SUCCESSFUL)
192 192 {
193 193 PRINTF1("in INIT *** ERR in create_message_queues, code %d", status)
194 194 }
195 195
196 196 status = create_all_tasks(); // create all tasks
197 197 if (status != RTEMS_SUCCESSFUL)
198 198 {
199 199 PRINTF1("in INIT *** ERR in create_all_tasks, code %d\n", status)
200 200 }
201 201
202 202 // **************************
203 203 // <SPACEWIRE INITIALIZATION>
204 204 status_spw = spacewire_open_link(); // (1) open the link
205 205 if ( status_spw != RTEMS_SUCCESSFUL )
206 206 {
207 207 PRINTF1("in INIT *** ERR spacewire_open_link code %d\n", status_spw )
208 208 }
209 209
210 210 if ( status_spw == RTEMS_SUCCESSFUL ) // (2) configure the link
211 211 {
212 212 status_spw = spacewire_configure_link( fdSPW );
213 213 if ( status_spw != RTEMS_SUCCESSFUL )
214 214 {
215 215 PRINTF1("in INIT *** ERR spacewire_configure_link code %d\n", status_spw )
216 216 }
217 217 }
218 218
219 219 if ( status_spw == RTEMS_SUCCESSFUL) // (3) start the link
220 220 {
221 221 status_spw = spacewire_start_link( fdSPW );
222 222 if ( status_spw != RTEMS_SUCCESSFUL )
223 223 {
224 224 PRINTF1("in INIT *** ERR spacewire_start_link code %d\n", status_spw )
225 225 }
226 226 }
227 227 // </SPACEWIRE INITIALIZATION>
228 228 // ***************************
229 229
230 230 status = start_all_tasks(); // start all tasks
231 231 if (status != RTEMS_SUCCESSFUL)
232 232 {
233 233 PRINTF1("in INIT *** ERR in start_all_tasks, code %d", status)
234 234 }
235 235
236 236 // start RECV and SEND *AFTER* SpaceWire Initialization, due to the timeout of the start call during the initialization
237 237 status = start_recv_send_tasks();
238 238 if ( status != RTEMS_SUCCESSFUL )
239 239 {
240 240 PRINTF1("in INIT *** ERR start_recv_send_tasks code %d\n", status )
241 241 }
242 242
243 243 // suspend science tasks, they will be restarted later depending on the mode
244 244 status = suspend_science_tasks(); // suspend science tasks (not done in stop_current_mode if current mode = STANDBY)
245 245 if (status != RTEMS_SUCCESSFUL)
246 246 {
247 247 PRINTF1("in INIT *** in suspend_science_tasks *** ERR code: %d\n", status)
248 248 }
249 249
250 250 // configure IRQ handling for the waveform picker unit
251 251 status = rtems_interrupt_catch( waveforms_isr,
252 252 IRQ_SPARC_WAVEFORM_PICKER,
253 253 &old_isr_handler) ;
254 254 // configure IRQ handling for the spectral matrices unit
255 255 status = rtems_interrupt_catch( spectral_matrices_isr,
256 256 IRQ_SPARC_SPECTRAL_MATRIX,
257 257 &old_isr_handler) ;
258 258
259 259 // if the spacewire link is not up then send an event to the SPIQ task for link recovery
260 260 if ( status_spw != RTEMS_SUCCESSFUL )
261 261 {
262 262 status = rtems_event_send( Task_id[TASKID_SPIQ], SPW_LINKERR_EVENT );
263 263 if ( status != RTEMS_SUCCESSFUL ) {
264 264 PRINTF1("in INIT *** ERR rtems_event_send to SPIQ code %d\n", status )
265 265 }
266 266 }
267 267
268 268 BOOT_PRINTF("delete INIT\n")
269 269
270 270 set_hk_lfr_sc_potential_flag( true );
271 271
272 272 // start the timer to detect a missing spacewire timecode
273 273 // the timeout is larger because the spw IP needs to receive several valid timecodes before generating a tickout
274 274 // if a tickout is generated, the timer is restarted
275 275 status = rtems_timer_fire_after( timecode_timer_id, TIMECODE_TIMER_TIMEOUT_INIT, timecode_timer_routine, NULL );
276
276 277 grspw_timecode_callback = &timecode_irq_handler;
277 278
278 279 status = rtems_task_delete(RTEMS_SELF);
279 280
280 281 }
281 282
282 283 void init_local_mode_parameters( void )
283 284 {
284 285 /** This function initialize the param_local global variable with default values.
285 286 *
286 287 */
287 288
288 289 unsigned int i;
289 290
290 291 // LOCAL PARAMETERS
291 292
292 293 BOOT_PRINTF1("local_sbm1_nb_cwf_max %d \n", param_local.local_sbm1_nb_cwf_max)
293 294 BOOT_PRINTF1("local_sbm2_nb_cwf_max %d \n", param_local.local_sbm2_nb_cwf_max)
294 295 BOOT_PRINTF1("nb_interrupt_f0_MAX = %d\n", param_local.local_nb_interrupt_f0_MAX)
295 296
296 297 // init sequence counters
297 298
298 299 for(i = 0; i<SEQ_CNT_NB_DEST_ID; i++)
299 300 {
300 301 sequenceCounters_TC_EXE[i] = 0x00;
301 302 sequenceCounters_TM_DUMP[i] = 0x00;
302 303 }
303 304 sequenceCounters_SCIENCE_NORMAL_BURST = 0x00;
304 305 sequenceCounters_SCIENCE_SBM1_SBM2 = 0x00;
305 306 sequenceCounterHK = TM_PACKET_SEQ_CTRL_STANDALONE << 8;
306 307 }
307 308
308 309 void reset_local_time( void )
309 310 {
310 311 time_management_regs->ctrl = time_management_regs->ctrl | 0x02; // [0010] software reset, coarse time = 0x80000000
311 312 }
312 313
313 314 void create_names( void ) // create all names for tasks and queues
314 315 {
315 316 /** This function creates all RTEMS names used in the software for tasks and queues.
316 317 *
317 318 * @return RTEMS directive status codes:
318 319 * - RTEMS_SUCCESSFUL - successful completion
319 320 *
320 321 */
321 322
322 323 // task names
323 324 Task_name[TASKID_RECV] = rtems_build_name( 'R', 'E', 'C', 'V' );
324 325 Task_name[TASKID_ACTN] = rtems_build_name( 'A', 'C', 'T', 'N' );
325 326 Task_name[TASKID_SPIQ] = rtems_build_name( 'S', 'P', 'I', 'Q' );
326 327 Task_name[TASKID_LOAD] = rtems_build_name( 'L', 'O', 'A', 'D' );
327 328 Task_name[TASKID_AVF0] = rtems_build_name( 'A', 'V', 'F', '0' );
328 329 Task_name[TASKID_SWBD] = rtems_build_name( 'S', 'W', 'B', 'D' );
329 330 Task_name[TASKID_WFRM] = rtems_build_name( 'W', 'F', 'R', 'M' );
330 331 Task_name[TASKID_DUMB] = rtems_build_name( 'D', 'U', 'M', 'B' );
331 332 Task_name[TASKID_HOUS] = rtems_build_name( 'H', 'O', 'U', 'S' );
332 333 Task_name[TASKID_PRC0] = rtems_build_name( 'P', 'R', 'C', '0' );
333 334 Task_name[TASKID_CWF3] = rtems_build_name( 'C', 'W', 'F', '3' );
334 335 Task_name[TASKID_CWF2] = rtems_build_name( 'C', 'W', 'F', '2' );
335 336 Task_name[TASKID_CWF1] = rtems_build_name( 'C', 'W', 'F', '1' );
336 337 Task_name[TASKID_SEND] = rtems_build_name( 'S', 'E', 'N', 'D' );
337 338 Task_name[TASKID_LINK] = rtems_build_name( 'L', 'I', 'N', 'K' );
338 339 Task_name[TASKID_AVF1] = rtems_build_name( 'A', 'V', 'F', '1' );
339 340 Task_name[TASKID_PRC1] = rtems_build_name( 'P', 'R', 'C', '1' );
340 341 Task_name[TASKID_AVF2] = rtems_build_name( 'A', 'V', 'F', '2' );
341 342 Task_name[TASKID_PRC2] = rtems_build_name( 'P', 'R', 'C', '2' );
342 343
343 344 // rate monotonic period names
344 345 name_hk_rate_monotonic = rtems_build_name( 'H', 'O', 'U', 'S' );
345 346
346 347 misc_name[QUEUE_RECV] = rtems_build_name( 'Q', '_', 'R', 'V' );
347 348 misc_name[QUEUE_SEND] = rtems_build_name( 'Q', '_', 'S', 'D' );
348 349 misc_name[QUEUE_PRC0] = rtems_build_name( 'Q', '_', 'P', '0' );
349 350 misc_name[QUEUE_PRC1] = rtems_build_name( 'Q', '_', 'P', '1' );
350 351 misc_name[QUEUE_PRC2] = rtems_build_name( 'Q', '_', 'P', '2' );
351 352
352 353 timecode_timer_name = rtems_build_name( 'S', 'P', 'T', 'C' );
353 354 }
354 355
355 356 int create_all_tasks( void ) // create all tasks which run in the software
356 357 {
357 358 /** This function creates all RTEMS tasks used in the software.
358 359 *
359 360 * @return RTEMS directive status codes:
360 361 * - RTEMS_SUCCESSFUL - task created successfully
361 362 * - RTEMS_INVALID_ADDRESS - id is NULL
362 363 * - RTEMS_INVALID_NAME - invalid task name
363 364 * - RTEMS_INVALID_PRIORITY - invalid task priority
364 365 * - RTEMS_MP_NOT_CONFIGURED - multiprocessing not configured
365 366 * - RTEMS_TOO_MANY - too many tasks created
366 367 * - RTEMS_UNSATISFIED - not enough memory for stack/FP context
367 368 * - RTEMS_TOO_MANY - too many global objects
368 369 *
369 370 */
370 371
371 372 rtems_status_code status;
372 373
373 374 //**********
374 375 // SPACEWIRE
375 376 // RECV
376 377 status = rtems_task_create(
377 378 Task_name[TASKID_RECV], TASK_PRIORITY_RECV, RTEMS_MINIMUM_STACK_SIZE,
378 379 RTEMS_DEFAULT_MODES,
379 380 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_RECV]
380 381 );
381 382 if (status == RTEMS_SUCCESSFUL) // SEND
382 383 {
383 384 status = rtems_task_create(
384 385 Task_name[TASKID_SEND], TASK_PRIORITY_SEND, RTEMS_MINIMUM_STACK_SIZE * 2,
385 386 RTEMS_DEFAULT_MODES,
386 387 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SEND]
387 388 );
388 389 }
389 390 if (status == RTEMS_SUCCESSFUL) // LINK
390 391 {
391 392 status = rtems_task_create(
392 393 Task_name[TASKID_LINK], TASK_PRIORITY_LINK, RTEMS_MINIMUM_STACK_SIZE,
393 394 RTEMS_DEFAULT_MODES,
394 395 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_LINK]
395 396 );
396 397 }
397 398 if (status == RTEMS_SUCCESSFUL) // ACTN
398 399 {
399 400 status = rtems_task_create(
400 401 Task_name[TASKID_ACTN], TASK_PRIORITY_ACTN, RTEMS_MINIMUM_STACK_SIZE,
401 402 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
402 403 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_ACTN]
403 404 );
404 405 }
405 406 if (status == RTEMS_SUCCESSFUL) // SPIQ
406 407 {
407 408 status = rtems_task_create(
408 409 Task_name[TASKID_SPIQ], TASK_PRIORITY_SPIQ, RTEMS_MINIMUM_STACK_SIZE,
409 410 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
410 411 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SPIQ]
411 412 );
412 413 }
413 414
414 415 //******************
415 416 // SPECTRAL MATRICES
416 417 if (status == RTEMS_SUCCESSFUL) // AVF0
417 418 {
418 419 status = rtems_task_create(
419 420 Task_name[TASKID_AVF0], TASK_PRIORITY_AVF0, RTEMS_MINIMUM_STACK_SIZE,
420 421 RTEMS_DEFAULT_MODES,
421 422 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF0]
422 423 );
423 424 }
424 425 if (status == RTEMS_SUCCESSFUL) // PRC0
425 426 {
426 427 status = rtems_task_create(
427 428 Task_name[TASKID_PRC0], TASK_PRIORITY_PRC0, RTEMS_MINIMUM_STACK_SIZE * 2,
428 429 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
429 430 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC0]
430 431 );
431 432 }
432 433 if (status == RTEMS_SUCCESSFUL) // AVF1
433 434 {
434 435 status = rtems_task_create(
435 436 Task_name[TASKID_AVF1], TASK_PRIORITY_AVF1, RTEMS_MINIMUM_STACK_SIZE,
436 437 RTEMS_DEFAULT_MODES,
437 438 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF1]
438 439 );
439 440 }
440 441 if (status == RTEMS_SUCCESSFUL) // PRC1
441 442 {
442 443 status = rtems_task_create(
443 444 Task_name[TASKID_PRC1], TASK_PRIORITY_PRC1, RTEMS_MINIMUM_STACK_SIZE * 2,
444 445 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
445 446 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC1]
446 447 );
447 448 }
448 449 if (status == RTEMS_SUCCESSFUL) // AVF2
449 450 {
450 451 status = rtems_task_create(
451 452 Task_name[TASKID_AVF2], TASK_PRIORITY_AVF2, RTEMS_MINIMUM_STACK_SIZE,
452 453 RTEMS_DEFAULT_MODES,
453 454 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF2]
454 455 );
455 456 }
456 457 if (status == RTEMS_SUCCESSFUL) // PRC2
457 458 {
458 459 status = rtems_task_create(
459 460 Task_name[TASKID_PRC2], TASK_PRIORITY_PRC2, RTEMS_MINIMUM_STACK_SIZE * 2,
460 461 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
461 462 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC2]
462 463 );
463 464 }
464 465
465 466 //****************
466 467 // WAVEFORM PICKER
467 468 if (status == RTEMS_SUCCESSFUL) // WFRM
468 469 {
469 470 status = rtems_task_create(
470 471 Task_name[TASKID_WFRM], TASK_PRIORITY_WFRM, RTEMS_MINIMUM_STACK_SIZE,
471 472 RTEMS_DEFAULT_MODES,
472 473 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_WFRM]
473 474 );
474 475 }
475 476 if (status == RTEMS_SUCCESSFUL) // CWF3
476 477 {
477 478 status = rtems_task_create(
478 479 Task_name[TASKID_CWF3], TASK_PRIORITY_CWF3, RTEMS_MINIMUM_STACK_SIZE,
479 480 RTEMS_DEFAULT_MODES,
480 481 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF3]
481 482 );
482 483 }
483 484 if (status == RTEMS_SUCCESSFUL) // CWF2
484 485 {
485 486 status = rtems_task_create(
486 487 Task_name[TASKID_CWF2], TASK_PRIORITY_CWF2, RTEMS_MINIMUM_STACK_SIZE,
487 488 RTEMS_DEFAULT_MODES,
488 489 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF2]
489 490 );
490 491 }
491 492 if (status == RTEMS_SUCCESSFUL) // CWF1
492 493 {
493 494 status = rtems_task_create(
494 495 Task_name[TASKID_CWF1], TASK_PRIORITY_CWF1, RTEMS_MINIMUM_STACK_SIZE,
495 496 RTEMS_DEFAULT_MODES,
496 497 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF1]
497 498 );
498 499 }
499 500 if (status == RTEMS_SUCCESSFUL) // SWBD
500 501 {
501 502 status = rtems_task_create(
502 503 Task_name[TASKID_SWBD], TASK_PRIORITY_SWBD, RTEMS_MINIMUM_STACK_SIZE,
503 504 RTEMS_DEFAULT_MODES,
504 505 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SWBD]
505 506 );
506 507 }
507 508
508 509 //*****
509 510 // MISC
510 511 if (status == RTEMS_SUCCESSFUL) // LOAD
511 512 {
512 513 status = rtems_task_create(
513 514 Task_name[TASKID_LOAD], TASK_PRIORITY_LOAD, RTEMS_MINIMUM_STACK_SIZE,
514 515 RTEMS_DEFAULT_MODES,
515 516 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_LOAD]
516 517 );
517 518 }
518 519 if (status == RTEMS_SUCCESSFUL) // DUMB
519 520 {
520 521 status = rtems_task_create(
521 522 Task_name[TASKID_DUMB], TASK_PRIORITY_DUMB, RTEMS_MINIMUM_STACK_SIZE,
522 523 RTEMS_DEFAULT_MODES,
523 524 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_DUMB]
524 525 );
525 526 }
526 527 if (status == RTEMS_SUCCESSFUL) // HOUS
527 528 {
528 529 status = rtems_task_create(
529 530 Task_name[TASKID_HOUS], TASK_PRIORITY_HOUS, RTEMS_MINIMUM_STACK_SIZE,
530 531 RTEMS_DEFAULT_MODES,
531 532 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_HOUS]
532 533 );
533 534 }
534 535
535 536 return status;
536 537 }
537 538
538 539 int start_recv_send_tasks( void )
539 540 {
540 541 rtems_status_code status;
541 542
542 543 status = rtems_task_start( Task_id[TASKID_RECV], recv_task, 1 );
543 544 if (status!=RTEMS_SUCCESSFUL) {
544 545 BOOT_PRINTF("in INIT *** Error starting TASK_RECV\n")
545 546 }
546 547
547 548 if (status == RTEMS_SUCCESSFUL) // SEND
548 549 {
549 550 status = rtems_task_start( Task_id[TASKID_SEND], send_task, 1 );
550 551 if (status!=RTEMS_SUCCESSFUL) {
551 552 BOOT_PRINTF("in INIT *** Error starting TASK_SEND\n")
552 553 }
553 554 }
554 555
555 556 return status;
556 557 }
557 558
558 559 int start_all_tasks( void ) // start all tasks except SEND RECV and HOUS
559 560 {
560 561 /** This function starts all RTEMS tasks used in the software.
561 562 *
562 563 * @return RTEMS directive status codes:
563 564 * - RTEMS_SUCCESSFUL - ask started successfully
564 565 * - RTEMS_INVALID_ADDRESS - invalid task entry point
565 566 * - RTEMS_INVALID_ID - invalid task id
566 567 * - RTEMS_INCORRECT_STATE - task not in the dormant state
567 568 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot start remote task
568 569 *
569 570 */
570 571 // starts all the tasks fot eh flight software
571 572
572 573 rtems_status_code status;
573 574
574 575 //**********
575 576 // SPACEWIRE
576 577 status = rtems_task_start( Task_id[TASKID_SPIQ], spiq_task, 1 );
577 578 if (status!=RTEMS_SUCCESSFUL) {
578 579 BOOT_PRINTF("in INIT *** Error starting TASK_SPIQ\n")
579 580 }
580 581
581 582 if (status == RTEMS_SUCCESSFUL) // LINK
582 583 {
583 584 status = rtems_task_start( Task_id[TASKID_LINK], link_task, 1 );
584 585 if (status!=RTEMS_SUCCESSFUL) {
585 586 BOOT_PRINTF("in INIT *** Error starting TASK_LINK\n")
586 587 }
587 588 }
588 589
589 590 if (status == RTEMS_SUCCESSFUL) // ACTN
590 591 {
591 592 status = rtems_task_start( Task_id[TASKID_ACTN], actn_task, 1 );
592 593 if (status!=RTEMS_SUCCESSFUL) {
593 594 BOOT_PRINTF("in INIT *** Error starting TASK_ACTN\n")
594 595 }
595 596 }
596 597
597 598 //******************
598 599 // SPECTRAL MATRICES
599 600 if (status == RTEMS_SUCCESSFUL) // AVF0
600 601 {
601 602 status = rtems_task_start( Task_id[TASKID_AVF0], avf0_task, LFR_MODE_STANDBY );
602 603 if (status!=RTEMS_SUCCESSFUL) {
603 604 BOOT_PRINTF("in INIT *** Error starting TASK_AVF0\n")
604 605 }
605 606 }
606 607 if (status == RTEMS_SUCCESSFUL) // PRC0
607 608 {
608 609 status = rtems_task_start( Task_id[TASKID_PRC0], prc0_task, LFR_MODE_STANDBY );
609 610 if (status!=RTEMS_SUCCESSFUL) {
610 611 BOOT_PRINTF("in INIT *** Error starting TASK_PRC0\n")
611 612 }
612 613 }
613 614 if (status == RTEMS_SUCCESSFUL) // AVF1
614 615 {
615 616 status = rtems_task_start( Task_id[TASKID_AVF1], avf1_task, LFR_MODE_STANDBY );
616 617 if (status!=RTEMS_SUCCESSFUL) {
617 618 BOOT_PRINTF("in INIT *** Error starting TASK_AVF1\n")
618 619 }
619 620 }
620 621 if (status == RTEMS_SUCCESSFUL) // PRC1
621 622 {
622 623 status = rtems_task_start( Task_id[TASKID_PRC1], prc1_task, LFR_MODE_STANDBY );
623 624 if (status!=RTEMS_SUCCESSFUL) {
624 625 BOOT_PRINTF("in INIT *** Error starting TASK_PRC1\n")
625 626 }
626 627 }
627 628 if (status == RTEMS_SUCCESSFUL) // AVF2
628 629 {
629 630 status = rtems_task_start( Task_id[TASKID_AVF2], avf2_task, 1 );
630 631 if (status!=RTEMS_SUCCESSFUL) {
631 632 BOOT_PRINTF("in INIT *** Error starting TASK_AVF2\n")
632 633 }
633 634 }
634 635 if (status == RTEMS_SUCCESSFUL) // PRC2
635 636 {
636 637 status = rtems_task_start( Task_id[TASKID_PRC2], prc2_task, 1 );
637 638 if (status!=RTEMS_SUCCESSFUL) {
638 639 BOOT_PRINTF("in INIT *** Error starting TASK_PRC2\n")
639 640 }
640 641 }
641 642
642 643 //****************
643 644 // WAVEFORM PICKER
644 645 if (status == RTEMS_SUCCESSFUL) // WFRM
645 646 {
646 647 status = rtems_task_start( Task_id[TASKID_WFRM], wfrm_task, 1 );
647 648 if (status!=RTEMS_SUCCESSFUL) {
648 649 BOOT_PRINTF("in INIT *** Error starting TASK_WFRM\n")
649 650 }
650 651 }
651 652 if (status == RTEMS_SUCCESSFUL) // CWF3
652 653 {
653 654 status = rtems_task_start( Task_id[TASKID_CWF3], cwf3_task, 1 );
654 655 if (status!=RTEMS_SUCCESSFUL) {
655 656 BOOT_PRINTF("in INIT *** Error starting TASK_CWF3\n")
656 657 }
657 658 }
658 659 if (status == RTEMS_SUCCESSFUL) // CWF2
659 660 {
660 661 status = rtems_task_start( Task_id[TASKID_CWF2], cwf2_task, 1 );
661 662 if (status!=RTEMS_SUCCESSFUL) {
662 663 BOOT_PRINTF("in INIT *** Error starting TASK_CWF2\n")
663 664 }
664 665 }
665 666 if (status == RTEMS_SUCCESSFUL) // CWF1
666 667 {
667 668 status = rtems_task_start( Task_id[TASKID_CWF1], cwf1_task, 1 );
668 669 if (status!=RTEMS_SUCCESSFUL) {
669 670 BOOT_PRINTF("in INIT *** Error starting TASK_CWF1\n")
670 671 }
671 672 }
672 673 if (status == RTEMS_SUCCESSFUL) // SWBD
673 674 {
674 675 status = rtems_task_start( Task_id[TASKID_SWBD], swbd_task, 1 );
675 676 if (status!=RTEMS_SUCCESSFUL) {
676 677 BOOT_PRINTF("in INIT *** Error starting TASK_SWBD\n")
677 678 }
678 679 }
679 680
680 681 //*****
681 682 // MISC
682 683 if (status == RTEMS_SUCCESSFUL) // HOUS
683 684 {
684 685 status = rtems_task_start( Task_id[TASKID_HOUS], hous_task, 1 );
685 686 if (status!=RTEMS_SUCCESSFUL) {
686 687 BOOT_PRINTF("in INIT *** Error starting TASK_HOUS\n")
687 688 }
688 689 }
689 690 if (status == RTEMS_SUCCESSFUL) // DUMB
690 691 {
691 692 status = rtems_task_start( Task_id[TASKID_DUMB], dumb_task, 1 );
692 693 if (status!=RTEMS_SUCCESSFUL) {
693 694 BOOT_PRINTF("in INIT *** Error starting TASK_DUMB\n")
694 695 }
695 696 }
696 697 if (status == RTEMS_SUCCESSFUL) // LOAD
697 698 {
698 699 status = rtems_task_start( Task_id[TASKID_LOAD], load_task, 1 );
699 700 if (status!=RTEMS_SUCCESSFUL) {
700 701 BOOT_PRINTF("in INIT *** Error starting TASK_LOAD\n")
701 702 }
702 703 }
703 704
704 705 return status;
705 706 }
706 707
707 708 rtems_status_code create_message_queues( void ) // create the two message queues used in the software
708 709 {
709 710 rtems_status_code status_recv;
710 711 rtems_status_code status_send;
711 712 rtems_status_code status_q_p0;
712 713 rtems_status_code status_q_p1;
713 714 rtems_status_code status_q_p2;
714 715 rtems_status_code ret;
715 716 rtems_id queue_id;
716 717
717 718 //****************************************
718 719 // create the queue for handling valid TCs
719 720 status_recv = rtems_message_queue_create( misc_name[QUEUE_RECV],
720 721 MSG_QUEUE_COUNT_RECV, CCSDS_TC_PKT_MAX_SIZE,
721 722 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
722 723 if ( status_recv != RTEMS_SUCCESSFUL ) {
723 724 PRINTF1("in create_message_queues *** ERR creating QUEU queue, %d\n", status_recv)
724 725 }
725 726
726 727 //************************************************
727 728 // create the queue for handling TM packet sending
728 729 status_send = rtems_message_queue_create( misc_name[QUEUE_SEND],
729 730 MSG_QUEUE_COUNT_SEND, MSG_QUEUE_SIZE_SEND,
730 731 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
731 732 if ( status_send != RTEMS_SUCCESSFUL ) {
732 733 PRINTF1("in create_message_queues *** ERR creating PKTS queue, %d\n", status_send)
733 734 }
734 735
735 736 //*****************************************************************************
736 737 // create the queue for handling averaged spectral matrices for processing @ f0
737 738 status_q_p0 = rtems_message_queue_create( misc_name[QUEUE_PRC0],
738 739 MSG_QUEUE_COUNT_PRC0, MSG_QUEUE_SIZE_PRC0,
739 740 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
740 741 if ( status_q_p0 != RTEMS_SUCCESSFUL ) {
741 742 PRINTF1("in create_message_queues *** ERR creating Q_P0 queue, %d\n", status_q_p0)
742 743 }
743 744
744 745 //*****************************************************************************
745 746 // create the queue for handling averaged spectral matrices for processing @ f1
746 747 status_q_p1 = rtems_message_queue_create( misc_name[QUEUE_PRC1],
747 748 MSG_QUEUE_COUNT_PRC1, MSG_QUEUE_SIZE_PRC1,
748 749 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
749 750 if ( status_q_p1 != RTEMS_SUCCESSFUL ) {
750 751 PRINTF1("in create_message_queues *** ERR creating Q_P1 queue, %d\n", status_q_p1)
751 752 }
752 753
753 754 //*****************************************************************************
754 755 // create the queue for handling averaged spectral matrices for processing @ f2
755 756 status_q_p2 = rtems_message_queue_create( misc_name[QUEUE_PRC2],
756 757 MSG_QUEUE_COUNT_PRC2, MSG_QUEUE_SIZE_PRC2,
757 758 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
758 759 if ( status_q_p2 != RTEMS_SUCCESSFUL ) {
759 760 PRINTF1("in create_message_queues *** ERR creating Q_P2 queue, %d\n", status_q_p2)
760 761 }
761 762
762 763 if ( status_recv != RTEMS_SUCCESSFUL )
763 764 {
764 765 ret = status_recv;
765 766 }
766 767 else if( status_send != RTEMS_SUCCESSFUL )
767 768 {
768 769 ret = status_send;
769 770 }
770 771 else if( status_q_p0 != RTEMS_SUCCESSFUL )
771 772 {
772 773 ret = status_q_p0;
773 774 }
774 775 else if( status_q_p1 != RTEMS_SUCCESSFUL )
775 776 {
776 777 ret = status_q_p1;
777 778 }
778 779 else
779 780 {
780 781 ret = status_q_p2;
781 782 }
782 783
783 784 return ret;
784 785 }
785 786
786 787 rtems_status_code create_timecode_timer( void )
787 788 {
788 789 rtems_status_code status;
789 790
790 791 status = rtems_timer_create( timecode_timer_name, &timecode_timer_id );
791 792
792 793 if ( status != RTEMS_SUCCESSFUL )
793 794 {
794 795 PRINTF1("in create_timer_timecode *** ERR creating SPTC timer, %d\n", status)
795 796 }
796 797 else
797 798 {
798 799 PRINTF("in create_timer_timecode *** OK creating SPTC timer\n")
799 800 }
800 801
801 802 return status;
802 803 }
803 804
804 805 rtems_status_code get_message_queue_id_send( rtems_id *queue_id )
805 806 {
806 807 rtems_status_code status;
807 808 rtems_name queue_name;
808 809
809 810 queue_name = rtems_build_name( 'Q', '_', 'S', 'D' );
810 811
811 812 status = rtems_message_queue_ident( queue_name, 0, queue_id );
812 813
813 814 return status;
814 815 }
815 816
816 817 rtems_status_code get_message_queue_id_recv( rtems_id *queue_id )
817 818 {
818 819 rtems_status_code status;
819 820 rtems_name queue_name;
820 821
821 822 queue_name = rtems_build_name( 'Q', '_', 'R', 'V' );
822 823
823 824 status = rtems_message_queue_ident( queue_name, 0, queue_id );
824 825
825 826 return status;
826 827 }
827 828
828 829 rtems_status_code get_message_queue_id_prc0( rtems_id *queue_id )
829 830 {
830 831 rtems_status_code status;
831 832 rtems_name queue_name;
832 833
833 834 queue_name = rtems_build_name( 'Q', '_', 'P', '0' );
834 835
835 836 status = rtems_message_queue_ident( queue_name, 0, queue_id );
836 837
837 838 return status;
838 839 }
839 840
840 841 rtems_status_code get_message_queue_id_prc1( rtems_id *queue_id )
841 842 {
842 843 rtems_status_code status;
843 844 rtems_name queue_name;
844 845
845 846 queue_name = rtems_build_name( 'Q', '_', 'P', '1' );
846 847
847 848 status = rtems_message_queue_ident( queue_name, 0, queue_id );
848 849
849 850 return status;
850 851 }
851 852
852 853 rtems_status_code get_message_queue_id_prc2( rtems_id *queue_id )
853 854 {
854 855 rtems_status_code status;
855 856 rtems_name queue_name;
856 857
857 858 queue_name = rtems_build_name( 'Q', '_', 'P', '2' );
858 859
859 860 status = rtems_message_queue_ident( queue_name, 0, queue_id );
860 861
861 862 return status;
862 863 }
863 864
864 865 void update_queue_max_count( rtems_id queue_id, unsigned char*fifo_size_max )
865 866 {
866 867 u_int32_t count;
867 868 rtems_status_code status;
868 869
869 870 status = rtems_message_queue_get_number_pending( queue_id, &count );
870 871
871 872 count = count + 1;
872 873
873 874 if (status != RTEMS_SUCCESSFUL)
874 875 {
875 876 PRINTF1("in update_queue_max_count *** ERR = %d\n", status)
876 877 }
877 878 else
878 879 {
879 880 if (count > *fifo_size_max)
880 881 {
881 882 *fifo_size_max = count;
882 883 }
883 884 }
884 885 }
885 886
886 887 void init_ring(ring_node ring[], unsigned char nbNodes, volatile int buffer[], unsigned int bufferSize )
887 888 {
888 889 unsigned char i;
889 890
890 891 //***************
891 892 // BUFFER ADDRESS
892 893 for(i=0; i<nbNodes; i++)
893 894 {
894 895 ring[i].coarseTime = 0xffffffff;
895 896 ring[i].fineTime = 0xffffffff;
896 897 ring[i].sid = 0x00;
897 898 ring[i].status = 0x00;
898 899 ring[i].buffer_address = (int) &buffer[ i * bufferSize ];
899 900 }
900 901
901 902 //*****
902 903 // NEXT
903 904 ring[ nbNodes - 1 ].next = (ring_node*) &ring[ 0 ];
904 905 for(i=0; i<nbNodes-1; i++)
905 906 {
906 907 ring[i].next = (ring_node*) &ring[ i + 1 ];
907 908 }
908 909
909 910 //*********
910 911 // PREVIOUS
911 912 ring[ 0 ].previous = (ring_node*) &ring[ nbNodes - 1 ];
912 913 for(i=1; i<nbNodes; i++)
913 914 {
914 915 ring[i].previous = (ring_node*) &ring[ i - 1 ];
915 916 }
916 917 }
@@ -1,1310 +1,1302
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 typedef enum resynchro_state_t
47 47 {
48 MEASURE_0,
49 MEASURE_1,
50 CORRECTION_0,
51 CORRECTION_1
48 MEASURE,
49 CORRECTION
52 50 } resynchro_state;
53 51
54 52 //*********************
55 53 // Interrupt SubRoutine
56 54
57 55 ring_node * getRingNodeToSendCWF( unsigned char frequencyChannel)
58 56 {
59 57 ring_node *node;
60 58
61 59 node = NULL;
62 60 switch ( frequencyChannel ) {
63 61 case 1:
64 62 node = ring_node_to_send_cwf_f1;
65 63 break;
66 64 case 2:
67 65 node = ring_node_to_send_cwf_f2;
68 66 break;
69 67 case 3:
70 68 node = ring_node_to_send_cwf_f3;
71 69 break;
72 70 default:
73 71 break;
74 72 }
75 73
76 74 return node;
77 75 }
78 76
79 77 ring_node * getRingNodeToSendSWF( unsigned char frequencyChannel)
80 78 {
81 79 ring_node *node;
82 80
83 81 node = NULL;
84 82 switch ( frequencyChannel ) {
85 83 case 0:
86 84 node = ring_node_to_send_swf_f0;
87 85 break;
88 86 case 1:
89 87 node = ring_node_to_send_swf_f1;
90 88 break;
91 89 case 2:
92 90 node = ring_node_to_send_swf_f2;
93 91 break;
94 92 default:
95 93 break;
96 94 }
97 95
98 96 return node;
99 97 }
100 98
101 99 void reset_extractSWF( void )
102 100 {
103 101 extractSWF1 = false;
104 102 extractSWF2 = false;
105 103 swf0_ready_flag_f1 = false;
106 104 swf0_ready_flag_f2 = false;
107 105 swf1_ready = false;
108 106 swf2_ready = false;
109 107 }
110 108
111 109 inline void waveforms_isr_f3( void )
112 110 {
113 111 rtems_status_code spare_status;
114 112
115 113 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
116 114 || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) )
117 115 { // in modes other than STANDBY and BURST, send the CWF_F3 data
118 116 //***
119 117 // F3
120 118 if ( (waveform_picker_regs->status & 0xc0) != 0x00 ) { // [1100 0000] check the f3 full bits
121 119 ring_node_to_send_cwf_f3 = current_ring_node_f3->previous;
122 120 current_ring_node_f3 = current_ring_node_f3->next;
123 121 if ((waveform_picker_regs->status & 0x40) == 0x40){ // [0100 0000] f3 buffer 0 is full
124 122 ring_node_to_send_cwf_f3->coarseTime = waveform_picker_regs->f3_0_coarse_time;
125 123 ring_node_to_send_cwf_f3->fineTime = waveform_picker_regs->f3_0_fine_time;
126 124 waveform_picker_regs->addr_data_f3_0 = current_ring_node_f3->buffer_address;
127 125 waveform_picker_regs->status = waveform_picker_regs->status & 0x00008840; // [1000 1000 0100 0000]
128 126 }
129 127 else if ((waveform_picker_regs->status & 0x80) == 0x80){ // [1000 0000] f3 buffer 1 is full
130 128 ring_node_to_send_cwf_f3->coarseTime = waveform_picker_regs->f3_1_coarse_time;
131 129 ring_node_to_send_cwf_f3->fineTime = waveform_picker_regs->f3_1_fine_time;
132 130 waveform_picker_regs->addr_data_f3_1 = current_ring_node_f3->buffer_address;
133 131 waveform_picker_regs->status = waveform_picker_regs->status & 0x00008880; // [1000 1000 1000 0000]
134 132 }
135 133 if (rtems_event_send( Task_id[TASKID_CWF3], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
136 134 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
137 135 }
138 136 }
139 137 }
140 138 }
141 139
142 140 inline void waveforms_isr_burst( void )
143 141 {
144 142 unsigned char status;
145 143 rtems_status_code spare_status;
146 144
147 145 status = (waveform_picker_regs->status & 0x30) >> 4; // [0011 0000] get the status bits for f2
148 146
149 147
150 148 switch(status)
151 149 {
152 150 case 1:
153 151 ring_node_to_send_cwf_f2 = current_ring_node_f2->previous;
154 152 ring_node_to_send_cwf_f2->sid = SID_BURST_CWF_F2;
155 153 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_0_coarse_time;
156 154 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_0_fine_time;
157 155 current_ring_node_f2 = current_ring_node_f2->next;
158 156 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->buffer_address;
159 157 if (rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_BURST ) != RTEMS_SUCCESSFUL) {
160 158 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
161 159 }
162 160 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004410; // [0100 0100 0001 0000]
163 161 break;
164 162 case 2:
165 163 ring_node_to_send_cwf_f2 = current_ring_node_f2->previous;
166 164 ring_node_to_send_cwf_f2->sid = SID_BURST_CWF_F2;
167 165 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_1_coarse_time;
168 166 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_1_fine_time;
169 167 current_ring_node_f2 = current_ring_node_f2->next;
170 168 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address;
171 169 if (rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_BURST ) != RTEMS_SUCCESSFUL) {
172 170 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
173 171 }
174 172 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004420; // [0100 0100 0010 0000]
175 173 break;
176 174 default:
177 175 break;
178 176 }
179 177 }
180 178
181 179 inline void waveform_isr_normal_sbm1_sbm2( void )
182 180 {
183 181 rtems_status_code status;
184 182
185 183 //***
186 184 // F0
187 185 if ( (waveform_picker_regs->status & 0x03) != 0x00 ) // [0000 0011] check the f0 full bits
188 186 {
189 187 swf0_ready_flag_f1 = true;
190 188 swf0_ready_flag_f2 = true;
191 189 ring_node_to_send_swf_f0 = current_ring_node_f0->previous;
192 190 current_ring_node_f0 = current_ring_node_f0->next;
193 191 if ( (waveform_picker_regs->status & 0x01) == 0x01)
194 192 {
195 193
196 194 ring_node_to_send_swf_f0->coarseTime = waveform_picker_regs->f0_0_coarse_time;
197 195 ring_node_to_send_swf_f0->fineTime = waveform_picker_regs->f0_0_fine_time;
198 196 waveform_picker_regs->addr_data_f0_0 = current_ring_node_f0->buffer_address;
199 197 waveform_picker_regs->status = waveform_picker_regs->status & 0x00001101; // [0001 0001 0000 0001]
200 198 }
201 199 else if ( (waveform_picker_regs->status & 0x02) == 0x02)
202 200 {
203 201 ring_node_to_send_swf_f0->coarseTime = waveform_picker_regs->f0_1_coarse_time;
204 202 ring_node_to_send_swf_f0->fineTime = waveform_picker_regs->f0_1_fine_time;
205 203 waveform_picker_regs->addr_data_f0_1 = current_ring_node_f0->buffer_address;
206 204 waveform_picker_regs->status = waveform_picker_regs->status & 0x00001102; // [0001 0001 0000 0010]
207 205 }
206 // send an event to the WFRM task for resynchro activities
207 status = rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_SWF_RESYNCH );
208 208 }
209 209
210 210 //***
211 211 // F1
212 212 if ( (waveform_picker_regs->status & 0x0c) != 0x00 ) { // [0000 1100] check the f1 full bits
213 213 // (1) change the receiving buffer for the waveform picker
214 214 ring_node_to_send_cwf_f1 = current_ring_node_f1->previous;
215 215 current_ring_node_f1 = current_ring_node_f1->next;
216 216 if ( (waveform_picker_regs->status & 0x04) == 0x04)
217 217 {
218 218 ring_node_to_send_cwf_f1->coarseTime = waveform_picker_regs->f1_0_coarse_time;
219 219 ring_node_to_send_cwf_f1->fineTime = waveform_picker_regs->f1_0_fine_time;
220 220 waveform_picker_regs->addr_data_f1_0 = current_ring_node_f1->buffer_address;
221 221 waveform_picker_regs->status = waveform_picker_regs->status & 0x00002204; // [0010 0010 0000 0100] f1 bits = 0
222 222 }
223 223 else if ( (waveform_picker_regs->status & 0x08) == 0x08)
224 224 {
225 225 ring_node_to_send_cwf_f1->coarseTime = waveform_picker_regs->f1_1_coarse_time;
226 226 ring_node_to_send_cwf_f1->fineTime = waveform_picker_regs->f1_1_fine_time;
227 227 waveform_picker_regs->addr_data_f1_1 = current_ring_node_f1->buffer_address;
228 228 waveform_picker_regs->status = waveform_picker_regs->status & 0x00002208; // [0010 0010 0000 1000] f1 bits = 0
229 229 }
230 230 // (2) send an event for the the CWF1 task for transmission (and snapshot extraction if needed)
231 231 status = rtems_event_send( Task_id[TASKID_CWF1], RTEMS_EVENT_MODE_NORM_S1_S2 );
232 232 }
233 233
234 234 //***
235 235 // F2
236 236 if ( (waveform_picker_regs->status & 0x30) != 0x00 ) { // [0011 0000] check the f2 full bit
237 237 // (1) change the receiving buffer for the waveform picker
238 238 ring_node_to_send_cwf_f2 = current_ring_node_f2->previous;
239 239 ring_node_to_send_cwf_f2->sid = SID_SBM2_CWF_F2;
240 240 current_ring_node_f2 = current_ring_node_f2->next;
241 241 if ( (waveform_picker_regs->status & 0x10) == 0x10)
242 242 {
243 243 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_0_coarse_time;
244 244 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_0_fine_time;
245 245 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->buffer_address;
246 246 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004410; // [0100 0100 0001 0000]
247 247 }
248 248 else if ( (waveform_picker_regs->status & 0x20) == 0x20)
249 249 {
250 250 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_1_coarse_time;
251 251 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_1_fine_time;
252 252 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address;
253 253 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004420; // [0100 0100 0010 0000]
254 254 }
255 255 // (2) send an event for the waveforms transmission
256 256 status = rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_NORM_S1_S2 );
257 257 }
258 258 }
259 259
260 260 rtems_isr waveforms_isr( rtems_vector_number vector )
261 261 {
262 262 /** This is the interrupt sub routine called by the waveform picker core.
263 263 *
264 264 * This ISR launch different actions depending mainly on two pieces of information:
265 265 * 1. the values read in the registers of the waveform picker.
266 266 * 2. the current LFR mode.
267 267 *
268 268 */
269 269
270 270 // STATUS
271 271 // new error error buffer full
272 272 // 15 14 13 12 11 10 9 8
273 273 // f3 f2 f1 f0 f3 f2 f1 f0
274 274 //
275 275 // ready buffer
276 276 // 7 6 5 4 3 2 1 0
277 277 // f3_1 f3_0 f2_1 f2_0 f1_1 f1_0 f0_1 f0_0
278 278
279 279 rtems_status_code spare_status;
280 280
281 281 waveforms_isr_f3();
282 282
283 283 //*************************************************
284 284 // copy the status bits in the housekeeping packets
285 285 housekeeping_packet.hk_lfr_vhdl_iir_cal =
286 286 (unsigned char) ((waveform_picker_regs->status & 0xff00) >> 8);
287 287
288 288 if ( (waveform_picker_regs->status & 0xff00) != 0x00) // [1111 1111 0000 0000] check the error bits
289 289 {
290 290 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_10 );
291 291 }
292 292
293 293 switch(lfrCurrentMode)
294 294 {
295 295 //********
296 296 // STANDBY
297 297 case LFR_MODE_STANDBY:
298 298 break;
299 299 //**************************
300 300 // LFR NORMAL, SBM1 and SBM2
301 301 case LFR_MODE_NORMAL:
302 302 case LFR_MODE_SBM1:
303 303 case LFR_MODE_SBM2:
304 304 waveform_isr_normal_sbm1_sbm2();
305 305 break;
306 306 //******
307 307 // BURST
308 308 case LFR_MODE_BURST:
309 309 waveforms_isr_burst();
310 310 break;
311 311 //********
312 312 // DEFAULT
313 313 default:
314 314 break;
315 315 }
316 316 }
317 317
318 318 //************
319 319 // RTEMS TASKS
320 320
321 321 rtems_task wfrm_task(rtems_task_argument argument) //used with the waveform picker VHDL IP
322 322 {
323 323 /** This RTEMS task is dedicated to the transmission of snapshots of the NORMAL mode.
324 324 *
325 325 * @param unused is the starting argument of the RTEMS task
326 326 *
327 327 * The following data packets are sent by this task:
328 328 * - TM_LFR_SCIENCE_NORMAL_SWF_F0
329 329 * - TM_LFR_SCIENCE_NORMAL_SWF_F1
330 330 * - TM_LFR_SCIENCE_NORMAL_SWF_F2
331 331 *
332 332 */
333 333
334 334 rtems_event_set event_out;
335 335 rtems_id queue_id;
336 336 rtems_status_code status;
337 337 ring_node *ring_node_swf1_extracted_ptr;
338 338 ring_node *ring_node_swf2_extracted_ptr;
339 339
340 340 ring_node_swf1_extracted_ptr = (ring_node *) &ring_node_swf1_extracted;
341 341 ring_node_swf2_extracted_ptr = (ring_node *) &ring_node_swf2_extracted;
342 342
343 343 status = get_message_queue_id_send( &queue_id );
344 344 if (status != RTEMS_SUCCESSFUL)
345 345 {
346 346 PRINTF1("in WFRM *** ERR get_message_queue_id_send %d\n", status);
347 347 }
348 348
349 349 BOOT_PRINTF("in WFRM ***\n");
350 350
351 351 while(1){
352 352 // wait for an RTEMS_EVENT
353 rtems_event_receive(RTEMS_EVENT_MODE_NORMAL,
353 rtems_event_receive(RTEMS_EVENT_MODE_NORMAL | RTEMS_EVENT_SWF_RESYNCH,
354 354 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
355 355
356 snapshot_resynchronization( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
357
358 356 if (event_out == RTEMS_EVENT_MODE_NORMAL)
359 357 {
360 358 DEBUG_PRINTF("WFRM received RTEMS_EVENT_MODE_SBM2\n");
361 359 ring_node_to_send_swf_f0->sid = SID_NORM_SWF_F0;
362 360 ring_node_swf1_extracted_ptr->sid = SID_NORM_SWF_F1;
363 361 ring_node_swf2_extracted_ptr->sid = SID_NORM_SWF_F2;
364 362 status = rtems_message_queue_send( queue_id, &ring_node_to_send_swf_f0, sizeof( ring_node* ) );
365 363 status = rtems_message_queue_send( queue_id, &ring_node_swf1_extracted_ptr, sizeof( ring_node* ) );
366 364 status = rtems_message_queue_send( queue_id, &ring_node_swf2_extracted_ptr, sizeof( ring_node* ) );
367 365 }
366 if (event_out == RTEMS_EVENT_SWF_RESYNCH)
367 {
368 snapshot_resynchronization( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
369 }
368 370 }
369 371 }
370 372
371 373 rtems_task cwf3_task(rtems_task_argument argument) //used with the waveform picker VHDL IP
372 374 {
373 375 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f3.
374 376 *
375 377 * @param unused is the starting argument of the RTEMS task
376 378 *
377 379 * The following data packet is sent by this task:
378 380 * - TM_LFR_SCIENCE_NORMAL_CWF_F3
379 381 *
380 382 */
381 383
382 384 rtems_event_set event_out;
383 385 rtems_id queue_id;
384 386 rtems_status_code status;
385 387 ring_node ring_node_cwf3_light;
386 388 ring_node *ring_node_to_send_cwf;
387 389
388 390 status = get_message_queue_id_send( &queue_id );
389 391 if (status != RTEMS_SUCCESSFUL)
390 392 {
391 393 PRINTF1("in CWF3 *** ERR get_message_queue_id_send %d\n", status)
392 394 }
393 395
394 396 ring_node_to_send_cwf_f3->sid = SID_NORM_CWF_LONG_F3;
395 397
396 398 // init the ring_node_cwf3_light structure
397 399 ring_node_cwf3_light.buffer_address = (int) wf_cont_f3_light;
398 400 ring_node_cwf3_light.coarseTime = 0x00;
399 401 ring_node_cwf3_light.fineTime = 0x00;
400 402 ring_node_cwf3_light.next = NULL;
401 403 ring_node_cwf3_light.previous = NULL;
402 404 ring_node_cwf3_light.sid = SID_NORM_CWF_F3;
403 405 ring_node_cwf3_light.status = 0x00;
404 406
405 407 BOOT_PRINTF("in CWF3 ***\n")
406 408
407 409 while(1){
408 410 // wait for an RTEMS_EVENT
409 411 rtems_event_receive( RTEMS_EVENT_0,
410 412 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
411 413 if ( (lfrCurrentMode == LFR_MODE_NORMAL)
412 414 || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode==LFR_MODE_SBM2) )
413 415 {
414 416 ring_node_to_send_cwf = getRingNodeToSendCWF( 3 );
415 417 if ( (parameter_dump_packet.sy_lfr_n_cwf_long_f3 & 0x01) == 0x01)
416 418 {
417 419 PRINTF("send CWF_LONG_F3\n")
418 420 ring_node_to_send_cwf_f3->sid = SID_NORM_CWF_LONG_F3;
419 421 status = rtems_message_queue_send( queue_id, &ring_node_to_send_cwf, sizeof( ring_node* ) );
420 422 }
421 423 else
422 424 {
423 425 PRINTF("send CWF_F3 (light)\n")
424 426 send_waveform_CWF3_light( ring_node_to_send_cwf, &ring_node_cwf3_light, queue_id );
425 427 }
426 428
427 429 }
428 430 else
429 431 {
430 432 PRINTF1("in CWF3 *** lfrCurrentMode is %d, no data will be sent\n", lfrCurrentMode)
431 433 }
432 434 }
433 435 }
434 436
435 437 rtems_task cwf2_task(rtems_task_argument argument) // ONLY USED IN BURST AND SBM2
436 438 {
437 439 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f2.
438 440 *
439 441 * @param unused is the starting argument of the RTEMS task
440 442 *
441 443 * The following data packet is sent by this function:
442 444 * - TM_LFR_SCIENCE_BURST_CWF_F2
443 445 * - TM_LFR_SCIENCE_SBM2_CWF_F2
444 446 *
445 447 */
446 448
447 449 rtems_event_set event_out;
448 450 rtems_id queue_id;
449 451 rtems_status_code status;
450 452 ring_node *ring_node_to_send;
451 453 unsigned long long int acquisitionTimeF0_asLong;
452 454
453 455 acquisitionTimeF0_asLong = 0x00;
454 456
455 457 status = get_message_queue_id_send( &queue_id );
456 458 if (status != RTEMS_SUCCESSFUL)
457 459 {
458 460 PRINTF1("in CWF2 *** ERR get_message_queue_id_send %d\n", status)
459 461 }
460 462
461 463 BOOT_PRINTF("in CWF2 ***\n")
462 464
463 465 while(1){
464 // wait for an RTEMS_EVENT
466 // wait for an RTEMS_EVENT// send the snapshot when built
467 status = rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_SBM2 );
465 468 rtems_event_receive( RTEMS_EVENT_MODE_NORM_S1_S2 | RTEMS_EVENT_MODE_BURST,
466 469 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
467 470 ring_node_to_send = getRingNodeToSendCWF( 2 );
468 471 if (event_out == RTEMS_EVENT_MODE_BURST)
469 472 {
470 473 status = rtems_message_queue_send( queue_id, &ring_node_to_send, sizeof( ring_node* ) );
471 474 }
472 475 else if (event_out == RTEMS_EVENT_MODE_NORM_S1_S2)
473 476 {
474 477 if ( lfrCurrentMode == LFR_MODE_SBM2 )
475 478 {
476 479 status = rtems_message_queue_send( queue_id, &ring_node_to_send, sizeof( ring_node* ) );
477 480 }
478 481 // launch snapshot extraction if needed
479 482 if (extractSWF2 == true)
480 483 {
481 484 ring_node_to_send_swf_f2 = ring_node_to_send_cwf_f2;
482 485 // extract the snapshot
483 486 build_snapshot_from_ring( ring_node_to_send_swf_f2, 2, acquisitionTimeF0_asLong,
484 487 &ring_node_swf2_extracted, swf2_extracted );
485 // send the snapshot when built
486 status = rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_SBM2 );
487 488 extractSWF2 = false;
488 swf2_ready = true;
489 swf2_ready = true; // once the snapshot at f2 is ready the CWF1 task will send an event to WFRM
489 490 }
490 491 if (swf0_ready_flag_f2 == true)
491 492 {
492 493 extractSWF2 = true;
493 494 // record the acquition time of the f0 snapshot to use to build the snapshot at f2
494 495 acquisitionTimeF0_asLong = get_acquisition_time( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
495 496 swf0_ready_flag_f2 = false;
496 497 }
497 498 }
498 499 }
499 500 }
500 501
501 502 rtems_task cwf1_task(rtems_task_argument argument) // ONLY USED IN SBM1
502 503 {
503 504 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f1.
504 505 *
505 506 * @param unused is the starting argument of the RTEMS task
506 507 *
507 508 * The following data packet is sent by this function:
508 509 * - TM_LFR_SCIENCE_SBM1_CWF_F1
509 510 *
510 511 */
511 512
512 513 rtems_event_set event_out;
513 514 rtems_id queue_id;
514 515 rtems_status_code status;
515 516
516 517 ring_node *ring_node_to_send_cwf;
517 518
518 519 status = get_message_queue_id_send( &queue_id );
519 520 if (status != RTEMS_SUCCESSFUL)
520 521 {
521 522 PRINTF1("in CWF1 *** ERR get_message_queue_id_send %d\n", status)
522 523 }
523 524
524 525 BOOT_PRINTF("in CWF1 ***\n");
525 526
526 527 while(1){
527 528 // wait for an RTEMS_EVENT
528 529 rtems_event_receive( RTEMS_EVENT_MODE_NORM_S1_S2,
529 530 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
530 531 ring_node_to_send_cwf = getRingNodeToSendCWF( 1 );
531 532 ring_node_to_send_cwf_f1->sid = SID_SBM1_CWF_F1;
532 533 if (lfrCurrentMode == LFR_MODE_SBM1)
533 534 {
534 535 status = rtems_message_queue_send( queue_id, &ring_node_to_send_cwf, sizeof( ring_node* ) );
535 536 if (status != 0)
536 537 {
537 538 PRINTF("cwf sending failed\n")
538 539 }
539 540 }
540 541 // launch snapshot extraction if needed
541 542 if (extractSWF1 == true)
542 543 {
543 544 ring_node_to_send_swf_f1 = ring_node_to_send_cwf;
544 545 // launch the snapshot extraction
545 546 status = rtems_event_send( Task_id[TASKID_SWBD], RTEMS_EVENT_MODE_NORM_S1_S2 );
546 547 extractSWF1 = false;
547 548 }
548 549 if (swf0_ready_flag_f1 == true)
549 550 {
550 551 extractSWF1 = true;
551 552 swf0_ready_flag_f1 = false; // this step shall be executed only one time
552 553 }
553 554 if ((swf1_ready == true) && (swf2_ready == true)) // swf_f1 is ready after the extraction
554 555 {
555 556 status = rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_NORMAL );
556 557 swf1_ready = false;
557 558 swf2_ready = false;
558 559 }
559 560 }
560 561 }
561 562
562 563 rtems_task swbd_task(rtems_task_argument argument)
563 564 {
564 565 /** This RTEMS task is dedicated to the building of snapshots from different continuous waveforms buffers.
565 566 *
566 567 * @param unused is the starting argument of the RTEMS task
567 568 *
568 569 */
569 570
570 571 rtems_event_set event_out;
571 572 unsigned long long int acquisitionTimeF0_asLong;
572 573
573 574 acquisitionTimeF0_asLong = 0x00;
574 575
575 576 BOOT_PRINTF("in SWBD ***\n")
576 577
577 578 while(1){
578 579 // wait for an RTEMS_EVENT
579 580 rtems_event_receive( RTEMS_EVENT_MODE_NORM_S1_S2,
580 581 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
581 582 if (event_out == RTEMS_EVENT_MODE_NORM_S1_S2)
582 583 {
583 584 acquisitionTimeF0_asLong = get_acquisition_time( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
584 585 build_snapshot_from_ring( ring_node_to_send_swf_f1, 1, acquisitionTimeF0_asLong,
585 586 &ring_node_swf1_extracted, swf1_extracted );
586 587 swf1_ready = true; // the snapshot has been extracted and is ready to be sent
587 588 }
588 589 else
589 590 {
590 591 PRINTF1("in SWBD *** unexpected rtems event received %x\n", (int) event_out)
591 592 }
592 593 }
593 594 }
594 595
595 596 //******************
596 597 // general functions
597 598
598 599 void WFP_init_rings( void )
599 600 {
600 601 // F0 RING
601 602 init_ring( waveform_ring_f0, NB_RING_NODES_F0, wf_buffer_f0, WFRM_BUFFER );
602 603 // F1 RING
603 604 init_ring( waveform_ring_f1, NB_RING_NODES_F1, wf_buffer_f1, WFRM_BUFFER );
604 605 // F2 RING
605 606 init_ring( waveform_ring_f2, NB_RING_NODES_F2, wf_buffer_f2, WFRM_BUFFER );
606 607 // F3 RING
607 608 init_ring( waveform_ring_f3, NB_RING_NODES_F3, wf_buffer_f3, WFRM_BUFFER );
608 609
609 610 ring_node_swf1_extracted.buffer_address = (int) swf1_extracted;
610 611 ring_node_swf2_extracted.buffer_address = (int) swf2_extracted;
611 612
612 613 DEBUG_PRINTF1("waveform_ring_f0 @%x\n", (unsigned int) waveform_ring_f0)
613 614 DEBUG_PRINTF1("waveform_ring_f1 @%x\n", (unsigned int) waveform_ring_f1)
614 615 DEBUG_PRINTF1("waveform_ring_f2 @%x\n", (unsigned int) waveform_ring_f2)
615 616 DEBUG_PRINTF1("waveform_ring_f3 @%x\n", (unsigned int) waveform_ring_f3)
616 617 DEBUG_PRINTF1("wf_buffer_f0 @%x\n", (unsigned int) wf_buffer_f0)
617 618 DEBUG_PRINTF1("wf_buffer_f1 @%x\n", (unsigned int) wf_buffer_f1)
618 619 DEBUG_PRINTF1("wf_buffer_f2 @%x\n", (unsigned int) wf_buffer_f2)
619 620 DEBUG_PRINTF1("wf_buffer_f3 @%x\n", (unsigned int) wf_buffer_f3)
620 621
621 622 }
622 623
623 624 void WFP_reset_current_ring_nodes( void )
624 625 {
625 626 current_ring_node_f0 = waveform_ring_f0[0].next;
626 627 current_ring_node_f1 = waveform_ring_f1[0].next;
627 628 current_ring_node_f2 = waveform_ring_f2[0].next;
628 629 current_ring_node_f3 = waveform_ring_f3[0].next;
629 630
630 631 ring_node_to_send_swf_f0 = waveform_ring_f0;
631 632 ring_node_to_send_swf_f1 = waveform_ring_f1;
632 633 ring_node_to_send_swf_f2 = waveform_ring_f2;
633 634
634 635 ring_node_to_send_cwf_f1 = waveform_ring_f1;
635 636 ring_node_to_send_cwf_f2 = waveform_ring_f2;
636 637 ring_node_to_send_cwf_f3 = waveform_ring_f3;
637 638 }
638 639
639 640 int send_waveform_CWF3_light( ring_node *ring_node_to_send, ring_node *ring_node_cwf3_light, rtems_id queue_id )
640 641 {
641 642 /** This function sends CWF_F3 CCSDS packets without the b1, b2 and b3 data.
642 643 *
643 644 * @param waveform points to the buffer containing the data that will be send.
644 645 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
645 646 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
646 647 * contain information to setup the transmission of the data packets.
647 648 *
648 649 * By default, CWF_F3 packet are send without the b1, b2 and b3 data. This function rebuilds a data buffer
649 650 * from the incoming data and sends it in 7 packets, 6 containing 340 blocks and 1 one containing 8 blocks.
650 651 *
651 652 */
652 653
653 654 unsigned int i;
654 655 int ret;
655 656 rtems_status_code status;
656 657
657 658 char *sample;
658 659 int *dataPtr;
659 660
660 661 ret = LFR_DEFAULT;
661 662
662 663 dataPtr = (int*) ring_node_to_send->buffer_address;
663 664
664 665 ring_node_cwf3_light->coarseTime = ring_node_to_send->coarseTime;
665 666 ring_node_cwf3_light->fineTime = ring_node_to_send->fineTime;
666 667
667 668 //**********************
668 669 // BUILD CWF3_light DATA
669 670 for ( i=0; i< NB_SAMPLES_PER_SNAPSHOT; i++)
670 671 {
671 672 sample = (char*) &dataPtr[ (i * NB_WORDS_SWF_BLK) ];
672 673 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) ] = sample[ 0 ];
673 674 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 1 ] = sample[ 1 ];
674 675 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 2 ] = sample[ 2 ];
675 676 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 3 ] = sample[ 3 ];
676 677 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 4 ] = sample[ 4 ];
677 678 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 5 ] = sample[ 5 ];
678 679 }
679 680
680 681 // SEND PACKET
681 682 status = rtems_message_queue_send( queue_id, &ring_node_cwf3_light, sizeof( ring_node* ) );
682 683 if (status != RTEMS_SUCCESSFUL) {
683 684 ret = LFR_DEFAULT;
684 685 }
685 686
686 687 return ret;
687 688 }
688 689
689 690 void compute_acquisition_time( unsigned int coarseTime, unsigned int fineTime,
690 691 unsigned int sid, unsigned char pa_lfr_pkt_nr, unsigned char * acquisitionTime )
691 692 {
692 693 unsigned long long int acquisitionTimeAsLong;
693 694 unsigned char localAcquisitionTime[6];
694 695 double deltaT;
695 696
696 697 deltaT = 0.;
697 698
698 699 localAcquisitionTime[0] = (unsigned char) ( coarseTime >> 24 );
699 700 localAcquisitionTime[1] = (unsigned char) ( coarseTime >> 16 );
700 701 localAcquisitionTime[2] = (unsigned char) ( coarseTime >> 8 );
701 702 localAcquisitionTime[3] = (unsigned char) ( coarseTime );
702 703 localAcquisitionTime[4] = (unsigned char) ( fineTime >> 8 );
703 704 localAcquisitionTime[5] = (unsigned char) ( fineTime );
704 705
705 706 acquisitionTimeAsLong = ( (unsigned long long int) localAcquisitionTime[0] << 40 )
706 707 + ( (unsigned long long int) localAcquisitionTime[1] << 32 )
707 708 + ( (unsigned long long int) localAcquisitionTime[2] << 24 )
708 709 + ( (unsigned long long int) localAcquisitionTime[3] << 16 )
709 710 + ( (unsigned long long int) localAcquisitionTime[4] << 8 )
710 711 + ( (unsigned long long int) localAcquisitionTime[5] );
711 712
712 713 switch( sid )
713 714 {
714 715 case SID_NORM_SWF_F0:
715 716 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 24576. ;
716 717 break;
717 718
718 719 case SID_NORM_SWF_F1:
719 720 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 4096. ;
720 721 break;
721 722
722 723 case SID_NORM_SWF_F2:
723 724 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 256. ;
724 725 break;
725 726
726 727 case SID_SBM1_CWF_F1:
727 728 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 4096. ;
728 729 break;
729 730
730 731 case SID_SBM2_CWF_F2:
731 732 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 256. ;
732 733 break;
733 734
734 735 case SID_BURST_CWF_F2:
735 736 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 256. ;
736 737 break;
737 738
738 739 case SID_NORM_CWF_F3:
739 740 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF_SHORT_F3 * 65536. / 16. ;
740 741 break;
741 742
742 743 case SID_NORM_CWF_LONG_F3:
743 744 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 16. ;
744 745 break;
745 746
746 747 default:
747 748 PRINTF1("in compute_acquisition_time *** ERR unexpected sid %d\n", sid)
748 749 deltaT = 0.;
749 750 break;
750 751 }
751 752
752 753 acquisitionTimeAsLong = acquisitionTimeAsLong + (unsigned long long int) deltaT;
753 754 //
754 755 acquisitionTime[0] = (unsigned char) (acquisitionTimeAsLong >> 40);
755 756 acquisitionTime[1] = (unsigned char) (acquisitionTimeAsLong >> 32);
756 757 acquisitionTime[2] = (unsigned char) (acquisitionTimeAsLong >> 24);
757 758 acquisitionTime[3] = (unsigned char) (acquisitionTimeAsLong >> 16);
758 759 acquisitionTime[4] = (unsigned char) (acquisitionTimeAsLong >> 8 );
759 760 acquisitionTime[5] = (unsigned char) (acquisitionTimeAsLong );
760 761
761 762 }
762 763
763 764 void build_snapshot_from_ring( ring_node *ring_node_to_send,
764 765 unsigned char frequencyChannel,
765 766 unsigned long long int acquisitionTimeF0_asLong,
766 767 ring_node *ring_node_swf_extracted,
767 768 int *swf_extracted)
768 769 {
769 770 unsigned int i;
770 771 unsigned long long int centerTime_asLong;
771 772 unsigned long long int acquisitionTime_asLong;
772 773 unsigned long long int bufferAcquisitionTime_asLong;
773 774 unsigned char *ptr1;
774 775 unsigned char *ptr2;
775 776 unsigned char *timeCharPtr;
776 777 unsigned char nb_ring_nodes;
777 778 unsigned long long int frequency_asLong;
778 779 unsigned long long int nbTicksPerSample_asLong;
779 780 unsigned long long int nbSamplesPart1_asLong;
780 781 unsigned long long int sampleOffset_asLong;
781 782
782 783 unsigned int deltaT_F0;
783 784 unsigned int deltaT_F1;
784 785 unsigned long long int deltaT_F2;
785 786
786 787 deltaT_F0 = 2731; // (2048. / 24576. / 2.) * 65536. = 2730.667;
787 788 deltaT_F1 = 16384; // (2048. / 4096. / 2.) * 65536. = 16384;
788 789 deltaT_F2 = 262144; // (2048. / 256. / 2.) * 65536. = 262144;
789 790 sampleOffset_asLong = 0x00;
790 791
791 792 // (1) get the f0 acquisition time => the value is passed in argument
792 793
793 794 // (2) compute the central reference time
794 795 centerTime_asLong = acquisitionTimeF0_asLong + deltaT_F0;
795 796
796 797 // (3) compute the acquisition time of the current snapshot
797 798 switch(frequencyChannel)
798 799 {
799 800 case 1: // 1 is for F1 = 4096 Hz
800 801 acquisitionTime_asLong = centerTime_asLong - deltaT_F1;
801 802 nb_ring_nodes = NB_RING_NODES_F1;
802 803 frequency_asLong = 4096;
803 804 nbTicksPerSample_asLong = 16; // 65536 / 4096;
804 805 break;
805 806 case 2: // 2 is for F2 = 256 Hz
806 807 acquisitionTime_asLong = centerTime_asLong - deltaT_F2;
807 808 nb_ring_nodes = NB_RING_NODES_F2;
808 809 frequency_asLong = 256;
809 810 nbTicksPerSample_asLong = 256; // 65536 / 256;
810 811 break;
811 812 default:
812 813 acquisitionTime_asLong = centerTime_asLong;
813 814 frequency_asLong = 256;
814 815 nbTicksPerSample_asLong = 256;
815 816 break;
816 817 }
817 818
818 819 //****************************************************************************
819 820 // (4) search the ring_node with the acquisition time <= acquisitionTime_asLong
820 821 for (i=0; i<nb_ring_nodes; i++)
821 822 {
822 823 //PRINTF1("%d ... ", i);
823 824 bufferAcquisitionTime_asLong = get_acquisition_time( (unsigned char *) &ring_node_to_send->coarseTime );
824 825 if (bufferAcquisitionTime_asLong <= acquisitionTime_asLong)
825 826 {
826 827 //PRINTF1("buffer found with acquisition time = %llx\n", bufferAcquisitionTime_asLong);
827 828 break;
828 829 }
829 830 ring_node_to_send = ring_node_to_send->previous;
830 831 }
831 832
832 833 // (5) compute the number of samples to take in the current buffer
833 834 sampleOffset_asLong = ((acquisitionTime_asLong - bufferAcquisitionTime_asLong) * frequency_asLong ) >> 16;
834 835 nbSamplesPart1_asLong = NB_SAMPLES_PER_SNAPSHOT - sampleOffset_asLong;
835 836 //PRINTF2("sampleOffset_asLong = %lld, nbSamplesPart1_asLong = %lld\n", sampleOffset_asLong, nbSamplesPart1_asLong);
836 837
837 838 // (6) compute the final acquisition time
838 839 acquisitionTime_asLong = bufferAcquisitionTime_asLong +
839 840 sampleOffset_asLong * nbTicksPerSample_asLong;
840 841
841 842 // (7) copy the acquisition time at the beginning of the extrated snapshot
842 843 ptr1 = (unsigned char*) &acquisitionTime_asLong;
843 844 // fine time
844 845 ptr2 = (unsigned char*) &ring_node_swf_extracted->fineTime;
845 846 ptr2[2] = ptr1[ 4 + 2 ];
846 847 ptr2[3] = ptr1[ 5 + 2 ];
847 848 // coarse time
848 849 ptr2 = (unsigned char*) &ring_node_swf_extracted->coarseTime;
849 850 ptr2[0] = ptr1[ 0 + 2 ];
850 851 ptr2[1] = ptr1[ 1 + 2 ];
851 852 ptr2[2] = ptr1[ 2 + 2 ];
852 853 ptr2[3] = ptr1[ 3 + 2 ];
853 854
854 855 // re set the synchronization bit
855 856 timeCharPtr = (unsigned char*) &ring_node_to_send->coarseTime;
856 857 ptr2[0] = ptr2[0] | (timeCharPtr[0] & 0x80); // [1000 0000]
857 858
858 859 if ( (nbSamplesPart1_asLong >= NB_SAMPLES_PER_SNAPSHOT) | (nbSamplesPart1_asLong < 0) )
859 860 {
860 861 nbSamplesPart1_asLong = 0;
861 862 }
862 863 // copy the part 1 of the snapshot in the extracted buffer
863 864 for ( i = 0; i < (nbSamplesPart1_asLong * NB_WORDS_SWF_BLK); i++ )
864 865 {
865 866 swf_extracted[i] =
866 867 ((int*) ring_node_to_send->buffer_address)[ i + (sampleOffset_asLong * NB_WORDS_SWF_BLK) ];
867 868 }
868 869 // copy the part 2 of the snapshot in the extracted buffer
869 870 ring_node_to_send = ring_node_to_send->next;
870 871 for ( i = (nbSamplesPart1_asLong * NB_WORDS_SWF_BLK); i < (NB_SAMPLES_PER_SNAPSHOT * NB_WORDS_SWF_BLK); i++ )
871 872 {
872 873 swf_extracted[i] =
873 874 ((int*) ring_node_to_send->buffer_address)[ (i-(nbSamplesPart1_asLong * NB_WORDS_SWF_BLK)) ];
874 875 }
875 876 }
876 877
877 878 double computeCorrection( unsigned char *timePtr )
878 879 {
879 880 unsigned long long int acquisitionTime;
880 881 unsigned long long int centerTime;
881 882 unsigned long long int previousTick;
882 883 unsigned long long int nextTick;
883 884 unsigned long long int deltaPreviousTick;
884 885 unsigned long long int deltaNextTick;
885 886 double deltaPrevious_ms;
886 887 double deltaNext_ms;
887 888 double correctionInF2;
888 889
889 890 // get acquisition time in fine time ticks
890 891 acquisitionTime = get_acquisition_time( timePtr );
891 892
892 893 // compute center time
893 894 centerTime = acquisitionTime + 2731; // (2048. / 24576. / 2.) * 65536. = 2730.667;
894 895 previousTick = centerTime - (centerTime & 0xffff);
895 896 nextTick = previousTick + 65536;
896 897
897 898 deltaPreviousTick = centerTime - previousTick;
898 899 deltaNextTick = nextTick - centerTime;
899 900
900 901 deltaPrevious_ms = ((double) deltaPreviousTick) / 65536. * 1000.;
901 902 deltaNext_ms = ((double) deltaNextTick) / 65536. * 1000.;
902 903
903 904 PRINTF2(" delta previous = %.3f ms, delta next = %.2f ms\n", deltaPrevious_ms, deltaNext_ms);
904 905 // PRINTF2(" delta previous = %llu fine time ticks, delta next = %llu fine time ticks\n",
905 906 // deltaPreviousTick, deltaNextTick);
906 907
907 908 // which tick is the closest?
908 909 if (deltaPreviousTick > deltaNextTick)
909 910 {
910 911 // the snapshot center is just before the second => increase delta_snapshot
911 912 correctionInF2 = + (deltaNext_ms * 256. / 1000. );
912 913 }
913 914 else
914 915 {
915 916 // the snapshot center is just after the second => decrease delta_snapshot
916 917 correctionInF2 = - (deltaPrevious_ms * 256. / 1000. );
917 918 }
918 919
919 920 PRINTF1(" correctionInF2 = %.2f\n", correctionInF2);
920 921
921 922 return correctionInF2;
922 923 }
923 924
924 925 void applyCorrection( double correction )
925 926 {
926 927 int correctionInt;
927 928
928 929 if (correction>=0.)
929 930 {
930 931 if ( correction > 0.5 )
931 932 {
932 933 correctionInt = 1;
933 934 }
934 935 else
935 936 {
936 937 correctionInt = floor(correction);
937 938 }
938 939 }
939 940 else
940 941 {
941 942 if ( correction < -0.5)
942 943 {
943 944 correctionInt = -1;
944 945 }
945 946 else
946 947 {
947 948 correctionInt = ceil(correction);
948 949 }
949 950 }
950 951 waveform_picker_regs->delta_snapshot = waveform_picker_regs->delta_snapshot + correctionInt;
951 952 }
952 953
953 954 void snapshot_resynchronization( unsigned char *timePtr )
954 955 {
955 956 static double correction = 0.;
956 static resynchro_state state = MEASURE_0;
957 static resynchro_state state = MEASURE;
957 958
958 959 int correctionInt;
959 960
960 961 correctionInt = 0;
961 962
962 963 switch (state)
963 964 {
964 965
965 case MEASURE_0:
966 case MEASURE:
966 967 // ********
967 PRINTF("MEASURE_0 ===\n");
968 state = CORRECTION_0;
968 PRINTF("MEASURE ===\n");
969 state = CORRECTION;
969 970 correction = computeCorrection( timePtr );
970 PRINTF1("MEASURE_0 === correction = %.2f\n", correction );
971 PRINTF1("MEASURE === correction = %.2f\n", correction );
971 972 applyCorrection( correction );
972 PRINTF1("MEASURE_0 === delta_snapshot = %d\n", waveform_picker_regs->delta_snapshot);
973 PRINTF1("MEASURE === delta_snapshot = %d\n", waveform_picker_regs->delta_snapshot);
973 974 //****
974 975 break;
975 976
976 case CORRECTION_0:
977 case CORRECTION:
977 978 //************
978 PRINTF("CORRECTION_0 ===\n");
979 state = CORRECTION_1;
979 PRINTF("CORRECTION ===\n");
980 state = MEASURE;
980 981 computeCorrection( timePtr );
981 982 correction = -correction;
982 PRINTF1("CORRECTION_0 === correction = %.2f\n", correction );
983 PRINTF1("CORRECTION === correction = %.2f\n", correction );
983 984 applyCorrection( correction );
984 PRINTF1("CORRECTION_0 === delta_snapshot = %d\n", waveform_picker_regs->delta_snapshot);
985 //****
986 break;
987
988 case CORRECTION_1:
989 //************
990 PRINTF("CORRECTION_1 ===\n");
991 state = MEASURE_0;
992 computeCorrection( timePtr );
993 PRINTF1("CORRECTION_1 === delta_snapshot = %d\n", waveform_picker_regs->delta_snapshot);
985 PRINTF1("CORRECTION === delta_snapshot = %d\n", waveform_picker_regs->delta_snapshot);
994 986 //****
995 987 break;
996 988
997 989 default:
998 990 break;
999 991
1000 992 }
1001 993 }
1002 994
1003 995 //**************
1004 996 // wfp registers
1005 997 void reset_wfp_burst_enable( void )
1006 998 {
1007 999 /** This function resets the waveform picker burst_enable register.
1008 1000 *
1009 1001 * The burst bits [f2 f1 f0] and the enable bits [f3 f2 f1 f0] are set to 0.
1010 1002 *
1011 1003 */
1012 1004
1013 1005 // [1000 000] burst f2, f1, f0 enable f3, f2, f1, f0
1014 1006 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable & 0x80;
1015 1007 }
1016 1008
1017 1009 void reset_wfp_status( void )
1018 1010 {
1019 1011 /** This function resets the waveform picker status register.
1020 1012 *
1021 1013 * All status bits are set to 0 [new_err full_err full].
1022 1014 *
1023 1015 */
1024 1016
1025 1017 waveform_picker_regs->status = 0xffff;
1026 1018 }
1027 1019
1028 1020 void reset_wfp_buffer_addresses( void )
1029 1021 {
1030 1022 // F0
1031 1023 waveform_picker_regs->addr_data_f0_0 = current_ring_node_f0->previous->buffer_address; // 0x08
1032 1024 waveform_picker_regs->addr_data_f0_1 = current_ring_node_f0->buffer_address; // 0x0c
1033 1025 // F1
1034 1026 waveform_picker_regs->addr_data_f1_0 = current_ring_node_f1->previous->buffer_address; // 0x10
1035 1027 waveform_picker_regs->addr_data_f1_1 = current_ring_node_f1->buffer_address; // 0x14
1036 1028 // F2
1037 1029 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->previous->buffer_address; // 0x18
1038 1030 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address; // 0x1c
1039 1031 // F3
1040 1032 waveform_picker_regs->addr_data_f3_0 = current_ring_node_f3->previous->buffer_address; // 0x20
1041 1033 waveform_picker_regs->addr_data_f3_1 = current_ring_node_f3->buffer_address; // 0x24
1042 1034 }
1043 1035
1044 1036 void reset_waveform_picker_regs( void )
1045 1037 {
1046 1038 /** This function resets the waveform picker module registers.
1047 1039 *
1048 1040 * The registers affected by this function are located at the following offset addresses:
1049 1041 * - 0x00 data_shaping
1050 1042 * - 0x04 run_burst_enable
1051 1043 * - 0x08 addr_data_f0
1052 1044 * - 0x0C addr_data_f1
1053 1045 * - 0x10 addr_data_f2
1054 1046 * - 0x14 addr_data_f3
1055 1047 * - 0x18 status
1056 1048 * - 0x1C delta_snapshot
1057 1049 * - 0x20 delta_f0
1058 1050 * - 0x24 delta_f0_2
1059 1051 * - 0x28 delta_f1 (obsolet parameter)
1060 1052 * - 0x2c delta_f2
1061 1053 * - 0x30 nb_data_by_buffer
1062 1054 * - 0x34 nb_snapshot_param
1063 1055 * - 0x38 start_date
1064 1056 * - 0x3c nb_word_in_buffer
1065 1057 *
1066 1058 */
1067 1059
1068 1060 set_wfp_data_shaping(); // 0x00 *** R1 R0 SP1 SP0 BW
1069 1061
1070 1062 reset_wfp_burst_enable(); // 0x04 *** [run *** burst f2, f1, f0 *** enable f3, f2, f1, f0 ]
1071 1063
1072 1064 reset_wfp_buffer_addresses();
1073 1065
1074 1066 reset_wfp_status(); // 0x18
1075 1067
1076 1068 set_wfp_delta_snapshot(); // 0x1c *** 300 s => 0x12bff
1077 1069
1078 1070 set_wfp_delta_f0_f0_2(); // 0x20, 0x24
1079 1071
1080 1072 //the parameter delta_f1 [0x28] is not used anymore
1081 1073
1082 1074 set_wfp_delta_f2(); // 0x2c
1083 1075
1084 1076 DEBUG_PRINTF1("delta_snapshot %x\n", waveform_picker_regs->delta_snapshot);
1085 1077 DEBUG_PRINTF1("delta_f0 %x\n", waveform_picker_regs->delta_f0);
1086 1078 DEBUG_PRINTF1("delta_f0_2 %x\n", waveform_picker_regs->delta_f0_2);
1087 1079 DEBUG_PRINTF1("delta_f1 %x\n", waveform_picker_regs->delta_f1);
1088 1080 DEBUG_PRINTF1("delta_f2 %x\n", waveform_picker_regs->delta_f2);
1089 1081 // 2688 = 8 * 336
1090 1082 waveform_picker_regs->nb_data_by_buffer = 0xa7f; // 0x30 *** 2688 - 1 => nb samples -1
1091 1083 waveform_picker_regs->snapshot_param = 0xa80; // 0x34 *** 2688 => nb samples
1092 1084 waveform_picker_regs->start_date = 0x7fffffff; // 0x38
1093 1085 //
1094 1086 // coarse time and fine time registers are not initialized, they are volatile
1095 1087 //
1096 1088 waveform_picker_regs->buffer_length = 0x1f8;// buffer length in burst = 3 * 2688 / 16 = 504 = 0x1f8
1097 1089 }
1098 1090
1099 1091 void set_wfp_data_shaping( void )
1100 1092 {
1101 1093 /** This function sets the data_shaping register of the waveform picker module.
1102 1094 *
1103 1095 * The value is read from one field of the parameter_dump_packet structure:\n
1104 1096 * bw_sp0_sp1_r0_r1
1105 1097 *
1106 1098 */
1107 1099
1108 1100 unsigned char data_shaping;
1109 1101
1110 1102 // get the parameters for the data shaping [BW SP0 SP1 R0 R1] in sy_lfr_common1 and configure the register
1111 1103 // waveform picker : [R1 R0 SP1 SP0 BW]
1112 1104
1113 1105 data_shaping = parameter_dump_packet.sy_lfr_common_parameters;
1114 1106
1115 1107 waveform_picker_regs->data_shaping =
1116 1108 ( (data_shaping & 0x20) >> 5 ) // BW
1117 1109 + ( (data_shaping & 0x10) >> 3 ) // SP0
1118 1110 + ( (data_shaping & 0x08) >> 1 ) // SP1
1119 1111 + ( (data_shaping & 0x04) << 1 ) // R0
1120 1112 + ( (data_shaping & 0x02) << 3 ) // R1
1121 1113 + ( (data_shaping & 0x01) << 5 ); // R2
1122 1114 }
1123 1115
1124 1116 void set_wfp_burst_enable_register( unsigned char mode )
1125 1117 {
1126 1118 /** This function sets the waveform picker burst_enable register depending on the mode.
1127 1119 *
1128 1120 * @param mode is the LFR mode to launch.
1129 1121 *
1130 1122 * The burst bits shall be before the enable bits.
1131 1123 *
1132 1124 */
1133 1125
1134 1126 // [0000 0000] burst f2, f1, f0 enable f3 f2 f1 f0
1135 1127 // the burst bits shall be set first, before the enable bits
1136 1128 switch(mode) {
1137 1129 case LFR_MODE_NORMAL:
1138 1130 case LFR_MODE_SBM1:
1139 1131 case LFR_MODE_SBM2:
1140 1132 waveform_picker_regs->run_burst_enable = 0x60; // [0110 0000] enable f2 and f1 burst
1141 1133 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x0f; // [1111] enable f3 f2 f1 f0
1142 1134 break;
1143 1135 case LFR_MODE_BURST:
1144 1136 waveform_picker_regs->run_burst_enable = 0x40; // [0100 0000] f2 burst enabled
1145 1137 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x0c; // [1100] enable f3 and f2
1146 1138 break;
1147 1139 default:
1148 1140 waveform_picker_regs->run_burst_enable = 0x00; // [0000 0000] no burst enabled, no waveform enabled
1149 1141 break;
1150 1142 }
1151 1143 }
1152 1144
1153 1145 void set_wfp_delta_snapshot( void )
1154 1146 {
1155 1147 /** This function sets the delta_snapshot register of the waveform picker module.
1156 1148 *
1157 1149 * The value is read from two (unsigned char) of the parameter_dump_packet structure:
1158 1150 * - sy_lfr_n_swf_p[0]
1159 1151 * - sy_lfr_n_swf_p[1]
1160 1152 *
1161 1153 */
1162 1154
1163 1155 unsigned int delta_snapshot;
1164 1156 unsigned int delta_snapshot_in_T2;
1165 1157
1166 1158 delta_snapshot = parameter_dump_packet.sy_lfr_n_swf_p[0]*256
1167 1159 + parameter_dump_packet.sy_lfr_n_swf_p[1];
1168 1160
1169 1161 delta_snapshot_in_T2 = delta_snapshot * 256;
1170 1162 waveform_picker_regs->delta_snapshot = delta_snapshot_in_T2 - 1; // max 4 bytes
1171 1163 }
1172 1164
1173 1165 void set_wfp_delta_f0_f0_2( void )
1174 1166 {
1175 1167 unsigned int delta_snapshot;
1176 1168 unsigned int nb_samples_per_snapshot;
1177 1169 float delta_f0_in_float;
1178 1170
1179 1171 delta_snapshot = waveform_picker_regs->delta_snapshot;
1180 1172 nb_samples_per_snapshot = parameter_dump_packet.sy_lfr_n_swf_l[0] * 256 + parameter_dump_packet.sy_lfr_n_swf_l[1];
1181 1173 delta_f0_in_float = nb_samples_per_snapshot / 2. * ( 1. / 256. - 1. / 24576.) * 256.;
1182 1174
1183 1175 waveform_picker_regs->delta_f0 = delta_snapshot - floor( delta_f0_in_float );
1184 1176 waveform_picker_regs->delta_f0_2 = 0x30; // 48 = 11 0000, max 7 bits
1185 1177 }
1186 1178
1187 1179 void set_wfp_delta_f1( void )
1188 1180 {
1189 1181 /** Sets the value of the delta_f1 parameter
1190 1182 *
1191 1183 * @param void
1192 1184 *
1193 1185 * @return void
1194 1186 *
1195 1187 * delta_f1 is not used, the snapshots are extracted from CWF_F1 waveforms.
1196 1188 *
1197 1189 */
1198 1190
1199 1191 unsigned int delta_snapshot;
1200 1192 unsigned int nb_samples_per_snapshot;
1201 1193 float delta_f1_in_float;
1202 1194
1203 1195 delta_snapshot = waveform_picker_regs->delta_snapshot;
1204 1196 nb_samples_per_snapshot = parameter_dump_packet.sy_lfr_n_swf_l[0] * 256 + parameter_dump_packet.sy_lfr_n_swf_l[1];
1205 1197 delta_f1_in_float = nb_samples_per_snapshot / 2. * ( 1. / 256. - 1. / 4096.) * 256.;
1206 1198
1207 1199 waveform_picker_regs->delta_f1 = delta_snapshot - floor( delta_f1_in_float );
1208 1200 }
1209 1201
1210 1202 void set_wfp_delta_f2( void ) // parameter not used, only delta_f0 and delta_f0_2 are used
1211 1203 {
1212 1204 /** Sets the value of the delta_f2 parameter
1213 1205 *
1214 1206 * @param void
1215 1207 *
1216 1208 * @return void
1217 1209 *
1218 1210 * delta_f2 is used only for the first snapshot generation, even when the snapshots are extracted from CWF_F2
1219 1211 * waveforms (see lpp_waveform_snapshot_controler.vhd for details).
1220 1212 *
1221 1213 */
1222 1214
1223 1215 unsigned int delta_snapshot;
1224 1216 unsigned int nb_samples_per_snapshot;
1225 1217
1226 1218 delta_snapshot = waveform_picker_regs->delta_snapshot;
1227 1219 nb_samples_per_snapshot = parameter_dump_packet.sy_lfr_n_swf_l[0] * 256 + parameter_dump_packet.sy_lfr_n_swf_l[1];
1228 1220
1229 1221 waveform_picker_regs->delta_f2 = delta_snapshot - nb_samples_per_snapshot / 2 - 1;
1230 1222 }
1231 1223
1232 1224 //*****************
1233 1225 // local parameters
1234 1226
1235 1227 void increment_seq_counter_source_id( unsigned char *packet_sequence_control, unsigned int sid )
1236 1228 {
1237 1229 /** This function increments the parameter "sequence_cnt" depending on the sid passed in argument.
1238 1230 *
1239 1231 * @param packet_sequence_control is a pointer toward the parameter sequence_cnt to update.
1240 1232 * @param sid is the source identifier of the packet being updated.
1241 1233 *
1242 1234 * REQ-LFR-SRS-5240 / SSS-CP-FS-590
1243 1235 * The sequence counters shall wrap around from 2^14 to zero.
1244 1236 * The sequence counter shall start at zero at startup.
1245 1237 *
1246 1238 * REQ-LFR-SRS-5239 / SSS-CP-FS-580
1247 1239 * All TM_LFR_SCIENCE_ packets are sent to ground, i.e. destination id = 0
1248 1240 *
1249 1241 */
1250 1242
1251 1243 unsigned short *sequence_cnt;
1252 1244 unsigned short segmentation_grouping_flag;
1253 1245 unsigned short new_packet_sequence_control;
1254 1246 rtems_mode initial_mode_set;
1255 1247 rtems_mode current_mode_set;
1256 1248 rtems_status_code status;
1257 1249
1258 1250 //******************************************
1259 1251 // CHANGE THE MODE OF THE CALLING RTEMS TASK
1260 1252 status = rtems_task_mode( RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &initial_mode_set );
1261 1253
1262 1254 if ( (sid == SID_NORM_SWF_F0) || (sid == SID_NORM_SWF_F1) || (sid == SID_NORM_SWF_F2)
1263 1255 || (sid == SID_NORM_CWF_F3) || (sid == SID_NORM_CWF_LONG_F3)
1264 1256 || (sid == SID_BURST_CWF_F2)
1265 1257 || (sid == SID_NORM_ASM_F0) || (sid == SID_NORM_ASM_F1) || (sid == SID_NORM_ASM_F2)
1266 1258 || (sid == SID_NORM_BP1_F0) || (sid == SID_NORM_BP1_F1) || (sid == SID_NORM_BP1_F2)
1267 1259 || (sid == SID_NORM_BP2_F0) || (sid == SID_NORM_BP2_F1) || (sid == SID_NORM_BP2_F2)
1268 1260 || (sid == SID_BURST_BP1_F0) || (sid == SID_BURST_BP2_F0)
1269 1261 || (sid == SID_BURST_BP1_F1) || (sid == SID_BURST_BP2_F1) )
1270 1262 {
1271 1263 sequence_cnt = (unsigned short *) &sequenceCounters_SCIENCE_NORMAL_BURST;
1272 1264 }
1273 1265 else if ( (sid ==SID_SBM1_CWF_F1) || (sid ==SID_SBM2_CWF_F2)
1274 1266 || (sid == SID_SBM1_BP1_F0) || (sid == SID_SBM1_BP2_F0)
1275 1267 || (sid == SID_SBM2_BP1_F0) || (sid == SID_SBM2_BP2_F0)
1276 1268 || (sid == SID_SBM2_BP1_F1) || (sid == SID_SBM2_BP2_F1) )
1277 1269 {
1278 1270 sequence_cnt = (unsigned short *) &sequenceCounters_SCIENCE_SBM1_SBM2;
1279 1271 }
1280 1272 else
1281 1273 {
1282 1274 sequence_cnt = (unsigned short *) NULL;
1283 1275 PRINTF1("in increment_seq_counter_source_id *** ERR apid_destid %d not known\n", sid)
1284 1276 }
1285 1277
1286 1278 if (sequence_cnt != NULL)
1287 1279 {
1288 1280 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << 8;
1289 1281 *sequence_cnt = (*sequence_cnt) & 0x3fff;
1290 1282
1291 1283 new_packet_sequence_control = segmentation_grouping_flag | (*sequence_cnt) ;
1292 1284
1293 1285 packet_sequence_control[0] = (unsigned char) (new_packet_sequence_control >> 8);
1294 1286 packet_sequence_control[1] = (unsigned char) (new_packet_sequence_control );
1295 1287
1296 1288 // increment the sequence counter
1297 1289 if ( *sequence_cnt < SEQ_CNT_MAX)
1298 1290 {
1299 1291 *sequence_cnt = *sequence_cnt + 1;
1300 1292 }
1301 1293 else
1302 1294 {
1303 1295 *sequence_cnt = 0;
1304 1296 }
1305 1297 }
1306 1298
1307 1299 //*************************************
1308 1300 // RESTORE THE MODE OF THE CALLING TASK
1309 1301 status = rtems_task_mode( initial_mode_set, RTEMS_PREEMPT_MASK, &current_mode_set );
1310 1302 }
General Comments 0
You need to be logged in to leave comments. Login now