##// END OF EJS Templates
bug 456 pa_bia_status_info byte is updated upon the reception of...
paul -
r224:9a302da28d79 R3
parent child
Show More
@@ -1,2 +1,2
1 1 3081d1f9bb20b2b64a192585337a292a9804e0c5 LFR_basic-parameters
2 bb9afa759d57093f7646d3be18f4a9923a4cbf84 header/lfr_common_headers
2 a0ca246cc2057880086d028aab3cf35be244efbc header/lfr_common_headers
@@ -1,113 +1,113
1 1 TEMPLATE = app
2 2 # CONFIG += console v8 sim
3 3 # CONFIG options = verbose *** boot_messages *** debug_messages *** cpu_usage_report *** stack_report *** vhdl_dev *** debug_tch
4 4 # lpp_dpu_destid
5 CONFIG += console verbose lpp_dpu_destid
5 CONFIG += console verbose lpp_dpu_destid stack_report
6 6 CONFIG -= qt
7 7
8 8 include(./sparc.pri)
9 9
10 10 # flight software version
11 11 SWVERSION=-1-0
12 12 DEFINES += SW_VERSION_N1=3 # major
13 13 DEFINES += SW_VERSION_N2=0 # minor
14 14 DEFINES += SW_VERSION_N3=0 # patch
15 15 DEFINES += SW_VERSION_N4=9 # internal
16 16
17 17 # <GCOV>
18 18 #QMAKE_CFLAGS_RELEASE += -fprofile-arcs -ftest-coverage
19 19 #LIBS += -lgcov /opt/GCOV/01A/lib/overload.o -lc
20 20 #LIBS += -lgcov /opt/GCOV/HOWTO_gcov_for_lfr_test/01A/lib/overload.o -lc
21 21 # </GCOV>
22 22
23 23 # <CHANGE BEFORE FLIGHT>
24 24 contains( CONFIG, lpp_dpu_destid ) {
25 25 DEFINES += LPP_DPU_DESTID
26 26 }
27 27 # </CHANGE BEFORE FLIGHT>
28 28
29 29 contains( CONFIG, debug_tch ) {
30 30 DEFINES += DEBUG_TCH
31 31 }
32 32 DEFINES += MSB_FIRST_TCH
33 33
34 34 contains( CONFIG, vhdl_dev ) {
35 35 DEFINES += VHDL_DEV
36 36 }
37 37
38 38 contains( CONFIG, verbose ) {
39 39 DEFINES += PRINT_MESSAGES_ON_CONSOLE
40 40 }
41 41
42 42 contains( CONFIG, debug_messages ) {
43 43 DEFINES += DEBUG_MESSAGES
44 44 }
45 45
46 46 contains( CONFIG, cpu_usage_report ) {
47 47 DEFINES += PRINT_TASK_STATISTICS
48 48 }
49 49
50 50 contains( CONFIG, stack_report ) {
51 51 DEFINES += PRINT_STACK_REPORT
52 52 }
53 53
54 54 contains( CONFIG, boot_messages ) {
55 55 DEFINES += BOOT_MESSAGES
56 56 }
57 57
58 58 #doxygen.target = doxygen
59 59 #doxygen.commands = doxygen ../doc/Doxyfile
60 60 #QMAKE_EXTRA_TARGETS += doxygen
61 61
62 62 TARGET = fsw
63 63
64 64 INCLUDEPATH += \
65 65 $${PWD}/../src \
66 66 $${PWD}/../header \
67 67 $${PWD}/../header/lfr_common_headers \
68 68 $${PWD}/../header/processing \
69 69 $${PWD}/../LFR_basic-parameters
70 70
71 71 SOURCES += \
72 72 ../src/wf_handler.c \
73 73 ../src/tc_handler.c \
74 74 ../src/fsw_misc.c \
75 75 ../src/fsw_init.c \
76 76 ../src/fsw_globals.c \
77 77 ../src/fsw_spacewire.c \
78 78 ../src/tc_load_dump_parameters.c \
79 79 ../src/tm_lfr_tc_exe.c \
80 80 ../src/tc_acceptance.c \
81 81 ../src/processing/fsw_processing.c \
82 82 ../src/processing/avf0_prc0.c \
83 83 ../src/processing/avf1_prc1.c \
84 84 ../src/processing/avf2_prc2.c \
85 85 ../src/lfr_cpu_usage_report.c \
86 86 ../LFR_basic-parameters/basic_parameters.c
87 87
88 88 HEADERS += \
89 89 ../header/wf_handler.h \
90 90 ../header/tc_handler.h \
91 91 ../header/grlib_regs.h \
92 92 ../header/fsw_misc.h \
93 93 ../header/fsw_init.h \
94 94 ../header/fsw_spacewire.h \
95 95 ../header/tc_load_dump_parameters.h \
96 96 ../header/tm_lfr_tc_exe.h \
97 97 ../header/tc_acceptance.h \
98 98 ../header/processing/fsw_processing.h \
99 99 ../header/processing/avf0_prc0.h \
100 100 ../header/processing/avf1_prc1.h \
101 101 ../header/processing/avf2_prc2.h \
102 102 ../header/fsw_params_wf_handler.h \
103 103 ../header/lfr_cpu_usage_report.h \
104 104 ../header/lfr_common_headers/ccsds_types.h \
105 105 ../header/lfr_common_headers/fsw_params.h \
106 106 ../header/lfr_common_headers/fsw_params_nb_bytes.h \
107 107 ../header/lfr_common_headers/fsw_params_processing.h \
108 108 ../header/lfr_common_headers/TC_types.h \
109 109 ../header/lfr_common_headers/tm_byte_positions.h \
110 110 ../LFR_basic-parameters/basic_parameters.h \
111 111 ../LFR_basic-parameters/basic_parameters_params.h \
112 112 ../header/GscMemoryLPP.hpp
113 113
@@ -1,50 +1,51
1 1 #ifndef FSW_INIT_H_INCLUDED
2 2 #define FSW_INIT_H_INCLUDED
3 3
4 4 #include <rtems.h>
5 5 #include <leon.h>
6 6
7 7 #include "fsw_params.h"
8 8 #include "fsw_misc.h"
9 9 #include "fsw_processing.h"
10 10
11 11 #include "tc_handler.h"
12 12 #include "wf_handler.h"
13 13 #include "fsw_spacewire.h"
14 14
15 15 #include "avf0_prc0.h"
16 16 #include "avf1_prc1.h"
17 17 #include "avf2_prc2.h"
18 18
19 19 extern rtems_name Task_name[20]; /* array of task names */
20 20 extern rtems_id Task_id[20]; /* array of task ids */
21 extern unsigned char pa_bia_status_info;
21 22
22 23 // RTEMS TASKS
23 24 rtems_task Init( rtems_task_argument argument);
24 25
25 26 // OTHER functions
26 27 void create_names( void );
27 28 int create_all_tasks( void );
28 29 int start_all_tasks( void );
29 30 //
30 31 rtems_status_code create_message_queues( void );
31 32 rtems_status_code get_message_queue_id_send( rtems_id *queue_id );
32 33 rtems_status_code get_message_queue_id_recv( rtems_id *queue_id );
33 34 rtems_status_code get_message_queue_id_prc0( rtems_id *queue_id );
34 35 rtems_status_code get_message_queue_id_prc1( rtems_id *queue_id );
35 36 rtems_status_code get_message_queue_id_prc2( rtems_id *queue_id );
36 37 void update_queue_max_count( rtems_id queue_id, unsigned char*fifo_size_max );
37 38 void init_ring(ring_node ring[], unsigned char nbNodes, volatile int buffer[], unsigned int bufferSize );
38 39 //
39 40 int start_recv_send_tasks( void );
40 41 //
41 42 void init_local_mode_parameters( void );
42 43 void reset_local_time( void );
43 44
44 45 extern void rtems_cpu_usage_report( void );
45 46 extern void rtems_cpu_usage_reset( void );
46 47 extern void rtems_stack_checker_report_usage( void );
47 48
48 49 extern int sched_yield( void );
49 50
50 51 #endif // FSW_INIT_H_INCLUDED
@@ -1,57 +1,58
1 1 #ifndef FSW_MISC_H_INCLUDED
2 2 #define FSW_MISC_H_INCLUDED
3 3
4 4 #include <rtems.h>
5 5 #include <stdio.h>
6 6 #include <grspw.h>
7 7 #include <grlib_regs.h>
8 8
9 9 #include "fsw_params.h"
10 10 #include "fsw_spacewire.h"
11 11 #include "lfr_cpu_usage_report.h"
12 12
13 13 rtems_name name_hk_rate_monotonic; // name of the HK rate monotonic
14 14 rtems_id HK_id; // id of the HK rate monotonic period
15 15
16 16 void configure_timer(gptimer_regs_t *gptimer_regs, unsigned char timer, unsigned int clock_divider,
17 17 unsigned char interrupt_level, rtems_isr (*timer_isr)() );
18 18 void timer_start( gptimer_regs_t *gptimer_regs, unsigned char timer );
19 19 void timer_stop( gptimer_regs_t *gptimer_regs, unsigned char timer );
20 20 void timer_set_clock_divider(gptimer_regs_t *gptimer_regs, unsigned char timer, unsigned int clock_divider);
21 21
22 22 // SERIAL LINK
23 23 int send_console_outputs_on_apbuart_port( void );
24 24 int enable_apbuart_transmitter( void );
25 25 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value);
26 26
27 27 // RTEMS TASKS
28 28 rtems_task stat_task( rtems_task_argument argument );
29 29 rtems_task hous_task( rtems_task_argument argument );
30 30 rtems_task dumb_task( rtems_task_argument unused );
31 31
32 32 void init_housekeeping_parameters( void );
33 33 void increment_seq_counter(unsigned short *packetSequenceControl);
34 34 void getTime( unsigned char *time);
35 35 unsigned long long int getTimeAsUnsignedLongLongInt( );
36 36 void send_dumb_hk( void );
37 37 void get_temperatures( unsigned char *temperatures );
38 38 void get_v_e1_e2_f3( unsigned char *spacecraft_potential );
39 39 void get_cpu_load( unsigned char *resource_statistics );
40 40 void set_hk_lfr_sc_potential_flag( bool state );
41 void set_hk_lfr_mag_fields_flag( bool state );
41 42 void set_hk_lfr_calib_enable( bool state );
42 43
43 44
44 45 extern int sched_yield( void );
45 46 extern void rtems_cpu_usage_reset();
46 47 extern ring_node *current_ring_node_f3;
47 48 extern ring_node *ring_node_to_send_cwf_f3;
48 49 extern ring_node waveform_ring_f3[];
49 50 extern unsigned short sequenceCounterHK;
50 51
51 52 extern unsigned char hk_lfr_q_sd_fifo_size_max;
52 53 extern unsigned char hk_lfr_q_rv_fifo_size_max;
53 54 extern unsigned char hk_lfr_q_p0_fifo_size_max;
54 55 extern unsigned char hk_lfr_q_p1_fifo_size_max;
55 56 extern unsigned char hk_lfr_q_p2_fifo_size_max;
56 57
57 58 #endif // FSW_MISC_H_INCLUDED
@@ -1,78 +1,79
1 1 /** Global variables of the LFR flight software.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * Among global variables, there are:
7 7 * - RTEMS names and id.
8 8 * - APB configuration registers.
9 9 * - waveforms global buffers, used by the waveform picker hardware module to store data.
10 10 * - spectral matrices buffesr, used by the hardware module to store data.
11 11 * - variable related to LFR modes parameters.
12 12 * - the global HK packet buffer.
13 13 * - the global dump parameter buffer.
14 14 *
15 15 */
16 16
17 17 #include <rtems.h>
18 18 #include <grspw.h>
19 19
20 20 #include "ccsds_types.h"
21 21 #include "grlib_regs.h"
22 22 #include "fsw_params.h"
23 23 #include "fsw_params_wf_handler.h"
24 24
25 25 // RTEMS GLOBAL VARIABLES
26 26 rtems_name misc_name[5];
27 27 rtems_name Task_name[20]; /* array of task names */
28 28 rtems_id Task_id[20]; /* array of task ids */
29 29 int fdSPW = 0;
30 30 int fdUART = 0;
31 31 unsigned char lfrCurrentMode;
32 unsigned char pa_bia_status_info;
32 33
33 34 // WAVEFORMS GLOBAL VARIABLES // 2048 * 3 * 4 + 2 * 4 = 24576 + 8 bytes = 24584
34 35 // 97 * 256 = 24832 => delta = 248 bytes = 62 words
35 36 // WAVEFORMS GLOBAL VARIABLES // 2688 * 3 * 4 + 2 * 4 = 32256 + 8 bytes = 32264
36 37 // 127 * 256 = 32512 => delta = 248 bytes = 62 words
37 38 // F0 F1 F2 F3
38 39 volatile int wf_buffer_f0[ NB_RING_NODES_F0 * WFRM_BUFFER ] __attribute__((aligned(0x100)));
39 40 volatile int wf_buffer_f1[ NB_RING_NODES_F1 * WFRM_BUFFER ] __attribute__((aligned(0x100)));
40 41 volatile int wf_buffer_f2[ NB_RING_NODES_F2 * WFRM_BUFFER ] __attribute__((aligned(0x100)));
41 42 volatile int wf_buffer_f3[ NB_RING_NODES_F3 * WFRM_BUFFER ] __attribute__((aligned(0x100)));
42 43
43 44 //***********************************
44 45 // SPECTRAL MATRICES GLOBAL VARIABLES
45 46
46 47 // alignment constraints for the spectral matrices buffers => the first data after the time (8 bytes) shall be aligned on 0x00
47 48 volatile int sm_f0[ NB_RING_NODES_SM_F0 * TOTAL_SIZE_SM ] __attribute__((aligned(0x100)));
48 49 volatile int sm_f1[ NB_RING_NODES_SM_F1 * TOTAL_SIZE_SM ] __attribute__((aligned(0x100)));
49 50 volatile int sm_f2[ NB_RING_NODES_SM_F2 * TOTAL_SIZE_SM ] __attribute__((aligned(0x100)));
50 51
51 52 // APB CONFIGURATION REGISTERS
52 53 time_management_regs_t *time_management_regs = (time_management_regs_t*) REGS_ADDR_TIME_MANAGEMENT;
53 54 gptimer_regs_t *gptimer_regs = (gptimer_regs_t *) REGS_ADDR_GPTIMER;
54 55 waveform_picker_regs_0_1_18_t *waveform_picker_regs = (waveform_picker_regs_0_1_18_t*) REGS_ADDR_WAVEFORM_PICKER;
55 56 spectral_matrix_regs_t *spectral_matrix_regs = (spectral_matrix_regs_t*) REGS_ADDR_SPECTRAL_MATRIX;
56 57
57 58 // MODE PARAMETERS
58 59 Packet_TM_LFR_PARAMETER_DUMP_t parameter_dump_packet;
59 60 struct param_local_str param_local;
60 61
61 62 // HK PACKETS
62 63 Packet_TM_LFR_HK_t housekeeping_packet;
63 64 // message queues occupancy
64 65 unsigned char hk_lfr_q_sd_fifo_size_max;
65 66 unsigned char hk_lfr_q_rv_fifo_size_max;
66 67 unsigned char hk_lfr_q_p0_fifo_size_max;
67 68 unsigned char hk_lfr_q_p1_fifo_size_max;
68 69 unsigned char hk_lfr_q_p2_fifo_size_max;
69 70 // sequence counters are incremented by APID (PID + CAT) and destination ID
70 71 unsigned short sequenceCounters_SCIENCE_NORMAL_BURST;
71 72 unsigned short sequenceCounters_SCIENCE_SBM1_SBM2;
72 73 unsigned short sequenceCounters_TC_EXE[SEQ_CNT_NB_DEST_ID];
73 74 unsigned short sequenceCounterHK;
74 75 unsigned short sequenceCounterParameterDump;
75 76 spw_stats spacewire_stats;
76 77 spw_stats spacewire_stats_backup;
77 78
78 79
@@ -1,869 +1,872
1 1 /** This is the RTEMS initialization module.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * This module contains two very different information:
7 7 * - specific instructions to configure the compilation of the RTEMS executive
8 8 * - functions related to the fligth softwre initialization, especially the INIT RTEMS task
9 9 *
10 10 */
11 11
12 12 //*************************
13 13 // GPL reminder to be added
14 14 //*************************
15 15
16 16 #include <rtems.h>
17 17
18 18 /* configuration information */
19 19
20 20 #define CONFIGURE_INIT
21 21
22 22 #include <bsp.h> /* for device driver prototypes */
23 23
24 24 /* configuration information */
25 25
26 26 #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
27 27 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
28 28
29 29 #define CONFIGURE_MAXIMUM_TASKS 20
30 30 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
31 31 #define CONFIGURE_EXTRA_TASK_STACKS (3 * RTEMS_MINIMUM_STACK_SIZE)
32 32 #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
33 33 #define CONFIGURE_INIT_TASK_PRIORITY 1 // instead of 100
34 34 #define CONFIGURE_INIT_TASK_MODE (RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT)
35 35 #define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT)
36 36 #define CONFIGURE_MAXIMUM_DRIVERS 16
37 37 #define CONFIGURE_MAXIMUM_PERIODS 5
38 38 #define CONFIGURE_MAXIMUM_TIMERS 5 // STAT (1s), send SWF (0.3s), send CWF3 (1s)
39 39 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 5
40 40 #ifdef PRINT_STACK_REPORT
41 41 #define CONFIGURE_STACK_CHECKER_ENABLED
42 42 #endif
43 43
44 44 #include <rtems/confdefs.h>
45 45
46 46 /* If --drvmgr was enabled during the configuration of the RTEMS kernel */
47 47 #ifdef RTEMS_DRVMGR_STARTUP
48 48 #ifdef LEON3
49 49 /* Add Timer and UART Driver */
50 50 #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
51 51 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GPTIMER
52 52 #endif
53 53 #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
54 54 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_APBUART
55 55 #endif
56 56 #endif
57 57 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GRSPW /* GRSPW Driver */
58 58 #include <drvmgr/drvmgr_confdefs.h>
59 59 #endif
60 60
61 61 #include "fsw_init.h"
62 62 #include "fsw_config.c"
63 63 #include "GscMemoryLPP.hpp"
64 64
65 65 void initCache()
66 66 {
67 67 unsigned int cacheControlRegister;
68 68
69 69 cacheControlRegister = getCacheControlRegister();
70 70 printf("(0) cacheControlRegister = %x\n", cacheControlRegister);
71 71
72 72 resetCacheControlRegister();
73 73
74 74 enableInstructionCache();
75 75 enableDataCache();
76 76 enableInstructionBurstFetch();
77 77
78 78 cacheControlRegister = getCacheControlRegister();
79 79 printf("(1) cacheControlRegister = %x\n", cacheControlRegister);
80 80 }
81 81
82 82 rtems_task Init( rtems_task_argument ignored )
83 83 {
84 84 /** This is the RTEMS INIT taks, it is the first task launched by the system.
85 85 *
86 86 * @param unused is the starting argument of the RTEMS task
87 87 *
88 88 * The INIT task create and run all other RTEMS tasks.
89 89 *
90 90 */
91 91
92 92 //***********
93 93 // INIT CACHE
94 94
95 95 unsigned char *vhdlVersion;
96 96
97 97 reset_lfr();
98 98
99 99 reset_local_time();
100 100
101 101 rtems_cpu_usage_reset();
102 102
103 103 rtems_status_code status;
104 104 rtems_status_code status_spw;
105 105 rtems_isr_entry old_isr_handler;
106 106
107 107 // UART settings
108 108 send_console_outputs_on_apbuart_port();
109 109 set_apbuart_scaler_reload_register(REGS_ADDR_APBUART, APBUART_SCALER_RELOAD_VALUE);
110 110 enable_apbuart_transmitter();
111 111
112 112 DEBUG_PRINTF("\n\n\n\n\nIn INIT *** Now the console is on port COM1\n")
113 113
114 114
115 115 PRINTF("\n\n\n\n\n")
116 116
117 117 initCache();
118 118
119 119 PRINTF("*************************\n")
120 120 PRINTF("** LFR Flight Software **\n")
121 121 PRINTF1("** %d.", SW_VERSION_N1)
122 122 PRINTF1("%d." , SW_VERSION_N2)
123 123 PRINTF1("%d." , SW_VERSION_N3)
124 124 PRINTF1("%d **\n", SW_VERSION_N4)
125 125
126 126 vhdlVersion = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
127 127 PRINTF("** VHDL **\n")
128 128 PRINTF1("** %d.", vhdlVersion[1])
129 129 PRINTF1("%d." , vhdlVersion[2])
130 130 PRINTF1("%d **\n", vhdlVersion[3])
131 131 PRINTF("*************************\n")
132 132 PRINTF("\n\n")
133 133
134 134 init_parameter_dump();
135 135 init_kcoefficients_dump();
136 136 init_local_mode_parameters();
137 137 init_housekeeping_parameters();
138 138 init_k_coefficients_prc0();
139 139 init_k_coefficients_prc1();
140 140 init_k_coefficients_prc2();
141 pa_bia_status_info = 0x00;
141 142
142 143 // waveform picker initialization
143 144 WFP_init_rings(); // initialize the waveform rings
144 145 WFP_reset_current_ring_nodes();
145 146 reset_waveform_picker_regs();
146 147
147 148 // spectral matrices initialization
148 149 SM_init_rings(); // initialize spectral matrices rings
149 150 SM_reset_current_ring_nodes();
150 151 reset_spectral_matrix_regs();
151 152
152 153 // configure calibration
153 154 configureCalibration( false ); // true means interleaved mode, false is for normal mode
154 155
155 156 updateLFRCurrentMode();
156 157
157 158 BOOT_PRINTF1("in INIT *** lfrCurrentMode is %d\n", lfrCurrentMode)
158 159
159 160 create_names(); // create all names
160 161
161 162 status = create_message_queues(); // create message queues
162 163 if (status != RTEMS_SUCCESSFUL)
163 164 {
164 165 PRINTF1("in INIT *** ERR in create_message_queues, code %d", status)
165 166 }
166 167
167 168 status = create_all_tasks(); // create all tasks
168 169 if (status != RTEMS_SUCCESSFUL)
169 170 {
170 171 PRINTF1("in INIT *** ERR in create_all_tasks, code %d\n", status)
171 172 }
172 173
173 174 // **************************
174 175 // <SPACEWIRE INITIALIZATION>
175 176 grspw_timecode_callback = &timecode_irq_handler;
176 177
177 178 status_spw = spacewire_open_link(); // (1) open the link
178 179 if ( status_spw != RTEMS_SUCCESSFUL )
179 180 {
180 181 PRINTF1("in INIT *** ERR spacewire_open_link code %d\n", status_spw )
181 182 }
182 183
183 184 if ( status_spw == RTEMS_SUCCESSFUL ) // (2) configure the link
184 185 {
185 186 status_spw = spacewire_configure_link( fdSPW );
186 187 if ( status_spw != RTEMS_SUCCESSFUL )
187 188 {
188 189 PRINTF1("in INIT *** ERR spacewire_configure_link code %d\n", status_spw )
189 190 }
190 191 }
191 192
192 193 if ( status_spw == RTEMS_SUCCESSFUL) // (3) start the link
193 194 {
194 195 status_spw = spacewire_start_link( fdSPW );
195 196 if ( status_spw != RTEMS_SUCCESSFUL )
196 197 {
197 198 PRINTF1("in INIT *** ERR spacewire_start_link code %d\n", status_spw )
198 199 }
199 200 }
200 201 // </SPACEWIRE INITIALIZATION>
201 202 // ***************************
202 203
203 204 status = start_all_tasks(); // start all tasks
204 205 if (status != RTEMS_SUCCESSFUL)
205 206 {
206 207 PRINTF1("in INIT *** ERR in start_all_tasks, code %d", status)
207 208 }
208 209
209 210 // start RECV and SEND *AFTER* SpaceWire Initialization, due to the timeout of the start call during the initialization
210 211 status = start_recv_send_tasks();
211 212 if ( status != RTEMS_SUCCESSFUL )
212 213 {
213 214 PRINTF1("in INIT *** ERR start_recv_send_tasks code %d\n", status )
214 215 }
215 216
216 217 // suspend science tasks, they will be restarted later depending on the mode
217 218 status = suspend_science_tasks(); // suspend science tasks (not done in stop_current_mode if current mode = STANDBY)
218 219 if (status != RTEMS_SUCCESSFUL)
219 220 {
220 221 PRINTF1("in INIT *** in suspend_science_tasks *** ERR code: %d\n", status)
221 222 }
222 223
223 224 //******************************
224 225 // <SPECTRAL MATRICES SIMULATOR>
225 226 LEON_Mask_interrupt( IRQ_SM_SIMULATOR );
226 227 configure_timer((gptimer_regs_t*) REGS_ADDR_GPTIMER, TIMER_SM_SIMULATOR, CLKDIV_SM_SIMULATOR,
227 228 IRQ_SPARC_SM_SIMULATOR, spectral_matrices_isr_simu );
228 229 // </SPECTRAL MATRICES SIMULATOR>
229 230 //*******************************
230 231
231 232 // configure IRQ handling for the waveform picker unit
232 233 status = rtems_interrupt_catch( waveforms_isr,
233 234 IRQ_SPARC_WAVEFORM_PICKER,
234 235 &old_isr_handler) ;
235 236 // configure IRQ handling for the spectral matrices unit
236 237 status = rtems_interrupt_catch( spectral_matrices_isr,
237 238 IRQ_SPARC_SPECTRAL_MATRIX,
238 239 &old_isr_handler) ;
239 240
240 241 // if the spacewire link is not up then send an event to the SPIQ task for link recovery
241 242 if ( status_spw != RTEMS_SUCCESSFUL )
242 243 {
243 244 status = rtems_event_send( Task_id[TASKID_SPIQ], SPW_LINKERR_EVENT );
244 245 if ( status != RTEMS_SUCCESSFUL ) {
245 246 PRINTF1("in INIT *** ERR rtems_event_send to SPIQ code %d\n", status )
246 247 }
247 248 }
248 249
249 250 BOOT_PRINTF("delete INIT\n")
250 251
252 set_hk_lfr_sc_potential_flag( true );
253
251 254 status = rtems_task_delete(RTEMS_SELF);
252 255
253 256 }
254 257
255 258 void init_local_mode_parameters( void )
256 259 {
257 260 /** This function initialize the param_local global variable with default values.
258 261 *
259 262 */
260 263
261 264 unsigned int i;
262 265
263 266 // LOCAL PARAMETERS
264 267
265 268 BOOT_PRINTF1("local_sbm1_nb_cwf_max %d \n", param_local.local_sbm1_nb_cwf_max)
266 269 BOOT_PRINTF1("local_sbm2_nb_cwf_max %d \n", param_local.local_sbm2_nb_cwf_max)
267 270 BOOT_PRINTF1("nb_interrupt_f0_MAX = %d\n", param_local.local_nb_interrupt_f0_MAX)
268 271
269 272 // init sequence counters
270 273
271 274 for(i = 0; i<SEQ_CNT_NB_DEST_ID; i++)
272 275 {
273 276 sequenceCounters_TC_EXE[i] = 0x00;
274 277 }
275 278 sequenceCounters_SCIENCE_NORMAL_BURST = 0x00;
276 279 sequenceCounters_SCIENCE_SBM1_SBM2 = 0x00;
277 280 sequenceCounterHK = TM_PACKET_SEQ_CTRL_STANDALONE << 8;
278 281 sequenceCounterParameterDump = TM_PACKET_SEQ_CTRL_STANDALONE << 8;
279 282 }
280 283
281 284 void reset_local_time( void )
282 285 {
283 286 time_management_regs->ctrl = time_management_regs->ctrl | 0x02; // [0010] software reset, coarse time = 0x80000000
284 287 }
285 288
286 289 void create_names( void ) // create all names for tasks and queues
287 290 {
288 291 /** This function creates all RTEMS names used in the software for tasks and queues.
289 292 *
290 293 * @return RTEMS directive status codes:
291 294 * - RTEMS_SUCCESSFUL - successful completion
292 295 *
293 296 */
294 297
295 298 // task names
296 299 Task_name[TASKID_RECV] = rtems_build_name( 'R', 'E', 'C', 'V' );
297 300 Task_name[TASKID_ACTN] = rtems_build_name( 'A', 'C', 'T', 'N' );
298 301 Task_name[TASKID_SPIQ] = rtems_build_name( 'S', 'P', 'I', 'Q' );
299 302 Task_name[TASKID_STAT] = rtems_build_name( 'S', 'T', 'A', 'T' );
300 303 Task_name[TASKID_AVF0] = rtems_build_name( 'A', 'V', 'F', '0' );
301 304 Task_name[TASKID_SWBD] = rtems_build_name( 'S', 'W', 'B', 'D' );
302 305 Task_name[TASKID_WFRM] = rtems_build_name( 'W', 'F', 'R', 'M' );
303 306 Task_name[TASKID_DUMB] = rtems_build_name( 'D', 'U', 'M', 'B' );
304 307 Task_name[TASKID_HOUS] = rtems_build_name( 'H', 'O', 'U', 'S' );
305 308 Task_name[TASKID_PRC0] = rtems_build_name( 'P', 'R', 'C', '0' );
306 309 Task_name[TASKID_CWF3] = rtems_build_name( 'C', 'W', 'F', '3' );
307 310 Task_name[TASKID_CWF2] = rtems_build_name( 'C', 'W', 'F', '2' );
308 311 Task_name[TASKID_CWF1] = rtems_build_name( 'C', 'W', 'F', '1' );
309 312 Task_name[TASKID_SEND] = rtems_build_name( 'S', 'E', 'N', 'D' );
310 313 Task_name[TASKID_WTDG] = rtems_build_name( 'W', 'T', 'D', 'G' );
311 314 Task_name[TASKID_AVF1] = rtems_build_name( 'A', 'V', 'F', '1' );
312 315 Task_name[TASKID_PRC1] = rtems_build_name( 'P', 'R', 'C', '1' );
313 316 Task_name[TASKID_AVF2] = rtems_build_name( 'A', 'V', 'F', '2' );
314 317 Task_name[TASKID_PRC2] = rtems_build_name( 'P', 'R', 'C', '2' );
315 318
316 319 // rate monotonic period names
317 320 name_hk_rate_monotonic = rtems_build_name( 'H', 'O', 'U', 'S' );
318 321
319 322 misc_name[QUEUE_RECV] = rtems_build_name( 'Q', '_', 'R', 'V' );
320 323 misc_name[QUEUE_SEND] = rtems_build_name( 'Q', '_', 'S', 'D' );
321 324 misc_name[QUEUE_PRC0] = rtems_build_name( 'Q', '_', 'P', '0' );
322 325 misc_name[QUEUE_PRC1] = rtems_build_name( 'Q', '_', 'P', '1' );
323 326 misc_name[QUEUE_PRC2] = rtems_build_name( 'Q', '_', 'P', '2' );
324 327 }
325 328
326 329 int create_all_tasks( void ) // create all tasks which run in the software
327 330 {
328 331 /** This function creates all RTEMS tasks used in the software.
329 332 *
330 333 * @return RTEMS directive status codes:
331 334 * - RTEMS_SUCCESSFUL - task created successfully
332 335 * - RTEMS_INVALID_ADDRESS - id is NULL
333 336 * - RTEMS_INVALID_NAME - invalid task name
334 337 * - RTEMS_INVALID_PRIORITY - invalid task priority
335 338 * - RTEMS_MP_NOT_CONFIGURED - multiprocessing not configured
336 339 * - RTEMS_TOO_MANY - too many tasks created
337 340 * - RTEMS_UNSATISFIED - not enough memory for stack/FP context
338 341 * - RTEMS_TOO_MANY - too many global objects
339 342 *
340 343 */
341 344
342 345 rtems_status_code status;
343 346
344 347 //**********
345 348 // SPACEWIRE
346 349 // RECV
347 350 status = rtems_task_create(
348 351 Task_name[TASKID_RECV], TASK_PRIORITY_RECV, RTEMS_MINIMUM_STACK_SIZE,
349 352 RTEMS_DEFAULT_MODES,
350 353 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_RECV]
351 354 );
352 355 if (status == RTEMS_SUCCESSFUL) // SEND
353 356 {
354 357 status = rtems_task_create(
355 358 Task_name[TASKID_SEND], TASK_PRIORITY_SEND, RTEMS_MINIMUM_STACK_SIZE * 2,
356 359 RTEMS_DEFAULT_MODES,
357 360 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SEND]
358 361 );
359 362 }
360 363 if (status == RTEMS_SUCCESSFUL) // WTDG
361 364 {
362 365 status = rtems_task_create(
363 366 Task_name[TASKID_WTDG], TASK_PRIORITY_WTDG, RTEMS_MINIMUM_STACK_SIZE,
364 367 RTEMS_DEFAULT_MODES,
365 368 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_WTDG]
366 369 );
367 370 }
368 371 if (status == RTEMS_SUCCESSFUL) // ACTN
369 372 {
370 373 status = rtems_task_create(
371 374 Task_name[TASKID_ACTN], TASK_PRIORITY_ACTN, RTEMS_MINIMUM_STACK_SIZE,
372 375 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
373 376 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_ACTN]
374 377 );
375 378 }
376 379 if (status == RTEMS_SUCCESSFUL) // SPIQ
377 380 {
378 381 status = rtems_task_create(
379 382 Task_name[TASKID_SPIQ], TASK_PRIORITY_SPIQ, RTEMS_MINIMUM_STACK_SIZE,
380 383 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
381 384 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SPIQ]
382 385 );
383 386 }
384 387
385 388 //******************
386 389 // SPECTRAL MATRICES
387 390 if (status == RTEMS_SUCCESSFUL) // AVF0
388 391 {
389 392 status = rtems_task_create(
390 393 Task_name[TASKID_AVF0], TASK_PRIORITY_AVF0, RTEMS_MINIMUM_STACK_SIZE,
391 394 RTEMS_DEFAULT_MODES,
392 395 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF0]
393 396 );
394 397 }
395 398 if (status == RTEMS_SUCCESSFUL) // PRC0
396 399 {
397 400 status = rtems_task_create(
398 401 Task_name[TASKID_PRC0], TASK_PRIORITY_PRC0, RTEMS_MINIMUM_STACK_SIZE * 2,
399 402 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
400 403 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC0]
401 404 );
402 405 }
403 406 if (status == RTEMS_SUCCESSFUL) // AVF1
404 407 {
405 408 status = rtems_task_create(
406 409 Task_name[TASKID_AVF1], TASK_PRIORITY_AVF1, RTEMS_MINIMUM_STACK_SIZE,
407 410 RTEMS_DEFAULT_MODES,
408 411 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF1]
409 412 );
410 413 }
411 414 if (status == RTEMS_SUCCESSFUL) // PRC1
412 415 {
413 416 status = rtems_task_create(
414 417 Task_name[TASKID_PRC1], TASK_PRIORITY_PRC1, RTEMS_MINIMUM_STACK_SIZE * 2,
415 418 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
416 419 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC1]
417 420 );
418 421 }
419 422 if (status == RTEMS_SUCCESSFUL) // AVF2
420 423 {
421 424 status = rtems_task_create(
422 425 Task_name[TASKID_AVF2], TASK_PRIORITY_AVF2, RTEMS_MINIMUM_STACK_SIZE,
423 426 RTEMS_DEFAULT_MODES,
424 427 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF2]
425 428 );
426 429 }
427 430 if (status == RTEMS_SUCCESSFUL) // PRC2
428 431 {
429 432 status = rtems_task_create(
430 433 Task_name[TASKID_PRC2], TASK_PRIORITY_PRC2, RTEMS_MINIMUM_STACK_SIZE * 2,
431 434 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
432 435 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC2]
433 436 );
434 437 }
435 438
436 439 //****************
437 440 // WAVEFORM PICKER
438 441 if (status == RTEMS_SUCCESSFUL) // WFRM
439 442 {
440 443 status = rtems_task_create(
441 444 Task_name[TASKID_WFRM], TASK_PRIORITY_WFRM, RTEMS_MINIMUM_STACK_SIZE,
442 445 RTEMS_DEFAULT_MODES,
443 446 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_WFRM]
444 447 );
445 448 }
446 449 if (status == RTEMS_SUCCESSFUL) // CWF3
447 450 {
448 451 status = rtems_task_create(
449 452 Task_name[TASKID_CWF3], TASK_PRIORITY_CWF3, RTEMS_MINIMUM_STACK_SIZE,
450 453 RTEMS_DEFAULT_MODES,
451 454 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF3]
452 455 );
453 456 }
454 457 if (status == RTEMS_SUCCESSFUL) // CWF2
455 458 {
456 459 status = rtems_task_create(
457 460 Task_name[TASKID_CWF2], TASK_PRIORITY_CWF2, RTEMS_MINIMUM_STACK_SIZE,
458 461 RTEMS_DEFAULT_MODES,
459 462 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF2]
460 463 );
461 464 }
462 465 if (status == RTEMS_SUCCESSFUL) // CWF1
463 466 {
464 467 status = rtems_task_create(
465 468 Task_name[TASKID_CWF1], TASK_PRIORITY_CWF1, RTEMS_MINIMUM_STACK_SIZE,
466 469 RTEMS_DEFAULT_MODES,
467 470 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF1]
468 471 );
469 472 }
470 473 if (status == RTEMS_SUCCESSFUL) // SWBD
471 474 {
472 475 status = rtems_task_create(
473 476 Task_name[TASKID_SWBD], TASK_PRIORITY_SWBD, RTEMS_MINIMUM_STACK_SIZE,
474 477 RTEMS_DEFAULT_MODES,
475 478 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SWBD]
476 479 );
477 480 }
478 481
479 482 //*****
480 483 // MISC
481 484 if (status == RTEMS_SUCCESSFUL) // STAT
482 485 {
483 486 status = rtems_task_create(
484 487 Task_name[TASKID_STAT], TASK_PRIORITY_STAT, RTEMS_MINIMUM_STACK_SIZE,
485 488 RTEMS_DEFAULT_MODES,
486 489 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_STAT]
487 490 );
488 491 }
489 492 if (status == RTEMS_SUCCESSFUL) // DUMB
490 493 {
491 494 status = rtems_task_create(
492 495 Task_name[TASKID_DUMB], TASK_PRIORITY_DUMB, RTEMS_MINIMUM_STACK_SIZE,
493 496 RTEMS_DEFAULT_MODES,
494 497 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_DUMB]
495 498 );
496 499 }
497 500 if (status == RTEMS_SUCCESSFUL) // HOUS
498 501 {
499 502 status = rtems_task_create(
500 503 Task_name[TASKID_HOUS], TASK_PRIORITY_HOUS, RTEMS_MINIMUM_STACK_SIZE,
501 504 RTEMS_DEFAULT_MODES,
502 505 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_HOUS]
503 506 );
504 507 }
505 508
506 509 return status;
507 510 }
508 511
509 512 int start_recv_send_tasks( void )
510 513 {
511 514 rtems_status_code status;
512 515
513 516 status = rtems_task_start( Task_id[TASKID_RECV], recv_task, 1 );
514 517 if (status!=RTEMS_SUCCESSFUL) {
515 518 BOOT_PRINTF("in INIT *** Error starting TASK_RECV\n")
516 519 }
517 520
518 521 if (status == RTEMS_SUCCESSFUL) // SEND
519 522 {
520 523 status = rtems_task_start( Task_id[TASKID_SEND], send_task, 1 );
521 524 if (status!=RTEMS_SUCCESSFUL) {
522 525 BOOT_PRINTF("in INIT *** Error starting TASK_SEND\n")
523 526 }
524 527 }
525 528
526 529 return status;
527 530 }
528 531
529 532 int start_all_tasks( void ) // start all tasks except SEND RECV and HOUS
530 533 {
531 534 /** This function starts all RTEMS tasks used in the software.
532 535 *
533 536 * @return RTEMS directive status codes:
534 537 * - RTEMS_SUCCESSFUL - ask started successfully
535 538 * - RTEMS_INVALID_ADDRESS - invalid task entry point
536 539 * - RTEMS_INVALID_ID - invalid task id
537 540 * - RTEMS_INCORRECT_STATE - task not in the dormant state
538 541 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot start remote task
539 542 *
540 543 */
541 544 // starts all the tasks fot eh flight software
542 545
543 546 rtems_status_code status;
544 547
545 548 //**********
546 549 // SPACEWIRE
547 550 status = rtems_task_start( Task_id[TASKID_SPIQ], spiq_task, 1 );
548 551 if (status!=RTEMS_SUCCESSFUL) {
549 552 BOOT_PRINTF("in INIT *** Error starting TASK_SPIQ\n")
550 553 }
551 554
552 555 if (status == RTEMS_SUCCESSFUL) // WTDG
553 556 {
554 557 status = rtems_task_start( Task_id[TASKID_WTDG], wtdg_task, 1 );
555 558 if (status!=RTEMS_SUCCESSFUL) {
556 559 BOOT_PRINTF("in INIT *** Error starting TASK_WTDG\n")
557 560 }
558 561 }
559 562
560 563 if (status == RTEMS_SUCCESSFUL) // ACTN
561 564 {
562 565 status = rtems_task_start( Task_id[TASKID_ACTN], actn_task, 1 );
563 566 if (status!=RTEMS_SUCCESSFUL) {
564 567 BOOT_PRINTF("in INIT *** Error starting TASK_ACTN\n")
565 568 }
566 569 }
567 570
568 571 //******************
569 572 // SPECTRAL MATRICES
570 573 if (status == RTEMS_SUCCESSFUL) // AVF0
571 574 {
572 575 status = rtems_task_start( Task_id[TASKID_AVF0], avf0_task, LFR_MODE_STANDBY );
573 576 if (status!=RTEMS_SUCCESSFUL) {
574 577 BOOT_PRINTF("in INIT *** Error starting TASK_AVF0\n")
575 578 }
576 579 }
577 580 if (status == RTEMS_SUCCESSFUL) // PRC0
578 581 {
579 582 status = rtems_task_start( Task_id[TASKID_PRC0], prc0_task, LFR_MODE_STANDBY );
580 583 if (status!=RTEMS_SUCCESSFUL) {
581 584 BOOT_PRINTF("in INIT *** Error starting TASK_PRC0\n")
582 585 }
583 586 }
584 587 if (status == RTEMS_SUCCESSFUL) // AVF1
585 588 {
586 589 status = rtems_task_start( Task_id[TASKID_AVF1], avf1_task, LFR_MODE_STANDBY );
587 590 if (status!=RTEMS_SUCCESSFUL) {
588 591 BOOT_PRINTF("in INIT *** Error starting TASK_AVF1\n")
589 592 }
590 593 }
591 594 if (status == RTEMS_SUCCESSFUL) // PRC1
592 595 {
593 596 status = rtems_task_start( Task_id[TASKID_PRC1], prc1_task, LFR_MODE_STANDBY );
594 597 if (status!=RTEMS_SUCCESSFUL) {
595 598 BOOT_PRINTF("in INIT *** Error starting TASK_PRC1\n")
596 599 }
597 600 }
598 601 if (status == RTEMS_SUCCESSFUL) // AVF2
599 602 {
600 603 status = rtems_task_start( Task_id[TASKID_AVF2], avf2_task, 1 );
601 604 if (status!=RTEMS_SUCCESSFUL) {
602 605 BOOT_PRINTF("in INIT *** Error starting TASK_AVF2\n")
603 606 }
604 607 }
605 608 if (status == RTEMS_SUCCESSFUL) // PRC2
606 609 {
607 610 status = rtems_task_start( Task_id[TASKID_PRC2], prc2_task, 1 );
608 611 if (status!=RTEMS_SUCCESSFUL) {
609 612 BOOT_PRINTF("in INIT *** Error starting TASK_PRC2\n")
610 613 }
611 614 }
612 615
613 616 //****************
614 617 // WAVEFORM PICKER
615 618 if (status == RTEMS_SUCCESSFUL) // WFRM
616 619 {
617 620 status = rtems_task_start( Task_id[TASKID_WFRM], wfrm_task, 1 );
618 621 if (status!=RTEMS_SUCCESSFUL) {
619 622 BOOT_PRINTF("in INIT *** Error starting TASK_WFRM\n")
620 623 }
621 624 }
622 625 if (status == RTEMS_SUCCESSFUL) // CWF3
623 626 {
624 627 status = rtems_task_start( Task_id[TASKID_CWF3], cwf3_task, 1 );
625 628 if (status!=RTEMS_SUCCESSFUL) {
626 629 BOOT_PRINTF("in INIT *** Error starting TASK_CWF3\n")
627 630 }
628 631 }
629 632 if (status == RTEMS_SUCCESSFUL) // CWF2
630 633 {
631 634 status = rtems_task_start( Task_id[TASKID_CWF2], cwf2_task, 1 );
632 635 if (status!=RTEMS_SUCCESSFUL) {
633 636 BOOT_PRINTF("in INIT *** Error starting TASK_CWF2\n")
634 637 }
635 638 }
636 639 if (status == RTEMS_SUCCESSFUL) // CWF1
637 640 {
638 641 status = rtems_task_start( Task_id[TASKID_CWF1], cwf1_task, 1 );
639 642 if (status!=RTEMS_SUCCESSFUL) {
640 643 BOOT_PRINTF("in INIT *** Error starting TASK_CWF1\n")
641 644 }
642 645 }
643 646 if (status == RTEMS_SUCCESSFUL) // SWBD
644 647 {
645 648 status = rtems_task_start( Task_id[TASKID_SWBD], swbd_task, 1 );
646 649 if (status!=RTEMS_SUCCESSFUL) {
647 650 BOOT_PRINTF("in INIT *** Error starting TASK_SWBD\n")
648 651 }
649 652 }
650 653
651 654 //*****
652 655 // MISC
653 656 if (status == RTEMS_SUCCESSFUL) // HOUS
654 657 {
655 658 status = rtems_task_start( Task_id[TASKID_HOUS], hous_task, 1 );
656 659 if (status!=RTEMS_SUCCESSFUL) {
657 660 BOOT_PRINTF("in INIT *** Error starting TASK_HOUS\n")
658 661 }
659 662 }
660 663 if (status == RTEMS_SUCCESSFUL) // DUMB
661 664 {
662 665 status = rtems_task_start( Task_id[TASKID_DUMB], dumb_task, 1 );
663 666 if (status!=RTEMS_SUCCESSFUL) {
664 667 BOOT_PRINTF("in INIT *** Error starting TASK_DUMB\n")
665 668 }
666 669 }
667 670 if (status == RTEMS_SUCCESSFUL) // STAT
668 671 {
669 672 status = rtems_task_start( Task_id[TASKID_STAT], stat_task, 1 );
670 673 if (status!=RTEMS_SUCCESSFUL) {
671 674 BOOT_PRINTF("in INIT *** Error starting TASK_STAT\n")
672 675 }
673 676 }
674 677
675 678 return status;
676 679 }
677 680
678 681 rtems_status_code create_message_queues( void ) // create the two message queues used in the software
679 682 {
680 683 rtems_status_code status_recv;
681 684 rtems_status_code status_send;
682 685 rtems_status_code status_q_p0;
683 686 rtems_status_code status_q_p1;
684 687 rtems_status_code status_q_p2;
685 688 rtems_status_code ret;
686 689 rtems_id queue_id;
687 690
688 691 //****************************************
689 692 // create the queue for handling valid TCs
690 693 status_recv = rtems_message_queue_create( misc_name[QUEUE_RECV],
691 694 MSG_QUEUE_COUNT_RECV, CCSDS_TC_PKT_MAX_SIZE,
692 695 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
693 696 if ( status_recv != RTEMS_SUCCESSFUL ) {
694 697 PRINTF1("in create_message_queues *** ERR creating QUEU queue, %d\n", status_recv)
695 698 }
696 699
697 700 //************************************************
698 701 // create the queue for handling TM packet sending
699 702 status_send = rtems_message_queue_create( misc_name[QUEUE_SEND],
700 703 MSG_QUEUE_COUNT_SEND, MSG_QUEUE_SIZE_SEND,
701 704 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
702 705 if ( status_send != RTEMS_SUCCESSFUL ) {
703 706 PRINTF1("in create_message_queues *** ERR creating PKTS queue, %d\n", status_send)
704 707 }
705 708
706 709 //*****************************************************************************
707 710 // create the queue for handling averaged spectral matrices for processing @ f0
708 711 status_q_p0 = rtems_message_queue_create( misc_name[QUEUE_PRC0],
709 712 MSG_QUEUE_COUNT_PRC0, MSG_QUEUE_SIZE_PRC0,
710 713 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
711 714 if ( status_q_p0 != RTEMS_SUCCESSFUL ) {
712 715 PRINTF1("in create_message_queues *** ERR creating Q_P0 queue, %d\n", status_q_p0)
713 716 }
714 717
715 718 //*****************************************************************************
716 719 // create the queue for handling averaged spectral matrices for processing @ f1
717 720 status_q_p1 = rtems_message_queue_create( misc_name[QUEUE_PRC1],
718 721 MSG_QUEUE_COUNT_PRC1, MSG_QUEUE_SIZE_PRC1,
719 722 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
720 723 if ( status_q_p1 != RTEMS_SUCCESSFUL ) {
721 724 PRINTF1("in create_message_queues *** ERR creating Q_P1 queue, %d\n", status_q_p1)
722 725 }
723 726
724 727 //*****************************************************************************
725 728 // create the queue for handling averaged spectral matrices for processing @ f2
726 729 status_q_p2 = rtems_message_queue_create( misc_name[QUEUE_PRC2],
727 730 MSG_QUEUE_COUNT_PRC2, MSG_QUEUE_SIZE_PRC2,
728 731 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
729 732 if ( status_q_p2 != RTEMS_SUCCESSFUL ) {
730 733 PRINTF1("in create_message_queues *** ERR creating Q_P2 queue, %d\n", status_q_p2)
731 734 }
732 735
733 736 if ( status_recv != RTEMS_SUCCESSFUL )
734 737 {
735 738 ret = status_recv;
736 739 }
737 740 else if( status_send != RTEMS_SUCCESSFUL )
738 741 {
739 742 ret = status_send;
740 743 }
741 744 else if( status_q_p0 != RTEMS_SUCCESSFUL )
742 745 {
743 746 ret = status_q_p0;
744 747 }
745 748 else if( status_q_p1 != RTEMS_SUCCESSFUL )
746 749 {
747 750 ret = status_q_p1;
748 751 }
749 752 else
750 753 {
751 754 ret = status_q_p2;
752 755 }
753 756
754 757 return ret;
755 758 }
756 759
757 760 rtems_status_code get_message_queue_id_send( rtems_id *queue_id )
758 761 {
759 762 rtems_status_code status;
760 763 rtems_name queue_name;
761 764
762 765 queue_name = rtems_build_name( 'Q', '_', 'S', 'D' );
763 766
764 767 status = rtems_message_queue_ident( queue_name, 0, queue_id );
765 768
766 769 return status;
767 770 }
768 771
769 772 rtems_status_code get_message_queue_id_recv( rtems_id *queue_id )
770 773 {
771 774 rtems_status_code status;
772 775 rtems_name queue_name;
773 776
774 777 queue_name = rtems_build_name( 'Q', '_', 'R', 'V' );
775 778
776 779 status = rtems_message_queue_ident( queue_name, 0, queue_id );
777 780
778 781 return status;
779 782 }
780 783
781 784 rtems_status_code get_message_queue_id_prc0( rtems_id *queue_id )
782 785 {
783 786 rtems_status_code status;
784 787 rtems_name queue_name;
785 788
786 789 queue_name = rtems_build_name( 'Q', '_', 'P', '0' );
787 790
788 791 status = rtems_message_queue_ident( queue_name, 0, queue_id );
789 792
790 793 return status;
791 794 }
792 795
793 796 rtems_status_code get_message_queue_id_prc1( rtems_id *queue_id )
794 797 {
795 798 rtems_status_code status;
796 799 rtems_name queue_name;
797 800
798 801 queue_name = rtems_build_name( 'Q', '_', 'P', '1' );
799 802
800 803 status = rtems_message_queue_ident( queue_name, 0, queue_id );
801 804
802 805 return status;
803 806 }
804 807
805 808 rtems_status_code get_message_queue_id_prc2( rtems_id *queue_id )
806 809 {
807 810 rtems_status_code status;
808 811 rtems_name queue_name;
809 812
810 813 queue_name = rtems_build_name( 'Q', '_', 'P', '2' );
811 814
812 815 status = rtems_message_queue_ident( queue_name, 0, queue_id );
813 816
814 817 return status;
815 818 }
816 819
817 820 void update_queue_max_count( rtems_id queue_id, unsigned char*fifo_size_max )
818 821 {
819 822 u_int32_t count;
820 823 rtems_status_code status;
821 824
822 825 status = rtems_message_queue_get_number_pending( queue_id, &count );
823 826
824 827 count = count + 1;
825 828
826 829 if (status != RTEMS_SUCCESSFUL)
827 830 {
828 831 PRINTF1("in update_queue_max_count *** ERR = %d\n", status)
829 832 }
830 833 else
831 834 {
832 835 if (count > *fifo_size_max)
833 836 {
834 837 *fifo_size_max = count;
835 838 }
836 839 }
837 840 }
838 841
839 842 void init_ring(ring_node ring[], unsigned char nbNodes, volatile int buffer[], unsigned int bufferSize )
840 843 {
841 844 unsigned char i;
842 845
843 846 //***************
844 847 // BUFFER ADDRESS
845 848 for(i=0; i<nbNodes; i++)
846 849 {
847 850 ring[i].coarseTime = 0xffffffff;
848 851 ring[i].fineTime = 0xffffffff;
849 852 ring[i].sid = 0x00;
850 853 ring[i].status = 0x00;
851 854 ring[i].buffer_address = (int) &buffer[ i * bufferSize ];
852 855 }
853 856
854 857 //*****
855 858 // NEXT
856 859 ring[ nbNodes - 1 ].next = (ring_node*) &ring[ 0 ];
857 860 for(i=0; i<nbNodes-1; i++)
858 861 {
859 862 ring[i].next = (ring_node*) &ring[ i + 1 ];
860 863 }
861 864
862 865 //*********
863 866 // PREVIOUS
864 867 ring[ 0 ].previous = (ring_node*) &ring[ nbNodes - 1 ];
865 868 for(i=1; i<nbNodes; i++)
866 869 {
867 870 ring[i].previous = (ring_node*) &ring[ i - 1 ];
868 871 }
869 872 }
@@ -1,551 +1,564
1 1 /** General usage functions and RTEMS tasks.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 */
7 7
8 8 #include "fsw_misc.h"
9 9
10 10 void configure_timer(gptimer_regs_t *gptimer_regs, unsigned char timer, unsigned int clock_divider,
11 11 unsigned char interrupt_level, rtems_isr (*timer_isr)() )
12 12 {
13 13 /** This function configures a GPTIMER timer instantiated in the VHDL design.
14 14 *
15 15 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
16 16 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
17 17 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
18 18 * @param interrupt_level is the interrupt level that the timer drives.
19 19 * @param timer_isr is the interrupt subroutine that will be attached to the IRQ driven by the timer.
20 20 *
21 21 * Interrupt levels are described in the SPARC documentation sparcv8.pdf p.76
22 22 *
23 23 */
24 24
25 25 rtems_status_code status;
26 26 rtems_isr_entry old_isr_handler;
27 27
28 28 gptimer_regs->timer[timer].ctrl = 0x00; // reset the control register
29 29
30 30 status = rtems_interrupt_catch( timer_isr, interrupt_level, &old_isr_handler) ; // see sparcv8.pdf p.76 for interrupt levels
31 31 if (status!=RTEMS_SUCCESSFUL)
32 32 {
33 33 PRINTF("in configure_timer *** ERR rtems_interrupt_catch\n")
34 34 }
35 35
36 36 timer_set_clock_divider( gptimer_regs, timer, clock_divider);
37 37 }
38 38
39 39 void timer_start(gptimer_regs_t *gptimer_regs, unsigned char timer)
40 40 {
41 41 /** This function starts a GPTIMER timer.
42 42 *
43 43 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
44 44 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
45 45 *
46 46 */
47 47
48 48 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
49 49 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000004; // LD load value from the reload register
50 50 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000001; // EN enable the timer
51 51 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000002; // RS restart
52 52 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000008; // IE interrupt enable
53 53 }
54 54
55 55 void timer_stop(gptimer_regs_t *gptimer_regs, unsigned char timer)
56 56 {
57 57 /** This function stops a GPTIMER timer.
58 58 *
59 59 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
60 60 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
61 61 *
62 62 */
63 63
64 64 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xfffffffe; // EN enable the timer
65 65 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xffffffef; // IE interrupt enable
66 66 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
67 67 }
68 68
69 69 void timer_set_clock_divider(gptimer_regs_t *gptimer_regs, unsigned char timer, unsigned int clock_divider)
70 70 {
71 71 /** This function sets the clock divider of a GPTIMER timer.
72 72 *
73 73 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
74 74 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
75 75 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
76 76 *
77 77 */
78 78
79 79 gptimer_regs->timer[timer].reload = clock_divider; // base clock frequency is 1 MHz
80 80 }
81 81
82 82 int send_console_outputs_on_apbuart_port( void ) // Send the console outputs on the apbuart port
83 83 {
84 84 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
85 85
86 86 apbuart_regs->ctrl = APBUART_CTRL_REG_MASK_TE;
87 87
88 88 return 0;
89 89 }
90 90
91 91 int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register
92 92 {
93 93 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
94 94
95 95 apbuart_regs->ctrl = apbuart_regs->ctrl | APBUART_CTRL_REG_MASK_TE;
96 96
97 97 return 0;
98 98 }
99 99
100 100 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value)
101 101 {
102 102 /** This function sets the scaler reload register of the apbuart module
103 103 *
104 104 * @param regs is the address of the apbuart registers in memory
105 105 * @param value is the value that will be stored in the scaler register
106 106 *
107 107 * The value shall be set by the software to get data on the serial interface.
108 108 *
109 109 */
110 110
111 111 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs;
112 112
113 113 apbuart_regs->scaler = value;
114 114 BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value)
115 115 }
116 116
117 117 //************
118 118 // RTEMS TASKS
119 119
120 120 rtems_task stat_task(rtems_task_argument argument)
121 121 {
122 122 int i;
123 123 int j;
124 124 i = 0;
125 125 j = 0;
126 126 BOOT_PRINTF("in STAT *** \n")
127 127 while(1){
128 128 rtems_task_wake_after(1000);
129 129 PRINTF1("%d\n", j)
130 130 if (i == CPU_USAGE_REPORT_PERIOD) {
131 131 // #ifdef PRINT_TASK_STATISTICS
132 132 // rtems_cpu_usage_report();
133 133 // rtems_cpu_usage_reset();
134 134 // #endif
135 135 i = 0;
136 136 }
137 137 else i++;
138 138 j++;
139 139 }
140 140 }
141 141
142 142 rtems_task hous_task(rtems_task_argument argument)
143 143 {
144 144 rtems_status_code status;
145 145 rtems_status_code spare_status;
146 146 rtems_id queue_id;
147 147 rtems_rate_monotonic_period_status period_status;
148 148
149 149 status = get_message_queue_id_send( &queue_id );
150 150 if (status != RTEMS_SUCCESSFUL)
151 151 {
152 152 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
153 153 }
154 154
155 155 BOOT_PRINTF("in HOUS ***\n")
156 156
157 157 if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
158 158 status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id );
159 159 if( status != RTEMS_SUCCESSFUL ) {
160 160 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status )
161 161 }
162 162 }
163 163
164 164 status = rtems_rate_monotonic_cancel(HK_id);
165 165 if( status != RTEMS_SUCCESSFUL ) {
166 166 PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status )
167 167 }
168 168 else {
169 169 DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n")
170 170 }
171 171
172 172 // startup phase
173 173 status = rtems_rate_monotonic_period( HK_id, SY_LFR_TIME_SYN_TIMEOUT_in_ticks );
174 174 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
175 175 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
176 176 while(period_status.state != RATE_MONOTONIC_EXPIRED ) // after SY_LFR_TIME_SYN_TIMEOUT ms, starts HK anyway
177 177 {
178 178 if ((time_management_regs->coarse_time & 0x80000000) == 0x00000000) // check time synchronization
179 179 {
180 180 break; // break if LFR is synchronized
181 181 }
182 182 else
183 183 {
184 184 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
185 185 // sched_yield();
186 186 status = rtems_task_wake_after( 10 ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 100 ms = 10 * 10 ms
187 187 }
188 188 }
189 189 status = rtems_rate_monotonic_cancel(HK_id);
190 190 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
191 191
192 192 while(1){ // launch the rate monotonic task
193 193 status = rtems_rate_monotonic_period( HK_id, HK_PERIOD );
194 194 if ( status != RTEMS_SUCCESSFUL ) {
195 195 PRINTF1( "in HOUS *** ERR period: %d\n", status);
196 196 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 );
197 197 }
198 198 else {
199 199 housekeeping_packet.packetSequenceControl[0] = (unsigned char) (sequenceCounterHK >> 8);
200 200 housekeeping_packet.packetSequenceControl[1] = (unsigned char) (sequenceCounterHK );
201 201 increment_seq_counter( &sequenceCounterHK );
202 202
203 203 housekeeping_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
204 204 housekeeping_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
205 205 housekeeping_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
206 206 housekeeping_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
207 207 housekeeping_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
208 208 housekeeping_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
209 209
210 210 spacewire_update_statistics();
211 211
212 212 housekeeping_packet.hk_lfr_q_sd_fifo_size_max = hk_lfr_q_sd_fifo_size_max;
213 213 housekeeping_packet.hk_lfr_q_rv_fifo_size_max = hk_lfr_q_rv_fifo_size_max;
214 214 housekeeping_packet.hk_lfr_q_p0_fifo_size_max = hk_lfr_q_p0_fifo_size_max;
215 215 housekeeping_packet.hk_lfr_q_p1_fifo_size_max = hk_lfr_q_p1_fifo_size_max;
216 216 housekeeping_packet.hk_lfr_q_p2_fifo_size_max = hk_lfr_q_p2_fifo_size_max;
217 217
218 218 housekeeping_packet.sy_lfr_common_parameters_spare = parameter_dump_packet.sy_lfr_common_parameters_spare;
219 219 housekeeping_packet.sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
220 220 get_temperatures( housekeeping_packet.hk_lfr_temp_scm );
221 221 get_v_e1_e2_f3( housekeeping_packet.hk_lfr_sc_v_f3 );
222 222 get_cpu_load( (unsigned char *) &housekeeping_packet.hk_lfr_cpu_load );
223 223
224 224 // SEND PACKET
225 225 status = rtems_message_queue_send( queue_id, &housekeeping_packet,
226 226 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
227 227 if (status != RTEMS_SUCCESSFUL) {
228 228 PRINTF1("in HOUS *** ERR send: %d\n", status)
229 229 }
230 230 }
231 231 }
232 232
233 233 PRINTF("in HOUS *** deleting task\n")
234 234
235 235 status = rtems_task_delete( RTEMS_SELF ); // should not return
236 236 printf( "rtems_task_delete returned with status of %d.\n", status );
237 237 return;
238 238 }
239 239
240 240 rtems_task dumb_task( rtems_task_argument unused )
241 241 {
242 242 /** This RTEMS taks is used to print messages without affecting the general behaviour of the software.
243 243 *
244 244 * @param unused is the starting argument of the RTEMS task
245 245 *
246 246 * The DUMB taks waits for RTEMS events and print messages depending on the incoming events.
247 247 *
248 248 */
249 249
250 250 unsigned int i;
251 251 unsigned int intEventOut;
252 252 unsigned int coarse_time = 0;
253 253 unsigned int fine_time = 0;
254 254 rtems_event_set event_out;
255 255
256 256 char *DumbMessages[12] = {"in DUMB *** default", // RTEMS_EVENT_0
257 257 "in DUMB *** timecode_irq_handler", // RTEMS_EVENT_1
258 258 "in DUMB *** f3 buffer changed", // RTEMS_EVENT_2
259 259 "in DUMB *** in SMIQ *** Error sending event to AVF0", // RTEMS_EVENT_3
260 260 "in DUMB *** spectral_matrices_isr *** Error sending event to SMIQ", // RTEMS_EVENT_4
261 261 "in DUMB *** waveforms_simulator_isr", // RTEMS_EVENT_5
262 262 "VHDL SM *** two buffers f0 ready", // RTEMS_EVENT_6
263 263 "ready for dump", // RTEMS_EVENT_7
264 264 "VHDL ERR *** spectral matrix", // RTEMS_EVENT_8
265 265 "tick", // RTEMS_EVENT_9
266 266 "VHDL ERR *** waveform picker", // RTEMS_EVENT_10
267 267 "VHDL ERR *** unexpected ready matrix values" // RTEMS_EVENT_11
268 268 };
269 269
270 270 BOOT_PRINTF("in DUMB *** \n")
271 271
272 272 while(1){
273 273 rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3
274 274 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7
275 275 | RTEMS_EVENT_8 | RTEMS_EVENT_9,
276 276 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT
277 277 intEventOut = (unsigned int) event_out;
278 278 for ( i=0; i<32; i++)
279 279 {
280 280 if ( ((intEventOut >> i) & 0x0001) != 0)
281 281 {
282 282 coarse_time = time_management_regs->coarse_time;
283 283 fine_time = time_management_regs->fine_time;
284 284 printf("in DUMB *** coarse: %x, fine: %x, %s\n", coarse_time, fine_time, DumbMessages[i]);
285 285 if (i==8)
286 286 {
287 287 }
288 288 if (i==10)
289 289 {
290 290 }
291 291 }
292 292 }
293 293 }
294 294 }
295 295
296 296 //*****************************
297 297 // init housekeeping parameters
298 298
299 299 void init_housekeeping_parameters( void )
300 300 {
301 301 /** This function initialize the housekeeping_packet global variable with default values.
302 302 *
303 303 */
304 304
305 305 unsigned int i = 0;
306 306 unsigned char *parameters;
307 307 unsigned char sizeOfHK;
308 308
309 309 sizeOfHK = sizeof( Packet_TM_LFR_HK_t );
310 310
311 311 parameters = (unsigned char*) &housekeeping_packet;
312 312
313 313 for(i = 0; i< sizeOfHK; i++)
314 314 {
315 315 parameters[i] = 0x00;
316 316 }
317 317
318 318 housekeeping_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
319 319 housekeeping_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
320 320 housekeeping_packet.reserved = DEFAULT_RESERVED;
321 321 housekeeping_packet.userApplication = CCSDS_USER_APP;
322 322 housekeeping_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
323 323 housekeeping_packet.packetID[1] = (unsigned char) (APID_TM_HK);
324 324 housekeeping_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
325 325 housekeeping_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
326 326 housekeeping_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
327 327 housekeeping_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
328 328 housekeeping_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
329 329 housekeeping_packet.serviceType = TM_TYPE_HK;
330 330 housekeeping_packet.serviceSubType = TM_SUBTYPE_HK;
331 331 housekeeping_packet.destinationID = TM_DESTINATION_ID_GROUND;
332 332 housekeeping_packet.sid = SID_HK;
333 333
334 334 // init status word
335 335 housekeeping_packet.lfr_status_word[0] = DEFAULT_STATUS_WORD_BYTE0;
336 336 housekeeping_packet.lfr_status_word[1] = DEFAULT_STATUS_WORD_BYTE1;
337 337 // init software version
338 338 housekeeping_packet.lfr_sw_version[0] = SW_VERSION_N1;
339 339 housekeeping_packet.lfr_sw_version[1] = SW_VERSION_N2;
340 340 housekeeping_packet.lfr_sw_version[2] = SW_VERSION_N3;
341 341 housekeeping_packet.lfr_sw_version[3] = SW_VERSION_N4;
342 342 // init fpga version
343 343 parameters = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
344 344 housekeeping_packet.lfr_fpga_version[0] = parameters[1]; // n1
345 345 housekeeping_packet.lfr_fpga_version[1] = parameters[2]; // n2
346 346 housekeeping_packet.lfr_fpga_version[2] = parameters[3]; // n3
347 347
348 348 housekeeping_packet.hk_lfr_q_sd_fifo_size = MSG_QUEUE_COUNT_SEND;
349 349 housekeeping_packet.hk_lfr_q_rv_fifo_size = MSG_QUEUE_COUNT_RECV;
350 350 housekeeping_packet.hk_lfr_q_p0_fifo_size = MSG_QUEUE_COUNT_PRC0;
351 351 housekeeping_packet.hk_lfr_q_p1_fifo_size = MSG_QUEUE_COUNT_PRC1;
352 352 housekeeping_packet.hk_lfr_q_p2_fifo_size = MSG_QUEUE_COUNT_PRC2;
353 353 }
354 354
355 355 void increment_seq_counter( unsigned short *packetSequenceControl )
356 356 {
357 357 /** This function increment the sequence counter passes in argument.
358 358 *
359 359 * The increment does not affect the grouping flag. In case of an overflow, the counter is reset to 0.
360 360 *
361 361 */
362 362
363 363 unsigned short segmentation_grouping_flag;
364 364 unsigned short sequence_cnt;
365 365
366 366 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << 8; // keep bits 7 downto 6
367 367 sequence_cnt = (*packetSequenceControl) & 0x3fff; // [0011 1111 1111 1111]
368 368
369 369 if ( sequence_cnt < SEQ_CNT_MAX)
370 370 {
371 371 sequence_cnt = sequence_cnt + 1;
372 372 }
373 373 else
374 374 {
375 375 sequence_cnt = 0;
376 376 }
377 377
378 378 *packetSequenceControl = segmentation_grouping_flag | sequence_cnt ;
379 379 }
380 380
381 381 void getTime( unsigned char *time)
382 382 {
383 383 /** This function write the current local time in the time buffer passed in argument.
384 384 *
385 385 */
386 386
387 387 time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
388 388 time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
389 389 time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
390 390 time[3] = (unsigned char) (time_management_regs->coarse_time);
391 391 time[4] = (unsigned char) (time_management_regs->fine_time>>8);
392 392 time[5] = (unsigned char) (time_management_regs->fine_time);
393 393 }
394 394
395 395 unsigned long long int getTimeAsUnsignedLongLongInt( )
396 396 {
397 397 /** This function write the current local time in the time buffer passed in argument.
398 398 *
399 399 */
400 400 unsigned long long int time;
401 401
402 402 time = ( (unsigned long long int) (time_management_regs->coarse_time & 0x7fffffff) << 16 )
403 403 + time_management_regs->fine_time;
404 404
405 405 return time;
406 406 }
407 407
408 408 void send_dumb_hk( void )
409 409 {
410 410 Packet_TM_LFR_HK_t dummy_hk_packet;
411 411 unsigned char *parameters;
412 412 unsigned int i;
413 413 rtems_id queue_id;
414 414
415 415 dummy_hk_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
416 416 dummy_hk_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
417 417 dummy_hk_packet.reserved = DEFAULT_RESERVED;
418 418 dummy_hk_packet.userApplication = CCSDS_USER_APP;
419 419 dummy_hk_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
420 420 dummy_hk_packet.packetID[1] = (unsigned char) (APID_TM_HK);
421 421 dummy_hk_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
422 422 dummy_hk_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
423 423 dummy_hk_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
424 424 dummy_hk_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
425 425 dummy_hk_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
426 426 dummy_hk_packet.serviceType = TM_TYPE_HK;
427 427 dummy_hk_packet.serviceSubType = TM_SUBTYPE_HK;
428 428 dummy_hk_packet.destinationID = TM_DESTINATION_ID_GROUND;
429 429 dummy_hk_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
430 430 dummy_hk_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
431 431 dummy_hk_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
432 432 dummy_hk_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
433 433 dummy_hk_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
434 434 dummy_hk_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
435 435 dummy_hk_packet.sid = SID_HK;
436 436
437 437 // init status word
438 438 dummy_hk_packet.lfr_status_word[0] = 0xff;
439 439 dummy_hk_packet.lfr_status_word[1] = 0xff;
440 440 // init software version
441 441 dummy_hk_packet.lfr_sw_version[0] = SW_VERSION_N1;
442 442 dummy_hk_packet.lfr_sw_version[1] = SW_VERSION_N2;
443 443 dummy_hk_packet.lfr_sw_version[2] = SW_VERSION_N3;
444 444 dummy_hk_packet.lfr_sw_version[3] = SW_VERSION_N4;
445 445 // init fpga version
446 446 parameters = (unsigned char *) (REGS_ADDR_WAVEFORM_PICKER + 0xb0);
447 447 dummy_hk_packet.lfr_fpga_version[0] = parameters[1]; // n1
448 448 dummy_hk_packet.lfr_fpga_version[1] = parameters[2]; // n2
449 449 dummy_hk_packet.lfr_fpga_version[2] = parameters[3]; // n3
450 450
451 451 parameters = (unsigned char *) &dummy_hk_packet.hk_lfr_cpu_load;
452 452
453 453 for (i=0; i<100; i++)
454 454 {
455 455 parameters[i] = 0xff;
456 456 }
457 457
458 458 get_message_queue_id_send( &queue_id );
459 459
460 460 rtems_message_queue_send( queue_id, &dummy_hk_packet,
461 461 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
462 462 }
463 463
464 464 void get_temperatures( unsigned char *temperatures )
465 465 {
466 466 unsigned char* temp_scm_ptr;
467 467 unsigned char* temp_pcb_ptr;
468 468 unsigned char* temp_fpga_ptr;
469 469
470 470 // SEL1 SEL0
471 471 // 0 0 => PCB
472 472 // 0 1 => FPGA
473 473 // 1 0 => SCM
474 474
475 475 temp_scm_ptr = (unsigned char *) &time_management_regs->temp_scm;
476 476 temp_pcb_ptr = (unsigned char *) &time_management_regs->temp_pcb;
477 477 temp_fpga_ptr = (unsigned char *) &time_management_regs->temp_fpga;
478 478
479 479 temperatures[0] = temp_scm_ptr[2];
480 480 temperatures[1] = temp_scm_ptr[3];
481 481 temperatures[2] = temp_pcb_ptr[2];
482 482 temperatures[3] = temp_pcb_ptr[3];
483 483 temperatures[4] = temp_fpga_ptr[2];
484 484 temperatures[5] = temp_fpga_ptr[3];
485 485 }
486 486
487 487 void get_v_e1_e2_f3( unsigned char *spacecraft_potential )
488 488 {
489 489 unsigned char* v_ptr;
490 490 unsigned char* e1_ptr;
491 491 unsigned char* e2_ptr;
492 492
493 493 v_ptr = (unsigned char *) &waveform_picker_regs->v;
494 494 e1_ptr = (unsigned char *) &waveform_picker_regs->e1;
495 495 e2_ptr = (unsigned char *) &waveform_picker_regs->e2;
496 496
497 497 spacecraft_potential[0] = v_ptr[2];
498 498 spacecraft_potential[1] = v_ptr[3];
499 499 spacecraft_potential[2] = e1_ptr[2];
500 500 spacecraft_potential[3] = e1_ptr[3];
501 501 spacecraft_potential[4] = e2_ptr[2];
502 502 spacecraft_potential[5] = e2_ptr[3];
503 503 }
504 504
505 505 void get_cpu_load( unsigned char *resource_statistics )
506 506 {
507 507 unsigned char cpu_load;
508 508
509 509 cpu_load = lfr_rtems_cpu_usage_report();
510 510
511 511 // HK_LFR_CPU_LOAD
512 512 resource_statistics[0] = cpu_load;
513 513
514 514 // HK_LFR_CPU_LOAD_MAX
515 515 if (cpu_load > resource_statistics[1])
516 516 {
517 517 resource_statistics[1] = cpu_load;
518 518 }
519 519
520 520 // CPU_LOAD_AVE
521 521 resource_statistics[2] = 0;
522 522
523 523 #ifndef PRINT_TASK_STATISTICS
524 524 rtems_cpu_usage_reset();
525 525 #endif
526 526
527 527 }
528 528
529 529 void set_hk_lfr_sc_potential_flag( bool state )
530 530 {
531 531 if (state == true)
532 532 {
533 533 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x40; // [0100 0000]
534 534 }
535 535 else
536 536 {
537 537 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xbf; // [1011 1111]
538 538 }
539 539 }
540 540
541 void set_hk_lfr_mag_fields_flag( bool state )
542 {
543 if (state == true)
544 {
545 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x20; // [0010 0000]
546 }
547 else
548 {
549 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xd7; // [1101 1111]
550 }
551 }
552
541 553 void set_hk_lfr_calib_enable( bool state )
542 554 {
543 555 if (state == true)
544 556 {
545 557 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x08; // [0000 1000]
546 558 }
547 559 else
548 560 {
549 561 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xf7; // [1111 0111]
550 562 }
551 563 }
564
@@ -1,1283 +1,1289
1 1 /** Functions related to the SpaceWire interface.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * A group of functions to handle SpaceWire transmissions:
7 7 * - configuration of the SpaceWire link
8 8 * - SpaceWire related interruption requests processing
9 9 * - transmission of TeleMetry packets by a dedicated RTEMS task
10 10 * - reception of TeleCommands by a dedicated RTEMS task
11 11 *
12 12 */
13 13
14 14 #include "fsw_spacewire.h"
15 15
16 16 rtems_name semq_name;
17 17 rtems_id semq_id;
18 18
19 19 //*****************
20 20 // waveform headers
21 21 Header_TM_LFR_SCIENCE_CWF_t headerCWF;
22 22 Header_TM_LFR_SCIENCE_SWF_t headerSWF;
23 23 Header_TM_LFR_SCIENCE_ASM_t headerASM;
24 24
25 25 //***********
26 26 // RTEMS TASK
27 27 rtems_task spiq_task(rtems_task_argument unused)
28 28 {
29 29 /** This RTEMS task is awaken by an rtems_event sent by the interruption subroutine of the SpaceWire driver.
30 30 *
31 31 * @param unused is the starting argument of the RTEMS task
32 32 *
33 33 */
34 34
35 35 rtems_event_set event_out;
36 36 rtems_status_code status;
37 37 int linkStatus;
38 38
39 39 BOOT_PRINTF("in SPIQ *** \n")
40 40
41 41 while(true){
42 42 rtems_event_receive(SPW_LINKERR_EVENT, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an SPW_LINKERR_EVENT
43 43 PRINTF("in SPIQ *** got SPW_LINKERR_EVENT\n")
44 44
45 45 // [0] SUSPEND RECV AND SEND TASKS
46 46 status = rtems_task_suspend( Task_id[ TASKID_RECV ] );
47 47 if ( status != RTEMS_SUCCESSFUL ) {
48 48 PRINTF("in SPIQ *** ERR suspending RECV Task\n")
49 49 }
50 50 status = rtems_task_suspend( Task_id[ TASKID_SEND ] );
51 51 if ( status != RTEMS_SUCCESSFUL ) {
52 52 PRINTF("in SPIQ *** ERR suspending SEND Task\n")
53 53 }
54 54
55 55 // [1] CHECK THE LINK
56 56 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (1)
57 57 if ( linkStatus != 5) {
58 58 PRINTF1("in SPIQ *** linkStatus %d, wait...\n", linkStatus)
59 59 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
60 60 }
61 61
62 62 // [2] RECHECK THE LINK AFTER SY_LFR_DPU_CONNECT_TIMEOUT
63 63 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status (2)
64 64 if ( linkStatus != 5 ) // [2.a] not in run state, reset the link
65 65 {
66 66 spacewire_compute_stats_offsets();
67 67 status = spacewire_reset_link( );
68 68 }
69 69 else // [2.b] in run state, start the link
70 70 {
71 71 status = spacewire_stop_and_start_link( fdSPW ); // start the link
72 72 if ( status != RTEMS_SUCCESSFUL)
73 73 {
74 74 PRINTF1("in SPIQ *** ERR spacewire_stop_and_start_link %d\n", status)
75 75 }
76 76 }
77 77
78 78 // [3] COMPLETE RECOVERY ACTION AFTER SY_LFR_DPU_CONNECT_ATTEMPTS
79 79 if ( status == RTEMS_SUCCESSFUL ) // [3.a] the link is in run state and has been started successfully
80 80 {
81 81 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
82 82 if ( status != RTEMS_SUCCESSFUL ) {
83 83 PRINTF("in SPIQ *** ERR resuming SEND Task\n")
84 84 }
85 85 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
86 86 if ( status != RTEMS_SUCCESSFUL ) {
87 87 PRINTF("in SPIQ *** ERR resuming RECV Task\n")
88 88 }
89 89 }
90 90 else // [3.b] the link is not in run state, go in STANDBY mode
91 91 {
92 92 status = enter_mode( LFR_MODE_STANDBY, 0 );
93 93 if ( status != RTEMS_SUCCESSFUL ) {
94 94 PRINTF1("in SPIQ *** ERR enter_standby_mode *** code %d\n", status)
95 95 }
96 96 // wake the WTDG task up to wait for the link recovery
97 97 status = rtems_event_send ( Task_id[TASKID_WTDG], RTEMS_EVENT_0 );
98 98 status = rtems_task_suspend( RTEMS_SELF );
99 99 }
100 100 }
101 101 }
102 102
103 103 rtems_task recv_task( rtems_task_argument unused )
104 104 {
105 105 /** This RTEMS task is dedicated to the reception of incoming TeleCommands.
106 106 *
107 107 * @param unused is the starting argument of the RTEMS task
108 108 *
109 109 * The RECV task blocks on a call to the read system call, waiting for incoming SpaceWire data. When unblocked:
110 110 * 1. It reads the incoming data.
111 111 * 2. Launches the acceptance procedure.
112 112 * 3. If the Telecommand is valid, sends it to a dedicated RTEMS message queue.
113 113 *
114 114 */
115 115
116 116 int len;
117 117 ccsdsTelecommandPacket_t currentTC;
118 118 unsigned char computed_CRC[ 2 ];
119 119 unsigned char currentTC_LEN_RCV[ 2 ];
120 120 unsigned char destinationID;
121 121 unsigned int estimatedPacketLength;
122 122 unsigned int parserCode;
123 123 rtems_status_code status;
124 124 rtems_id queue_recv_id;
125 125 rtems_id queue_send_id;
126 126
127 127 initLookUpTableForCRC(); // the table is used to compute Cyclic Redundancy Codes
128 128
129 129 status = get_message_queue_id_recv( &queue_recv_id );
130 130 if (status != RTEMS_SUCCESSFUL)
131 131 {
132 132 PRINTF1("in RECV *** ERR get_message_queue_id_recv %d\n", status)
133 133 }
134 134
135 135 status = get_message_queue_id_send( &queue_send_id );
136 136 if (status != RTEMS_SUCCESSFUL)
137 137 {
138 138 PRINTF1("in RECV *** ERR get_message_queue_id_send %d\n", status)
139 139 }
140 140
141 141 BOOT_PRINTF("in RECV *** \n")
142 142
143 143 while(1)
144 144 {
145 145 len = read( fdSPW, (char*) &currentTC, CCSDS_TC_PKT_MAX_SIZE ); // the call to read is blocking
146 146 if (len == -1){ // error during the read call
147 147 PRINTF1("in RECV *** last read call returned -1, ERRNO %d\n", errno)
148 148 }
149 149 else {
150 150 if ( (len+1) < CCSDS_TC_PKT_MIN_SIZE ) {
151 151 PRINTF("in RECV *** packet lenght too short\n")
152 152 }
153 153 else {
154 154 estimatedPacketLength = (unsigned int) (len - CCSDS_TC_TM_PACKET_OFFSET - 3); // => -3 is for Prot ID, Reserved and User App bytes
155 155 currentTC_LEN_RCV[ 0 ] = (unsigned char) (estimatedPacketLength >> 8);
156 156 currentTC_LEN_RCV[ 1 ] = (unsigned char) (estimatedPacketLength );
157 157 // CHECK THE TC
158 158 parserCode = tc_parser( &currentTC, estimatedPacketLength, computed_CRC ) ;
159 159 if ( (parserCode == ILLEGAL_APID) || (parserCode == WRONG_LEN_PKT)
160 160 || (parserCode == INCOR_CHECKSUM) || (parserCode == ILL_TYPE)
161 161 || (parserCode == ILL_SUBTYPE) || (parserCode == WRONG_APP_DATA)
162 162 || (parserCode == WRONG_SRC_ID) )
163 163 { // send TM_LFR_TC_EXE_CORRUPTED
164 164 PRINTF1("TC corrupted received, with code: %d\n", parserCode)
165 165 if ( !( (currentTC.serviceType==TC_TYPE_TIME) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_TIME) )
166 166 &&
167 167 !( (currentTC.serviceType==TC_TYPE_GEN) && (currentTC.serviceSubType==TC_SUBTYPE_UPDT_INFO))
168 168 )
169 169 {
170 170 if ( parserCode == WRONG_SRC_ID )
171 171 {
172 172 destinationID = SID_TC_GROUND;
173 173 }
174 174 else
175 175 {
176 176 destinationID = currentTC.sourceID;
177 177 }
178 178 send_tm_lfr_tc_exe_corrupted( &currentTC, queue_send_id,
179 179 computed_CRC, currentTC_LEN_RCV,
180 180 destinationID );
181 181 }
182 182 }
183 183 else
184 184 { // send valid TC to the action launcher
185 185 status = rtems_message_queue_send( queue_recv_id, &currentTC,
186 186 estimatedPacketLength + CCSDS_TC_TM_PACKET_OFFSET + 3);
187 187 }
188 188 }
189 189 }
190 190
191 191 update_queue_max_count( queue_recv_id, &hk_lfr_q_rv_fifo_size_max );
192 192
193 193 }
194 194 }
195 195
196 196 rtems_task send_task( rtems_task_argument argument)
197 197 {
198 198 /** This RTEMS task is dedicated to the transmission of TeleMetry packets.
199 199 *
200 200 * @param unused is the starting argument of the RTEMS task
201 201 *
202 202 * The SEND task waits for a message to become available in the dedicated RTEMS queue. When a message arrives:
203 203 * - if the first byte is equal to CCSDS_DESTINATION_ID, the message is sent as is using the write system call.
204 204 * - if the first byte is not equal to CCSDS_DESTINATION_ID, the message is handled as a spw_ioctl_pkt_send. After
205 205 * analyzis, the packet is sent either using the write system call or using the ioctl call SPACEWIRE_IOCTRL_SEND, depending on the
206 206 * data it contains.
207 207 *
208 208 */
209 209
210 210 rtems_status_code status; // RTEMS status code
211 211 char incomingData[MSG_QUEUE_SIZE_SEND]; // incoming data buffer
212 212 ring_node *incomingRingNodePtr;
213 213 int ring_node_address;
214 214 char *charPtr;
215 215 spw_ioctl_pkt_send *spw_ioctl_send;
216 216 size_t size; // size of the incoming TC packet
217 217 rtems_id queue_send_id;
218 218 unsigned int sid;
219 219
220 220 incomingRingNodePtr = NULL;
221 221 ring_node_address = 0;
222 222 charPtr = (char *) &ring_node_address;
223 223 sid = 0;
224 224
225 225 init_header_cwf( &headerCWF );
226 226 init_header_swf( &headerSWF );
227 227 init_header_asm( &headerASM );
228 228
229 229 status = get_message_queue_id_send( &queue_send_id );
230 230 if (status != RTEMS_SUCCESSFUL)
231 231 {
232 232 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
233 233 }
234 234
235 235 BOOT_PRINTF("in SEND *** \n")
236 236
237 237 while(1)
238 238 {
239 239 status = rtems_message_queue_receive( queue_send_id, incomingData, &size,
240 240 RTEMS_WAIT, RTEMS_NO_TIMEOUT );
241 241
242 242 if (status!=RTEMS_SUCCESSFUL)
243 243 {
244 244 PRINTF1("in SEND *** (1) ERR = %d\n", status)
245 245 }
246 246 else
247 247 {
248 248 if ( size == sizeof(ring_node*) )
249 249 {
250 250 charPtr[0] = incomingData[0];
251 251 charPtr[1] = incomingData[1];
252 252 charPtr[2] = incomingData[2];
253 253 charPtr[3] = incomingData[3];
254 254 incomingRingNodePtr = (ring_node*) ring_node_address;
255 255 sid = incomingRingNodePtr->sid;
256 256 if ( (sid==SID_NORM_CWF_LONG_F3)
257 257 || (sid==SID_BURST_CWF_F2 )
258 258 || (sid==SID_SBM1_CWF_F1 )
259 259 || (sid==SID_SBM2_CWF_F2 ))
260 260 {
261 261 spw_send_waveform_CWF( incomingRingNodePtr, &headerCWF );
262 262 }
263 263 else if ( (sid==SID_NORM_SWF_F0) || (sid== SID_NORM_SWF_F1) || (sid==SID_NORM_SWF_F2) )
264 264 {
265 265 spw_send_waveform_SWF( incomingRingNodePtr, &headerSWF );
266 266 }
267 267 else if ( (sid==SID_NORM_CWF_F3) )
268 268 {
269 269 spw_send_waveform_CWF3_light( incomingRingNodePtr, &headerCWF );
270 270 }
271 271 else if (sid==SID_NORM_ASM_F0)
272 272 {
273 273 spw_send_asm_f0( incomingRingNodePtr, &headerASM );
274 274 }
275 275 else if (sid==SID_NORM_ASM_F1)
276 276 {
277 277 spw_send_asm_f1( incomingRingNodePtr, &headerASM );
278 278 }
279 279 else if (sid==SID_NORM_ASM_F2)
280 280 {
281 281 spw_send_asm_f2( incomingRingNodePtr, &headerASM );
282 282 }
283 283 else if ( sid==TM_CODE_K_DUMP )
284 284 {
285 285 spw_send_k_dump( incomingRingNodePtr );
286 286 }
287 287 else
288 288 {
289 289 printf("unexpected sid = %d\n", sid);
290 290 }
291 291 }
292 292 else if ( incomingData[0] == CCSDS_DESTINATION_ID ) // the incoming message is a ccsds packet
293 293 {
294 294 status = write( fdSPW, incomingData, size );
295 295 if (status == -1){
296 296 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
297 297 }
298 298 }
299 299 else // the incoming message is a spw_ioctl_pkt_send structure
300 300 {
301 301 spw_ioctl_send = (spw_ioctl_pkt_send*) incomingData;
302 302 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, spw_ioctl_send );
303 303 if (status == -1){
304 304 printf("size = %d, %x, %x, %x, %x, %x\n",
305 305 size,
306 306 incomingData[0],
307 307 incomingData[1],
308 308 incomingData[2],
309 309 incomingData[3],
310 310 incomingData[4]);
311 311 PRINTF2("in SEND *** (2.b) ERRNO = %d, RTEMS = %d\n", errno, status)
312 312 }
313 313 }
314 314 }
315 315
316 316 update_queue_max_count( queue_send_id, &hk_lfr_q_sd_fifo_size_max );
317 317
318 318 }
319 319 }
320 320
321 321 rtems_task wtdg_task( rtems_task_argument argument )
322 322 {
323 323 rtems_event_set event_out;
324 324 rtems_status_code status;
325 325 int linkStatus;
326 326
327 327 BOOT_PRINTF("in WTDG ***\n")
328 328
329 329 while(1)
330 330 {
331 331 // wait for an RTEMS_EVENT
332 332 rtems_event_receive( RTEMS_EVENT_0,
333 333 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
334 334 PRINTF("in WTDG *** wait for the link\n")
335 335 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
336 336 while( linkStatus != 5) // wait for the link
337 337 {
338 338 status = rtems_task_wake_after( 10 ); // monitor the link each 100ms
339 339 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
340 340 }
341 341
342 342 status = spacewire_stop_and_start_link( fdSPW );
343 343
344 344 if (status != RTEMS_SUCCESSFUL)
345 345 {
346 346 PRINTF1("in WTDG *** ERR link not started %d\n", status)
347 347 }
348 348 else
349 349 {
350 350 PRINTF("in WTDG *** OK link started\n")
351 351 }
352 352
353 353 // restart the SPIQ task
354 354 status = rtems_task_restart( Task_id[TASKID_SPIQ], 1 );
355 355 if ( status != RTEMS_SUCCESSFUL ) {
356 356 PRINTF("in SPIQ *** ERR restarting SPIQ Task\n")
357 357 }
358 358
359 359 // restart RECV and SEND
360 360 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
361 361 if ( status != RTEMS_SUCCESSFUL ) {
362 362 PRINTF("in SPIQ *** ERR restarting SEND Task\n")
363 363 }
364 364 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
365 365 if ( status != RTEMS_SUCCESSFUL ) {
366 366 PRINTF("in SPIQ *** ERR restarting RECV Task\n")
367 367 }
368 368 }
369 369 }
370 370
371 371 //****************
372 372 // OTHER FUNCTIONS
373 373 int spacewire_open_link( void ) // by default, the driver resets the core: [SPW_CTRL_WRITE(pDev, SPW_CTRL_RESET);]
374 374 {
375 375 /** This function opens the SpaceWire link.
376 376 *
377 377 * @return a valid file descriptor in case of success, -1 in case of a failure
378 378 *
379 379 */
380 380 rtems_status_code status;
381 381
382 382 fdSPW = open(GRSPW_DEVICE_NAME, O_RDWR); // open the device. the open call resets the hardware
383 383 if ( fdSPW < 0 ) {
384 384 PRINTF1("ERR *** in configure_spw_link *** error opening "GRSPW_DEVICE_NAME" with ERR %d\n", errno)
385 385 }
386 386 else
387 387 {
388 388 status = RTEMS_SUCCESSFUL;
389 389 }
390 390
391 391 return status;
392 392 }
393 393
394 394 int spacewire_start_link( int fd )
395 395 {
396 396 rtems_status_code status;
397 397
398 398 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
399 399 // -1 default hardcoded driver timeout
400 400
401 401 return status;
402 402 }
403 403
404 404 int spacewire_stop_and_start_link( int fd )
405 405 {
406 406 rtems_status_code status;
407 407
408 408 status = ioctl( fd, SPACEWIRE_IOCTRL_STOP); // start fails if link pDev->running != 0
409 409 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
410 410 // -1 default hardcoded driver timeout
411 411
412 412 return status;
413 413 }
414 414
415 415 int spacewire_configure_link( int fd )
416 416 {
417 417 /** This function configures the SpaceWire link.
418 418 *
419 419 * @return GR-RTEMS-DRIVER directive status codes:
420 420 * - 22 EINVAL - Null pointer or an out of range value was given as the argument.
421 421 * - 16 EBUSY - Only used for SEND. Returned when no descriptors are avialble in non-blocking mode.
422 422 * - 88 ENOSYS - Returned for SET_DESTKEY if RMAP command handler is not available or if a non-implemented call is used.
423 423 * - 116 ETIMEDOUT - REturned for SET_PACKET_SIZE and START if the link could not be brought up.
424 424 * - 12 ENOMEM - Returned for SET_PACKETSIZE if it was unable to allocate the new buffers.
425 425 * - 5 EIO - Error when writing to grswp hardware registers.
426 426 * - 2 ENOENT - No such file or directory
427 427 */
428 428
429 429 rtems_status_code status;
430 430
431 431 spacewire_set_NP(1, REGS_ADDR_GRSPW); // [N]o [P]ort force
432 432 spacewire_set_RE(1, REGS_ADDR_GRSPW); // [R]MAP [E]nable, the dedicated call seems to break the no port force configuration
433 433
434 434 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_RXBLOCK, 1); // sets the blocking mode for reception
435 435 if (status!=RTEMS_SUCCESSFUL) {
436 436 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_RXBLOCK\n")
437 437 }
438 438 //
439 439 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_EVENT_ID, Task_id[TASKID_SPIQ]); // sets the task ID to which an event is sent when a
440 440 if (status!=RTEMS_SUCCESSFUL) {
441 441 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_EVENT_ID\n") // link-error interrupt occurs
442 442 }
443 443 //
444 444 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_DISABLE_ERR, 0); // automatic link-disabling due to link-error interrupts
445 445 if (status!=RTEMS_SUCCESSFUL) {
446 446 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_DISABLE_ERR\n")
447 447 }
448 448 //
449 449 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ, 1); // sets the link-error interrupt bit
450 450 if (status!=RTEMS_SUCCESSFUL) {
451 451 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ\n")
452 452 }
453 453 //
454 454 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK, 1); // transmission blocks
455 455 if (status!=RTEMS_SUCCESSFUL) {
456 456 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK\n")
457 457 }
458 458 //
459 459 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL, 1); // transmission blocks when no transmission descriptor is available
460 460 if (status!=RTEMS_SUCCESSFUL) {
461 461 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL\n")
462 462 }
463 463 //
464 464 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TCODE_CTRL, 0x0909); // [Time Rx : Time Tx : Link error : Tick-out IRQ]
465 465 if (status!=RTEMS_SUCCESSFUL) {
466 466 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TCODE_CTRL,\n")
467 467 }
468 468
469 469 return status;
470 470 }
471 471
472 472 int spacewire_reset_link( void )
473 473 {
474 474 /** This function is executed by the SPIQ rtems_task wehn it has been awaken by an interruption raised by the SpaceWire driver.
475 475 *
476 476 * @return RTEMS directive status code:
477 477 * - RTEMS_UNSATISFIED is returned is the link is not in the running state after 10 s.
478 478 * - RTEMS_SUCCESSFUL is returned if the link is up before the timeout.
479 479 *
480 480 */
481 481
482 482 rtems_status_code status_spw;
483 483 rtems_status_code status;
484 484 int i;
485 485
486 486 for ( i=0; i<SY_LFR_DPU_CONNECT_ATTEMPT; i++ )
487 487 {
488 488 PRINTF1("in spacewire_reset_link *** link recovery, try %d\n", i);
489 489
490 490 // CLOSING THE DRIVER AT THIS POINT WILL MAKE THE SEND TASK BLOCK THE SYSTEM
491 491
492 492 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
493 493
494 494 status_spw = spacewire_stop_and_start_link( fdSPW );
495 495 if ( status_spw != RTEMS_SUCCESSFUL )
496 496 {
497 497 PRINTF1("in spacewire_reset_link *** ERR spacewire_start_link code %d\n", status_spw)
498 498 }
499 499
500 500 if ( status_spw == RTEMS_SUCCESSFUL)
501 501 {
502 502 break;
503 503 }
504 504 }
505 505
506 506 return status_spw;
507 507 }
508 508
509 509 void spacewire_set_NP( unsigned char val, unsigned int regAddr ) // [N]o [P]ort force
510 510 {
511 511 /** This function sets the [N]o [P]ort force bit of the GRSPW control register.
512 512 *
513 513 * @param val is the value, 0 or 1, used to set the value of the NP bit.
514 514 * @param regAddr is the address of the GRSPW control register.
515 515 *
516 516 * NP is the bit 20 of the GRSPW control register.
517 517 *
518 518 */
519 519
520 520 unsigned int *spwptr = (unsigned int*) regAddr;
521 521
522 522 if (val == 1) {
523 523 *spwptr = *spwptr | 0x00100000; // [NP] set the No port force bit
524 524 }
525 525 if (val== 0) {
526 526 *spwptr = *spwptr & 0xffdfffff;
527 527 }
528 528 }
529 529
530 530 void spacewire_set_RE( unsigned char val, unsigned int regAddr ) // [R]MAP [E]nable
531 531 {
532 532 /** This function sets the [R]MAP [E]nable bit of the GRSPW control register.
533 533 *
534 534 * @param val is the value, 0 or 1, used to set the value of the RE bit.
535 535 * @param regAddr is the address of the GRSPW control register.
536 536 *
537 537 * RE is the bit 16 of the GRSPW control register.
538 538 *
539 539 */
540 540
541 541 unsigned int *spwptr = (unsigned int*) regAddr;
542 542
543 543 if (val == 1)
544 544 {
545 545 *spwptr = *spwptr | 0x00010000; // [RE] set the RMAP Enable bit
546 546 }
547 547 if (val== 0)
548 548 {
549 549 *spwptr = *spwptr & 0xfffdffff;
550 550 }
551 551 }
552 552
553 553 void spacewire_compute_stats_offsets( void )
554 554 {
555 555 /** This function computes the SpaceWire statistics offsets in case of a SpaceWire related interruption raising.
556 556 *
557 557 * The offsets keep a record of the statistics in case of a reset of the statistics. They are added to the current statistics
558 558 * to keep the counters consistent even after a reset of the SpaceWire driver (the counter are set to zero by the driver when it
559 559 * during the open systel call).
560 560 *
561 561 */
562 562
563 563 spw_stats spacewire_stats_grspw;
564 564 rtems_status_code status;
565 565
566 566 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &spacewire_stats_grspw );
567 567
568 568 spacewire_stats_backup.packets_received = spacewire_stats_grspw.packets_received
569 569 + spacewire_stats.packets_received;
570 570 spacewire_stats_backup.packets_sent = spacewire_stats_grspw.packets_sent
571 571 + spacewire_stats.packets_sent;
572 572 spacewire_stats_backup.parity_err = spacewire_stats_grspw.parity_err
573 573 + spacewire_stats.parity_err;
574 574 spacewire_stats_backup.disconnect_err = spacewire_stats_grspw.disconnect_err
575 575 + spacewire_stats.disconnect_err;
576 576 spacewire_stats_backup.escape_err = spacewire_stats_grspw.escape_err
577 577 + spacewire_stats.escape_err;
578 578 spacewire_stats_backup.credit_err = spacewire_stats_grspw.credit_err
579 579 + spacewire_stats.credit_err;
580 580 spacewire_stats_backup.write_sync_err = spacewire_stats_grspw.write_sync_err
581 581 + spacewire_stats.write_sync_err;
582 582 spacewire_stats_backup.rx_rmap_header_crc_err = spacewire_stats_grspw.rx_rmap_header_crc_err
583 583 + spacewire_stats.rx_rmap_header_crc_err;
584 584 spacewire_stats_backup.rx_rmap_data_crc_err = spacewire_stats_grspw.rx_rmap_data_crc_err
585 585 + spacewire_stats.rx_rmap_data_crc_err;
586 586 spacewire_stats_backup.early_ep = spacewire_stats_grspw.early_ep
587 587 + spacewire_stats.early_ep;
588 588 spacewire_stats_backup.invalid_address = spacewire_stats_grspw.invalid_address
589 589 + spacewire_stats.invalid_address;
590 590 spacewire_stats_backup.rx_eep_err = spacewire_stats_grspw.rx_eep_err
591 591 + spacewire_stats.rx_eep_err;
592 592 spacewire_stats_backup.rx_truncated = spacewire_stats_grspw.rx_truncated
593 593 + spacewire_stats.rx_truncated;
594 594 }
595 595
596 596 void spacewire_update_statistics( void )
597 597 {
598 598 rtems_status_code status;
599 599 spw_stats spacewire_stats_grspw;
600 600
601 601 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &spacewire_stats_grspw );
602 602
603 603 spacewire_stats.packets_received = spacewire_stats_backup.packets_received
604 604 + spacewire_stats_grspw.packets_received;
605 605 spacewire_stats.packets_sent = spacewire_stats_backup.packets_sent
606 606 + spacewire_stats_grspw.packets_sent;
607 607 spacewire_stats.parity_err = spacewire_stats_backup.parity_err
608 608 + spacewire_stats_grspw.parity_err;
609 609 spacewire_stats.disconnect_err = spacewire_stats_backup.disconnect_err
610 610 + spacewire_stats_grspw.disconnect_err;
611 611 spacewire_stats.escape_err = spacewire_stats_backup.escape_err
612 612 + spacewire_stats_grspw.escape_err;
613 613 spacewire_stats.credit_err = spacewire_stats_backup.credit_err
614 614 + spacewire_stats_grspw.credit_err;
615 615 spacewire_stats.write_sync_err = spacewire_stats_backup.write_sync_err
616 616 + spacewire_stats_grspw.write_sync_err;
617 617 spacewire_stats.rx_rmap_header_crc_err = spacewire_stats_backup.rx_rmap_header_crc_err
618 618 + spacewire_stats_grspw.rx_rmap_header_crc_err;
619 619 spacewire_stats.rx_rmap_data_crc_err = spacewire_stats_backup.rx_rmap_data_crc_err
620 620 + spacewire_stats_grspw.rx_rmap_data_crc_err;
621 621 spacewire_stats.early_ep = spacewire_stats_backup.early_ep
622 622 + spacewire_stats_grspw.early_ep;
623 623 spacewire_stats.invalid_address = spacewire_stats_backup.invalid_address
624 624 + spacewire_stats_grspw.invalid_address;
625 625 spacewire_stats.rx_eep_err = spacewire_stats_backup.rx_eep_err
626 626 + spacewire_stats_grspw.rx_eep_err;
627 627 spacewire_stats.rx_truncated = spacewire_stats_backup.rx_truncated
628 628 + spacewire_stats_grspw.rx_truncated;
629 629 //spacewire_stats.tx_link_err;
630 630
631 631 //****************************
632 632 // DPU_SPACEWIRE_IF_STATISTICS
633 633 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[0] = (unsigned char) (spacewire_stats.packets_received >> 8);
634 634 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[1] = (unsigned char) (spacewire_stats.packets_received);
635 635 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[0] = (unsigned char) (spacewire_stats.packets_sent >> 8);
636 636 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[1] = (unsigned char) (spacewire_stats.packets_sent);
637 637 //housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt;
638 638 //housekeeping_packet.hk_lfr_dpu_spw_last_timc;
639 639
640 640 //******************************************
641 641 // ERROR COUNTERS / SPACEWIRE / LOW SEVERITY
642 642 housekeeping_packet.hk_lfr_dpu_spw_parity = (unsigned char) spacewire_stats.parity_err;
643 643 housekeeping_packet.hk_lfr_dpu_spw_disconnect = (unsigned char) spacewire_stats.disconnect_err;
644 644 housekeeping_packet.hk_lfr_dpu_spw_escape = (unsigned char) spacewire_stats.escape_err;
645 645 housekeeping_packet.hk_lfr_dpu_spw_credit = (unsigned char) spacewire_stats.credit_err;
646 646 housekeeping_packet.hk_lfr_dpu_spw_write_sync = (unsigned char) spacewire_stats.write_sync_err;
647 647
648 648 //*********************************************
649 649 // ERROR COUNTERS / SPACEWIRE / MEDIUM SEVERITY
650 650 housekeeping_packet.hk_lfr_dpu_spw_early_eop = (unsigned char) spacewire_stats.early_ep;
651 651 housekeeping_packet.hk_lfr_dpu_spw_invalid_addr = (unsigned char) spacewire_stats.invalid_address;
652 652 housekeeping_packet.hk_lfr_dpu_spw_eep = (unsigned char) spacewire_stats.rx_eep_err;
653 653 housekeeping_packet.hk_lfr_dpu_spw_rx_too_big = (unsigned char) spacewire_stats.rx_truncated;
654 654 }
655 655
656 656 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc )
657 657 {
658 658 // a valid timecode has been received, write it in the HK report
659 659 unsigned int * grspwPtr;
660 660
661 661 grspwPtr = (unsigned int *) (REGS_ADDR_GRSPW + APB_OFFSET_GRSPW_TIME_REGISTER);
662 662
663 663 housekeeping_packet.hk_lfr_dpu_spw_last_timc = (unsigned char) (grspwPtr[0] & 0xff); // [11 1111]
664 664
665 665 // update the number of valid timecodes that have been received
666 666 if (housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt == 255)
667 667 {
668 668 housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt = 0;
669 669 }
670 670 else
671 671 {
672 672 housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt = housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt + 1;
673 673 }
674 674 }
675 675
676 676 rtems_timer_service_routine user_routine( rtems_id timer_id, void *user_data )
677 677 {
678 678 int linkStatus;
679 679 rtems_status_code status;
680 680
681 681 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
682 682
683 683 if ( linkStatus == 5) {
684 684 PRINTF("in spacewire_reset_link *** link is running\n")
685 685 status = RTEMS_SUCCESSFUL;
686 686 }
687 687 }
688 688
689 689 void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header )
690 690 {
691 691 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
692 692 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
693 693 header->reserved = DEFAULT_RESERVED;
694 694 header->userApplication = CCSDS_USER_APP;
695 695 header->packetSequenceControl[0]= TM_PACKET_SEQ_CTRL_STANDALONE;
696 696 header->packetSequenceControl[1]= TM_PACKET_SEQ_CNT_DEFAULT;
697 697 header->packetLength[0] = 0x00;
698 698 header->packetLength[1] = 0x00;
699 699 // DATA FIELD HEADER
700 700 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
701 701 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
702 702 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6; // service subtype
703 703 header->destinationID = TM_DESTINATION_ID_GROUND;
704 704 header->time[0] = 0x00;
705 705 header->time[0] = 0x00;
706 706 header->time[0] = 0x00;
707 707 header->time[0] = 0x00;
708 708 header->time[0] = 0x00;
709 709 header->time[0] = 0x00;
710 710 // AUXILIARY DATA HEADER
711 711 header->sid = 0x00;
712 712 header->hkBIA = DEFAULT_HKBIA;
713 713 header->blkNr[0] = 0x00;
714 714 header->blkNr[1] = 0x00;
715 715 }
716 716
717 717 void init_header_swf( Header_TM_LFR_SCIENCE_SWF_t *header )
718 718 {
719 719 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
720 720 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
721 721 header->reserved = DEFAULT_RESERVED;
722 722 header->userApplication = CCSDS_USER_APP;
723 723 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
724 724 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
725 725 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
726 726 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
727 727 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
728 728 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
729 729 // DATA FIELD HEADER
730 730 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
731 731 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
732 732 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6; // service subtype
733 733 header->destinationID = TM_DESTINATION_ID_GROUND;
734 734 header->time[0] = 0x00;
735 735 header->time[0] = 0x00;
736 736 header->time[0] = 0x00;
737 737 header->time[0] = 0x00;
738 738 header->time[0] = 0x00;
739 739 header->time[0] = 0x00;
740 740 // AUXILIARY DATA HEADER
741 741 header->sid = 0x00;
742 742 header->hkBIA = DEFAULT_HKBIA;
743 743 header->pktCnt = DEFAULT_PKTCNT; // PKT_CNT
744 744 header->pktNr = 0x00;
745 745 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
746 746 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
747 747 }
748 748
749 749 void init_header_asm( Header_TM_LFR_SCIENCE_ASM_t *header )
750 750 {
751 751 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
752 752 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
753 753 header->reserved = DEFAULT_RESERVED;
754 754 header->userApplication = CCSDS_USER_APP;
755 755 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
756 756 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
757 757 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
758 758 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
759 759 header->packetLength[0] = 0x00;
760 760 header->packetLength[1] = 0x00;
761 761 // DATA FIELD HEADER
762 762 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
763 763 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
764 764 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3; // service subtype
765 765 header->destinationID = TM_DESTINATION_ID_GROUND;
766 766 header->time[0] = 0x00;
767 767 header->time[0] = 0x00;
768 768 header->time[0] = 0x00;
769 769 header->time[0] = 0x00;
770 770 header->time[0] = 0x00;
771 771 header->time[0] = 0x00;
772 772 // AUXILIARY DATA HEADER
773 773 header->sid = 0x00;
774 774 header->biaStatusInfo = 0x00;
775 775 header->pa_lfr_pkt_cnt_asm = 0x00;
776 776 header->pa_lfr_pkt_nr_asm = 0x00;
777 777 header->pa_lfr_asm_blk_nr[0] = 0x00;
778 778 header->pa_lfr_asm_blk_nr[1] = 0x00;
779 779 }
780 780
781 781 int spw_send_waveform_CWF( ring_node *ring_node_to_send,
782 782 Header_TM_LFR_SCIENCE_CWF_t *header )
783 783 {
784 784 /** This function sends CWF CCSDS packets (F2, F1 or F0).
785 785 *
786 786 * @param waveform points to the buffer containing the data that will be send.
787 787 * @param sid is the source identifier of the data that will be sent.
788 788 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
789 789 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
790 790 * contain information to setup the transmission of the data packets.
791 791 *
792 792 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
793 793 *
794 794 */
795 795
796 796 unsigned int i;
797 797 int ret;
798 798 unsigned int coarseTime;
799 799 unsigned int fineTime;
800 800 rtems_status_code status;
801 801 spw_ioctl_pkt_send spw_ioctl_send_CWF;
802 802 int *dataPtr;
803 803 unsigned char sid;
804 804
805 805 spw_ioctl_send_CWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_CWF;
806 806 spw_ioctl_send_CWF.options = 0;
807 807
808 808 ret = LFR_DEFAULT;
809 809 sid = (unsigned char) ring_node_to_send->sid;
810 810
811 811 coarseTime = ring_node_to_send->coarseTime;
812 812 fineTime = ring_node_to_send->fineTime;
813 813 dataPtr = (int*) ring_node_to_send->buffer_address;
814 814
815 815 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
816 816 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
817 header->hkBIA = pa_bia_status_info;
817 818 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
818 819 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
819 820 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
820 821
821 822 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF; i++) // send waveform
822 823 {
823 824 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF * NB_WORDS_SWF_BLK) ];
824 825 spw_ioctl_send_CWF.hdr = (char*) header;
825 826 // BUILD THE DATA
826 827 spw_ioctl_send_CWF.dlen = BLK_NR_CWF * NB_BYTES_SWF_BLK;
827 828
828 829 // SET PACKET SEQUENCE CONTROL
829 830 increment_seq_counter_source_id( header->packetSequenceControl, sid );
830 831
831 832 // SET SID
832 833 header->sid = sid;
833 834
834 835 // SET PACKET TIME
835 836 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime);
836 837 //
837 838 header->time[0] = header->acquisitionTime[0];
838 839 header->time[1] = header->acquisitionTime[1];
839 840 header->time[2] = header->acquisitionTime[2];
840 841 header->time[3] = header->acquisitionTime[3];
841 842 header->time[4] = header->acquisitionTime[4];
842 843 header->time[5] = header->acquisitionTime[5];
843 844
844 845 // SET PACKET ID
845 846 if ( (sid == SID_SBM1_CWF_F1) || (sid == SID_SBM2_CWF_F2) )
846 847 {
847 848 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2 >> 8);
848 849 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2);
849 850 }
850 851 else
851 852 {
852 853 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
853 854 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
854 855 }
855 856
856 857 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
857 858 if (status != RTEMS_SUCCESSFUL) {
858 859 printf("%d-%d, ERR %d\n", sid, i, (int) status);
859 860 ret = LFR_DEFAULT;
860 861 }
861 862 }
862 863
863 864 return ret;
864 865 }
865 866
866 867 int spw_send_waveform_SWF( ring_node *ring_node_to_send,
867 868 Header_TM_LFR_SCIENCE_SWF_t *header )
868 869 {
869 870 /** This function sends SWF CCSDS packets (F2, F1 or F0).
870 871 *
871 872 * @param waveform points to the buffer containing the data that will be send.
872 873 * @param sid is the source identifier of the data that will be sent.
873 874 * @param headerSWF points to a table of headers that have been prepared for the data transmission.
874 875 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
875 876 * contain information to setup the transmission of the data packets.
876 877 *
877 878 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
878 879 *
879 880 */
880 881
881 882 unsigned int i;
882 883 int ret;
883 884 unsigned int coarseTime;
884 885 unsigned int fineTime;
885 886 rtems_status_code status;
886 887 spw_ioctl_pkt_send spw_ioctl_send_SWF;
887 888 int *dataPtr;
888 889 unsigned char sid;
889 890
890 891 spw_ioctl_send_SWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_SWF;
891 892 spw_ioctl_send_SWF.options = 0;
892 893
893 894 ret = LFR_DEFAULT;
894 895
895 896 coarseTime = ring_node_to_send->coarseTime;
896 897 fineTime = ring_node_to_send->fineTime;
897 898 dataPtr = (int*) ring_node_to_send->buffer_address;
898 899 sid = ring_node_to_send->sid;
899 900
901 header->hkBIA = pa_bia_status_info;
900 902 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
901 903
902 904 for (i=0; i<7; i++) // send waveform
903 905 {
904 906 spw_ioctl_send_SWF.data = (char*) &dataPtr[ (i * BLK_NR_304 * NB_WORDS_SWF_BLK) ];
905 907 spw_ioctl_send_SWF.hdr = (char*) header;
906 908
907 909 // SET PACKET SEQUENCE CONTROL
908 910 increment_seq_counter_source_id( header->packetSequenceControl, sid );
909 911
910 912 // SET PACKET LENGTH AND BLKNR
911 913 if (i == 6)
912 914 {
913 915 spw_ioctl_send_SWF.dlen = BLK_NR_224 * NB_BYTES_SWF_BLK;
914 916 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_224 >> 8);
915 917 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_224 );
916 918 header->blkNr[0] = (unsigned char) (BLK_NR_224 >> 8);
917 919 header->blkNr[1] = (unsigned char) (BLK_NR_224 );
918 920 }
919 921 else
920 922 {
921 923 spw_ioctl_send_SWF.dlen = BLK_NR_304 * NB_BYTES_SWF_BLK;
922 924 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_304 >> 8);
923 925 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_304 );
924 926 header->blkNr[0] = (unsigned char) (BLK_NR_304 >> 8);
925 927 header->blkNr[1] = (unsigned char) (BLK_NR_304 );
926 928 }
927 929
928 930 // SET PACKET TIME
929 931 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime );
930 932 //
931 933 header->time[0] = header->acquisitionTime[0];
932 934 header->time[1] = header->acquisitionTime[1];
933 935 header->time[2] = header->acquisitionTime[2];
934 936 header->time[3] = header->acquisitionTime[3];
935 937 header->time[4] = header->acquisitionTime[4];
936 938 header->time[5] = header->acquisitionTime[5];
937 939
938 940 // SET SID
939 941 header->sid = sid;
940 942
941 943 // SET PKTNR
942 944 header->pktNr = i+1; // PKT_NR
943 945
944 946 // SEND PACKET
945 947 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_SWF );
946 948 if (status != RTEMS_SUCCESSFUL) {
947 949 printf("%d-%d, ERR %d\n", sid, i, (int) status);
948 950 ret = LFR_DEFAULT;
949 951 }
950 952 }
951 953
952 954 return ret;
953 955 }
954 956
955 957 int spw_send_waveform_CWF3_light( ring_node *ring_node_to_send,
956 958 Header_TM_LFR_SCIENCE_CWF_t *header )
957 959 {
958 960 /** This function sends CWF_F3 CCSDS packets without the b1, b2 and b3 data.
959 961 *
960 962 * @param waveform points to the buffer containing the data that will be send.
961 963 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
962 964 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
963 965 * contain information to setup the transmission of the data packets.
964 966 *
965 967 * By default, CWF_F3 packet are send without the b1, b2 and b3 data. This function rebuilds a data buffer
966 968 * from the incoming data and sends it in 7 packets, 6 containing 340 blocks and 1 one containing 8 blocks.
967 969 *
968 970 */
969 971
970 972 unsigned int i;
971 973 int ret;
972 974 unsigned int coarseTime;
973 975 unsigned int fineTime;
974 976 rtems_status_code status;
975 977 spw_ioctl_pkt_send spw_ioctl_send_CWF;
976 978 char *dataPtr;
977 979 unsigned char sid;
978 980
979 981 spw_ioctl_send_CWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_CWF;
980 982 spw_ioctl_send_CWF.options = 0;
981 983
982 984 ret = LFR_DEFAULT;
983 985 sid = ring_node_to_send->sid;
984 986
985 987 coarseTime = ring_node_to_send->coarseTime;
986 988 fineTime = ring_node_to_send->fineTime;
987 989 dataPtr = (char*) ring_node_to_send->buffer_address;
988 990
989 991 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_672 >> 8);
990 992 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_672 );
993 header->hkBIA = pa_bia_status_info;
991 994 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
992 995 header->blkNr[0] = (unsigned char) (BLK_NR_CWF_SHORT_F3 >> 8);
993 996 header->blkNr[1] = (unsigned char) (BLK_NR_CWF_SHORT_F3 );
994 997
995 998 //*********************
996 999 // SEND CWF3_light DATA
997 1000 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF_LIGHT; i++) // send waveform
998 1001 {
999 1002 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK) ];
1000 1003 spw_ioctl_send_CWF.hdr = (char*) header;
1001 1004 // BUILD THE DATA
1002 1005 spw_ioctl_send_CWF.dlen = BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK;
1003 1006
1004 1007 // SET PACKET SEQUENCE COUNTER
1005 1008 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1006 1009
1007 1010 // SET SID
1008 1011 header->sid = sid;
1009 1012
1010 1013 // SET PACKET TIME
1011 1014 compute_acquisition_time( coarseTime, fineTime, SID_NORM_CWF_F3, i, header->acquisitionTime );
1012 1015 //
1013 1016 header->time[0] = header->acquisitionTime[0];
1014 1017 header->time[1] = header->acquisitionTime[1];
1015 1018 header->time[2] = header->acquisitionTime[2];
1016 1019 header->time[3] = header->acquisitionTime[3];
1017 1020 header->time[4] = header->acquisitionTime[4];
1018 1021 header->time[5] = header->acquisitionTime[5];
1019 1022
1020 1023 // SET PACKET ID
1021 1024 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1022 1025 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1023 1026
1024 1027 // SEND PACKET
1025 1028 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
1026 1029 if (status != RTEMS_SUCCESSFUL) {
1027 1030 printf("%d-%d, ERR %d\n", sid, i, (int) status);
1028 1031 ret = LFR_DEFAULT;
1029 1032 }
1030 1033 }
1031 1034
1032 1035 return ret;
1033 1036 }
1034 1037
1035 1038 void spw_send_asm_f0( ring_node *ring_node_to_send,
1036 1039 Header_TM_LFR_SCIENCE_ASM_t *header )
1037 1040 {
1038 1041 unsigned int i;
1039 1042 unsigned int length = 0;
1040 1043 rtems_status_code status;
1041 1044 unsigned int sid;
1042 1045 float *spectral_matrix;
1043 1046 int coarseTime;
1044 1047 int fineTime;
1045 1048 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1046 1049
1047 1050 sid = ring_node_to_send->sid;
1048 1051 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1049 1052 coarseTime = ring_node_to_send->coarseTime;
1050 1053 fineTime = ring_node_to_send->fineTime;
1051 1054
1055 header->biaStatusInfo = pa_bia_status_info;
1052 1056 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1053 1057
1054 1058 for (i=0; i<3; i++)
1055 1059 {
1056 1060 if ((i==0) || (i==1))
1057 1061 {
1058 1062 spw_ioctl_send_ASM.dlen = DLEN_ASM_F0_PKT_1;
1059 1063 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1060 1064 ( (ASM_F0_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F0_1) ) * NB_VALUES_PER_SM )
1061 1065 ];
1062 1066 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0_1;
1063 1067 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1064 1068 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0_1) >> 8 ); // BLK_NR MSB
1065 1069 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0_1); // BLK_NR LSB
1066 1070 }
1067 1071 else
1068 1072 {
1069 1073 spw_ioctl_send_ASM.dlen = DLEN_ASM_F0_PKT_2;
1070 1074 spw_ioctl_send_ASM.data = (char*) &spectral_matrix[
1071 1075 ( (ASM_F0_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F0_1) ) * NB_VALUES_PER_SM )
1072 1076 ];
1073 1077 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0_2;
1074 1078 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1075 1079 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0_2) >> 8 ); // BLK_NR MSB
1076 1080 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0_2); // BLK_NR LSB
1077 1081 }
1078 1082
1079 1083 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1080 1084 spw_ioctl_send_ASM.hdr = (char *) header;
1081 1085 spw_ioctl_send_ASM.options = 0;
1082 1086
1083 1087 // (2) BUILD THE HEADER
1084 1088 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1085 1089 header->packetLength[0] = (unsigned char) (length>>8);
1086 1090 header->packetLength[1] = (unsigned char) (length);
1087 1091 header->sid = (unsigned char) sid; // SID
1088 1092 header->pa_lfr_pkt_cnt_asm = 3;
1089 1093 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1090 1094
1091 1095 // (3) SET PACKET TIME
1092 1096 header->time[0] = (unsigned char) (coarseTime>>24);
1093 1097 header->time[1] = (unsigned char) (coarseTime>>16);
1094 1098 header->time[2] = (unsigned char) (coarseTime>>8);
1095 1099 header->time[3] = (unsigned char) (coarseTime);
1096 1100 header->time[4] = (unsigned char) (fineTime>>8);
1097 1101 header->time[5] = (unsigned char) (fineTime);
1098 1102 //
1099 1103 header->acquisitionTime[0] = header->time[0];
1100 1104 header->acquisitionTime[1] = header->time[1];
1101 1105 header->acquisitionTime[2] = header->time[2];
1102 1106 header->acquisitionTime[3] = header->time[3];
1103 1107 header->acquisitionTime[4] = header->time[4];
1104 1108 header->acquisitionTime[5] = header->time[5];
1105 1109
1106 1110 // (4) SEND PACKET
1107 1111 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1108 1112 if (status != RTEMS_SUCCESSFUL) {
1109 1113 printf("in ASM_send *** ERR %d\n", (int) status);
1110 1114 }
1111 1115 }
1112 1116 }
1113 1117
1114 1118 void spw_send_asm_f1( ring_node *ring_node_to_send,
1115 1119 Header_TM_LFR_SCIENCE_ASM_t *header )
1116 1120 {
1117 1121 unsigned int i;
1118 1122 unsigned int length = 0;
1119 1123 rtems_status_code status;
1120 1124 unsigned int sid;
1121 1125 float *spectral_matrix;
1122 1126 int coarseTime;
1123 1127 int fineTime;
1124 1128 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1125 1129
1126 1130 sid = ring_node_to_send->sid;
1127 1131 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1128 1132 coarseTime = ring_node_to_send->coarseTime;
1129 1133 fineTime = ring_node_to_send->fineTime;
1130 1134
1135 header->biaStatusInfo = pa_bia_status_info;
1131 1136 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1132 1137
1133 1138 for (i=0; i<3; i++)
1134 1139 {
1135 1140 if ((i==0) || (i==1))
1136 1141 {
1137 1142 spw_ioctl_send_ASM.dlen = DLEN_ASM_F1_PKT_1;
1138 1143 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1139 1144 ( (ASM_F1_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F1_1) ) * NB_VALUES_PER_SM )
1140 1145 ];
1141 1146 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F1_1;
1142 1147 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1143 1148 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F1_1) >> 8 ); // BLK_NR MSB
1144 1149 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F1_1); // BLK_NR LSB
1145 1150 }
1146 1151 else
1147 1152 {
1148 1153 spw_ioctl_send_ASM.dlen = DLEN_ASM_F1_PKT_2;
1149 1154 spw_ioctl_send_ASM.data = (char*) &spectral_matrix[
1150 1155 ( (ASM_F1_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F1_1) ) * NB_VALUES_PER_SM )
1151 1156 ];
1152 1157 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F1_2;
1153 1158 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1154 1159 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F1_2) >> 8 ); // BLK_NR MSB
1155 1160 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F1_2); // BLK_NR LSB
1156 1161 }
1157 1162
1158 1163 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1159 1164 spw_ioctl_send_ASM.hdr = (char *) header;
1160 1165 spw_ioctl_send_ASM.options = 0;
1161 1166
1162 1167 // (2) BUILD THE HEADER
1163 1168 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1164 1169 header->packetLength[0] = (unsigned char) (length>>8);
1165 1170 header->packetLength[1] = (unsigned char) (length);
1166 1171 header->sid = (unsigned char) sid; // SID
1167 1172 header->pa_lfr_pkt_cnt_asm = 3;
1168 1173 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1169 1174
1170 1175 // (3) SET PACKET TIME
1171 1176 header->time[0] = (unsigned char) (coarseTime>>24);
1172 1177 header->time[1] = (unsigned char) (coarseTime>>16);
1173 1178 header->time[2] = (unsigned char) (coarseTime>>8);
1174 1179 header->time[3] = (unsigned char) (coarseTime);
1175 1180 header->time[4] = (unsigned char) (fineTime>>8);
1176 1181 header->time[5] = (unsigned char) (fineTime);
1177 1182 //
1178 1183 header->acquisitionTime[0] = header->time[0];
1179 1184 header->acquisitionTime[1] = header->time[1];
1180 1185 header->acquisitionTime[2] = header->time[2];
1181 1186 header->acquisitionTime[3] = header->time[3];
1182 1187 header->acquisitionTime[4] = header->time[4];
1183 1188 header->acquisitionTime[5] = header->time[5];
1184 1189
1185 1190 // (4) SEND PACKET
1186 1191 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1187 1192 if (status != RTEMS_SUCCESSFUL) {
1188 1193 printf("in ASM_send *** ERR %d\n", (int) status);
1189 1194 }
1190 1195 }
1191 1196 }
1192 1197
1193 1198 void spw_send_asm_f2( ring_node *ring_node_to_send,
1194 1199 Header_TM_LFR_SCIENCE_ASM_t *header )
1195 1200 {
1196 1201 unsigned int i;
1197 1202 unsigned int length = 0;
1198 1203 rtems_status_code status;
1199 1204 unsigned int sid;
1200 1205 float *spectral_matrix;
1201 1206 int coarseTime;
1202 1207 int fineTime;
1203 1208 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1204 1209
1205 1210 sid = ring_node_to_send->sid;
1206 1211 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1207 1212 coarseTime = ring_node_to_send->coarseTime;
1208 1213 fineTime = ring_node_to_send->fineTime;
1209 1214
1215 header->biaStatusInfo = pa_bia_status_info;
1210 1216 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1211 1217
1212 1218 for (i=0; i<3; i++)
1213 1219 {
1214 1220
1215 1221 spw_ioctl_send_ASM.dlen = DLEN_ASM_F2_PKT;
1216 1222 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1217 1223 ( (ASM_F2_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F2) ) * NB_VALUES_PER_SM )
1218 1224 ];
1219 1225 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F2;
1220 1226 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3;
1221 1227 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F2) >> 8 ); // BLK_NR MSB
1222 1228 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F2); // BLK_NR LSB
1223 1229
1224 1230 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1225 1231 spw_ioctl_send_ASM.hdr = (char *) header;
1226 1232 spw_ioctl_send_ASM.options = 0;
1227 1233
1228 1234 // (2) BUILD THE HEADER
1229 1235 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1230 1236 header->packetLength[0] = (unsigned char) (length>>8);
1231 1237 header->packetLength[1] = (unsigned char) (length);
1232 1238 header->sid = (unsigned char) sid; // SID
1233 1239 header->pa_lfr_pkt_cnt_asm = 3;
1234 1240 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1235 1241
1236 1242 // (3) SET PACKET TIME
1237 1243 header->time[0] = (unsigned char) (coarseTime>>24);
1238 1244 header->time[1] = (unsigned char) (coarseTime>>16);
1239 1245 header->time[2] = (unsigned char) (coarseTime>>8);
1240 1246 header->time[3] = (unsigned char) (coarseTime);
1241 1247 header->time[4] = (unsigned char) (fineTime>>8);
1242 1248 header->time[5] = (unsigned char) (fineTime);
1243 1249 //
1244 1250 header->acquisitionTime[0] = header->time[0];
1245 1251 header->acquisitionTime[1] = header->time[1];
1246 1252 header->acquisitionTime[2] = header->time[2];
1247 1253 header->acquisitionTime[3] = header->time[3];
1248 1254 header->acquisitionTime[4] = header->time[4];
1249 1255 header->acquisitionTime[5] = header->time[5];
1250 1256
1251 1257 // (4) SEND PACKET
1252 1258 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1253 1259 if (status != RTEMS_SUCCESSFUL) {
1254 1260 printf("in ASM_send *** ERR %d\n", (int) status);
1255 1261 }
1256 1262 }
1257 1263 }
1258 1264
1259 1265 void spw_send_k_dump( ring_node *ring_node_to_send )
1260 1266 {
1261 1267 rtems_status_code status;
1262 1268 Packet_TM_LFR_KCOEFFICIENTS_DUMP_t *kcoefficients_dump;
1263 1269 unsigned int packetLength;
1264 1270 unsigned int size;
1265 1271
1266 1272 printf("spw_send_k_dump\n");
1267 1273
1268 1274 kcoefficients_dump = (Packet_TM_LFR_KCOEFFICIENTS_DUMP_t *) ring_node_to_send->buffer_address;
1269 1275
1270 1276 packetLength = kcoefficients_dump->packetLength[0] * 256 + kcoefficients_dump->packetLength[1];
1271 1277
1272 1278 size = packetLength + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
1273 1279
1274 1280 printf("packetLength %d, size %d\n", packetLength, size );
1275 1281
1276 1282 status = write( fdSPW, (char *) ring_node_to_send->buffer_address, size );
1277 1283
1278 1284 if (status == -1){
1279 1285 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
1280 1286 }
1281 1287
1282 1288 ring_node_to_send->status = 0x00;
1283 1289 }
@@ -1,1169 +1,1180
1 1 /** Functions and tasks related to TeleCommand handling.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * A group of functions to handle TeleCommands:\n
7 7 * action launching\n
8 8 * TC parsing\n
9 9 * ...
10 10 *
11 11 */
12 12
13 13 #include "tc_handler.h"
14 14 #include "math.h"
15 15
16 16 //***********
17 17 // RTEMS TASK
18 18
19 19 rtems_task actn_task( rtems_task_argument unused )
20 20 {
21 21 /** This RTEMS task is responsible for launching actions upton the reception of valid TeleCommands.
22 22 *
23 23 * @param unused is the starting argument of the RTEMS task
24 24 *
25 25 * The ACTN task waits for data coming from an RTEMS msesage queue. When data arrives, it launches specific actions depending
26 26 * on the incoming TeleCommand.
27 27 *
28 28 */
29 29
30 30 int result;
31 31 rtems_status_code status; // RTEMS status code
32 32 ccsdsTelecommandPacket_t TC; // TC sent to the ACTN task
33 33 size_t size; // size of the incoming TC packet
34 34 unsigned char subtype; // subtype of the current TC packet
35 35 unsigned char time[6];
36 36 rtems_id queue_rcv_id;
37 37 rtems_id queue_snd_id;
38 38
39 39 status = get_message_queue_id_recv( &queue_rcv_id );
40 40 if (status != RTEMS_SUCCESSFUL)
41 41 {
42 42 PRINTF1("in ACTN *** ERR get_message_queue_id_recv %d\n", status)
43 43 }
44 44
45 45 status = get_message_queue_id_send( &queue_snd_id );
46 46 if (status != RTEMS_SUCCESSFUL)
47 47 {
48 48 PRINTF1("in ACTN *** ERR get_message_queue_id_send %d\n", status)
49 49 }
50 50
51 51 result = LFR_SUCCESSFUL;
52 52 subtype = 0; // subtype of the current TC packet
53 53
54 54 BOOT_PRINTF("in ACTN *** \n")
55 55
56 56 while(1)
57 57 {
58 58 status = rtems_message_queue_receive( queue_rcv_id, (char*) &TC, &size,
59 59 RTEMS_WAIT, RTEMS_NO_TIMEOUT);
60 60 getTime( time ); // set time to the current time
61 61 if (status!=RTEMS_SUCCESSFUL)
62 62 {
63 63 PRINTF1("ERR *** in task ACTN *** error receiving a message, code %d \n", status)
64 64 }
65 65 else
66 66 {
67 67 subtype = TC.serviceSubType;
68 68 switch(subtype)
69 69 {
70 70 case TC_SUBTYPE_RESET:
71 71 result = action_reset( &TC, queue_snd_id, time );
72 72 close_action( &TC, result, queue_snd_id );
73 73 break;
74 74 case TC_SUBTYPE_LOAD_COMM:
75 75 result = action_load_common_par( &TC );
76 76 close_action( &TC, result, queue_snd_id );
77 77 break;
78 78 case TC_SUBTYPE_LOAD_NORM:
79 79 result = action_load_normal_par( &TC, queue_snd_id, time );
80 80 close_action( &TC, result, queue_snd_id );
81 81 break;
82 82 case TC_SUBTYPE_LOAD_BURST:
83 83 result = action_load_burst_par( &TC, queue_snd_id, time );
84 84 close_action( &TC, result, queue_snd_id );
85 85 break;
86 86 case TC_SUBTYPE_LOAD_SBM1:
87 87 result = action_load_sbm1_par( &TC, queue_snd_id, time );
88 88 close_action( &TC, result, queue_snd_id );
89 89 break;
90 90 case TC_SUBTYPE_LOAD_SBM2:
91 91 result = action_load_sbm2_par( &TC, queue_snd_id, time );
92 92 close_action( &TC, result, queue_snd_id );
93 93 break;
94 94 case TC_SUBTYPE_DUMP:
95 95 result = action_dump_par( &TC, queue_snd_id );
96 96 close_action( &TC, result, queue_snd_id );
97 97 break;
98 98 case TC_SUBTYPE_ENTER:
99 99 result = action_enter_mode( &TC, queue_snd_id );
100 100 close_action( &TC, result, queue_snd_id );
101 101 break;
102 102 case TC_SUBTYPE_UPDT_INFO:
103 103 result = action_update_info( &TC, queue_snd_id );
104 104 close_action( &TC, result, queue_snd_id );
105 105 break;
106 106 case TC_SUBTYPE_EN_CAL:
107 107 result = action_enable_calibration( &TC, queue_snd_id, time );
108 108 close_action( &TC, result, queue_snd_id );
109 109 break;
110 110 case TC_SUBTYPE_DIS_CAL:
111 111 result = action_disable_calibration( &TC, queue_snd_id, time );
112 112 close_action( &TC, result, queue_snd_id );
113 113 break;
114 114 case TC_SUBTYPE_LOAD_K:
115 115 result = action_load_kcoefficients( &TC, queue_snd_id, time );
116 116 close_action( &TC, result, queue_snd_id );
117 117 break;
118 118 case TC_SUBTYPE_DUMP_K:
119 119 result = action_dump_kcoefficients( &TC, queue_snd_id, time );
120 120 close_action( &TC, result, queue_snd_id );
121 121 break;
122 122 case TC_SUBTYPE_LOAD_FBINS:
123 123 result = action_load_fbins_mask( &TC, queue_snd_id, time );
124 124 close_action( &TC, result, queue_snd_id );
125 125 break;
126 126 case TC_SUBTYPE_UPDT_TIME:
127 127 result = action_update_time( &TC );
128 128 close_action( &TC, result, queue_snd_id );
129 129 break;
130 130 default:
131 131 break;
132 132 }
133 133 }
134 134 }
135 135 }
136 136
137 137 //***********
138 138 // TC ACTIONS
139 139
140 140 int action_reset(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
141 141 {
142 142 /** This function executes specific actions when a TC_LFR_RESET TeleCommand has been received.
143 143 *
144 144 * @param TC points to the TeleCommand packet that is being processed
145 145 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
146 146 *
147 147 */
148 148
149 149 printf("this is the end!!!\n");
150 150 exit(0);
151 151 send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time );
152 152 return LFR_DEFAULT;
153 153 }
154 154
155 155 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id )
156 156 {
157 157 /** This function executes specific actions when a TC_LFR_ENTER_MODE TeleCommand has been received.
158 158 *
159 159 * @param TC points to the TeleCommand packet that is being processed
160 160 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
161 161 *
162 162 */
163 163
164 164 rtems_status_code status;
165 165 unsigned char requestedMode;
166 166 unsigned int *transitionCoarseTime_ptr;
167 167 unsigned int transitionCoarseTime;
168 168 unsigned char * bytePosPtr;
169 169
170 170 bytePosPtr = (unsigned char *) &TC->packetID;
171 171
172 172 requestedMode = bytePosPtr[ BYTE_POS_CP_MODE_LFR_SET ];
173 173 transitionCoarseTime_ptr = (unsigned int *) ( &bytePosPtr[ BYTE_POS_CP_LFR_ENTER_MODE_TIME ] );
174 174 transitionCoarseTime = (*transitionCoarseTime_ptr) & 0x7fffffff;
175 175
176 176 status = check_mode_value( requestedMode );
177 177
178 178 if ( status != LFR_SUCCESSFUL ) // the mode value is inconsistent
179 179 {
180 180 send_tm_lfr_tc_exe_inconsistent( TC, queue_id, BYTE_POS_CP_MODE_LFR_SET, requestedMode );
181 181 }
182 182 else // the mode value is valid, check the transition
183 183 {
184 184 status = check_mode_transition(requestedMode);
185 185 if (status != LFR_SUCCESSFUL)
186 186 {
187 187 PRINTF("ERR *** in action_enter_mode *** check_mode_transition\n")
188 188 send_tm_lfr_tc_exe_not_executable( TC, queue_id );
189 189 }
190 190 }
191 191
192 192 if ( status == LFR_SUCCESSFUL ) // the transition is valid, check the date
193 193 {
194 194 status = check_transition_date( transitionCoarseTime );
195 195 if (status != LFR_SUCCESSFUL)
196 196 {
197 197 PRINTF("ERR *** in action_enter_mode *** check_transition_date\n")
198 198 send_tm_lfr_tc_exe_inconsistent( TC, queue_id,
199 199 BYTE_POS_CP_LFR_ENTER_MODE_TIME,
200 200 bytePosPtr[ BYTE_POS_CP_LFR_ENTER_MODE_TIME + 3 ] );
201 201 }
202 202 }
203 203
204 204 if ( status == LFR_SUCCESSFUL ) // the date is valid, enter the mode
205 205 {
206 206 PRINTF1("OK *** in action_enter_mode *** enter mode %d\n", requestedMode);
207 207 status = enter_mode( requestedMode, transitionCoarseTime );
208 208 }
209 209
210 210 return status;
211 211 }
212 212
213 213 int action_update_info(ccsdsTelecommandPacket_t *TC, rtems_id queue_id)
214 214 {
215 215 /** This function executes specific actions when a TC_LFR_UPDATE_INFO TeleCommand has been received.
216 216 *
217 217 * @param TC points to the TeleCommand packet that is being processed
218 218 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
219 219 *
220 220 * @return LFR directive status code:
221 221 * - LFR_DEFAULT
222 222 * - LFR_SUCCESSFUL
223 223 *
224 224 */
225 225
226 226 unsigned int val;
227 227 int result;
228 228 unsigned int status;
229 229 unsigned char mode;
230 230 unsigned char * bytePosPtr;
231 231
232 232 bytePosPtr = (unsigned char *) &TC->packetID;
233 233
234 234 // check LFR mode
235 235 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET5 ] & 0x1e) >> 1;
236 236 status = check_update_info_hk_lfr_mode( mode );
237 237 if (status == LFR_SUCCESSFUL) // check TDS mode
238 238 {
239 239 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & 0xf0) >> 4;
240 240 status = check_update_info_hk_tds_mode( mode );
241 241 }
242 242 if (status == LFR_SUCCESSFUL) // check THR mode
243 243 {
244 244 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & 0x0f);
245 245 status = check_update_info_hk_thr_mode( mode );
246 246 }
247 247 if (status == LFR_SUCCESSFUL) // if the parameter check is successful
248 248 {
249 249 val = housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * 256
250 250 + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
251 251 val++;
252 252 housekeeping_packet.hk_lfr_update_info_tc_cnt[0] = (unsigned char) (val >> 8);
253 253 housekeeping_packet.hk_lfr_update_info_tc_cnt[1] = (unsigned char) (val);
254 254 }
255 255
256 // pa_bia_status_info
257 // => pa_bia_mode_mux_set 3 bits
258 // => pa_bia_mode_hv_enabled 1 bit
259 // => pa_bia_mode_bias1_enabled 1 bit
260 // => pa_bia_mode_bias2_enabled 1 bit
261 // => pa_bia_mode_bias3_enabled 1 bit
262 // => pa_bia_on_off (cp_dpu_bias_on_off)
263 pa_bia_status_info = bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET2 ] & 0xfe; // [1111 1110]
264 pa_bia_status_info = pa_bia_status_info
265 | (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET1 ] & 0x1);
266
256 267 result = status;
257 268
258 269 return result;
259 270 }
260 271
261 272 int action_enable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
262 273 {
263 274 /** This function executes specific actions when a TC_LFR_ENABLE_CALIBRATION TeleCommand has been received.
264 275 *
265 276 * @param TC points to the TeleCommand packet that is being processed
266 277 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
267 278 *
268 279 */
269 280
270 281 int result;
271 282
272 283 result = LFR_DEFAULT;
273 284
274 285 setCalibration( true );
275 286
276 287 result = LFR_SUCCESSFUL;
277 288
278 289 return result;
279 290 }
280 291
281 292 int action_disable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
282 293 {
283 294 /** This function executes specific actions when a TC_LFR_DISABLE_CALIBRATION TeleCommand has been received.
284 295 *
285 296 * @param TC points to the TeleCommand packet that is being processed
286 297 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
287 298 *
288 299 */
289 300
290 301 int result;
291 302
292 303 result = LFR_DEFAULT;
293 304
294 305 setCalibration( false );
295 306
296 307 result = LFR_SUCCESSFUL;
297 308
298 309 return result;
299 310 }
300 311
301 312 int action_update_time(ccsdsTelecommandPacket_t *TC)
302 313 {
303 314 /** This function executes specific actions when a TC_LFR_UPDATE_TIME TeleCommand has been received.
304 315 *
305 316 * @param TC points to the TeleCommand packet that is being processed
306 317 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
307 318 *
308 319 * @return LFR_SUCCESSFUL
309 320 *
310 321 */
311 322
312 323 unsigned int val;
313 324
314 325 time_management_regs->coarse_time_load = (TC->dataAndCRC[0] << 24)
315 326 + (TC->dataAndCRC[1] << 16)
316 327 + (TC->dataAndCRC[2] << 8)
317 328 + TC->dataAndCRC[3];
318 329
319 330 val = housekeeping_packet.hk_lfr_update_time_tc_cnt[0] * 256
320 331 + housekeeping_packet.hk_lfr_update_time_tc_cnt[1];
321 332 val++;
322 333 housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char) (val >> 8);
323 334 housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char) (val);
324 335
325 336 return LFR_SUCCESSFUL;
326 337 }
327 338
328 339 //*******************
329 340 // ENTERING THE MODES
330 341 int check_mode_value( unsigned char requestedMode )
331 342 {
332 343 int status;
333 344
334 345 if ( (requestedMode != LFR_MODE_STANDBY)
335 346 && (requestedMode != LFR_MODE_NORMAL) && (requestedMode != LFR_MODE_BURST)
336 347 && (requestedMode != LFR_MODE_SBM1) && (requestedMode != LFR_MODE_SBM2) )
337 348 {
338 349 status = LFR_DEFAULT;
339 350 }
340 351 else
341 352 {
342 353 status = LFR_SUCCESSFUL;
343 354 }
344 355
345 356 return status;
346 357 }
347 358
348 359 int check_mode_transition( unsigned char requestedMode )
349 360 {
350 361 /** This function checks the validity of the transition requested by the TC_LFR_ENTER_MODE.
351 362 *
352 363 * @param requestedMode is the mode requested by the TC_LFR_ENTER_MODE
353 364 *
354 365 * @return LFR directive status codes:
355 366 * - LFR_SUCCESSFUL - the transition is authorized
356 367 * - LFR_DEFAULT - the transition is not authorized
357 368 *
358 369 */
359 370
360 371 int status;
361 372
362 373 switch (requestedMode)
363 374 {
364 375 case LFR_MODE_STANDBY:
365 376 if ( lfrCurrentMode == LFR_MODE_STANDBY ) {
366 377 status = LFR_DEFAULT;
367 378 }
368 379 else
369 380 {
370 381 status = LFR_SUCCESSFUL;
371 382 }
372 383 break;
373 384 case LFR_MODE_NORMAL:
374 385 if ( lfrCurrentMode == LFR_MODE_NORMAL ) {
375 386 status = LFR_DEFAULT;
376 387 }
377 388 else {
378 389 status = LFR_SUCCESSFUL;
379 390 }
380 391 break;
381 392 case LFR_MODE_BURST:
382 393 if ( lfrCurrentMode == LFR_MODE_BURST ) {
383 394 status = LFR_DEFAULT;
384 395 }
385 396 else {
386 397 status = LFR_SUCCESSFUL;
387 398 }
388 399 break;
389 400 case LFR_MODE_SBM1:
390 401 if ( lfrCurrentMode == LFR_MODE_SBM1 ) {
391 402 status = LFR_DEFAULT;
392 403 }
393 404 else {
394 405 status = LFR_SUCCESSFUL;
395 406 }
396 407 break;
397 408 case LFR_MODE_SBM2:
398 409 if ( lfrCurrentMode == LFR_MODE_SBM2 ) {
399 410 status = LFR_DEFAULT;
400 411 }
401 412 else {
402 413 status = LFR_SUCCESSFUL;
403 414 }
404 415 break;
405 416 default:
406 417 status = LFR_DEFAULT;
407 418 break;
408 419 }
409 420
410 421 return status;
411 422 }
412 423
413 424 int check_transition_date( unsigned int transitionCoarseTime )
414 425 {
415 426 int status;
416 427 unsigned int localCoarseTime;
417 428 unsigned int deltaCoarseTime;
418 429
419 430 status = LFR_SUCCESSFUL;
420 431
421 432 if (transitionCoarseTime == 0) // transition time = 0 means an instant transition
422 433 {
423 434 status = LFR_SUCCESSFUL;
424 435 }
425 436 else
426 437 {
427 438 localCoarseTime = time_management_regs->coarse_time & 0x7fffffff;
428 439
429 440 PRINTF2("localTime = %x, transitionTime = %x\n", localCoarseTime, transitionCoarseTime)
430 441
431 442 if ( transitionCoarseTime <= localCoarseTime ) // SSS-CP-EQS-322
432 443 {
433 444 status = LFR_DEFAULT;
434 445 PRINTF("ERR *** in check_transition_date *** transitionCoarseTime <= localCoarseTime\n")
435 446 }
436 447
437 448 if (status == LFR_SUCCESSFUL)
438 449 {
439 450 deltaCoarseTime = transitionCoarseTime - localCoarseTime;
440 451 if ( deltaCoarseTime > 3 ) // SSS-CP-EQS-323
441 452 {
442 453 status = LFR_DEFAULT;
443 454 PRINTF1("ERR *** in check_transition_date *** deltaCoarseTime = %x\n", deltaCoarseTime)
444 455 }
445 456 }
446 457 }
447 458
448 459 return status;
449 460 }
450 461
451 462 int stop_current_mode( void )
452 463 {
453 464 /** This function stops the current mode by masking interrupt lines and suspending science tasks.
454 465 *
455 466 * @return RTEMS directive status codes:
456 467 * - RTEMS_SUCCESSFUL - task restarted successfully
457 468 * - RTEMS_INVALID_ID - task id invalid
458 469 * - RTEMS_ALREADY_SUSPENDED - task already suspended
459 470 *
460 471 */
461 472
462 473 rtems_status_code status;
463 474
464 475 status = RTEMS_SUCCESSFUL;
465 476
466 477 // (1) mask interruptions
467 478 LEON_Mask_interrupt( IRQ_WAVEFORM_PICKER ); // mask waveform picker interrupt
468 479 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
469 480
470 481 // (2) reset waveform picker registers
471 482 reset_wfp_burst_enable(); // reset burst and enable bits
472 483 reset_wfp_status(); // reset all the status bits
473 484
474 485 // (3) reset spectral matrices registers
475 486 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
476 487 reset_sm_status();
477 488
478 489 // reset lfr VHDL module
479 490 reset_lfr();
480 491
481 492 reset_extractSWF(); // reset the extractSWF flag to false
482 493
483 494 // (4) clear interruptions
484 495 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER ); // clear waveform picker interrupt
485 496 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
486 497
487 498 // <Spectral Matrices simulator>
488 499 LEON_Mask_interrupt( IRQ_SM_SIMULATOR ); // mask spectral matrix interrupt simulator
489 500 timer_stop( (gptimer_regs_t*) REGS_ADDR_GPTIMER, TIMER_SM_SIMULATOR );
490 501 LEON_Clear_interrupt( IRQ_SM_SIMULATOR ); // clear spectral matrix interrupt simulator
491 502 // </Spectral Matrices simulator>
492 503
493 504 // suspend several tasks
494 505 if (lfrCurrentMode != LFR_MODE_STANDBY) {
495 506 status = suspend_science_tasks();
496 507 }
497 508
498 509 if (status != RTEMS_SUCCESSFUL)
499 510 {
500 511 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
501 512 }
502 513
503 514 return status;
504 515 }
505 516
506 517 int enter_mode( unsigned char mode, unsigned int transitionCoarseTime )
507 518 {
508 519 /** This function is launched after a mode transition validation.
509 520 *
510 521 * @param mode is the mode in which LFR will be put.
511 522 *
512 523 * @return RTEMS directive status codes:
513 524 * - RTEMS_SUCCESSFUL - the mode has been entered successfully
514 525 * - RTEMS_NOT_SATISFIED - the mode has not been entered successfully
515 526 *
516 527 */
517 528
518 529 rtems_status_code status;
519 530
520 531 //**********************
521 532 // STOP THE CURRENT MODE
522 533 status = stop_current_mode();
523 534 if (status != RTEMS_SUCCESSFUL)
524 535 {
525 536 PRINTF1("ERR *** in enter_mode *** stop_current_mode with mode = %d\n", mode)
526 537 }
527 538
528 539 //*************************
529 540 // ENTER THE REQUESTED MODE
530 541 if (status == RTEMS_SUCCESSFUL) // if the current mode has been successfully stopped
531 542 {
532 543 if ( (mode == LFR_MODE_NORMAL) || (mode == LFR_MODE_BURST)
533 544 || (mode == LFR_MODE_SBM1) || (mode == LFR_MODE_SBM2) )
534 545 {
535 546 #ifdef PRINT_TASK_STATISTICS
536 547 rtems_cpu_usage_reset();
537 548 #endif
538 549 status = restart_science_tasks( mode );
539 550 if (status == RTEMS_SUCCESSFUL)
540 551 {
541 552 launch_spectral_matrix( );
542 553 launch_waveform_picker( mode, transitionCoarseTime );
543 554 }
544 555 }
545 556 else if ( mode == LFR_MODE_STANDBY )
546 557 {
547 558 #ifdef PRINT_TASK_STATISTICS
548 559 rtems_cpu_usage_report();
549 560 #endif
550 561
551 562 #ifdef PRINT_STACK_REPORT
552 563 PRINTF("stack report selected\n")
553 564 rtems_stack_checker_report_usage();
554 565 #endif
555 566 }
556 567 else
557 568 {
558 569 status = RTEMS_UNSATISFIED;
559 570 }
560 571 }
561 572
562 573 if (status != RTEMS_SUCCESSFUL)
563 574 {
564 575 PRINTF1("ERR *** in enter_mode *** status = %d\n", status)
565 576 status = RTEMS_UNSATISFIED;
566 577 }
567 578
568 579 return status;
569 580 }
570 581
571 582 int restart_science_tasks(unsigned char lfrRequestedMode )
572 583 {
573 584 /** This function is used to restart all science tasks.
574 585 *
575 586 * @return RTEMS directive status codes:
576 587 * - RTEMS_SUCCESSFUL - task restarted successfully
577 588 * - RTEMS_INVALID_ID - task id invalid
578 589 * - RTEMS_INCORRECT_STATE - task never started
579 590 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
580 591 *
581 592 * Science tasks are AVF0, PRC0, WFRM, CWF3, CW2, CWF1
582 593 *
583 594 */
584 595
585 596 rtems_status_code status[10];
586 597 rtems_status_code ret;
587 598
588 599 ret = RTEMS_SUCCESSFUL;
589 600
590 601 status[0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
591 602 if (status[0] != RTEMS_SUCCESSFUL)
592 603 {
593 604 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[0])
594 605 }
595 606
596 607 status[1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
597 608 if (status[1] != RTEMS_SUCCESSFUL)
598 609 {
599 610 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[1])
600 611 }
601 612
602 613 status[2] = rtems_task_restart( Task_id[TASKID_WFRM],1 );
603 614 if (status[2] != RTEMS_SUCCESSFUL)
604 615 {
605 616 PRINTF1("in restart_science_task *** WFRM ERR %d\n", status[2])
606 617 }
607 618
608 619 status[3] = rtems_task_restart( Task_id[TASKID_CWF3],1 );
609 620 if (status[3] != RTEMS_SUCCESSFUL)
610 621 {
611 622 PRINTF1("in restart_science_task *** CWF3 ERR %d\n", status[3])
612 623 }
613 624
614 625 status[4] = rtems_task_restart( Task_id[TASKID_CWF2],1 );
615 626 if (status[4] != RTEMS_SUCCESSFUL)
616 627 {
617 628 PRINTF1("in restart_science_task *** CWF2 ERR %d\n", status[4])
618 629 }
619 630
620 631 status[5] = rtems_task_restart( Task_id[TASKID_CWF1],1 );
621 632 if (status[5] != RTEMS_SUCCESSFUL)
622 633 {
623 634 PRINTF1("in restart_science_task *** CWF1 ERR %d\n", status[5])
624 635 }
625 636
626 637 status[6] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
627 638 if (status[6] != RTEMS_SUCCESSFUL)
628 639 {
629 640 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[6])
630 641 }
631 642
632 643 status[7] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
633 644 if (status[7] != RTEMS_SUCCESSFUL)
634 645 {
635 646 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[7])
636 647 }
637 648
638 649 status[8] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
639 650 if (status[8] != RTEMS_SUCCESSFUL)
640 651 {
641 652 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[8])
642 653 }
643 654
644 655 status[9] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
645 656 if (status[9] != RTEMS_SUCCESSFUL)
646 657 {
647 658 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[9])
648 659 }
649 660
650 661 if ( (status[0] != RTEMS_SUCCESSFUL) || (status[1] != RTEMS_SUCCESSFUL) ||
651 662 (status[2] != RTEMS_SUCCESSFUL) || (status[3] != RTEMS_SUCCESSFUL) ||
652 663 (status[4] != RTEMS_SUCCESSFUL) || (status[5] != RTEMS_SUCCESSFUL) ||
653 664 (status[6] != RTEMS_SUCCESSFUL) || (status[7] != RTEMS_SUCCESSFUL) ||
654 665 (status[8] != RTEMS_SUCCESSFUL) || (status[9] != RTEMS_SUCCESSFUL) )
655 666 {
656 667 ret = RTEMS_UNSATISFIED;
657 668 }
658 669
659 670 return ret;
660 671 }
661 672
662 673 int suspend_science_tasks()
663 674 {
664 675 /** This function suspends the science tasks.
665 676 *
666 677 * @return RTEMS directive status codes:
667 678 * - RTEMS_SUCCESSFUL - task restarted successfully
668 679 * - RTEMS_INVALID_ID - task id invalid
669 680 * - RTEMS_ALREADY_SUSPENDED - task already suspended
670 681 *
671 682 */
672 683
673 684 rtems_status_code status;
674 685
675 686 printf("in suspend_science_tasks\n");
676 687
677 688 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
678 689 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
679 690 {
680 691 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
681 692 }
682 693 else
683 694 {
684 695 status = RTEMS_SUCCESSFUL;
685 696 }
686 697 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
687 698 {
688 699 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
689 700 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
690 701 {
691 702 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
692 703 }
693 704 else
694 705 {
695 706 status = RTEMS_SUCCESSFUL;
696 707 }
697 708 }
698 709 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
699 710 {
700 711 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
701 712 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
702 713 {
703 714 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
704 715 }
705 716 else
706 717 {
707 718 status = RTEMS_SUCCESSFUL;
708 719 }
709 720 }
710 721 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
711 722 {
712 723 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
713 724 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
714 725 {
715 726 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
716 727 }
717 728 else
718 729 {
719 730 status = RTEMS_SUCCESSFUL;
720 731 }
721 732 }
722 733 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
723 734 {
724 735 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
725 736 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
726 737 {
727 738 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
728 739 }
729 740 else
730 741 {
731 742 status = RTEMS_SUCCESSFUL;
732 743 }
733 744 }
734 745 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
735 746 {
736 747 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
737 748 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
738 749 {
739 750 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
740 751 }
741 752 else
742 753 {
743 754 status = RTEMS_SUCCESSFUL;
744 755 }
745 756 }
746 757 if (status == RTEMS_SUCCESSFUL) // suspend WFRM
747 758 {
748 759 status = rtems_task_suspend( Task_id[TASKID_WFRM] );
749 760 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
750 761 {
751 762 PRINTF1("in suspend_science_task *** WFRM ERR %d\n", status)
752 763 }
753 764 else
754 765 {
755 766 status = RTEMS_SUCCESSFUL;
756 767 }
757 768 }
758 769 if (status == RTEMS_SUCCESSFUL) // suspend CWF3
759 770 {
760 771 status = rtems_task_suspend( Task_id[TASKID_CWF3] );
761 772 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
762 773 {
763 774 PRINTF1("in suspend_science_task *** CWF3 ERR %d\n", status)
764 775 }
765 776 else
766 777 {
767 778 status = RTEMS_SUCCESSFUL;
768 779 }
769 780 }
770 781 if (status == RTEMS_SUCCESSFUL) // suspend CWF2
771 782 {
772 783 status = rtems_task_suspend( Task_id[TASKID_CWF2] );
773 784 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
774 785 {
775 786 PRINTF1("in suspend_science_task *** CWF2 ERR %d\n", status)
776 787 }
777 788 else
778 789 {
779 790 status = RTEMS_SUCCESSFUL;
780 791 }
781 792 }
782 793 if (status == RTEMS_SUCCESSFUL) // suspend CWF1
783 794 {
784 795 status = rtems_task_suspend( Task_id[TASKID_CWF1] );
785 796 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
786 797 {
787 798 PRINTF1("in suspend_science_task *** CWF1 ERR %d\n", status)
788 799 }
789 800 else
790 801 {
791 802 status = RTEMS_SUCCESSFUL;
792 803 }
793 804 }
794 805
795 806 return status;
796 807 }
797 808
798 809 void launch_waveform_picker( unsigned char mode, unsigned int transitionCoarseTime )
799 810 {
800 811 WFP_reset_current_ring_nodes();
801 812
802 813 reset_waveform_picker_regs();
803 814
804 815 set_wfp_burst_enable_register( mode );
805 816
806 817 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER );
807 818 LEON_Unmask_interrupt( IRQ_WAVEFORM_PICKER );
808 819
809 820 if (transitionCoarseTime == 0)
810 821 {
811 822 waveform_picker_regs->start_date = time_management_regs->coarse_time;
812 823 }
813 824 else
814 825 {
815 826 waveform_picker_regs->start_date = transitionCoarseTime;
816 827 }
817 828
818 829 }
819 830
820 831 void launch_spectral_matrix( void )
821 832 {
822 833 SM_reset_current_ring_nodes();
823 834
824 835 reset_spectral_matrix_regs();
825 836
826 837 reset_nb_sm();
827 838
828 839 set_sm_irq_onNewMatrix( 1 );
829 840
830 841 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX );
831 842 LEON_Unmask_interrupt( IRQ_SPECTRAL_MATRIX );
832 843
833 844 }
834 845
835 846 void launch_spectral_matrix_simu( void )
836 847 {
837 848 SM_reset_current_ring_nodes();
838 849 reset_spectral_matrix_regs();
839 850 reset_nb_sm();
840 851
841 852 // Spectral Matrices simulator
842 853 timer_start( (gptimer_regs_t*) REGS_ADDR_GPTIMER, TIMER_SM_SIMULATOR );
843 854 LEON_Clear_interrupt( IRQ_SM_SIMULATOR );
844 855 LEON_Unmask_interrupt( IRQ_SM_SIMULATOR );
845 856 }
846 857
847 858 void set_sm_irq_onNewMatrix( unsigned char value )
848 859 {
849 860 if (value == 1)
850 861 {
851 862 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x01;
852 863 }
853 864 else
854 865 {
855 866 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffe; // 1110
856 867 }
857 868 }
858 869
859 870 void set_sm_irq_onError( unsigned char value )
860 871 {
861 872 if (value == 1)
862 873 {
863 874 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x02;
864 875 }
865 876 else
866 877 {
867 878 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffd; // 1101
868 879 }
869 880 }
870 881
871 882 //*****************************
872 883 // CONFIGURE CALIBRATION SIGNAL
873 884 void setCalibrationPrescaler( unsigned int prescaler )
874 885 {
875 886 // prescaling of the master clock (25 MHz)
876 887 // master clock is divided by 2^prescaler
877 888 time_management_regs->calPrescaler = prescaler;
878 889 }
879 890
880 891 void setCalibrationDivisor( unsigned int divisionFactor )
881 892 {
882 893 // division of the prescaled clock by the division factor
883 894 time_management_regs->calDivisor = divisionFactor;
884 895 }
885 896
886 897 void setCalibrationData( void ){
887 898 unsigned int k;
888 899 unsigned short data;
889 900 float val;
890 901 float f0;
891 902 float f1;
892 903 float fs;
893 904 float Ts;
894 905 float scaleFactor;
895 906
896 907 f0 = 625;
897 908 f1 = 10000;
898 909 fs = 160256.410;
899 910 Ts = 1. / fs;
900 911 scaleFactor = 0.250 / 0.000654; // 191, 500 mVpp, 2 sinus waves => 500 mVpp each, amplitude = 250 mV
901 912
902 913 time_management_regs->calDataPtr = 0x00;
903 914
904 915 // build the signal for the SCM calibration
905 916 for (k=0; k<256; k++)
906 917 {
907 918 val = sin( 2 * pi * f0 * k * Ts )
908 919 + sin( 2 * pi * f1 * k * Ts );
909 920 data = (unsigned short) ((val * scaleFactor) + 2048);
910 921 time_management_regs->calData = data & 0xfff;
911 922 }
912 923 }
913 924
914 925 void setCalibrationDataInterleaved( void ){
915 926 unsigned int k;
916 927 float val;
917 928 float f0;
918 929 float f1;
919 930 float fs;
920 931 float Ts;
921 932 unsigned short data[384];
922 933 unsigned char *dataPtr;
923 934
924 935 f0 = 625;
925 936 f1 = 10000;
926 937 fs = 240384.615;
927 938 Ts = 1. / fs;
928 939
929 940 time_management_regs->calDataPtr = 0x00;
930 941
931 942 // build the signal for the SCM calibration
932 943 for (k=0; k<384; k++)
933 944 {
934 945 val = sin( 2 * pi * f0 * k * Ts )
935 946 + sin( 2 * pi * f1 * k * Ts );
936 947 data[k] = (unsigned short) (val * 512 + 2048);
937 948 }
938 949
939 950 // write the signal in interleaved mode
940 951 for (k=0; k<128; k++)
941 952 {
942 953 dataPtr = (unsigned char*) &data[k*3 + 2];
943 954 time_management_regs->calData = (data[k*3] & 0xfff)
944 955 + ( (dataPtr[0] & 0x3f) << 12);
945 956 time_management_regs->calData = (data[k*3 + 1] & 0xfff)
946 957 + ( (dataPtr[1] & 0x3f) << 12);
947 958 }
948 959 }
949 960
950 961 void setCalibrationReload( bool state)
951 962 {
952 963 if (state == true)
953 964 {
954 965 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000010; // [0001 0000]
955 966 }
956 967 else
957 968 {
958 969 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffef; // [1110 1111]
959 970 }
960 971 }
961 972
962 973 void setCalibrationEnable( bool state )
963 974 {
964 975 // this bit drives the multiplexer
965 976 if (state == true)
966 977 {
967 978 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000040; // [0100 0000]
968 979 }
969 980 else
970 981 {
971 982 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffbf; // [1011 1111]
972 983 }
973 984 }
974 985
975 986 void setCalibrationInterleaved( bool state )
976 987 {
977 988 // this bit drives the multiplexer
978 989 if (state == true)
979 990 {
980 991 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000020; // [0010 0000]
981 992 }
982 993 else
983 994 {
984 995 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffdf; // [1101 1111]
985 996 }
986 997 }
987 998
988 999 void setCalibration( bool state )
989 1000 {
990 1001 if (state == true)
991 1002 {
992 1003 setCalibrationEnable( true );
993 1004 setCalibrationReload( false );
994 1005 set_hk_lfr_calib_enable( true );
995 1006 }
996 1007 else
997 1008 {
998 1009 setCalibrationEnable( false );
999 1010 setCalibrationReload( true );
1000 1011 set_hk_lfr_calib_enable( false );
1001 1012 }
1002 1013 }
1003 1014
1004 1015 void configureCalibration( bool interleaved )
1005 1016 {
1006 1017 setCalibration( false );
1007 1018 if ( interleaved == true )
1008 1019 {
1009 1020 setCalibrationInterleaved( true );
1010 1021 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1011 1022 setCalibrationDivisor( 26 ); // => 240 384
1012 1023 setCalibrationDataInterleaved();
1013 1024 }
1014 1025 else
1015 1026 {
1016 1027 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1017 1028 setCalibrationDivisor( 38 ); // => 160 256 (39 - 1)
1018 1029 setCalibrationData();
1019 1030 }
1020 1031 }
1021 1032
1022 1033 //****************
1023 1034 // CLOSING ACTIONS
1024 1035 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC, unsigned char * time )
1025 1036 {
1026 1037 /** This function is used to update the HK packets statistics after a successful TC execution.
1027 1038 *
1028 1039 * @param TC points to the TC being processed
1029 1040 * @param time is the time used to date the TC execution
1030 1041 *
1031 1042 */
1032 1043
1033 1044 unsigned int val;
1034 1045
1035 1046 housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
1036 1047 housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
1037 1048 housekeeping_packet.hk_lfr_last_exe_tc_type[0] = 0x00;
1038 1049 housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
1039 1050 housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = 0x00;
1040 1051 housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
1041 1052 housekeeping_packet.hk_lfr_last_exe_tc_time[0] = time[0];
1042 1053 housekeeping_packet.hk_lfr_last_exe_tc_time[1] = time[1];
1043 1054 housekeeping_packet.hk_lfr_last_exe_tc_time[2] = time[2];
1044 1055 housekeeping_packet.hk_lfr_last_exe_tc_time[3] = time[3];
1045 1056 housekeeping_packet.hk_lfr_last_exe_tc_time[4] = time[4];
1046 1057 housekeeping_packet.hk_lfr_last_exe_tc_time[5] = time[5];
1047 1058
1048 1059 val = housekeeping_packet.hk_lfr_exe_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
1049 1060 val++;
1050 1061 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> 8);
1051 1062 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
1052 1063 }
1053 1064
1054 1065 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC, unsigned char * time )
1055 1066 {
1056 1067 /** This function is used to update the HK packets statistics after a TC rejection.
1057 1068 *
1058 1069 * @param TC points to the TC being processed
1059 1070 * @param time is the time used to date the TC rejection
1060 1071 *
1061 1072 */
1062 1073
1063 1074 unsigned int val;
1064 1075
1065 1076 housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
1066 1077 housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
1067 1078 housekeeping_packet.hk_lfr_last_rej_tc_type[0] = 0x00;
1068 1079 housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
1069 1080 housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = 0x00;
1070 1081 housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
1071 1082 housekeeping_packet.hk_lfr_last_rej_tc_time[0] = time[0];
1072 1083 housekeeping_packet.hk_lfr_last_rej_tc_time[1] = time[1];
1073 1084 housekeeping_packet.hk_lfr_last_rej_tc_time[2] = time[2];
1074 1085 housekeeping_packet.hk_lfr_last_rej_tc_time[3] = time[3];
1075 1086 housekeeping_packet.hk_lfr_last_rej_tc_time[4] = time[4];
1076 1087 housekeeping_packet.hk_lfr_last_rej_tc_time[5] = time[5];
1077 1088
1078 1089 val = housekeeping_packet.hk_lfr_rej_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
1079 1090 val++;
1080 1091 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> 8);
1081 1092 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
1082 1093 }
1083 1094
1084 1095 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id )
1085 1096 {
1086 1097 /** This function is the last step of the TC execution workflow.
1087 1098 *
1088 1099 * @param TC points to the TC being processed
1089 1100 * @param result is the result of the TC execution (LFR_SUCCESSFUL / LFR_DEFAULT)
1090 1101 * @param queue_id is the id of the RTEMS message queue used to send TM packets
1091 1102 * @param time is the time used to date the TC execution
1092 1103 *
1093 1104 */
1094 1105
1095 1106 unsigned char requestedMode;
1096 1107
1097 1108 if (result == LFR_SUCCESSFUL)
1098 1109 {
1099 1110 if ( !( (TC->serviceType==TC_TYPE_TIME) & (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
1100 1111 &
1101 1112 !( (TC->serviceType==TC_TYPE_GEN) & (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
1102 1113 )
1103 1114 {
1104 1115 send_tm_lfr_tc_exe_success( TC, queue_id );
1105 1116 }
1106 1117 if ( (TC->serviceType == TC_TYPE_GEN) & (TC->serviceSubType == TC_SUBTYPE_ENTER) )
1107 1118 {
1108 1119 //**********************************
1109 1120 // UPDATE THE LFRMODE LOCAL VARIABLE
1110 1121 requestedMode = TC->dataAndCRC[1];
1111 1122 housekeeping_packet.lfr_status_word[0] = (unsigned char) ((requestedMode << 4) + 0x0d);
1112 1123 updateLFRCurrentMode();
1113 1124 }
1114 1125 }
1115 1126 else if (result == LFR_EXE_ERROR)
1116 1127 {
1117 1128 send_tm_lfr_tc_exe_error( TC, queue_id );
1118 1129 }
1119 1130 }
1120 1131
1121 1132 //***************************
1122 1133 // Interrupt Service Routines
1123 1134 rtems_isr commutation_isr1( rtems_vector_number vector )
1124 1135 {
1125 1136 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1126 1137 printf("In commutation_isr1 *** Error sending event to DUMB\n");
1127 1138 }
1128 1139 }
1129 1140
1130 1141 rtems_isr commutation_isr2( rtems_vector_number vector )
1131 1142 {
1132 1143 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1133 1144 printf("In commutation_isr2 *** Error sending event to DUMB\n");
1134 1145 }
1135 1146 }
1136 1147
1137 1148 //****************
1138 1149 // OTHER FUNCTIONS
1139 1150 void updateLFRCurrentMode()
1140 1151 {
1141 1152 /** This function updates the value of the global variable lfrCurrentMode.
1142 1153 *
1143 1154 * lfrCurrentMode is a parameter used by several functions to know in which mode LFR is running.
1144 1155 *
1145 1156 */
1146 1157 // update the local value of lfrCurrentMode with the value contained in the housekeeping_packet structure
1147 1158 lfrCurrentMode = (housekeeping_packet.lfr_status_word[0] & 0xf0) >> 4;
1148 1159 }
1149 1160
1150 1161 void set_lfr_soft_reset( unsigned char value )
1151 1162 {
1152 1163 if (value == 1)
1153 1164 {
1154 1165 time_management_regs->ctrl = time_management_regs->ctrl | 0x00000004; // [0100]
1155 1166 }
1156 1167 else
1157 1168 {
1158 1169 time_management_regs->ctrl = time_management_regs->ctrl & 0xfffffffb; // [1011]
1159 1170 }
1160 1171 }
1161 1172
1162 1173 void reset_lfr( void )
1163 1174 {
1164 1175 set_lfr_soft_reset( 1 );
1165 1176
1166 1177 set_lfr_soft_reset( 0 );
1167 1178
1168 1179 set_hk_lfr_sc_potential_flag( true );
1169 1180 }
General Comments 0
You need to be logged in to leave comments. Login now