##// END OF EJS Templates
enter_mode removed...
paul -
r237:b287f3b429dd R3
parent child
Show More
@@ -1,112 +1,112
1 1 TEMPLATE = app
2 2 # CONFIG += console v8 sim
3 3 # CONFIG options = verbose *** boot_messages *** debug_messages *** cpu_usage_report *** stack_report *** vhdl_dev *** debug_tch
4 4 # lpp_dpu_destid
5 CONFIG += console verbose lpp_dpu_destid cpu_usage_report
5 CONFIG += console verbose lpp_dpu_destid cpu_usage_report 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=12 # internal
16 16
17 17 # <GCOV>
18 18 #QMAKE_CFLAGS_RELEASE += -fprofile-arcs -ftest-coverage
19 19 #LIBS += -lgcov /opt/GCOV/01A/lib/overload.o -lc
20 20 # </GCOV>
21 21
22 22 # <CHANGE BEFORE FLIGHT>
23 23 contains( CONFIG, lpp_dpu_destid ) {
24 24 DEFINES += LPP_DPU_DESTID
25 25 }
26 26 # </CHANGE BEFORE FLIGHT>
27 27
28 28 contains( CONFIG, debug_tch ) {
29 29 DEFINES += DEBUG_TCH
30 30 }
31 31 DEFINES += MSB_FIRST_TCH
32 32
33 33 contains( CONFIG, vhdl_dev ) {
34 34 DEFINES += VHDL_DEV
35 35 }
36 36
37 37 contains( CONFIG, verbose ) {
38 38 DEFINES += PRINT_MESSAGES_ON_CONSOLE
39 39 }
40 40
41 41 contains( CONFIG, debug_messages ) {
42 42 DEFINES += DEBUG_MESSAGES
43 43 }
44 44
45 45 contains( CONFIG, cpu_usage_report ) {
46 46 DEFINES += PRINT_TASK_STATISTICS
47 47 }
48 48
49 49 contains( CONFIG, stack_report ) {
50 50 DEFINES += PRINT_STACK_REPORT
51 51 }
52 52
53 53 contains( CONFIG, boot_messages ) {
54 54 DEFINES += BOOT_MESSAGES
55 55 }
56 56
57 57 #doxygen.target = doxygen
58 58 #doxygen.commands = doxygen ../doc/Doxyfile
59 59 #QMAKE_EXTRA_TARGETS += doxygen
60 60
61 61 TARGET = fsw
62 62
63 63 INCLUDEPATH += \
64 64 $${PWD}/../src \
65 65 $${PWD}/../header \
66 66 $${PWD}/../header/lfr_common_headers \
67 67 $${PWD}/../header/processing \
68 68 $${PWD}/../LFR_basic-parameters
69 69
70 70 SOURCES += \
71 71 ../src/wf_handler.c \
72 72 ../src/tc_handler.c \
73 73 ../src/fsw_misc.c \
74 74 ../src/fsw_init.c \
75 75 ../src/fsw_globals.c \
76 76 ../src/fsw_spacewire.c \
77 77 ../src/tc_load_dump_parameters.c \
78 78 ../src/tm_lfr_tc_exe.c \
79 79 ../src/tc_acceptance.c \
80 80 ../src/processing/fsw_processing.c \
81 81 ../src/processing/avf0_prc0.c \
82 82 ../src/processing/avf1_prc1.c \
83 83 ../src/processing/avf2_prc2.c \
84 84 ../src/lfr_cpu_usage_report.c \
85 85 ../LFR_basic-parameters/basic_parameters.c
86 86
87 87 HEADERS += \
88 88 ../header/wf_handler.h \
89 89 ../header/tc_handler.h \
90 90 ../header/grlib_regs.h \
91 91 ../header/fsw_misc.h \
92 92 ../header/fsw_init.h \
93 93 ../header/fsw_spacewire.h \
94 94 ../header/tc_load_dump_parameters.h \
95 95 ../header/tm_lfr_tc_exe.h \
96 96 ../header/tc_acceptance.h \
97 97 ../header/processing/fsw_processing.h \
98 98 ../header/processing/avf0_prc0.h \
99 99 ../header/processing/avf1_prc1.h \
100 100 ../header/processing/avf2_prc2.h \
101 101 ../header/fsw_params_wf_handler.h \
102 102 ../header/lfr_cpu_usage_report.h \
103 103 ../header/lfr_common_headers/ccsds_types.h \
104 104 ../header/lfr_common_headers/fsw_params.h \
105 105 ../header/lfr_common_headers/fsw_params_nb_bytes.h \
106 106 ../header/lfr_common_headers/fsw_params_processing.h \
107 107 ../header/lfr_common_headers/TC_types.h \
108 108 ../header/lfr_common_headers/tm_byte_positions.h \
109 109 ../LFR_basic-parameters/basic_parameters.h \
110 110 ../LFR_basic-parameters/basic_parameters_params.h \
111 111 ../header/GscMemoryLPP.hpp
112 112
@@ -1,97 +1,97
1 1 CONFIG += console
2 2 CONFIG -= qt
3 3 QMAKE_CC=sparc-rtems-gcc
4 4 message(C compiler forced to: $$QMAKE_CC)
5 5 QMAKE_CXX=sparc-rtems-g++
6 6 message(C++ compiler forced to: $$QMAKE_CXX)
7 7 QMAKE_AR=sparc-rtems-ar rcs
8 8 message(Archiver forced to: $$QMAKE_AR)
9 9 QMAKE_LINK=sparc-rtems-g++
10 10 message(Linker forced to: $$QMAKE_LINK)
11 11 QMAKE_LINK_SHLIB=sparc-rtems-g++
12 12 QMAKE_OBJCOPY= sparc-rtems-objcopy
13 13 QMAKE_STRIP=sparc-rtems-strip
14 14 QMAKE_GDB=sparc-rtems-gdb
15 15
16 16 INCLUDEPATH += /opt/rtems-4.10
17 17
18 18 QMAKE_CFLAGS_DEBUG= -g
19 19 QMAKE_CFLAGS_RELEASE=""
20 20 QMAKE_CXXFLAGS_DEBUG= -g
21 21 QMAKE_CXXFLAGS_RELEASE=""
22 22 QMAKE_LFLAGS_RELEASE=""
23 23 QMAKE_LFLAGS_DEBUG= -g
24 24 QMAKE_CXXFLAGS_DEPS =
25 25 QMAKE_CXXFLAGS_WARN_ON = -Wall
26 26 QMAKE_CXXFLAGS_WARN_OFF = -w
27 27 QMAKE_CXXFLAGS_RELEASE =
28 28 QMAKE_CXXFLAGS_DEBUG =
29 29 QMAKE_CXXFLAGS_YACC =
30 30 QMAKE_CXXFLAGS_THREAD =
31 31 QMAKE_CXXFLAGS_RTTI_ON =
32 32 QMAKE_CXXFLAGS_RTTI_OFF =
33 33 QMAKE_CXXFLAGS_EXCEPTIONS_ON =
34 34 QMAKE_CXXFLAGS_EXCEPTIONS_OFF =
35 35 QMAKE_CFLAGS_WARN_ON = -Wall
36 36 QMAKE_CFLAGS_WARN_OFF = -w
37 37 QMAKE_CFLAGS_RELEASE =
38 38 QMAKE_CFLAGS_YACC =
39 39 QMAKE_LFLAGS_EXCEPTIONS_ON =
40 40 QMAKE_LFLAGS_EXCEPTIONS_OFF =
41 QMAKE_LFLAGS_RELEASE =
41 QMAKE_LFLAGS_RELEASE = -Xlinker -Map=output.map
42 42 QMAKE_LFLAGS_CONSOLE =
43 43 QMAKE_LFLAGS_WINDOWS =
44 44 QMAKE_LFLAGS_DLL =
45 45 QMAKE_INCDIR_QT =
46 46 QMAKE_INCDIR =
47 47 QMAKE_CFLAGS_SHLIB =
48 48 QMAKE_CFLAGS_STATIC_LIB =
49 49 QMAKE_CXXFLAGS_SHLIB =
50 50 QMAKE_CXXFLAGS_STATIC_LIB =
51 51 QMAKE_LIBS=""
52 52 INCLUDEPATH=""
53 53 DEFINES=""
54 54
55 55 contains( TEMPLATE, app ) {
56 56 OBJECTS_DIR=obj
57 57 DESTDIR=bin
58 58 }
59 59
60 60 #QMAKE_CFLAGS_RELEASE += -O0
61 61 #QMAKE_CFLAGS_DEBUG += -O0
62 62 #QMAKE_CXXFLAGS_RELEASE += -O0
63 63 #QMAKE_CXXFLAGS_DEBUG += -O0
64 64 QMAKE_CFLAGS_RELEASE += -O3
65 65 QMAKE_CFLAGS_DEBUG += -O3
66 66 QMAKE_CXXFLAGS_RELEASE += -O3
67 67 QMAKE_CXXFLAGS_DEBUG += -O3
68 68
69 69 #QMAKE_CFLAGS_RELEASE+= -O3 -std=c99
70 70 #QMAKE_CFLAGS_DEBUG+= -O3 -std=c99
71 71 #QMAKE_CXXFLAGS_RELEASE+= -O3 -std=c99
72 72 #QMAKE_CXXFLAGS_DEBUG+= -O3 -std=c99
73 73
74 74 contains( TEMPLATE, app ) {
75 75 grmon.target = grmon
76 76 grmon.commands = cd $$DESTDIR && C:/opt/grmon-eval-2.0.29b/win32/bin/grmon.exe -uart COM4 -u
77 77 QMAKE_EXTRA_TARGETS += grmon
78 78 }
79 79
80 80
81 81
82 82
83 83
84 84
85 85
86 86
87 87
88 88
89 89
90 90
91 91
92 92
93 93
94 94
95 95
96 96
97 97
@@ -1,71 +1,75
1 1 #ifndef TC_HANDLER_H_INCLUDED
2 2 #define TC_HANDLER_H_INCLUDED
3 3
4 4 #include <rtems.h>
5 5 #include <leon.h>
6 6
7 7 #include "tc_load_dump_parameters.h"
8 8 #include "tc_acceptance.h"
9 9 #include "tm_lfr_tc_exe.h"
10 10 #include "wf_handler.h"
11 11 #include "fsw_processing.h"
12 12
13 13 #include "lfr_cpu_usage_report.h"
14 14
15 15 //****
16 16 // ISR
17 17 rtems_isr commutation_isr1( rtems_vector_number vector );
18 18 rtems_isr commutation_isr2( rtems_vector_number vector );
19 19
20 20 //***********
21 21 // RTEMS TASK
22 22 rtems_task actn_task( rtems_task_argument unused );
23 23
24 24 //***********
25 25 // TC ACTIONS
26 26 int action_reset( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time );
27 27 int action_enter_mode(ccsdsTelecommandPacket_t *TC, rtems_id queue_id);
28 28 int action_update_info( ccsdsTelecommandPacket_t *TC, rtems_id queue_id );
29 29 int action_enable_calibration( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time );
30 30 int action_disable_calibration( ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time );
31 31 int action_update_time( ccsdsTelecommandPacket_t *TC);
32 32
33 33 // mode transition
34 34 int check_mode_value( unsigned char requestedMode );
35 35 int check_mode_transition( unsigned char requestedMode );
36 36 int check_transition_date( unsigned int transitionCoarseTime );
37 37 int stop_current_mode( void );
38 int enter_mode( unsigned char mode , unsigned int transitionCoarseTime );
38 int enter_mode_standby( void );
39 int enter_mode_normal( unsigned int transitionCoarseTime );
40 int enter_mode_burst( unsigned int transitionCoarseTime );
41 int enter_mode_sbm1( unsigned int transitionCoarseTime );
42 int enter_mode_sbm2( unsigned int transitionCoarseTime );
39 43 int restart_science_tasks( unsigned char lfrRequestedMode );
40 44 int suspend_science_tasks();
41 45 void launch_waveform_picker( unsigned char mode , unsigned int transitionCoarseTime );
42 46 void launch_spectral_matrix( void );
43 47 void launch_spectral_matrix_simu( void );
44 48 void set_sm_irq_onNewMatrix( unsigned char value );
45 49 void set_sm_irq_onError( unsigned char value );
46 50
47 51 // other functions
48 52 void updateLFRCurrentMode();
49 53 void set_lfr_soft_reset( unsigned char value );
50 54 void reset_lfr( void );
51 55 // CALIBRATION
52 56 void setCalibrationPrescaler( unsigned int prescaler );
53 57 void setCalibrationDivisor( unsigned int divisionFactor );
54 58 void setCalibrationData( void );
55 59 void setCalibrationReload( bool state);
56 60 void setCalibrationEnable( bool state );
57 61 void setCalibrationInterleaved( bool state );
58 62 void setCalibration( bool state );
59 63 void configureCalibration( bool interleaved );
60 64 //
61 65 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC , unsigned char *time );
62 66 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC , unsigned char *time );
63 67 void close_action( ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id );
64 68
65 69 extern rtems_status_code get_message_queue_id_send( rtems_id *queue_id );
66 70 extern rtems_status_code get_message_queue_id_recv( rtems_id *queue_id );
67 71
68 72 #endif // TC_HANDLER_H_INCLUDED
69 73
70 74
71 75
@@ -1,1308 +1,1308
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 status = enter_mode( LFR_MODE_STANDBY, 0 );
92 status = enter_mode_standby();
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 unsigned char sidAsUnsignedChar;
220 220 unsigned char type;
221 221
222 222 incomingRingNodePtr = NULL;
223 223 ring_node_address = 0;
224 224 charPtr = (char *) &ring_node_address;
225 225 sid = 0;
226 226 sidAsUnsignedChar = 0;
227 227
228 228 init_header_cwf( &headerCWF );
229 229 init_header_swf( &headerSWF );
230 230 init_header_asm( &headerASM );
231 231
232 232 status = get_message_queue_id_send( &queue_send_id );
233 233 if (status != RTEMS_SUCCESSFUL)
234 234 {
235 235 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
236 236 }
237 237
238 238 BOOT_PRINTF("in SEND *** \n")
239 239
240 240 while(1)
241 241 {
242 242 status = rtems_message_queue_receive( queue_send_id, incomingData, &size,
243 243 RTEMS_WAIT, RTEMS_NO_TIMEOUT );
244 244
245 245 if (status!=RTEMS_SUCCESSFUL)
246 246 {
247 247 PRINTF1("in SEND *** (1) ERR = %d\n", status)
248 248 }
249 249 else
250 250 {
251 251 if ( size == sizeof(ring_node*) )
252 252 {
253 253 charPtr[0] = incomingData[0];
254 254 charPtr[1] = incomingData[1];
255 255 charPtr[2] = incomingData[2];
256 256 charPtr[3] = incomingData[3];
257 257 incomingRingNodePtr = (ring_node*) ring_node_address;
258 258 sid = incomingRingNodePtr->sid;
259 259 if ( (sid==SID_NORM_CWF_LONG_F3)
260 260 || (sid==SID_BURST_CWF_F2 )
261 261 || (sid==SID_SBM1_CWF_F1 )
262 262 || (sid==SID_SBM2_CWF_F2 ))
263 263 {
264 264 spw_send_waveform_CWF( incomingRingNodePtr, &headerCWF );
265 265 }
266 266 else if ( (sid==SID_NORM_SWF_F0) || (sid== SID_NORM_SWF_F1) || (sid==SID_NORM_SWF_F2) )
267 267 {
268 268 spw_send_waveform_SWF( incomingRingNodePtr, &headerSWF );
269 269 }
270 270 else if ( (sid==SID_NORM_CWF_F3) )
271 271 {
272 272 spw_send_waveform_CWF3_light( incomingRingNodePtr, &headerCWF );
273 273 }
274 274 else if (sid==SID_NORM_ASM_F0)
275 275 {
276 276 spw_send_asm_f0( incomingRingNodePtr, &headerASM );
277 277 }
278 278 else if (sid==SID_NORM_ASM_F1)
279 279 {
280 280 spw_send_asm_f1( incomingRingNodePtr, &headerASM );
281 281 }
282 282 else if (sid==SID_NORM_ASM_F2)
283 283 {
284 284 spw_send_asm_f2( incomingRingNodePtr, &headerASM );
285 285 }
286 286 else if ( sid==TM_CODE_K_DUMP )
287 287 {
288 288 spw_send_k_dump( incomingRingNodePtr );
289 289 }
290 290 else
291 291 {
292 292 PRINTF1("unexpected sid = %d\n", sid);
293 293 }
294 294 }
295 295 else if ( incomingData[0] == CCSDS_DESTINATION_ID ) // the incoming message is a ccsds packet
296 296 {
297 297 sidAsUnsignedChar = (unsigned char) incomingData[ PACKET_POS_PA_LFR_SID_PKT ];
298 298 sid = sidAsUnsignedChar;
299 299 type = (unsigned char) incomingData[ PACKET_POS_SERVICE_TYPE ];
300 300 if (type == TM_TYPE_LFR_SCIENCE) // this is a BP packet, all other types are handled differently
301 301 // SET THE SEQUENCE_CNT PARAMETER IN CASE OF BP0 OR BP1 PACKETS
302 302 {
303 303 increment_seq_counter_source_id( (unsigned char*) &incomingData[ PACKET_POS_SEQUENCE_CNT ], sid );
304 304 }
305 305
306 306 status = write( fdSPW, incomingData, size );
307 307 if (status == -1){
308 308 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
309 309 }
310 310 }
311 311 else // the incoming message is a spw_ioctl_pkt_send structure
312 312 {
313 313 spw_ioctl_send = (spw_ioctl_pkt_send*) incomingData;
314 314 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, spw_ioctl_send );
315 315 if (status == -1){
316 316 PRINTF2("in SEND *** (2.b) ERRNO = %d, RTEMS = %d\n", errno, status)
317 317 }
318 318 }
319 319 }
320 320
321 321 update_queue_max_count( queue_send_id, &hk_lfr_q_sd_fifo_size_max );
322 322
323 323 }
324 324 }
325 325
326 326 rtems_task wtdg_task( rtems_task_argument argument )
327 327 {
328 328 rtems_event_set event_out;
329 329 rtems_status_code status;
330 330 int linkStatus;
331 331
332 332 BOOT_PRINTF("in WTDG ***\n")
333 333
334 334 while(1)
335 335 {
336 336 // wait for an RTEMS_EVENT
337 337 rtems_event_receive( RTEMS_EVENT_0,
338 338 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
339 339 PRINTF("in WTDG *** wait for the link\n")
340 340 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
341 341 while( linkStatus != 5) // wait for the link
342 342 {
343 343 status = rtems_task_wake_after( 10 ); // monitor the link each 100ms
344 344 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
345 345 }
346 346
347 347 status = spacewire_stop_and_start_link( fdSPW );
348 348
349 349 if (status != RTEMS_SUCCESSFUL)
350 350 {
351 351 PRINTF1("in WTDG *** ERR link not started %d\n", status)
352 352 }
353 353 else
354 354 {
355 355 PRINTF("in WTDG *** OK link started\n")
356 356 }
357 357
358 358 // restart the SPIQ task
359 359 status = rtems_task_restart( Task_id[TASKID_SPIQ], 1 );
360 360 if ( status != RTEMS_SUCCESSFUL ) {
361 361 PRINTF("in SPIQ *** ERR restarting SPIQ Task\n")
362 362 }
363 363
364 364 // restart RECV and SEND
365 365 status = rtems_task_restart( Task_id[ TASKID_SEND ], 1 );
366 366 if ( status != RTEMS_SUCCESSFUL ) {
367 367 PRINTF("in SPIQ *** ERR restarting SEND Task\n")
368 368 }
369 369 status = rtems_task_restart( Task_id[ TASKID_RECV ], 1 );
370 370 if ( status != RTEMS_SUCCESSFUL ) {
371 371 PRINTF("in SPIQ *** ERR restarting RECV Task\n")
372 372 }
373 373 }
374 374 }
375 375
376 376 //****************
377 377 // OTHER FUNCTIONS
378 378 int spacewire_open_link( void ) // by default, the driver resets the core: [SPW_CTRL_WRITE(pDev, SPW_CTRL_RESET);]
379 379 {
380 380 /** This function opens the SpaceWire link.
381 381 *
382 382 * @return a valid file descriptor in case of success, -1 in case of a failure
383 383 *
384 384 */
385 385 rtems_status_code status;
386 386
387 387 fdSPW = open(GRSPW_DEVICE_NAME, O_RDWR); // open the device. the open call resets the hardware
388 388 if ( fdSPW < 0 ) {
389 389 PRINTF1("ERR *** in configure_spw_link *** error opening "GRSPW_DEVICE_NAME" with ERR %d\n", errno)
390 390 }
391 391 else
392 392 {
393 393 status = RTEMS_SUCCESSFUL;
394 394 }
395 395
396 396 return status;
397 397 }
398 398
399 399 int spacewire_start_link( int fd )
400 400 {
401 401 rtems_status_code status;
402 402
403 403 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
404 404 // -1 default hardcoded driver timeout
405 405
406 406 return status;
407 407 }
408 408
409 409 int spacewire_stop_and_start_link( int fd )
410 410 {
411 411 rtems_status_code status;
412 412
413 413 status = ioctl( fd, SPACEWIRE_IOCTRL_STOP); // start fails if link pDev->running != 0
414 414 status = ioctl( fd, SPACEWIRE_IOCTRL_START, -1); // returns successfuly if the link is started
415 415 // -1 default hardcoded driver timeout
416 416
417 417 return status;
418 418 }
419 419
420 420 int spacewire_configure_link( int fd )
421 421 {
422 422 /** This function configures the SpaceWire link.
423 423 *
424 424 * @return GR-RTEMS-DRIVER directive status codes:
425 425 * - 22 EINVAL - Null pointer or an out of range value was given as the argument.
426 426 * - 16 EBUSY - Only used for SEND. Returned when no descriptors are avialble in non-blocking mode.
427 427 * - 88 ENOSYS - Returned for SET_DESTKEY if RMAP command handler is not available or if a non-implemented call is used.
428 428 * - 116 ETIMEDOUT - REturned for SET_PACKET_SIZE and START if the link could not be brought up.
429 429 * - 12 ENOMEM - Returned for SET_PACKETSIZE if it was unable to allocate the new buffers.
430 430 * - 5 EIO - Error when writing to grswp hardware registers.
431 431 * - 2 ENOENT - No such file or directory
432 432 */
433 433
434 434 rtems_status_code status;
435 435
436 436 spacewire_set_NP(1, REGS_ADDR_GRSPW); // [N]o [P]ort force
437 437 spacewire_set_RE(1, REGS_ADDR_GRSPW); // [R]MAP [E]nable, the dedicated call seems to break the no port force configuration
438 438
439 439 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_RXBLOCK, 1); // sets the blocking mode for reception
440 440 if (status!=RTEMS_SUCCESSFUL) {
441 441 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_RXBLOCK\n")
442 442 }
443 443 //
444 444 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_EVENT_ID, Task_id[TASKID_SPIQ]); // sets the task ID to which an event is sent when a
445 445 if (status!=RTEMS_SUCCESSFUL) {
446 446 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_EVENT_ID\n") // link-error interrupt occurs
447 447 }
448 448 //
449 449 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_DISABLE_ERR, 0); // automatic link-disabling due to link-error interrupts
450 450 if (status!=RTEMS_SUCCESSFUL) {
451 451 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_DISABLE_ERR\n")
452 452 }
453 453 //
454 454 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ, 1); // sets the link-error interrupt bit
455 455 if (status!=RTEMS_SUCCESSFUL) {
456 456 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_LINK_ERR_IRQ\n")
457 457 }
458 458 //
459 459 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK, 1); // transmission blocks
460 460 if (status!=RTEMS_SUCCESSFUL) {
461 461 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK\n")
462 462 }
463 463 //
464 464 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL, 1); // transmission blocks when no transmission descriptor is available
465 465 if (status!=RTEMS_SUCCESSFUL) {
466 466 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL\n")
467 467 }
468 468 //
469 469 status = ioctl(fd, SPACEWIRE_IOCTRL_SET_TCODE_CTRL, 0x0909); // [Time Rx : Time Tx : Link error : Tick-out IRQ]
470 470 if (status!=RTEMS_SUCCESSFUL) {
471 471 PRINTF("in SPIQ *** Error SPACEWIRE_IOCTRL_SET_TCODE_CTRL,\n")
472 472 }
473 473
474 474 return status;
475 475 }
476 476
477 477 int spacewire_reset_link( void )
478 478 {
479 479 /** This function is executed by the SPIQ rtems_task wehn it has been awaken by an interruption raised by the SpaceWire driver.
480 480 *
481 481 * @return RTEMS directive status code:
482 482 * - RTEMS_UNSATISFIED is returned is the link is not in the running state after 10 s.
483 483 * - RTEMS_SUCCESSFUL is returned if the link is up before the timeout.
484 484 *
485 485 */
486 486
487 487 rtems_status_code status_spw;
488 488 rtems_status_code status;
489 489 int i;
490 490
491 491 for ( i=0; i<SY_LFR_DPU_CONNECT_ATTEMPT; i++ )
492 492 {
493 493 PRINTF1("in spacewire_reset_link *** link recovery, try %d\n", i);
494 494
495 495 // CLOSING THE DRIVER AT THIS POINT WILL MAKE THE SEND TASK BLOCK THE SYSTEM
496 496
497 497 status = rtems_task_wake_after( SY_LFR_DPU_CONNECT_TIMEOUT ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 1000 ms
498 498
499 499 status_spw = spacewire_stop_and_start_link( fdSPW );
500 500 if ( status_spw != RTEMS_SUCCESSFUL )
501 501 {
502 502 PRINTF1("in spacewire_reset_link *** ERR spacewire_start_link code %d\n", status_spw)
503 503 }
504 504
505 505 if ( status_spw == RTEMS_SUCCESSFUL)
506 506 {
507 507 break;
508 508 }
509 509 }
510 510
511 511 return status_spw;
512 512 }
513 513
514 514 void spacewire_set_NP( unsigned char val, unsigned int regAddr ) // [N]o [P]ort force
515 515 {
516 516 /** This function sets the [N]o [P]ort force bit of the GRSPW control register.
517 517 *
518 518 * @param val is the value, 0 or 1, used to set the value of the NP bit.
519 519 * @param regAddr is the address of the GRSPW control register.
520 520 *
521 521 * NP is the bit 20 of the GRSPW control register.
522 522 *
523 523 */
524 524
525 525 unsigned int *spwptr = (unsigned int*) regAddr;
526 526
527 527 if (val == 1) {
528 528 *spwptr = *spwptr | 0x00100000; // [NP] set the No port force bit
529 529 }
530 530 if (val== 0) {
531 531 *spwptr = *spwptr & 0xffdfffff;
532 532 }
533 533 }
534 534
535 535 void spacewire_set_RE( unsigned char val, unsigned int regAddr ) // [R]MAP [E]nable
536 536 {
537 537 /** This function sets the [R]MAP [E]nable bit of the GRSPW control register.
538 538 *
539 539 * @param val is the value, 0 or 1, used to set the value of the RE bit.
540 540 * @param regAddr is the address of the GRSPW control register.
541 541 *
542 542 * RE is the bit 16 of the GRSPW control register.
543 543 *
544 544 */
545 545
546 546 unsigned int *spwptr = (unsigned int*) regAddr;
547 547
548 548 if (val == 1)
549 549 {
550 550 *spwptr = *spwptr | 0x00010000; // [RE] set the RMAP Enable bit
551 551 }
552 552 if (val== 0)
553 553 {
554 554 *spwptr = *spwptr & 0xfffdffff;
555 555 }
556 556 }
557 557
558 558 void spacewire_compute_stats_offsets( void )
559 559 {
560 560 /** This function computes the SpaceWire statistics offsets in case of a SpaceWire related interruption raising.
561 561 *
562 562 * The offsets keep a record of the statistics in case of a reset of the statistics. They are added to the current statistics
563 563 * to keep the counters consistent even after a reset of the SpaceWire driver (the counter are set to zero by the driver when it
564 564 * during the open systel call).
565 565 *
566 566 */
567 567
568 568 spw_stats spacewire_stats_grspw;
569 569 rtems_status_code status;
570 570
571 571 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &spacewire_stats_grspw );
572 572
573 573 spacewire_stats_backup.packets_received = spacewire_stats_grspw.packets_received
574 574 + spacewire_stats.packets_received;
575 575 spacewire_stats_backup.packets_sent = spacewire_stats_grspw.packets_sent
576 576 + spacewire_stats.packets_sent;
577 577 spacewire_stats_backup.parity_err = spacewire_stats_grspw.parity_err
578 578 + spacewire_stats.parity_err;
579 579 spacewire_stats_backup.disconnect_err = spacewire_stats_grspw.disconnect_err
580 580 + spacewire_stats.disconnect_err;
581 581 spacewire_stats_backup.escape_err = spacewire_stats_grspw.escape_err
582 582 + spacewire_stats.escape_err;
583 583 spacewire_stats_backup.credit_err = spacewire_stats_grspw.credit_err
584 584 + spacewire_stats.credit_err;
585 585 spacewire_stats_backup.write_sync_err = spacewire_stats_grspw.write_sync_err
586 586 + spacewire_stats.write_sync_err;
587 587 spacewire_stats_backup.rx_rmap_header_crc_err = spacewire_stats_grspw.rx_rmap_header_crc_err
588 588 + spacewire_stats.rx_rmap_header_crc_err;
589 589 spacewire_stats_backup.rx_rmap_data_crc_err = spacewire_stats_grspw.rx_rmap_data_crc_err
590 590 + spacewire_stats.rx_rmap_data_crc_err;
591 591 spacewire_stats_backup.early_ep = spacewire_stats_grspw.early_ep
592 592 + spacewire_stats.early_ep;
593 593 spacewire_stats_backup.invalid_address = spacewire_stats_grspw.invalid_address
594 594 + spacewire_stats.invalid_address;
595 595 spacewire_stats_backup.rx_eep_err = spacewire_stats_grspw.rx_eep_err
596 596 + spacewire_stats.rx_eep_err;
597 597 spacewire_stats_backup.rx_truncated = spacewire_stats_grspw.rx_truncated
598 598 + spacewire_stats.rx_truncated;
599 599 }
600 600
601 601 void spacewire_update_statistics( void )
602 602 {
603 603 rtems_status_code status;
604 604 spw_stats spacewire_stats_grspw;
605 605
606 606 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_GET_STATISTICS, &spacewire_stats_grspw );
607 607
608 608 spacewire_stats.packets_received = spacewire_stats_backup.packets_received
609 609 + spacewire_stats_grspw.packets_received;
610 610 spacewire_stats.packets_sent = spacewire_stats_backup.packets_sent
611 611 + spacewire_stats_grspw.packets_sent;
612 612 spacewire_stats.parity_err = spacewire_stats_backup.parity_err
613 613 + spacewire_stats_grspw.parity_err;
614 614 spacewire_stats.disconnect_err = spacewire_stats_backup.disconnect_err
615 615 + spacewire_stats_grspw.disconnect_err;
616 616 spacewire_stats.escape_err = spacewire_stats_backup.escape_err
617 617 + spacewire_stats_grspw.escape_err;
618 618 spacewire_stats.credit_err = spacewire_stats_backup.credit_err
619 619 + spacewire_stats_grspw.credit_err;
620 620 spacewire_stats.write_sync_err = spacewire_stats_backup.write_sync_err
621 621 + spacewire_stats_grspw.write_sync_err;
622 622 spacewire_stats.rx_rmap_header_crc_err = spacewire_stats_backup.rx_rmap_header_crc_err
623 623 + spacewire_stats_grspw.rx_rmap_header_crc_err;
624 624 spacewire_stats.rx_rmap_data_crc_err = spacewire_stats_backup.rx_rmap_data_crc_err
625 625 + spacewire_stats_grspw.rx_rmap_data_crc_err;
626 626 spacewire_stats.early_ep = spacewire_stats_backup.early_ep
627 627 + spacewire_stats_grspw.early_ep;
628 628 spacewire_stats.invalid_address = spacewire_stats_backup.invalid_address
629 629 + spacewire_stats_grspw.invalid_address;
630 630 spacewire_stats.rx_eep_err = spacewire_stats_backup.rx_eep_err
631 631 + spacewire_stats_grspw.rx_eep_err;
632 632 spacewire_stats.rx_truncated = spacewire_stats_backup.rx_truncated
633 633 + spacewire_stats_grspw.rx_truncated;
634 634 //spacewire_stats.tx_link_err;
635 635
636 636 //****************************
637 637 // DPU_SPACEWIRE_IF_STATISTICS
638 638 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[0] = (unsigned char) (spacewire_stats.packets_received >> 8);
639 639 housekeeping_packet.hk_lfr_dpu_spw_pkt_rcv_cnt[1] = (unsigned char) (spacewire_stats.packets_received);
640 640 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[0] = (unsigned char) (spacewire_stats.packets_sent >> 8);
641 641 housekeeping_packet.hk_lfr_dpu_spw_pkt_sent_cnt[1] = (unsigned char) (spacewire_stats.packets_sent);
642 642 //housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt;
643 643 //housekeeping_packet.hk_lfr_dpu_spw_last_timc;
644 644
645 645 //******************************************
646 646 // ERROR COUNTERS / SPACEWIRE / LOW SEVERITY
647 647 housekeeping_packet.hk_lfr_dpu_spw_parity = (unsigned char) spacewire_stats.parity_err;
648 648 housekeeping_packet.hk_lfr_dpu_spw_disconnect = (unsigned char) spacewire_stats.disconnect_err;
649 649 housekeeping_packet.hk_lfr_dpu_spw_escape = (unsigned char) spacewire_stats.escape_err;
650 650 housekeeping_packet.hk_lfr_dpu_spw_credit = (unsigned char) spacewire_stats.credit_err;
651 651 housekeeping_packet.hk_lfr_dpu_spw_write_sync = (unsigned char) spacewire_stats.write_sync_err;
652 652
653 653 //*********************************************
654 654 // ERROR COUNTERS / SPACEWIRE / MEDIUM SEVERITY
655 655 housekeeping_packet.hk_lfr_dpu_spw_early_eop = (unsigned char) spacewire_stats.early_ep;
656 656 housekeeping_packet.hk_lfr_dpu_spw_invalid_addr = (unsigned char) spacewire_stats.invalid_address;
657 657 housekeeping_packet.hk_lfr_dpu_spw_eep = (unsigned char) spacewire_stats.rx_eep_err;
658 658 housekeeping_packet.hk_lfr_dpu_spw_rx_too_big = (unsigned char) spacewire_stats.rx_truncated;
659 659 }
660 660
661 661 void timecode_irq_handler( void *pDev, void *regs, int minor, unsigned int tc )
662 662 {
663 663 // a valid timecode has been received, write it in the HK report
664 664 unsigned int *grspwPtr;
665 665 unsigned char timecodeCtr;
666 666 unsigned char updateTimeCtr;
667 667
668 668 grspwPtr = (unsigned int *) (REGS_ADDR_GRSPW + APB_OFFSET_GRSPW_TIME_REGISTER);
669 669
670 670 housekeeping_packet.hk_lfr_dpu_spw_last_timc = (unsigned char) (grspwPtr[0] & 0xff); // [1111 1111]
671 671 timecodeCtr = (unsigned char) (grspwPtr[0] & 0x3f); // [0011 1111]
672 672 updateTimeCtr = time_management_regs->coarse_time_load & 0x3f; // [0011 1111]
673 673
674 674 // update the number of valid timecodes that have been received
675 675 if (housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt == 255)
676 676 {
677 677 housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt = 0;
678 678 }
679 679 else
680 680 {
681 681 housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt = housekeeping_packet.hk_lfr_dpu_spw_tick_out_cnt + 1;
682 682 }
683 683
684 684 // check the value of the timecode with respect to the last TC_LFR_UPDATE_TIME => SSS-CP-FS-370
685 685 if (timecodeCtr != updateTimeCtr)
686 686 {
687 687 if (housekeeping_packet.hk_lfr_time_timecode_ctr == 255)
688 688 {
689 689 housekeeping_packet.hk_lfr_time_timecode_ctr = 0;
690 690 }
691 691 else
692 692 {
693 693 housekeeping_packet.hk_lfr_time_timecode_ctr = housekeeping_packet.hk_lfr_time_timecode_ctr + 1;
694 694 }
695 695 }
696 696 }
697 697
698 698 rtems_timer_service_routine user_routine( rtems_id timer_id, void *user_data )
699 699 {
700 700 int linkStatus;
701 701 rtems_status_code status;
702 702
703 703 status = ioctl(fdSPW, SPACEWIRE_IOCTRL_GET_LINK_STATUS, &linkStatus); // get the link status
704 704
705 705 if ( linkStatus == 5) {
706 706 PRINTF("in spacewire_reset_link *** link is running\n")
707 707 status = RTEMS_SUCCESSFUL;
708 708 }
709 709 }
710 710
711 711 void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header )
712 712 {
713 713 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
714 714 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
715 715 header->reserved = DEFAULT_RESERVED;
716 716 header->userApplication = CCSDS_USER_APP;
717 717 header->packetSequenceControl[0]= TM_PACKET_SEQ_CTRL_STANDALONE;
718 718 header->packetSequenceControl[1]= TM_PACKET_SEQ_CNT_DEFAULT;
719 719 header->packetLength[0] = 0x00;
720 720 header->packetLength[1] = 0x00;
721 721 // DATA FIELD HEADER
722 722 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
723 723 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
724 724 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6; // service subtype
725 725 header->destinationID = TM_DESTINATION_ID_GROUND;
726 726 header->time[0] = 0x00;
727 727 header->time[0] = 0x00;
728 728 header->time[0] = 0x00;
729 729 header->time[0] = 0x00;
730 730 header->time[0] = 0x00;
731 731 header->time[0] = 0x00;
732 732 // AUXILIARY DATA HEADER
733 733 header->sid = 0x00;
734 734 header->hkBIA = DEFAULT_HKBIA;
735 735 header->blkNr[0] = 0x00;
736 736 header->blkNr[1] = 0x00;
737 737 }
738 738
739 739 void init_header_swf( Header_TM_LFR_SCIENCE_SWF_t *header )
740 740 {
741 741 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
742 742 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
743 743 header->reserved = DEFAULT_RESERVED;
744 744 header->userApplication = CCSDS_USER_APP;
745 745 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
746 746 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
747 747 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
748 748 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
749 749 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
750 750 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
751 751 // DATA FIELD HEADER
752 752 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
753 753 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
754 754 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6; // service subtype
755 755 header->destinationID = TM_DESTINATION_ID_GROUND;
756 756 header->time[0] = 0x00;
757 757 header->time[0] = 0x00;
758 758 header->time[0] = 0x00;
759 759 header->time[0] = 0x00;
760 760 header->time[0] = 0x00;
761 761 header->time[0] = 0x00;
762 762 // AUXILIARY DATA HEADER
763 763 header->sid = 0x00;
764 764 header->hkBIA = DEFAULT_HKBIA;
765 765 header->pktCnt = DEFAULT_PKTCNT; // PKT_CNT
766 766 header->pktNr = 0x00;
767 767 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
768 768 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
769 769 }
770 770
771 771 void init_header_asm( Header_TM_LFR_SCIENCE_ASM_t *header )
772 772 {
773 773 header->targetLogicalAddress = CCSDS_DESTINATION_ID;
774 774 header->protocolIdentifier = CCSDS_PROTOCOLE_ID;
775 775 header->reserved = DEFAULT_RESERVED;
776 776 header->userApplication = CCSDS_USER_APP;
777 777 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
778 778 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
779 779 header->packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
780 780 header->packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
781 781 header->packetLength[0] = 0x00;
782 782 header->packetLength[1] = 0x00;
783 783 // DATA FIELD HEADER
784 784 header->spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
785 785 header->serviceType = TM_TYPE_LFR_SCIENCE; // service type
786 786 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3; // service subtype
787 787 header->destinationID = TM_DESTINATION_ID_GROUND;
788 788 header->time[0] = 0x00;
789 789 header->time[0] = 0x00;
790 790 header->time[0] = 0x00;
791 791 header->time[0] = 0x00;
792 792 header->time[0] = 0x00;
793 793 header->time[0] = 0x00;
794 794 // AUXILIARY DATA HEADER
795 795 header->sid = 0x00;
796 796 header->biaStatusInfo = 0x00;
797 797 header->pa_lfr_pkt_cnt_asm = 0x00;
798 798 header->pa_lfr_pkt_nr_asm = 0x00;
799 799 header->pa_lfr_asm_blk_nr[0] = 0x00;
800 800 header->pa_lfr_asm_blk_nr[1] = 0x00;
801 801 }
802 802
803 803 int spw_send_waveform_CWF( ring_node *ring_node_to_send,
804 804 Header_TM_LFR_SCIENCE_CWF_t *header )
805 805 {
806 806 /** This function sends CWF CCSDS packets (F2, F1 or F0).
807 807 *
808 808 * @param waveform points to the buffer containing the data that will be send.
809 809 * @param sid is the source identifier of the data that will be sent.
810 810 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
811 811 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
812 812 * contain information to setup the transmission of the data packets.
813 813 *
814 814 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
815 815 *
816 816 */
817 817
818 818 unsigned int i;
819 819 int ret;
820 820 unsigned int coarseTime;
821 821 unsigned int fineTime;
822 822 rtems_status_code status;
823 823 spw_ioctl_pkt_send spw_ioctl_send_CWF;
824 824 int *dataPtr;
825 825 unsigned char sid;
826 826
827 827 spw_ioctl_send_CWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_CWF;
828 828 spw_ioctl_send_CWF.options = 0;
829 829
830 830 ret = LFR_DEFAULT;
831 831 sid = (unsigned char) ring_node_to_send->sid;
832 832
833 833 coarseTime = ring_node_to_send->coarseTime;
834 834 fineTime = ring_node_to_send->fineTime;
835 835 dataPtr = (int*) ring_node_to_send->buffer_address;
836 836
837 837 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_336 >> 8);
838 838 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_336 );
839 839 header->hkBIA = pa_bia_status_info;
840 840 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
841 841 header->blkNr[0] = (unsigned char) (BLK_NR_CWF >> 8);
842 842 header->blkNr[1] = (unsigned char) (BLK_NR_CWF );
843 843
844 844 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF; i++) // send waveform
845 845 {
846 846 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF * NB_WORDS_SWF_BLK) ];
847 847 spw_ioctl_send_CWF.hdr = (char*) header;
848 848 // BUILD THE DATA
849 849 spw_ioctl_send_CWF.dlen = BLK_NR_CWF * NB_BYTES_SWF_BLK;
850 850
851 851 // SET PACKET SEQUENCE CONTROL
852 852 increment_seq_counter_source_id( header->packetSequenceControl, sid );
853 853
854 854 // SET SID
855 855 header->sid = sid;
856 856
857 857 // SET PACKET TIME
858 858 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime);
859 859 //
860 860 header->time[0] = header->acquisitionTime[0];
861 861 header->time[1] = header->acquisitionTime[1];
862 862 header->time[2] = header->acquisitionTime[2];
863 863 header->time[3] = header->acquisitionTime[3];
864 864 header->time[4] = header->acquisitionTime[4];
865 865 header->time[5] = header->acquisitionTime[5];
866 866
867 867 // SET PACKET ID
868 868 if ( (sid == SID_SBM1_CWF_F1) || (sid == SID_SBM2_CWF_F2) )
869 869 {
870 870 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2 >> 8);
871 871 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_SBM1_SBM2);
872 872 }
873 873 else
874 874 {
875 875 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
876 876 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
877 877 }
878 878
879 879 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
880 880 if (status != RTEMS_SUCCESSFUL) {
881 881 ret = LFR_DEFAULT;
882 882 }
883 883 }
884 884
885 885 return ret;
886 886 }
887 887
888 888 int spw_send_waveform_SWF( ring_node *ring_node_to_send,
889 889 Header_TM_LFR_SCIENCE_SWF_t *header )
890 890 {
891 891 /** This function sends SWF CCSDS packets (F2, F1 or F0).
892 892 *
893 893 * @param waveform points to the buffer containing the data that will be send.
894 894 * @param sid is the source identifier of the data that will be sent.
895 895 * @param headerSWF points to a table of headers that have been prepared for the data transmission.
896 896 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
897 897 * contain information to setup the transmission of the data packets.
898 898 *
899 899 * One group of 2048 samples is sent as 7 consecutive packets, 6 packets containing 340 blocks and 8 packets containing 8 blocks.
900 900 *
901 901 */
902 902
903 903 unsigned int i;
904 904 int ret;
905 905 unsigned int coarseTime;
906 906 unsigned int fineTime;
907 907 rtems_status_code status;
908 908 spw_ioctl_pkt_send spw_ioctl_send_SWF;
909 909 int *dataPtr;
910 910 unsigned char sid;
911 911
912 912 spw_ioctl_send_SWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_SWF;
913 913 spw_ioctl_send_SWF.options = 0;
914 914
915 915 ret = LFR_DEFAULT;
916 916
917 917 coarseTime = ring_node_to_send->coarseTime;
918 918 fineTime = ring_node_to_send->fineTime;
919 919 dataPtr = (int*) ring_node_to_send->buffer_address;
920 920 sid = ring_node_to_send->sid;
921 921
922 922 header->hkBIA = pa_bia_status_info;
923 923 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
924 924
925 925 for (i=0; i<7; i++) // send waveform
926 926 {
927 927 spw_ioctl_send_SWF.data = (char*) &dataPtr[ (i * BLK_NR_304 * NB_WORDS_SWF_BLK) ];
928 928 spw_ioctl_send_SWF.hdr = (char*) header;
929 929
930 930 // SET PACKET SEQUENCE CONTROL
931 931 increment_seq_counter_source_id( header->packetSequenceControl, sid );
932 932
933 933 // SET PACKET LENGTH AND BLKNR
934 934 if (i == 6)
935 935 {
936 936 spw_ioctl_send_SWF.dlen = BLK_NR_224 * NB_BYTES_SWF_BLK;
937 937 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_224 >> 8);
938 938 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_224 );
939 939 header->blkNr[0] = (unsigned char) (BLK_NR_224 >> 8);
940 940 header->blkNr[1] = (unsigned char) (BLK_NR_224 );
941 941 }
942 942 else
943 943 {
944 944 spw_ioctl_send_SWF.dlen = BLK_NR_304 * NB_BYTES_SWF_BLK;
945 945 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_SWF_304 >> 8);
946 946 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_SWF_304 );
947 947 header->blkNr[0] = (unsigned char) (BLK_NR_304 >> 8);
948 948 header->blkNr[1] = (unsigned char) (BLK_NR_304 );
949 949 }
950 950
951 951 // SET PACKET TIME
952 952 compute_acquisition_time( coarseTime, fineTime, sid, i, header->acquisitionTime );
953 953 //
954 954 header->time[0] = header->acquisitionTime[0];
955 955 header->time[1] = header->acquisitionTime[1];
956 956 header->time[2] = header->acquisitionTime[2];
957 957 header->time[3] = header->acquisitionTime[3];
958 958 header->time[4] = header->acquisitionTime[4];
959 959 header->time[5] = header->acquisitionTime[5];
960 960
961 961 // SET SID
962 962 header->sid = sid;
963 963
964 964 // SET PKTNR
965 965 header->pktNr = i+1; // PKT_NR
966 966
967 967 // SEND PACKET
968 968 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_SWF );
969 969 if (status != RTEMS_SUCCESSFUL) {
970 970 ret = LFR_DEFAULT;
971 971 }
972 972 }
973 973
974 974 return ret;
975 975 }
976 976
977 977 int spw_send_waveform_CWF3_light( ring_node *ring_node_to_send,
978 978 Header_TM_LFR_SCIENCE_CWF_t *header )
979 979 {
980 980 /** This function sends CWF_F3 CCSDS packets without the b1, b2 and b3 data.
981 981 *
982 982 * @param waveform points to the buffer containing the data that will be send.
983 983 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
984 984 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
985 985 * contain information to setup the transmission of the data packets.
986 986 *
987 987 * By default, CWF_F3 packet are send without the b1, b2 and b3 data. This function rebuilds a data buffer
988 988 * from the incoming data and sends it in 7 packets, 6 containing 340 blocks and 1 one containing 8 blocks.
989 989 *
990 990 */
991 991
992 992 unsigned int i;
993 993 int ret;
994 994 unsigned int coarseTime;
995 995 unsigned int fineTime;
996 996 rtems_status_code status;
997 997 spw_ioctl_pkt_send spw_ioctl_send_CWF;
998 998 char *dataPtr;
999 999 unsigned char sid;
1000 1000
1001 1001 spw_ioctl_send_CWF.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_CWF;
1002 1002 spw_ioctl_send_CWF.options = 0;
1003 1003
1004 1004 ret = LFR_DEFAULT;
1005 1005 sid = ring_node_to_send->sid;
1006 1006
1007 1007 coarseTime = ring_node_to_send->coarseTime;
1008 1008 fineTime = ring_node_to_send->fineTime;
1009 1009 dataPtr = (char*) ring_node_to_send->buffer_address;
1010 1010
1011 1011 header->packetLength[0] = (unsigned char) (TM_LEN_SCI_CWF_672 >> 8);
1012 1012 header->packetLength[1] = (unsigned char) (TM_LEN_SCI_CWF_672 );
1013 1013 header->hkBIA = pa_bia_status_info;
1014 1014 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1015 1015 header->blkNr[0] = (unsigned char) (BLK_NR_CWF_SHORT_F3 >> 8);
1016 1016 header->blkNr[1] = (unsigned char) (BLK_NR_CWF_SHORT_F3 );
1017 1017
1018 1018 //*********************
1019 1019 // SEND CWF3_light DATA
1020 1020 for (i=0; i<NB_PACKETS_PER_GROUP_OF_CWF_LIGHT; i++) // send waveform
1021 1021 {
1022 1022 spw_ioctl_send_CWF.data = (char*) &dataPtr[ (i * BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK) ];
1023 1023 spw_ioctl_send_CWF.hdr = (char*) header;
1024 1024 // BUILD THE DATA
1025 1025 spw_ioctl_send_CWF.dlen = BLK_NR_CWF_SHORT_F3 * NB_BYTES_CWF3_LIGHT_BLK;
1026 1026
1027 1027 // SET PACKET SEQUENCE COUNTER
1028 1028 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1029 1029
1030 1030 // SET SID
1031 1031 header->sid = sid;
1032 1032
1033 1033 // SET PACKET TIME
1034 1034 compute_acquisition_time( coarseTime, fineTime, SID_NORM_CWF_F3, i, header->acquisitionTime );
1035 1035 //
1036 1036 header->time[0] = header->acquisitionTime[0];
1037 1037 header->time[1] = header->acquisitionTime[1];
1038 1038 header->time[2] = header->acquisitionTime[2];
1039 1039 header->time[3] = header->acquisitionTime[3];
1040 1040 header->time[4] = header->acquisitionTime[4];
1041 1041 header->time[5] = header->acquisitionTime[5];
1042 1042
1043 1043 // SET PACKET ID
1044 1044 header->packetID[0] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST >> 8);
1045 1045 header->packetID[1] = (unsigned char) (APID_TM_SCIENCE_NORMAL_BURST);
1046 1046
1047 1047 // SEND PACKET
1048 1048 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_CWF );
1049 1049 if (status != RTEMS_SUCCESSFUL) {
1050 1050 ret = LFR_DEFAULT;
1051 1051 }
1052 1052 }
1053 1053
1054 1054 return ret;
1055 1055 }
1056 1056
1057 1057 void spw_send_asm_f0( ring_node *ring_node_to_send,
1058 1058 Header_TM_LFR_SCIENCE_ASM_t *header )
1059 1059 {
1060 1060 unsigned int i;
1061 1061 unsigned int length = 0;
1062 1062 rtems_status_code status;
1063 1063 unsigned int sid;
1064 1064 float *spectral_matrix;
1065 1065 int coarseTime;
1066 1066 int fineTime;
1067 1067 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1068 1068
1069 1069 sid = ring_node_to_send->sid;
1070 1070 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1071 1071 coarseTime = ring_node_to_send->coarseTime;
1072 1072 fineTime = ring_node_to_send->fineTime;
1073 1073
1074 1074 header->biaStatusInfo = pa_bia_status_info;
1075 1075 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1076 1076
1077 1077 for (i=0; i<3; i++)
1078 1078 {
1079 1079 if ((i==0) || (i==1))
1080 1080 {
1081 1081 spw_ioctl_send_ASM.dlen = DLEN_ASM_F0_PKT_1;
1082 1082 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1083 1083 ( (ASM_F0_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F0_1) ) * NB_VALUES_PER_SM )
1084 1084 ];
1085 1085 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0_1;
1086 1086 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1087 1087 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0_1) >> 8 ); // BLK_NR MSB
1088 1088 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0_1); // BLK_NR LSB
1089 1089 }
1090 1090 else
1091 1091 {
1092 1092 spw_ioctl_send_ASM.dlen = DLEN_ASM_F0_PKT_2;
1093 1093 spw_ioctl_send_ASM.data = (char*) &spectral_matrix[
1094 1094 ( (ASM_F0_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F0_1) ) * NB_VALUES_PER_SM )
1095 1095 ];
1096 1096 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0_2;
1097 1097 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1098 1098 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0_2) >> 8 ); // BLK_NR MSB
1099 1099 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0_2); // BLK_NR LSB
1100 1100 }
1101 1101
1102 1102 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1103 1103 spw_ioctl_send_ASM.hdr = (char *) header;
1104 1104 spw_ioctl_send_ASM.options = 0;
1105 1105
1106 1106 // (2) BUILD THE HEADER
1107 1107 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1108 1108 header->packetLength[0] = (unsigned char) (length>>8);
1109 1109 header->packetLength[1] = (unsigned char) (length);
1110 1110 header->sid = (unsigned char) sid; // SID
1111 1111 header->pa_lfr_pkt_cnt_asm = 3;
1112 1112 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1113 1113
1114 1114 // (3) SET PACKET TIME
1115 1115 header->time[0] = (unsigned char) (coarseTime>>24);
1116 1116 header->time[1] = (unsigned char) (coarseTime>>16);
1117 1117 header->time[2] = (unsigned char) (coarseTime>>8);
1118 1118 header->time[3] = (unsigned char) (coarseTime);
1119 1119 header->time[4] = (unsigned char) (fineTime>>8);
1120 1120 header->time[5] = (unsigned char) (fineTime);
1121 1121 //
1122 1122 header->acquisitionTime[0] = header->time[0];
1123 1123 header->acquisitionTime[1] = header->time[1];
1124 1124 header->acquisitionTime[2] = header->time[2];
1125 1125 header->acquisitionTime[3] = header->time[3];
1126 1126 header->acquisitionTime[4] = header->time[4];
1127 1127 header->acquisitionTime[5] = header->time[5];
1128 1128
1129 1129 // (4) SEND PACKET
1130 1130 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1131 1131 if (status != RTEMS_SUCCESSFUL) {
1132 1132 PRINTF1("in ASM_send *** ERR %d\n", (int) status)
1133 1133 }
1134 1134 }
1135 1135 }
1136 1136
1137 1137 void spw_send_asm_f1( ring_node *ring_node_to_send,
1138 1138 Header_TM_LFR_SCIENCE_ASM_t *header )
1139 1139 {
1140 1140 unsigned int i;
1141 1141 unsigned int length = 0;
1142 1142 rtems_status_code status;
1143 1143 unsigned int sid;
1144 1144 float *spectral_matrix;
1145 1145 int coarseTime;
1146 1146 int fineTime;
1147 1147 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1148 1148
1149 1149 sid = ring_node_to_send->sid;
1150 1150 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1151 1151 coarseTime = ring_node_to_send->coarseTime;
1152 1152 fineTime = ring_node_to_send->fineTime;
1153 1153
1154 1154 header->biaStatusInfo = pa_bia_status_info;
1155 1155 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1156 1156
1157 1157 for (i=0; i<3; i++)
1158 1158 {
1159 1159 if ((i==0) || (i==1))
1160 1160 {
1161 1161 spw_ioctl_send_ASM.dlen = DLEN_ASM_F1_PKT_1;
1162 1162 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1163 1163 ( (ASM_F1_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F1_1) ) * NB_VALUES_PER_SM )
1164 1164 ];
1165 1165 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F1_1;
1166 1166 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1167 1167 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F1_1) >> 8 ); // BLK_NR MSB
1168 1168 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F1_1); // BLK_NR LSB
1169 1169 }
1170 1170 else
1171 1171 {
1172 1172 spw_ioctl_send_ASM.dlen = DLEN_ASM_F1_PKT_2;
1173 1173 spw_ioctl_send_ASM.data = (char*) &spectral_matrix[
1174 1174 ( (ASM_F1_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F1_1) ) * NB_VALUES_PER_SM )
1175 1175 ];
1176 1176 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F1_2;
1177 1177 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_6;
1178 1178 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F1_2) >> 8 ); // BLK_NR MSB
1179 1179 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F1_2); // BLK_NR LSB
1180 1180 }
1181 1181
1182 1182 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1183 1183 spw_ioctl_send_ASM.hdr = (char *) header;
1184 1184 spw_ioctl_send_ASM.options = 0;
1185 1185
1186 1186 // (2) BUILD THE HEADER
1187 1187 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1188 1188 header->packetLength[0] = (unsigned char) (length>>8);
1189 1189 header->packetLength[1] = (unsigned char) (length);
1190 1190 header->sid = (unsigned char) sid; // SID
1191 1191 header->pa_lfr_pkt_cnt_asm = 3;
1192 1192 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1193 1193
1194 1194 // (3) SET PACKET TIME
1195 1195 header->time[0] = (unsigned char) (coarseTime>>24);
1196 1196 header->time[1] = (unsigned char) (coarseTime>>16);
1197 1197 header->time[2] = (unsigned char) (coarseTime>>8);
1198 1198 header->time[3] = (unsigned char) (coarseTime);
1199 1199 header->time[4] = (unsigned char) (fineTime>>8);
1200 1200 header->time[5] = (unsigned char) (fineTime);
1201 1201 //
1202 1202 header->acquisitionTime[0] = header->time[0];
1203 1203 header->acquisitionTime[1] = header->time[1];
1204 1204 header->acquisitionTime[2] = header->time[2];
1205 1205 header->acquisitionTime[3] = header->time[3];
1206 1206 header->acquisitionTime[4] = header->time[4];
1207 1207 header->acquisitionTime[5] = header->time[5];
1208 1208
1209 1209 // (4) SEND PACKET
1210 1210 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1211 1211 if (status != RTEMS_SUCCESSFUL) {
1212 1212 PRINTF1("in ASM_send *** ERR %d\n", (int) status)
1213 1213 }
1214 1214 }
1215 1215 }
1216 1216
1217 1217 void spw_send_asm_f2( ring_node *ring_node_to_send,
1218 1218 Header_TM_LFR_SCIENCE_ASM_t *header )
1219 1219 {
1220 1220 unsigned int i;
1221 1221 unsigned int length = 0;
1222 1222 rtems_status_code status;
1223 1223 unsigned int sid;
1224 1224 float *spectral_matrix;
1225 1225 int coarseTime;
1226 1226 int fineTime;
1227 1227 spw_ioctl_pkt_send spw_ioctl_send_ASM;
1228 1228
1229 1229 sid = ring_node_to_send->sid;
1230 1230 spectral_matrix = (float*) ring_node_to_send->buffer_address;
1231 1231 coarseTime = ring_node_to_send->coarseTime;
1232 1232 fineTime = ring_node_to_send->fineTime;
1233 1233
1234 1234 header->biaStatusInfo = pa_bia_status_info;
1235 1235 header->sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
1236 1236
1237 1237 for (i=0; i<3; i++)
1238 1238 {
1239 1239
1240 1240 spw_ioctl_send_ASM.dlen = DLEN_ASM_F2_PKT;
1241 1241 spw_ioctl_send_ASM.data = (char *) &spectral_matrix[
1242 1242 ( (ASM_F2_INDICE_START + (i*NB_BINS_PER_PKT_ASM_F2) ) * NB_VALUES_PER_SM )
1243 1243 ];
1244 1244 length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F2;
1245 1245 header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE_3;
1246 1246 header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F2) >> 8 ); // BLK_NR MSB
1247 1247 header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F2); // BLK_NR LSB
1248 1248
1249 1249 spw_ioctl_send_ASM.hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM;
1250 1250 spw_ioctl_send_ASM.hdr = (char *) header;
1251 1251 spw_ioctl_send_ASM.options = 0;
1252 1252
1253 1253 // (2) BUILD THE HEADER
1254 1254 increment_seq_counter_source_id( header->packetSequenceControl, sid );
1255 1255 header->packetLength[0] = (unsigned char) (length>>8);
1256 1256 header->packetLength[1] = (unsigned char) (length);
1257 1257 header->sid = (unsigned char) sid; // SID
1258 1258 header->pa_lfr_pkt_cnt_asm = 3;
1259 1259 header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1);
1260 1260
1261 1261 // (3) SET PACKET TIME
1262 1262 header->time[0] = (unsigned char) (coarseTime>>24);
1263 1263 header->time[1] = (unsigned char) (coarseTime>>16);
1264 1264 header->time[2] = (unsigned char) (coarseTime>>8);
1265 1265 header->time[3] = (unsigned char) (coarseTime);
1266 1266 header->time[4] = (unsigned char) (fineTime>>8);
1267 1267 header->time[5] = (unsigned char) (fineTime);
1268 1268 //
1269 1269 header->acquisitionTime[0] = header->time[0];
1270 1270 header->acquisitionTime[1] = header->time[1];
1271 1271 header->acquisitionTime[2] = header->time[2];
1272 1272 header->acquisitionTime[3] = header->time[3];
1273 1273 header->acquisitionTime[4] = header->time[4];
1274 1274 header->acquisitionTime[5] = header->time[5];
1275 1275
1276 1276 // (4) SEND PACKET
1277 1277 status = ioctl( fdSPW, SPACEWIRE_IOCTRL_SEND, &spw_ioctl_send_ASM );
1278 1278 if (status != RTEMS_SUCCESSFUL) {
1279 1279 PRINTF1("in ASM_send *** ERR %d\n", (int) status)
1280 1280 }
1281 1281 }
1282 1282 }
1283 1283
1284 1284 void spw_send_k_dump( ring_node *ring_node_to_send )
1285 1285 {
1286 1286 rtems_status_code status;
1287 1287 Packet_TM_LFR_KCOEFFICIENTS_DUMP_t *kcoefficients_dump;
1288 1288 unsigned int packetLength;
1289 1289 unsigned int size;
1290 1290
1291 1291 PRINTF("spw_send_k_dump\n")
1292 1292
1293 1293 kcoefficients_dump = (Packet_TM_LFR_KCOEFFICIENTS_DUMP_t *) ring_node_to_send->buffer_address;
1294 1294
1295 1295 packetLength = kcoefficients_dump->packetLength[0] * 256 + kcoefficients_dump->packetLength[1];
1296 1296
1297 1297 size = packetLength + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES;
1298 1298
1299 1299 PRINTF2("packetLength %d, size %d\n", packetLength, size )
1300 1300
1301 1301 status = write( fdSPW, (char *) ring_node_to_send->buffer_address, size );
1302 1302
1303 1303 if (status == -1){
1304 1304 PRINTF2("in SEND *** (2.a) ERRNO = %d, size = %d\n", errno, size)
1305 1305 }
1306 1306
1307 1307 ring_node_to_send->status = 0x00;
1308 1308 }
@@ -1,1180 +1,1322
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 status = enter_mode( requestedMode, transitionCoarseTime );
207
208 switch(requestedMode)
209 {
210 case LFR_MODE_STANDBY:
211 status = enter_mode_standby();
212 break;
213 case LFR_MODE_NORMAL:
214 status = enter_mode_normal( transitionCoarseTime );
215 break;
216 case LFR_MODE_BURST:
217 status = enter_mode_burst( transitionCoarseTime );
218 break;
219 case LFR_MODE_SBM1:
220 status = enter_mode_sbm1( transitionCoarseTime );
221 break;
222 case LFR_MODE_SBM2:
223 status = enter_mode_sbm2( transitionCoarseTime );
224 break;
225 default:
226 break;
227 }
208 228 }
209 229
210 230 return status;
211 231 }
212 232
213 233 int action_update_info(ccsdsTelecommandPacket_t *TC, rtems_id queue_id)
214 234 {
215 235 /** This function executes specific actions when a TC_LFR_UPDATE_INFO TeleCommand has been received.
216 236 *
217 237 * @param TC points to the TeleCommand packet that is being processed
218 238 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
219 239 *
220 240 * @return LFR directive status code:
221 241 * - LFR_DEFAULT
222 242 * - LFR_SUCCESSFUL
223 243 *
224 244 */
225 245
226 246 unsigned int val;
227 247 int result;
228 248 unsigned int status;
229 249 unsigned char mode;
230 250 unsigned char * bytePosPtr;
231 251
232 252 bytePosPtr = (unsigned char *) &TC->packetID;
233 253
234 254 // check LFR mode
235 255 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET5 ] & 0x1e) >> 1;
236 256 status = check_update_info_hk_lfr_mode( mode );
237 257 if (status == LFR_SUCCESSFUL) // check TDS mode
238 258 {
239 259 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & 0xf0) >> 4;
240 260 status = check_update_info_hk_tds_mode( mode );
241 261 }
242 262 if (status == LFR_SUCCESSFUL) // check THR mode
243 263 {
244 264 mode = (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET6 ] & 0x0f);
245 265 status = check_update_info_hk_thr_mode( mode );
246 266 }
247 267 if (status == LFR_SUCCESSFUL) // if the parameter check is successful
248 268 {
249 269 val = housekeeping_packet.hk_lfr_update_info_tc_cnt[0] * 256
250 270 + housekeeping_packet.hk_lfr_update_info_tc_cnt[1];
251 271 val++;
252 272 housekeeping_packet.hk_lfr_update_info_tc_cnt[0] = (unsigned char) (val >> 8);
253 273 housekeeping_packet.hk_lfr_update_info_tc_cnt[1] = (unsigned char) (val);
254 274 }
255 275
256 276 // pa_bia_status_info
257 277 // => pa_bia_mode_mux_set 3 bits
258 278 // => pa_bia_mode_hv_enabled 1 bit
259 279 // => pa_bia_mode_bias1_enabled 1 bit
260 280 // => pa_bia_mode_bias2_enabled 1 bit
261 281 // => pa_bia_mode_bias3_enabled 1 bit
262 282 // => pa_bia_on_off (cp_dpu_bias_on_off)
263 283 pa_bia_status_info = bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET2 ] & 0xfe; // [1111 1110]
264 284 pa_bia_status_info = pa_bia_status_info
265 285 | (bytePosPtr[ BYTE_POS_UPDATE_INFO_PARAMETERS_SET1 ] & 0x1);
266 286
267 287 result = status;
268 288
269 289 return result;
270 290 }
271 291
272 292 int action_enable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
273 293 {
274 294 /** This function executes specific actions when a TC_LFR_ENABLE_CALIBRATION TeleCommand has been received.
275 295 *
276 296 * @param TC points to the TeleCommand packet that is being processed
277 297 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
278 298 *
279 299 */
280 300
281 301 int result;
282 302
283 303 result = LFR_DEFAULT;
284 304
285 305 setCalibration( true );
286 306
287 307 result = LFR_SUCCESSFUL;
288 308
289 309 return result;
290 310 }
291 311
292 312 int action_disable_calibration(ccsdsTelecommandPacket_t *TC, rtems_id queue_id, unsigned char *time)
293 313 {
294 314 /** This function executes specific actions when a TC_LFR_DISABLE_CALIBRATION TeleCommand has been received.
295 315 *
296 316 * @param TC points to the TeleCommand packet that is being processed
297 317 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
298 318 *
299 319 */
300 320
301 321 int result;
302 322
303 323 result = LFR_DEFAULT;
304 324
305 325 setCalibration( false );
306 326
307 327 result = LFR_SUCCESSFUL;
308 328
309 329 return result;
310 330 }
311 331
312 332 int action_update_time(ccsdsTelecommandPacket_t *TC)
313 333 {
314 334 /** This function executes specific actions when a TC_LFR_UPDATE_TIME TeleCommand has been received.
315 335 *
316 336 * @param TC points to the TeleCommand packet that is being processed
317 337 * @param queue_id is the id of the queue which handles TM transmission by the SpaceWire driver
318 338 *
319 339 * @return LFR_SUCCESSFUL
320 340 *
321 341 */
322 342
323 343 unsigned int val;
324 344
325 345 time_management_regs->coarse_time_load = (TC->dataAndCRC[0] << 24)
326 346 + (TC->dataAndCRC[1] << 16)
327 347 + (TC->dataAndCRC[2] << 8)
328 348 + TC->dataAndCRC[3];
329 349
330 350 val = housekeeping_packet.hk_lfr_update_time_tc_cnt[0] * 256
331 351 + housekeeping_packet.hk_lfr_update_time_tc_cnt[1];
332 352 val++;
333 353 housekeeping_packet.hk_lfr_update_time_tc_cnt[0] = (unsigned char) (val >> 8);
334 354 housekeeping_packet.hk_lfr_update_time_tc_cnt[1] = (unsigned char) (val);
335 355
336 356 return LFR_SUCCESSFUL;
337 357 }
338 358
339 359 //*******************
340 360 // ENTERING THE MODES
341 361 int check_mode_value( unsigned char requestedMode )
342 362 {
343 363 int status;
344 364
345 365 if ( (requestedMode != LFR_MODE_STANDBY)
346 366 && (requestedMode != LFR_MODE_NORMAL) && (requestedMode != LFR_MODE_BURST)
347 367 && (requestedMode != LFR_MODE_SBM1) && (requestedMode != LFR_MODE_SBM2) )
348 368 {
349 369 status = LFR_DEFAULT;
350 370 }
351 371 else
352 372 {
353 373 status = LFR_SUCCESSFUL;
354 374 }
355 375
356 376 return status;
357 377 }
358 378
359 379 int check_mode_transition( unsigned char requestedMode )
360 380 {
361 381 /** This function checks the validity of the transition requested by the TC_LFR_ENTER_MODE.
362 382 *
363 383 * @param requestedMode is the mode requested by the TC_LFR_ENTER_MODE
364 384 *
365 385 * @return LFR directive status codes:
366 386 * - LFR_SUCCESSFUL - the transition is authorized
367 387 * - LFR_DEFAULT - the transition is not authorized
368 388 *
369 389 */
370 390
371 391 int status;
372 392
373 393 switch (requestedMode)
374 394 {
375 395 case LFR_MODE_STANDBY:
376 396 if ( lfrCurrentMode == LFR_MODE_STANDBY ) {
377 397 status = LFR_DEFAULT;
378 398 }
379 399 else
380 400 {
381 401 status = LFR_SUCCESSFUL;
382 402 }
383 403 break;
384 404 case LFR_MODE_NORMAL:
385 405 if ( lfrCurrentMode == LFR_MODE_NORMAL ) {
386 406 status = LFR_DEFAULT;
387 407 }
388 408 else {
389 409 status = LFR_SUCCESSFUL;
390 410 }
391 411 break;
392 412 case LFR_MODE_BURST:
393 413 if ( lfrCurrentMode == LFR_MODE_BURST ) {
394 414 status = LFR_DEFAULT;
395 415 }
396 416 else {
397 417 status = LFR_SUCCESSFUL;
398 418 }
399 419 break;
400 420 case LFR_MODE_SBM1:
401 421 if ( lfrCurrentMode == LFR_MODE_SBM1 ) {
402 422 status = LFR_DEFAULT;
403 423 }
404 424 else {
405 425 status = LFR_SUCCESSFUL;
406 426 }
407 427 break;
408 428 case LFR_MODE_SBM2:
409 429 if ( lfrCurrentMode == LFR_MODE_SBM2 ) {
410 430 status = LFR_DEFAULT;
411 431 }
412 432 else {
413 433 status = LFR_SUCCESSFUL;
414 434 }
415 435 break;
416 436 default:
417 437 status = LFR_DEFAULT;
418 438 break;
419 439 }
420 440
421 441 return status;
422 442 }
423 443
424 444 int check_transition_date( unsigned int transitionCoarseTime )
425 445 {
426 446 int status;
427 447 unsigned int localCoarseTime;
428 448 unsigned int deltaCoarseTime;
429 449
430 450 status = LFR_SUCCESSFUL;
431 451
432 452 if (transitionCoarseTime == 0) // transition time = 0 means an instant transition
433 453 {
434 454 status = LFR_SUCCESSFUL;
435 455 }
436 456 else
437 457 {
438 458 localCoarseTime = time_management_regs->coarse_time & 0x7fffffff;
439 459
440 460 PRINTF2("localTime = %x, transitionTime = %x\n", localCoarseTime, transitionCoarseTime)
441 461
442 462 if ( transitionCoarseTime <= localCoarseTime ) // SSS-CP-EQS-322
443 463 {
444 464 status = LFR_DEFAULT;
445 465 PRINTF("ERR *** in check_transition_date *** transitionCoarseTime <= localCoarseTime\n")
446 466 }
447 467
448 468 if (status == LFR_SUCCESSFUL)
449 469 {
450 470 deltaCoarseTime = transitionCoarseTime - localCoarseTime;
451 471 if ( deltaCoarseTime > 3 ) // SSS-CP-EQS-323
452 472 {
453 473 status = LFR_DEFAULT;
454 474 PRINTF1("ERR *** in check_transition_date *** deltaCoarseTime = %x\n", deltaCoarseTime)
455 475 }
456 476 }
457 477 }
458 478
459 479 return status;
460 480 }
461 481
462 482 int stop_current_mode( void )
463 483 {
464 484 /** This function stops the current mode by masking interrupt lines and suspending science tasks.
465 485 *
466 486 * @return RTEMS directive status codes:
467 487 * - RTEMS_SUCCESSFUL - task restarted successfully
468 488 * - RTEMS_INVALID_ID - task id invalid
469 489 * - RTEMS_ALREADY_SUSPENDED - task already suspended
470 490 *
471 491 */
472 492
473 493 rtems_status_code status;
474 494
475 495 status = RTEMS_SUCCESSFUL;
476 496
477 497 // (1) mask interruptions
478 498 LEON_Mask_interrupt( IRQ_WAVEFORM_PICKER ); // mask waveform picker interrupt
479 499 LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
480 500
481 501 // (2) reset waveform picker registers
482 502 reset_wfp_burst_enable(); // reset burst and enable bits
483 503 reset_wfp_status(); // reset all the status bits
484 504
485 505 // (3) reset spectral matrices registers
486 506 set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices
487 507 reset_sm_status();
488 508
489 509 // reset lfr VHDL module
490 510 reset_lfr();
491 511
492 512 reset_extractSWF(); // reset the extractSWF flag to false
493 513
494 514 // (4) clear interruptions
495 515 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER ); // clear waveform picker interrupt
496 516 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt
497 517
498 518 // <Spectral Matrices simulator>
499 519 LEON_Mask_interrupt( IRQ_SM_SIMULATOR ); // mask spectral matrix interrupt simulator
500 520 timer_stop( (gptimer_regs_t*) REGS_ADDR_GPTIMER, TIMER_SM_SIMULATOR );
501 521 LEON_Clear_interrupt( IRQ_SM_SIMULATOR ); // clear spectral matrix interrupt simulator
502 522 // </Spectral Matrices simulator>
503 523
504 524 // suspend several tasks
505 525 if (lfrCurrentMode != LFR_MODE_STANDBY) {
506 526 status = suspend_science_tasks();
507 527 }
508 528
509 529 if (status != RTEMS_SUCCESSFUL)
510 530 {
511 531 PRINTF1("in stop_current_mode *** in suspend_science_tasks *** ERR code: %d\n", status)
512 532 }
513 533
514 534 return status;
515 535 }
516 536
517 int enter_mode( unsigned char mode, unsigned int transitionCoarseTime )
518 {
519 /** This function is launched after a mode transition validation.
520 *
521 * @param mode is the mode in which LFR will be put.
522 *
523 * @return RTEMS directive status codes:
524 * - RTEMS_SUCCESSFUL - the mode has been entered successfully
525 * - RTEMS_NOT_SATISFIED - the mode has not been entered successfully
526 *
527 */
528
529 rtems_status_code status;
530
531 //**********************
532 // STOP THE CURRENT MODE
533 status = stop_current_mode();
534 if (status != RTEMS_SUCCESSFUL)
537 int enter_mode_standby()
535 538 {
536 PRINTF1("ERR *** in enter_mode *** stop_current_mode with mode = %d\n", mode)
537 }
539 int status;
538 540
539 //*************************
540 // ENTER THE REQUESTED MODE
541 if (status == RTEMS_SUCCESSFUL) // if the current mode has been successfully stopped
542 {
543 if ( (mode == LFR_MODE_NORMAL) || (mode == LFR_MODE_BURST)
544 || (mode == LFR_MODE_SBM1) || (mode == LFR_MODE_SBM2) )
545 {
546 #ifdef PRINT_TASK_STATISTICS
547 rtems_cpu_usage_reset();
548 #endif
549 status = restart_science_tasks( mode );
550 if (status == RTEMS_SUCCESSFUL)
551 {
552 launch_spectral_matrix( );
553 launch_waveform_picker( mode, transitionCoarseTime );
554 }
555 }
556 else if ( mode == LFR_MODE_STANDBY )
557 {
541 status = stop_current_mode(); // STOP THE CURRENT MODE
542
558 543 #ifdef PRINT_TASK_STATISTICS
559 544 rtems_cpu_usage_report();
560 545 #endif
561 546
562 547 #ifdef PRINT_STACK_REPORT
563 548 PRINTF("stack report selected\n")
564 549 rtems_stack_checker_report_usage();
565 550 #endif
551
552 return status;
566 553 }
567 else
554
555 int enter_mode_normal( unsigned int transitionCoarseTime )
556 {
557 int status;
558
559 #ifdef PRINT_TASK_STATISTICS
560 rtems_cpu_usage_reset();
561 #endif
562
563 status = RTEMS_UNSATISFIED;
564
565 switch( lfrCurrentMode )
566 {
567 case LFR_MODE_STANDBY:
568 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart science tasks
569 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
568 570 {
571 launch_spectral_matrix( );
572 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
573 }
574 break;
575 case LFR_MODE_BURST:
576 status = stop_current_mode(); // stop the current mode
577 status = restart_science_tasks( LFR_MODE_NORMAL ); // restart the science tasks
578 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
579 {
580 launch_spectral_matrix( );
581 launch_waveform_picker( LFR_MODE_NORMAL, transitionCoarseTime );
582 }
583 break;
584 case LFR_MODE_SBM1:
585 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
586 break;
587 case LFR_MODE_SBM2:
588 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
589 break;
590 default:
591 break;
592 }
593
594 if (status != RTEMS_SUCCESSFUL)
595 {
596 PRINTF1("ERR *** in enter_mode_normal *** status = %d\n", status)
569 597 status = RTEMS_UNSATISFIED;
570 598 }
599
600 return status;
601 }
602
603 int enter_mode_burst( unsigned int transitionCoarseTime )
604 {
605 int status;
606
607 #ifdef PRINT_TASK_STATISTICS
608 rtems_cpu_usage_reset();
609 #endif
610
611 status = stop_current_mode(); // stop the current mode
612 status = restart_science_tasks( LFR_MODE_BURST ); // restart the science tasks
613 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
614 {
615 launch_spectral_matrix( );
616 launch_waveform_picker( LFR_MODE_BURST, transitionCoarseTime );
571 617 }
572 618
573 619 if (status != RTEMS_SUCCESSFUL)
574 620 {
575 PRINTF1("ERR *** in enter_mode *** status = %d\n", status)
621 PRINTF1("ERR *** in enter_mode_burst *** status = %d\n", status)
622 status = RTEMS_UNSATISFIED;
623 }
624
625 return status;
626 }
627
628 int enter_mode_sbm1( unsigned int transitionCoarseTime )
629 {
630 int status;
631
632 #ifdef PRINT_TASK_STATISTICS
633 rtems_cpu_usage_reset();
634 #endif
635
636 status = RTEMS_UNSATISFIED;
637
638 switch( lfrCurrentMode )
639 {
640 case LFR_MODE_STANDBY:
641 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart science tasks
642 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
643 {
644 launch_spectral_matrix( );
645 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
646 }
647 break;
648 case LFR_MODE_NORMAL: // lfrCurrentMode will be updated after the execution of close_action
649 status = LFR_SUCCESSFUL;
650 break;
651 case LFR_MODE_BURST:
652 status = stop_current_mode(); // stop the current mode
653 status = restart_science_tasks( LFR_MODE_SBM1 ); // restart the science tasks
654 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
655 {
656 launch_spectral_matrix( );
657 launch_waveform_picker( LFR_MODE_SBM1, transitionCoarseTime );
658 }
659 break;
660 case LFR_MODE_SBM2:
661 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
662 break;
663 default:
664 break;
665 }
666
667 if (status != RTEMS_SUCCESSFUL)
668 {
669 PRINTF1("ERR *** in enter_mode_sbm1 *** status = %d\n", status)
670 status = RTEMS_UNSATISFIED;
671 }
672
673 return status;
674 }
675
676 int enter_mode_sbm2( unsigned int transitionCoarseTime )
677 {
678 int status;
679
680 #ifdef PRINT_TASK_STATISTICS
681 rtems_cpu_usage_reset();
682 #endif
683
684 status = RTEMS_UNSATISFIED;
685
686 switch( lfrCurrentMode )
687 {
688 case LFR_MODE_STANDBY:
689 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart science tasks
690 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
691 {
692 launch_spectral_matrix( );
693 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
694 }
695 break;
696 case LFR_MODE_NORMAL:
697 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
698 break;
699 case LFR_MODE_BURST:
700 status = stop_current_mode(); // stop the current mode
701 status = restart_science_tasks( LFR_MODE_SBM2 ); // restart the science tasks
702 if (status == RTEMS_SUCCESSFUL) // relaunch spectral_matrix and waveform_picker modules
703 {
704 launch_spectral_matrix( );
705 launch_waveform_picker( LFR_MODE_SBM2, transitionCoarseTime );
706 }
707 break;
708 case LFR_MODE_SBM1:
709 status = LFR_SUCCESSFUL; // lfrCurrentMode will be updated after the execution of close_action
710 break;
711 default:
712 break;
713 }
714
715 if (status != RTEMS_SUCCESSFUL)
716 {
717 PRINTF1("ERR *** in enter_mode_sbm2 *** status = %d\n", status)
576 718 status = RTEMS_UNSATISFIED;
577 719 }
578 720
579 721 return status;
580 722 }
581 723
582 724 int restart_science_tasks(unsigned char lfrRequestedMode )
583 725 {
584 726 /** This function is used to restart all science tasks.
585 727 *
586 728 * @return RTEMS directive status codes:
587 729 * - RTEMS_SUCCESSFUL - task restarted successfully
588 730 * - RTEMS_INVALID_ID - task id invalid
589 731 * - RTEMS_INCORRECT_STATE - task never started
590 732 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot restart remote task
591 733 *
592 734 * Science tasks are AVF0, PRC0, WFRM, CWF3, CW2, CWF1
593 735 *
594 736 */
595 737
596 738 rtems_status_code status[10];
597 739 rtems_status_code ret;
598 740
599 741 ret = RTEMS_SUCCESSFUL;
600 742
601 743 status[0] = rtems_task_restart( Task_id[TASKID_AVF0], lfrRequestedMode );
602 744 if (status[0] != RTEMS_SUCCESSFUL)
603 745 {
604 746 PRINTF1("in restart_science_task *** AVF0 ERR %d\n", status[0])
605 747 }
606 748
607 749 status[1] = rtems_task_restart( Task_id[TASKID_PRC0], lfrRequestedMode );
608 750 if (status[1] != RTEMS_SUCCESSFUL)
609 751 {
610 752 PRINTF1("in restart_science_task *** PRC0 ERR %d\n", status[1])
611 753 }
612 754
613 755 status[2] = rtems_task_restart( Task_id[TASKID_WFRM],1 );
614 756 if (status[2] != RTEMS_SUCCESSFUL)
615 757 {
616 758 PRINTF1("in restart_science_task *** WFRM ERR %d\n", status[2])
617 759 }
618 760
619 761 status[3] = rtems_task_restart( Task_id[TASKID_CWF3],1 );
620 762 if (status[3] != RTEMS_SUCCESSFUL)
621 763 {
622 764 PRINTF1("in restart_science_task *** CWF3 ERR %d\n", status[3])
623 765 }
624 766
625 767 status[4] = rtems_task_restart( Task_id[TASKID_CWF2],1 );
626 768 if (status[4] != RTEMS_SUCCESSFUL)
627 769 {
628 770 PRINTF1("in restart_science_task *** CWF2 ERR %d\n", status[4])
629 771 }
630 772
631 773 status[5] = rtems_task_restart( Task_id[TASKID_CWF1],1 );
632 774 if (status[5] != RTEMS_SUCCESSFUL)
633 775 {
634 776 PRINTF1("in restart_science_task *** CWF1 ERR %d\n", status[5])
635 777 }
636 778
637 779 status[6] = rtems_task_restart( Task_id[TASKID_AVF1], lfrRequestedMode );
638 780 if (status[6] != RTEMS_SUCCESSFUL)
639 781 {
640 782 PRINTF1("in restart_science_task *** AVF1 ERR %d\n", status[6])
641 783 }
642 784
643 785 status[7] = rtems_task_restart( Task_id[TASKID_PRC1],lfrRequestedMode );
644 786 if (status[7] != RTEMS_SUCCESSFUL)
645 787 {
646 788 PRINTF1("in restart_science_task *** PRC1 ERR %d\n", status[7])
647 789 }
648 790
649 791 status[8] = rtems_task_restart( Task_id[TASKID_AVF2], 1 );
650 792 if (status[8] != RTEMS_SUCCESSFUL)
651 793 {
652 794 PRINTF1("in restart_science_task *** AVF2 ERR %d\n", status[8])
653 795 }
654 796
655 797 status[9] = rtems_task_restart( Task_id[TASKID_PRC2], 1 );
656 798 if (status[9] != RTEMS_SUCCESSFUL)
657 799 {
658 800 PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[9])
659 801 }
660 802
661 803 if ( (status[0] != RTEMS_SUCCESSFUL) || (status[1] != RTEMS_SUCCESSFUL) ||
662 804 (status[2] != RTEMS_SUCCESSFUL) || (status[3] != RTEMS_SUCCESSFUL) ||
663 805 (status[4] != RTEMS_SUCCESSFUL) || (status[5] != RTEMS_SUCCESSFUL) ||
664 806 (status[6] != RTEMS_SUCCESSFUL) || (status[7] != RTEMS_SUCCESSFUL) ||
665 807 (status[8] != RTEMS_SUCCESSFUL) || (status[9] != RTEMS_SUCCESSFUL) )
666 808 {
667 809 ret = RTEMS_UNSATISFIED;
668 810 }
669 811
670 812 return ret;
671 813 }
672 814
673 815 int suspend_science_tasks()
674 816 {
675 817 /** This function suspends the science tasks.
676 818 *
677 819 * @return RTEMS directive status codes:
678 820 * - RTEMS_SUCCESSFUL - task restarted successfully
679 821 * - RTEMS_INVALID_ID - task id invalid
680 822 * - RTEMS_ALREADY_SUSPENDED - task already suspended
681 823 *
682 824 */
683 825
684 826 rtems_status_code status;
685 827
686 828 PRINTF("in suspend_science_tasks\n")
687 829
688 830 status = rtems_task_suspend( Task_id[TASKID_AVF0] ); // suspend AVF0
689 831 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
690 832 {
691 833 PRINTF1("in suspend_science_task *** AVF0 ERR %d\n", status)
692 834 }
693 835 else
694 836 {
695 837 status = RTEMS_SUCCESSFUL;
696 838 }
697 839 if (status == RTEMS_SUCCESSFUL) // suspend PRC0
698 840 {
699 841 status = rtems_task_suspend( Task_id[TASKID_PRC0] );
700 842 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
701 843 {
702 844 PRINTF1("in suspend_science_task *** PRC0 ERR %d\n", status)
703 845 }
704 846 else
705 847 {
706 848 status = RTEMS_SUCCESSFUL;
707 849 }
708 850 }
709 851 if (status == RTEMS_SUCCESSFUL) // suspend AVF1
710 852 {
711 853 status = rtems_task_suspend( Task_id[TASKID_AVF1] );
712 854 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
713 855 {
714 856 PRINTF1("in suspend_science_task *** AVF1 ERR %d\n", status)
715 857 }
716 858 else
717 859 {
718 860 status = RTEMS_SUCCESSFUL;
719 861 }
720 862 }
721 863 if (status == RTEMS_SUCCESSFUL) // suspend PRC1
722 864 {
723 865 status = rtems_task_suspend( Task_id[TASKID_PRC1] );
724 866 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
725 867 {
726 868 PRINTF1("in suspend_science_task *** PRC1 ERR %d\n", status)
727 869 }
728 870 else
729 871 {
730 872 status = RTEMS_SUCCESSFUL;
731 873 }
732 874 }
733 875 if (status == RTEMS_SUCCESSFUL) // suspend AVF2
734 876 {
735 877 status = rtems_task_suspend( Task_id[TASKID_AVF2] );
736 878 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
737 879 {
738 880 PRINTF1("in suspend_science_task *** AVF2 ERR %d\n", status)
739 881 }
740 882 else
741 883 {
742 884 status = RTEMS_SUCCESSFUL;
743 885 }
744 886 }
745 887 if (status == RTEMS_SUCCESSFUL) // suspend PRC2
746 888 {
747 889 status = rtems_task_suspend( Task_id[TASKID_PRC2] );
748 890 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
749 891 {
750 892 PRINTF1("in suspend_science_task *** PRC2 ERR %d\n", status)
751 893 }
752 894 else
753 895 {
754 896 status = RTEMS_SUCCESSFUL;
755 897 }
756 898 }
757 899 if (status == RTEMS_SUCCESSFUL) // suspend WFRM
758 900 {
759 901 status = rtems_task_suspend( Task_id[TASKID_WFRM] );
760 902 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
761 903 {
762 904 PRINTF1("in suspend_science_task *** WFRM ERR %d\n", status)
763 905 }
764 906 else
765 907 {
766 908 status = RTEMS_SUCCESSFUL;
767 909 }
768 910 }
769 911 if (status == RTEMS_SUCCESSFUL) // suspend CWF3
770 912 {
771 913 status = rtems_task_suspend( Task_id[TASKID_CWF3] );
772 914 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
773 915 {
774 916 PRINTF1("in suspend_science_task *** CWF3 ERR %d\n", status)
775 917 }
776 918 else
777 919 {
778 920 status = RTEMS_SUCCESSFUL;
779 921 }
780 922 }
781 923 if (status == RTEMS_SUCCESSFUL) // suspend CWF2
782 924 {
783 925 status = rtems_task_suspend( Task_id[TASKID_CWF2] );
784 926 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
785 927 {
786 928 PRINTF1("in suspend_science_task *** CWF2 ERR %d\n", status)
787 929 }
788 930 else
789 931 {
790 932 status = RTEMS_SUCCESSFUL;
791 933 }
792 934 }
793 935 if (status == RTEMS_SUCCESSFUL) // suspend CWF1
794 936 {
795 937 status = rtems_task_suspend( Task_id[TASKID_CWF1] );
796 938 if ((status != RTEMS_SUCCESSFUL) && (status != RTEMS_ALREADY_SUSPENDED))
797 939 {
798 940 PRINTF1("in suspend_science_task *** CWF1 ERR %d\n", status)
799 941 }
800 942 else
801 943 {
802 944 status = RTEMS_SUCCESSFUL;
803 945 }
804 946 }
805 947
806 948 return status;
807 949 }
808 950
809 951 void launch_waveform_picker( unsigned char mode, unsigned int transitionCoarseTime )
810 952 {
811 953 WFP_reset_current_ring_nodes();
812 954
813 955 reset_waveform_picker_regs();
814 956
815 957 set_wfp_burst_enable_register( mode );
816 958
817 959 LEON_Clear_interrupt( IRQ_WAVEFORM_PICKER );
818 960 LEON_Unmask_interrupt( IRQ_WAVEFORM_PICKER );
819 961
820 962 if (transitionCoarseTime == 0)
821 963 {
822 964 waveform_picker_regs->start_date = time_management_regs->coarse_time;
823 965 }
824 966 else
825 967 {
826 968 waveform_picker_regs->start_date = transitionCoarseTime;
827 969 }
828 970
829 971 }
830 972
831 973 void launch_spectral_matrix( void )
832 974 {
833 975 SM_reset_current_ring_nodes();
834 976
835 977 reset_spectral_matrix_regs();
836 978
837 979 reset_nb_sm();
838 980
839 981 set_sm_irq_onNewMatrix( 1 );
840 982
841 983 LEON_Clear_interrupt( IRQ_SPECTRAL_MATRIX );
842 984 LEON_Unmask_interrupt( IRQ_SPECTRAL_MATRIX );
843 985
844 986 }
845 987
846 988 void launch_spectral_matrix_simu( void )
847 989 {
848 990 SM_reset_current_ring_nodes();
849 991 reset_spectral_matrix_regs();
850 992 reset_nb_sm();
851 993
852 994 // Spectral Matrices simulator
853 995 timer_start( (gptimer_regs_t*) REGS_ADDR_GPTIMER, TIMER_SM_SIMULATOR );
854 996 LEON_Clear_interrupt( IRQ_SM_SIMULATOR );
855 997 LEON_Unmask_interrupt( IRQ_SM_SIMULATOR );
856 998 }
857 999
858 1000 void set_sm_irq_onNewMatrix( unsigned char value )
859 1001 {
860 1002 if (value == 1)
861 1003 {
862 1004 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x01;
863 1005 }
864 1006 else
865 1007 {
866 1008 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffe; // 1110
867 1009 }
868 1010 }
869 1011
870 1012 void set_sm_irq_onError( unsigned char value )
871 1013 {
872 1014 if (value == 1)
873 1015 {
874 1016 spectral_matrix_regs->config = spectral_matrix_regs->config | 0x02;
875 1017 }
876 1018 else
877 1019 {
878 1020 spectral_matrix_regs->config = spectral_matrix_regs->config & 0xfffffffd; // 1101
879 1021 }
880 1022 }
881 1023
882 1024 //*****************************
883 1025 // CONFIGURE CALIBRATION SIGNAL
884 1026 void setCalibrationPrescaler( unsigned int prescaler )
885 1027 {
886 1028 // prescaling of the master clock (25 MHz)
887 1029 // master clock is divided by 2^prescaler
888 1030 time_management_regs->calPrescaler = prescaler;
889 1031 }
890 1032
891 1033 void setCalibrationDivisor( unsigned int divisionFactor )
892 1034 {
893 1035 // division of the prescaled clock by the division factor
894 1036 time_management_regs->calDivisor = divisionFactor;
895 1037 }
896 1038
897 1039 void setCalibrationData( void ){
898 1040 unsigned int k;
899 1041 unsigned short data;
900 1042 float val;
901 1043 float f0;
902 1044 float f1;
903 1045 float fs;
904 1046 float Ts;
905 1047 float scaleFactor;
906 1048
907 1049 f0 = 625;
908 1050 f1 = 10000;
909 1051 fs = 160256.410;
910 1052 Ts = 1. / fs;
911 1053 scaleFactor = 0.250 / 0.000654; // 191, 500 mVpp, 2 sinus waves => 500 mVpp each, amplitude = 250 mV
912 1054
913 1055 time_management_regs->calDataPtr = 0x00;
914 1056
915 1057 // build the signal for the SCM calibration
916 1058 for (k=0; k<256; k++)
917 1059 {
918 1060 val = sin( 2 * pi * f0 * k * Ts )
919 1061 + sin( 2 * pi * f1 * k * Ts );
920 1062 data = (unsigned short) ((val * scaleFactor) + 2048);
921 1063 time_management_regs->calData = data & 0xfff;
922 1064 }
923 1065 }
924 1066
925 1067 void setCalibrationDataInterleaved( void ){
926 1068 unsigned int k;
927 1069 float val;
928 1070 float f0;
929 1071 float f1;
930 1072 float fs;
931 1073 float Ts;
932 1074 unsigned short data[384];
933 1075 unsigned char *dataPtr;
934 1076
935 1077 f0 = 625;
936 1078 f1 = 10000;
937 1079 fs = 240384.615;
938 1080 Ts = 1. / fs;
939 1081
940 1082 time_management_regs->calDataPtr = 0x00;
941 1083
942 1084 // build the signal for the SCM calibration
943 1085 for (k=0; k<384; k++)
944 1086 {
945 1087 val = sin( 2 * pi * f0 * k * Ts )
946 1088 + sin( 2 * pi * f1 * k * Ts );
947 1089 data[k] = (unsigned short) (val * 512 + 2048);
948 1090 }
949 1091
950 1092 // write the signal in interleaved mode
951 1093 for (k=0; k<128; k++)
952 1094 {
953 1095 dataPtr = (unsigned char*) &data[k*3 + 2];
954 1096 time_management_regs->calData = (data[k*3] & 0xfff)
955 1097 + ( (dataPtr[0] & 0x3f) << 12);
956 1098 time_management_regs->calData = (data[k*3 + 1] & 0xfff)
957 1099 + ( (dataPtr[1] & 0x3f) << 12);
958 1100 }
959 1101 }
960 1102
961 1103 void setCalibrationReload( bool state)
962 1104 {
963 1105 if (state == true)
964 1106 {
965 1107 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000010; // [0001 0000]
966 1108 }
967 1109 else
968 1110 {
969 1111 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffef; // [1110 1111]
970 1112 }
971 1113 }
972 1114
973 1115 void setCalibrationEnable( bool state )
974 1116 {
975 1117 // this bit drives the multiplexer
976 1118 if (state == true)
977 1119 {
978 1120 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000040; // [0100 0000]
979 1121 }
980 1122 else
981 1123 {
982 1124 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffbf; // [1011 1111]
983 1125 }
984 1126 }
985 1127
986 1128 void setCalibrationInterleaved( bool state )
987 1129 {
988 1130 // this bit drives the multiplexer
989 1131 if (state == true)
990 1132 {
991 1133 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000020; // [0010 0000]
992 1134 }
993 1135 else
994 1136 {
995 1137 time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffdf; // [1101 1111]
996 1138 }
997 1139 }
998 1140
999 1141 void setCalibration( bool state )
1000 1142 {
1001 1143 if (state == true)
1002 1144 {
1003 1145 setCalibrationEnable( true );
1004 1146 setCalibrationReload( false );
1005 1147 set_hk_lfr_calib_enable( true );
1006 1148 }
1007 1149 else
1008 1150 {
1009 1151 setCalibrationEnable( false );
1010 1152 setCalibrationReload( true );
1011 1153 set_hk_lfr_calib_enable( false );
1012 1154 }
1013 1155 }
1014 1156
1015 1157 void configureCalibration( bool interleaved )
1016 1158 {
1017 1159 setCalibration( false );
1018 1160 if ( interleaved == true )
1019 1161 {
1020 1162 setCalibrationInterleaved( true );
1021 1163 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1022 1164 setCalibrationDivisor( 26 ); // => 240 384
1023 1165 setCalibrationDataInterleaved();
1024 1166 }
1025 1167 else
1026 1168 {
1027 1169 setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000
1028 1170 setCalibrationDivisor( 38 ); // => 160 256 (39 - 1)
1029 1171 setCalibrationData();
1030 1172 }
1031 1173 }
1032 1174
1033 1175 //****************
1034 1176 // CLOSING ACTIONS
1035 1177 void update_last_TC_exe( ccsdsTelecommandPacket_t *TC, unsigned char * time )
1036 1178 {
1037 1179 /** This function is used to update the HK packets statistics after a successful TC execution.
1038 1180 *
1039 1181 * @param TC points to the TC being processed
1040 1182 * @param time is the time used to date the TC execution
1041 1183 *
1042 1184 */
1043 1185
1044 1186 unsigned int val;
1045 1187
1046 1188 housekeeping_packet.hk_lfr_last_exe_tc_id[0] = TC->packetID[0];
1047 1189 housekeeping_packet.hk_lfr_last_exe_tc_id[1] = TC->packetID[1];
1048 1190 housekeeping_packet.hk_lfr_last_exe_tc_type[0] = 0x00;
1049 1191 housekeeping_packet.hk_lfr_last_exe_tc_type[1] = TC->serviceType;
1050 1192 housekeeping_packet.hk_lfr_last_exe_tc_subtype[0] = 0x00;
1051 1193 housekeeping_packet.hk_lfr_last_exe_tc_subtype[1] = TC->serviceSubType;
1052 1194 housekeeping_packet.hk_lfr_last_exe_tc_time[0] = time[0];
1053 1195 housekeeping_packet.hk_lfr_last_exe_tc_time[1] = time[1];
1054 1196 housekeeping_packet.hk_lfr_last_exe_tc_time[2] = time[2];
1055 1197 housekeeping_packet.hk_lfr_last_exe_tc_time[3] = time[3];
1056 1198 housekeeping_packet.hk_lfr_last_exe_tc_time[4] = time[4];
1057 1199 housekeeping_packet.hk_lfr_last_exe_tc_time[5] = time[5];
1058 1200
1059 1201 val = housekeeping_packet.hk_lfr_exe_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_exe_tc_cnt[1];
1060 1202 val++;
1061 1203 housekeeping_packet.hk_lfr_exe_tc_cnt[0] = (unsigned char) (val >> 8);
1062 1204 housekeeping_packet.hk_lfr_exe_tc_cnt[1] = (unsigned char) (val);
1063 1205 }
1064 1206
1065 1207 void update_last_TC_rej(ccsdsTelecommandPacket_t *TC, unsigned char * time )
1066 1208 {
1067 1209 /** This function is used to update the HK packets statistics after a TC rejection.
1068 1210 *
1069 1211 * @param TC points to the TC being processed
1070 1212 * @param time is the time used to date the TC rejection
1071 1213 *
1072 1214 */
1073 1215
1074 1216 unsigned int val;
1075 1217
1076 1218 housekeeping_packet.hk_lfr_last_rej_tc_id[0] = TC->packetID[0];
1077 1219 housekeeping_packet.hk_lfr_last_rej_tc_id[1] = TC->packetID[1];
1078 1220 housekeeping_packet.hk_lfr_last_rej_tc_type[0] = 0x00;
1079 1221 housekeeping_packet.hk_lfr_last_rej_tc_type[1] = TC->serviceType;
1080 1222 housekeeping_packet.hk_lfr_last_rej_tc_subtype[0] = 0x00;
1081 1223 housekeeping_packet.hk_lfr_last_rej_tc_subtype[1] = TC->serviceSubType;
1082 1224 housekeeping_packet.hk_lfr_last_rej_tc_time[0] = time[0];
1083 1225 housekeeping_packet.hk_lfr_last_rej_tc_time[1] = time[1];
1084 1226 housekeeping_packet.hk_lfr_last_rej_tc_time[2] = time[2];
1085 1227 housekeeping_packet.hk_lfr_last_rej_tc_time[3] = time[3];
1086 1228 housekeeping_packet.hk_lfr_last_rej_tc_time[4] = time[4];
1087 1229 housekeeping_packet.hk_lfr_last_rej_tc_time[5] = time[5];
1088 1230
1089 1231 val = housekeeping_packet.hk_lfr_rej_tc_cnt[0] * 256 + housekeeping_packet.hk_lfr_rej_tc_cnt[1];
1090 1232 val++;
1091 1233 housekeeping_packet.hk_lfr_rej_tc_cnt[0] = (unsigned char) (val >> 8);
1092 1234 housekeeping_packet.hk_lfr_rej_tc_cnt[1] = (unsigned char) (val);
1093 1235 }
1094 1236
1095 1237 void close_action(ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id )
1096 1238 {
1097 1239 /** This function is the last step of the TC execution workflow.
1098 1240 *
1099 1241 * @param TC points to the TC being processed
1100 1242 * @param result is the result of the TC execution (LFR_SUCCESSFUL / LFR_DEFAULT)
1101 1243 * @param queue_id is the id of the RTEMS message queue used to send TM packets
1102 1244 * @param time is the time used to date the TC execution
1103 1245 *
1104 1246 */
1105 1247
1106 1248 unsigned char requestedMode;
1107 1249
1108 1250 if (result == LFR_SUCCESSFUL)
1109 1251 {
1110 1252 if ( !( (TC->serviceType==TC_TYPE_TIME) & (TC->serviceSubType==TC_SUBTYPE_UPDT_TIME) )
1111 1253 &
1112 1254 !( (TC->serviceType==TC_TYPE_GEN) & (TC->serviceSubType==TC_SUBTYPE_UPDT_INFO))
1113 1255 )
1114 1256 {
1115 1257 send_tm_lfr_tc_exe_success( TC, queue_id );
1116 1258 }
1117 1259 if ( (TC->serviceType == TC_TYPE_GEN) & (TC->serviceSubType == TC_SUBTYPE_ENTER) )
1118 1260 {
1119 1261 //**********************************
1120 1262 // UPDATE THE LFRMODE LOCAL VARIABLE
1121 1263 requestedMode = TC->dataAndCRC[1];
1122 1264 housekeeping_packet.lfr_status_word[0] = (unsigned char) ((requestedMode << 4) + 0x0d);
1123 1265 updateLFRCurrentMode();
1124 1266 }
1125 1267 }
1126 1268 else if (result == LFR_EXE_ERROR)
1127 1269 {
1128 1270 send_tm_lfr_tc_exe_error( TC, queue_id );
1129 1271 }
1130 1272 }
1131 1273
1132 1274 //***************************
1133 1275 // Interrupt Service Routines
1134 1276 rtems_isr commutation_isr1( rtems_vector_number vector )
1135 1277 {
1136 1278 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1137 1279 PRINTF("In commutation_isr1 *** Error sending event to DUMB\n")
1138 1280 }
1139 1281 }
1140 1282
1141 1283 rtems_isr commutation_isr2( rtems_vector_number vector )
1142 1284 {
1143 1285 if (rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
1144 1286 PRINTF("In commutation_isr2 *** Error sending event to DUMB\n")
1145 1287 }
1146 1288 }
1147 1289
1148 1290 //****************
1149 1291 // OTHER FUNCTIONS
1150 1292 void updateLFRCurrentMode()
1151 1293 {
1152 1294 /** This function updates the value of the global variable lfrCurrentMode.
1153 1295 *
1154 1296 * lfrCurrentMode is a parameter used by several functions to know in which mode LFR is running.
1155 1297 *
1156 1298 */
1157 1299 // update the local value of lfrCurrentMode with the value contained in the housekeeping_packet structure
1158 1300 lfrCurrentMode = (housekeeping_packet.lfr_status_word[0] & 0xf0) >> 4;
1159 1301 }
1160 1302
1161 1303 void set_lfr_soft_reset( unsigned char value )
1162 1304 {
1163 1305 if (value == 1)
1164 1306 {
1165 1307 time_management_regs->ctrl = time_management_regs->ctrl | 0x00000004; // [0100]
1166 1308 }
1167 1309 else
1168 1310 {
1169 1311 time_management_regs->ctrl = time_management_regs->ctrl & 0xfffffffb; // [1011]
1170 1312 }
1171 1313 }
1172 1314
1173 1315 void reset_lfr( void )
1174 1316 {
1175 1317 set_lfr_soft_reset( 1 );
1176 1318
1177 1319 set_lfr_soft_reset( 0 );
1178 1320
1179 1321 set_hk_lfr_sc_potential_flag( true );
1180 1322 }
@@ -1,1373 +1,1372
1 1 /** Functions and tasks related to waveform packet generation.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * A group of functions to handle waveforms, in snapshot or continuous format.\n
7 7 *
8 8 */
9 9
10 10 #include "wf_handler.h"
11 11
12 12 //***************
13 13 // waveform rings
14 14 // F0
15 15 ring_node waveform_ring_f0[NB_RING_NODES_F0];
16 16 ring_node *current_ring_node_f0;
17 17 ring_node *ring_node_to_send_swf_f0;
18 18 // F1
19 19 ring_node waveform_ring_f1[NB_RING_NODES_F1];
20 20 ring_node *current_ring_node_f1;
21 21 ring_node *ring_node_to_send_swf_f1;
22 22 ring_node *ring_node_to_send_cwf_f1;
23 23 // F2
24 24 ring_node waveform_ring_f2[NB_RING_NODES_F2];
25 25 ring_node *current_ring_node_f2;
26 26 ring_node *ring_node_to_send_swf_f2;
27 27 ring_node *ring_node_to_send_cwf_f2;
28 28 // F3
29 29 ring_node waveform_ring_f3[NB_RING_NODES_F3];
30 30 ring_node *current_ring_node_f3;
31 31 ring_node *ring_node_to_send_cwf_f3;
32 32 char wf_cont_f3_light[ (NB_SAMPLES_PER_SNAPSHOT) * NB_BYTES_CWF3_LIGHT_BLK ];
33 33
34 34 bool extractSWF = false;
35 35 bool swf_f0_ready = false;
36 36 bool swf_f1_ready = false;
37 37 bool swf_f2_ready = false;
38 38
39 39 int wf_snap_extracted[ (NB_SAMPLES_PER_SNAPSHOT * NB_WORDS_SWF_BLK) ];
40 40 ring_node ring_node_wf_snap_extracted;
41 41
42 42 //*********************
43 43 // Interrupt SubRoutine
44 44
45 45 ring_node * getRingNodeToSendCWF( unsigned char frequencyChannel)
46 46 {
47 47 ring_node *node;
48 48
49 49 node = NULL;
50 50 switch ( frequencyChannel ) {
51 51 case 1:
52 52 node = ring_node_to_send_cwf_f1;
53 53 break;
54 54 case 2:
55 55 node = ring_node_to_send_cwf_f2;
56 56 break;
57 57 case 3:
58 58 node = ring_node_to_send_cwf_f3;
59 59 break;
60 60 default:
61 61 break;
62 62 }
63 63
64 64 return node;
65 65 }
66 66
67 67 ring_node * getRingNodeToSendSWF( unsigned char frequencyChannel)
68 68 {
69 69 ring_node *node;
70 70
71 71 node = NULL;
72 72 switch ( frequencyChannel ) {
73 73 case 0:
74 74 node = ring_node_to_send_swf_f0;
75 75 break;
76 76 case 1:
77 77 node = ring_node_to_send_swf_f1;
78 78 break;
79 79 case 2:
80 80 node = ring_node_to_send_swf_f2;
81 81 break;
82 82 default:
83 83 break;
84 84 }
85 85
86 86 return node;
87 87 }
88 88
89 89 void reset_extractSWF( void )
90 90 {
91 91 extractSWF = false;
92 92 swf_f0_ready = false;
93 93 swf_f1_ready = false;
94 94 swf_f2_ready = false;
95 95 }
96 96
97 97 inline void waveforms_isr_f3( void )
98 98 {
99 99 rtems_status_code spare_status;
100 100
101 101 if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_BURST) // in BURST the data are used to place v, e1 and e2 in the HK packet
102 102 || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) )
103 103 { // in modes other than STANDBY and BURST, send the CWF_F3 data
104 104 //***
105 105 // F3
106 106 if ( (waveform_picker_regs->status & 0xc0) != 0x00 ) { // [1100 0000] check the f3 full bits
107 107 ring_node_to_send_cwf_f3 = current_ring_node_f3->previous;
108 108 current_ring_node_f3 = current_ring_node_f3->next;
109 109 if ((waveform_picker_regs->status & 0x40) == 0x40){ // [0100 0000] f3 buffer 0 is full
110 110 ring_node_to_send_cwf_f3->coarseTime = waveform_picker_regs->f3_0_coarse_time;
111 111 ring_node_to_send_cwf_f3->fineTime = waveform_picker_regs->f3_0_fine_time;
112 112 waveform_picker_regs->addr_data_f3_0 = current_ring_node_f3->buffer_address;
113 113 waveform_picker_regs->status = waveform_picker_regs->status & 0x00008840; // [1000 1000 0100 0000]
114 114 }
115 115 else if ((waveform_picker_regs->status & 0x80) == 0x80){ // [1000 0000] f3 buffer 1 is full
116 116 ring_node_to_send_cwf_f3->coarseTime = waveform_picker_regs->f3_1_coarse_time;
117 117 ring_node_to_send_cwf_f3->fineTime = waveform_picker_regs->f3_1_fine_time;
118 118 waveform_picker_regs->addr_data_f3_1 = current_ring_node_f3->buffer_address;
119 119 waveform_picker_regs->status = waveform_picker_regs->status & 0x00008880; // [1000 1000 1000 0000]
120 120 }
121 121 if (rtems_event_send( Task_id[TASKID_CWF3], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) {
122 122 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
123 123 }
124 124 }
125 125 }
126 126 }
127 127
128 128 inline void waveforms_isr_normal( void )
129 129 {
130 130 rtems_status_code status;
131 131
132 132 if ( ( (waveform_picker_regs->status & 0x30) != 0x00 ) // [0011 0000] check the f2 full bits
133 133 && ( (waveform_picker_regs->status & 0x0c) != 0x00 ) // [0000 1100] check the f1 full bits
134 134 && ( (waveform_picker_regs->status & 0x03) != 0x00 )) // [0000 0011] check the f0 full bits
135 135 {
136 136 //***
137 137 // F0
138 138 ring_node_to_send_swf_f0 = current_ring_node_f0->previous;
139 139 current_ring_node_f0 = current_ring_node_f0->next;
140 140 if ( (waveform_picker_regs->status & 0x01) == 0x01)
141 141 {
142 142
143 143 ring_node_to_send_swf_f0->coarseTime = waveform_picker_regs->f0_0_coarse_time;
144 144 ring_node_to_send_swf_f0->fineTime = waveform_picker_regs->f0_0_fine_time;
145 145 waveform_picker_regs->addr_data_f0_0 = current_ring_node_f0->buffer_address;
146 146 waveform_picker_regs->status = waveform_picker_regs->status & 0x00001101; // [0001 0001 0000 0001]
147 147 }
148 148 else if ( (waveform_picker_regs->status & 0x02) == 0x02)
149 149 {
150 150 ring_node_to_send_swf_f0->coarseTime = waveform_picker_regs->f0_1_coarse_time;
151 151 ring_node_to_send_swf_f0->fineTime = waveform_picker_regs->f0_1_fine_time;
152 152 waveform_picker_regs->addr_data_f0_1 = current_ring_node_f0->buffer_address;
153 153 waveform_picker_regs->status = waveform_picker_regs->status & 0x00001102; // [0001 0001 0000 0010]
154 154 }
155 155
156 156 //***
157 157 // F1
158 158 ring_node_to_send_swf_f1 = current_ring_node_f1->previous;
159 159 current_ring_node_f1 = current_ring_node_f1->next;
160 160 if ( (waveform_picker_regs->status & 0x04) == 0x04)
161 161 {
162 162 ring_node_to_send_swf_f1->coarseTime = waveform_picker_regs->f1_0_coarse_time;
163 163 ring_node_to_send_swf_f1->fineTime = waveform_picker_regs->f1_0_fine_time;
164 164 waveform_picker_regs->addr_data_f1_0 = current_ring_node_f1->buffer_address;
165 165 waveform_picker_regs->status = waveform_picker_regs->status & 0x00002204; // [0010 0010 0000 0100] f1 bits = 0
166 166 }
167 167 else if ( (waveform_picker_regs->status & 0x08) == 0x08)
168 168 {
169 169 ring_node_to_send_swf_f1->coarseTime = waveform_picker_regs->f1_1_coarse_time;
170 170 ring_node_to_send_swf_f1->fineTime = waveform_picker_regs->f1_1_fine_time;
171 171 waveform_picker_regs->addr_data_f1_1 = current_ring_node_f1->buffer_address;
172 172 waveform_picker_regs->status = waveform_picker_regs->status & 0x00002208; // [0010 0010 0000 1000] f1 bits = 0
173 173 }
174 174
175 175 //***
176 176 // F2
177 177 ring_node_to_send_swf_f2 = current_ring_node_f2->previous;
178 178 current_ring_node_f2 = current_ring_node_f2->next;
179 179 if ( (waveform_picker_regs->status & 0x10) == 0x10)
180 180 {
181 181 ring_node_to_send_swf_f2->coarseTime = waveform_picker_regs->f2_0_coarse_time;
182 182 ring_node_to_send_swf_f2->fineTime = waveform_picker_regs->f2_0_fine_time;
183 183 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->buffer_address;
184 184 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004410; // [0100 0100 0001 0000]
185 185 }
186 186 else if ( (waveform_picker_regs->status & 0x20) == 0x20)
187 187 {
188 188 ring_node_to_send_swf_f2->coarseTime = waveform_picker_regs->f2_1_coarse_time;
189 189 ring_node_to_send_swf_f2->fineTime = waveform_picker_regs->f2_1_fine_time;
190 190 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address;
191 191 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004420; // [0100 0100 0010 0000]
192 192 }
193 193 //
194 194 status = rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_NORMAL );
195 195 if ( status != RTEMS_SUCCESSFUL)
196 196 {
197 197 status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
198 198 }
199 199 }
200 200 }
201 201
202 202 inline void waveforms_isr_burst( void )
203 203 {
204 204 unsigned char status;
205 205 rtems_status_code spare_status;
206 206
207 207 status = (waveform_picker_regs->status & 0x30) >> 4; // [0011 0000] get the status bits for f2
208 208
209 209
210 210 switch(status)
211 211 {
212 212 case 1:
213 213 ring_node_to_send_cwf_f2 = current_ring_node_f2->previous;
214 214 ring_node_to_send_cwf_f2->sid = SID_BURST_CWF_F2;
215 215 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_0_coarse_time;
216 216 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_0_fine_time;
217 217 current_ring_node_f2 = current_ring_node_f2->next;
218 218 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->buffer_address;
219 219 if (rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_BURST ) != RTEMS_SUCCESSFUL) {
220 220 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
221 221 }
222 222 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004410; // [0100 0100 0001 0000]
223 223 break;
224 224 case 2:
225 225 ring_node_to_send_cwf_f2 = current_ring_node_f2->previous;
226 226 ring_node_to_send_cwf_f2->sid = SID_BURST_CWF_F2;
227 227 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_1_coarse_time;
228 228 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_1_fine_time;
229 229 current_ring_node_f2 = current_ring_node_f2->next;
230 230 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address;
231 231 if (rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_BURST ) != RTEMS_SUCCESSFUL) {
232 232 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_0 );
233 233 }
234 234 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004420; // [0100 0100 0010 0000]
235 235 break;
236 236 default:
237 237 break;
238 238 }
239 239 }
240 240
241 241 inline void waveforms_isr_sbm1( void )
242 242 {
243 243 rtems_status_code status;
244 244
245 245 //***
246 246 // F1
247 247 if ( (waveform_picker_regs->status & 0x0c) != 0x00 ) { // [0000 1100] check the f1 full bits
248 248 // (1) change the receiving buffer for the waveform picker
249 249 ring_node_to_send_cwf_f1 = current_ring_node_f1->previous;
250 250 current_ring_node_f1 = current_ring_node_f1->next;
251 251 if ( (waveform_picker_regs->status & 0x04) == 0x04)
252 252 {
253 253 ring_node_to_send_cwf_f1->coarseTime = waveform_picker_regs->f1_0_coarse_time;
254 254 ring_node_to_send_cwf_f1->fineTime = waveform_picker_regs->f1_0_fine_time;
255 255 waveform_picker_regs->addr_data_f1_0 = current_ring_node_f1->buffer_address;
256 256 waveform_picker_regs->status = waveform_picker_regs->status & 0x00002204; // [0010 0010 0000 0100] f1 bits = 0
257 257 }
258 258 else if ( (waveform_picker_regs->status & 0x08) == 0x08)
259 259 {
260 260 ring_node_to_send_cwf_f1->coarseTime = waveform_picker_regs->f1_1_coarse_time;
261 261 ring_node_to_send_cwf_f1->fineTime = waveform_picker_regs->f1_1_fine_time;
262 262 waveform_picker_regs->addr_data_f1_1 = current_ring_node_f1->buffer_address;
263 263 waveform_picker_regs->status = waveform_picker_regs->status & 0x00002208; // [0010 0010 0000 1000] f1 bits = 0
264 264 }
265 265 // (2) send an event for the the CWF1 task for transmission (and snapshot extraction if needed)
266 266 status = rtems_event_send( Task_id[TASKID_CWF1], RTEMS_EVENT_MODE_SBM1 );
267 267 }
268 268
269 269 //***
270 270 // F0
271 271 if ( (waveform_picker_regs->status & 0x03) != 0x00 ) { // [0000 0011] check the f0 full bits
272 272 swf_f0_ready = true;
273 273 // change f0 buffer
274 274 ring_node_to_send_swf_f0 = current_ring_node_f0->previous;
275 275 current_ring_node_f0 = current_ring_node_f0->next;
276 276 if ( (waveform_picker_regs->status & 0x01) == 0x01)
277 277 {
278 278
279 279 ring_node_to_send_swf_f0->coarseTime = waveform_picker_regs->f0_0_coarse_time;
280 280 ring_node_to_send_swf_f0->fineTime = waveform_picker_regs->f0_0_fine_time;
281 281 waveform_picker_regs->addr_data_f0_0 = current_ring_node_f0->buffer_address;
282 282 waveform_picker_regs->status = waveform_picker_regs->status & 0x00001101; // [0001 0001 0000 0001]
283 283 }
284 284 else if ( (waveform_picker_regs->status & 0x02) == 0x02)
285 285 {
286 286 ring_node_to_send_swf_f0->coarseTime = waveform_picker_regs->f0_1_coarse_time;
287 287 ring_node_to_send_swf_f0->fineTime = waveform_picker_regs->f0_1_fine_time;
288 288 waveform_picker_regs->addr_data_f0_1 = current_ring_node_f0->buffer_address;
289 289 waveform_picker_regs->status = waveform_picker_regs->status & 0x00001102; // [0001 0001 0000 0010]
290 290 }
291 291 }
292 292
293 293 //***
294 294 // F2
295 295 if ( (waveform_picker_regs->status & 0x30) != 0x00 ) { // [0011 0000] check the f2 full bits
296 296 swf_f2_ready = true;
297 297 // change f2 buffer
298 298 ring_node_to_send_swf_f2 = current_ring_node_f2->previous;
299 299 current_ring_node_f2 = current_ring_node_f2->next;
300 300 if ( (waveform_picker_regs->status & 0x10) == 0x10)
301 301 {
302 302 ring_node_to_send_swf_f2->coarseTime = waveform_picker_regs->f2_0_coarse_time;
303 303 ring_node_to_send_swf_f2->fineTime = waveform_picker_regs->f2_0_fine_time;
304 304 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->buffer_address;
305 305 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004410; // [0100 0100 0001 0000]
306 306 }
307 307 else if ( (waveform_picker_regs->status & 0x20) == 0x20)
308 308 {
309 309 ring_node_to_send_swf_f2->coarseTime = waveform_picker_regs->f2_1_coarse_time;
310 310 ring_node_to_send_swf_f2->fineTime = waveform_picker_regs->f2_1_fine_time;
311 311 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address;
312 312 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004420; // [0100 0100 0010 0000]
313 313 }
314 314 }
315 315 }
316 316
317 317 inline void waveforms_isr_sbm2( void )
318 318 {
319 319 rtems_status_code status;
320 320
321 321 //***
322 322 // F2
323 323 if ( (waveform_picker_regs->status & 0x30) != 0x00 ) { // [0011 0000] check the f2 full bit
324 324 // (1) change the receiving buffer for the waveform picker
325 325 ring_node_to_send_cwf_f2 = current_ring_node_f2->previous;
326 326 ring_node_to_send_cwf_f2->sid = SID_SBM2_CWF_F2;
327 327 current_ring_node_f2 = current_ring_node_f2->next;
328 328 if ( (waveform_picker_regs->status & 0x10) == 0x10)
329 329 {
330 330 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_0_coarse_time;
331 331 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_0_fine_time;
332 332 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->buffer_address;
333 333 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004410; // [0100 0100 0001 0000]
334 334 }
335 335 else if ( (waveform_picker_regs->status & 0x20) == 0x20)
336 336 {
337 337 ring_node_to_send_cwf_f2->coarseTime = waveform_picker_regs->f2_1_coarse_time;
338 338 ring_node_to_send_cwf_f2->fineTime = waveform_picker_regs->f2_1_fine_time;
339 339 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address;
340 340 waveform_picker_regs->status = waveform_picker_regs->status & 0x00004420; // [0100 0100 0010 0000]
341 341 }
342 342 // (2) send an event for the waveforms transmission
343 343 status = rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_SBM2 );
344 344 }
345 345
346 346 //***
347 347 // F0
348 348 if ( (waveform_picker_regs->status & 0x03) != 0x00 ) { // [0000 0011] check the f0 full bit
349 349 swf_f0_ready = true;
350 350 // change f0 buffer
351 351 ring_node_to_send_swf_f0 = current_ring_node_f0->previous;
352 352 current_ring_node_f0 = current_ring_node_f0->next;
353 353 if ( (waveform_picker_regs->status & 0x01) == 0x01)
354 354 {
355 355
356 356 ring_node_to_send_swf_f0->coarseTime = waveform_picker_regs->f0_0_coarse_time;
357 357 ring_node_to_send_swf_f0->fineTime = waveform_picker_regs->f0_0_fine_time;
358 358 waveform_picker_regs->addr_data_f0_0 = current_ring_node_f0->buffer_address;
359 359 waveform_picker_regs->status = waveform_picker_regs->status & 0x00001101; // [0001 0001 0000 0001]
360 360 }
361 361 else if ( (waveform_picker_regs->status & 0x02) == 0x02)
362 362 {
363 363 ring_node_to_send_swf_f0->coarseTime = waveform_picker_regs->f0_1_coarse_time;
364 364 ring_node_to_send_swf_f0->fineTime = waveform_picker_regs->f0_1_fine_time;
365 365 waveform_picker_regs->addr_data_f0_1 = current_ring_node_f0->buffer_address;
366 366 waveform_picker_regs->status = waveform_picker_regs->status & 0x00001102; // [0001 0001 0000 0010]
367 367 }
368 368 }
369 369
370 370 //***
371 371 // F1
372 372 if ( (waveform_picker_regs->status & 0x0c) != 0x00 ) { // [0000 1100] check the f1 full bit
373 373 swf_f1_ready = true;
374 374 ring_node_to_send_swf_f1 = current_ring_node_f1->previous;
375 375 current_ring_node_f1 = current_ring_node_f1->next;
376 376 if ( (waveform_picker_regs->status & 0x04) == 0x04)
377 377 {
378 378 ring_node_to_send_swf_f1->coarseTime = waveform_picker_regs->f1_0_coarse_time;
379 379 ring_node_to_send_swf_f1->fineTime = waveform_picker_regs->f1_0_fine_time;
380 380 waveform_picker_regs->addr_data_f1_0 = current_ring_node_f1->buffer_address;
381 381 waveform_picker_regs->status = waveform_picker_regs->status & 0x00002204; // [0010 0010 0000 0100] f1 bits = 0
382 382 }
383 383 else if ( (waveform_picker_regs->status & 0x08) == 0x08)
384 384 {
385 385 ring_node_to_send_swf_f1->coarseTime = waveform_picker_regs->f1_1_coarse_time;
386 386 ring_node_to_send_swf_f1->fineTime = waveform_picker_regs->f1_1_fine_time;
387 387 waveform_picker_regs->addr_data_f1_1 = current_ring_node_f1->buffer_address;
388 388 waveform_picker_regs->status = waveform_picker_regs->status & 0x00002208; // [0010 0010 0000 1000] f1 bits = 0
389 389 }
390 390 }
391 391 }
392 392
393 393 rtems_isr waveforms_isr( rtems_vector_number vector )
394 394 {
395 395 /** This is the interrupt sub routine called by the waveform picker core.
396 396 *
397 397 * This ISR launch different actions depending mainly on two pieces of information:
398 398 * 1. the values read in the registers of the waveform picker.
399 399 * 2. the current LFR mode.
400 400 *
401 401 */
402 402
403 403 // STATUS
404 404 // new error error buffer full
405 405 // 15 14 13 12 11 10 9 8
406 406 // f3 f2 f1 f0 f3 f2 f1 f0
407 407 //
408 408 // ready buffer
409 409 // 7 6 5 4 3 2 1 0
410 410 // f3_1 f3_0 f2_1 f2_0 f1_1 f1_0 f0_1 f0_0
411 411
412 412 rtems_status_code spare_status;
413 413
414 414 waveforms_isr_f3();
415 415
416 416 if ( (waveform_picker_regs->status & 0xff00) != 0x00) // [1111 1111 0000 0000] check the error bits
417 417 {
418 418 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_10 );
419 419 }
420 420
421 421 switch(lfrCurrentMode)
422 422 {
423 423 //********
424 424 // STANDBY
425 425 case(LFR_MODE_STANDBY):
426 426 break;
427 427
428 428 //******
429 429 // NORMAL
430 430 case(LFR_MODE_NORMAL):
431 431 waveforms_isr_normal();
432 432 break;
433 433
434 434 //******
435 435 // BURST
436 436 case(LFR_MODE_BURST):
437 437 waveforms_isr_burst();
438 438 break;
439 439
440 440 //*****
441 441 // SBM1
442 442 case(LFR_MODE_SBM1):
443 443 waveforms_isr_sbm1();
444 444 break;
445 445
446 446 //*****
447 447 // SBM2
448 448 case(LFR_MODE_SBM2):
449 449 waveforms_isr_sbm2();
450 450 break;
451 451
452 452 //********
453 453 // DEFAULT
454 454 default:
455 455 break;
456 456 }
457 457 }
458 458
459 459 //************
460 460 // RTEMS TASKS
461 461
462 462 rtems_task wfrm_task(rtems_task_argument argument) //used with the waveform picker VHDL IP
463 463 {
464 464 /** This RTEMS task is dedicated to the transmission of snapshots of the NORMAL mode.
465 465 *
466 466 * @param unused is the starting argument of the RTEMS task
467 467 *
468 468 * The following data packets are sent by this task:
469 469 * - TM_LFR_SCIENCE_NORMAL_SWF_F0
470 470 * - TM_LFR_SCIENCE_NORMAL_SWF_F1
471 471 * - TM_LFR_SCIENCE_NORMAL_SWF_F2
472 472 *
473 473 */
474 474
475 475 rtems_event_set event_out;
476 476 rtems_id queue_id;
477 477 rtems_status_code status;
478 478 bool resynchronisationEngaged;
479 479 ring_node *ring_node_wf_snap_extracted_ptr;
480 480
481 481 ring_node_wf_snap_extracted_ptr = (ring_node *) &ring_node_wf_snap_extracted;
482 482
483 483 resynchronisationEngaged = false;
484 484
485 485 status = get_message_queue_id_send( &queue_id );
486 486 if (status != RTEMS_SUCCESSFUL)
487 487 {
488 488 PRINTF1("in WFRM *** ERR get_message_queue_id_send %d\n", status)
489 489 }
490 490
491 491 BOOT_PRINTF("in WFRM ***\n")
492 492
493 493 while(1){
494 494 // wait for an RTEMS_EVENT
495 495 rtems_event_receive(RTEMS_EVENT_MODE_NORMAL | RTEMS_EVENT_MODE_SBM1
496 496 | RTEMS_EVENT_MODE_SBM2 | RTEMS_EVENT_MODE_SBM2_WFRM,
497 497 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
498 498 if(resynchronisationEngaged == false)
499 499 { // engage resynchronisation
500 500 snapshot_resynchronization( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
501 501 resynchronisationEngaged = true;
502 502 }
503 503 else
504 504 { // reset delta_snapshot to the nominal value
505 505 PRINTF("no resynchronisation, reset delta_snapshot to the nominal value\n")
506 506 set_wfp_delta_snapshot();
507 507 resynchronisationEngaged = false;
508 508 }
509 509 //
510 510
511 511 if (event_out == RTEMS_EVENT_MODE_NORMAL)
512 512 {
513 513 DEBUG_PRINTF("WFRM received RTEMS_EVENT_MODE_NORMAL\n")
514 514 ring_node_to_send_swf_f0->sid = SID_NORM_SWF_F0;
515 515 ring_node_to_send_swf_f1->sid = SID_NORM_SWF_F1;
516 516 ring_node_to_send_swf_f2->sid = SID_NORM_SWF_F2;
517 517 status = rtems_message_queue_send( queue_id, &ring_node_to_send_swf_f0, sizeof( ring_node* ) );
518 518 status = rtems_message_queue_send( queue_id, &ring_node_to_send_swf_f1, sizeof( ring_node* ) );
519 519 status = rtems_message_queue_send( queue_id, &ring_node_to_send_swf_f2, sizeof( ring_node* ) );
520 520 }
521 521 if (event_out == RTEMS_EVENT_MODE_SBM1)
522 522 {
523 523 DEBUG_PRINTF("WFRM received RTEMS_EVENT_MODE_SBM1\n")
524 524 ring_node_to_send_swf_f0->sid = SID_NORM_SWF_F0;
525 525 ring_node_wf_snap_extracted_ptr->sid = SID_NORM_SWF_F1;
526 526 ring_node_to_send_swf_f2->sid = SID_NORM_SWF_F2;
527 527 status = rtems_message_queue_send( queue_id, &ring_node_to_send_swf_f0, sizeof( ring_node* ) );
528 528 status = rtems_message_queue_send( queue_id, &ring_node_wf_snap_extracted_ptr, sizeof( ring_node* ) );
529 529 status = rtems_message_queue_send( queue_id, &ring_node_to_send_swf_f2, sizeof( ring_node* ) );
530 530 }
531 531 if (event_out == RTEMS_EVENT_MODE_SBM2)
532 532 {
533 533 DEBUG_PRINTF("WFRM received RTEMS_EVENT_MODE_SBM2\n")
534 534 ring_node_to_send_swf_f0->sid = SID_NORM_SWF_F0;
535 535 ring_node_to_send_swf_f1->sid = SID_NORM_SWF_F1;
536 536 ring_node_wf_snap_extracted_ptr->sid = SID_NORM_SWF_F2;
537 537 status = rtems_message_queue_send( queue_id, &ring_node_to_send_swf_f0, sizeof( ring_node* ) );
538 538 status = rtems_message_queue_send( queue_id, &ring_node_to_send_swf_f1, sizeof( ring_node* ) );
539 539 status = rtems_message_queue_send( queue_id, &ring_node_wf_snap_extracted_ptr, sizeof( ring_node* ) );
540 540 }
541 541 }
542 542 }
543 543
544 544 rtems_task cwf3_task(rtems_task_argument argument) //used with the waveform picker VHDL IP
545 545 {
546 546 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f3.
547 547 *
548 548 * @param unused is the starting argument of the RTEMS task
549 549 *
550 550 * The following data packet is sent by this task:
551 551 * - TM_LFR_SCIENCE_NORMAL_CWF_F3
552 552 *
553 553 */
554 554
555 555 rtems_event_set event_out;
556 556 rtems_id queue_id;
557 557 rtems_status_code status;
558 558 ring_node ring_node_cwf3_light;
559 559 ring_node *ring_node_to_send_cwf;
560 560
561 561 status = get_message_queue_id_send( &queue_id );
562 562 if (status != RTEMS_SUCCESSFUL)
563 563 {
564 564 PRINTF1("in CWF3 *** ERR get_message_queue_id_send %d\n", status)
565 565 }
566 566
567 567 ring_node_to_send_cwf_f3->sid = SID_NORM_CWF_LONG_F3;
568 568
569 569 // init the ring_node_cwf3_light structure
570 570 ring_node_cwf3_light.buffer_address = (int) wf_cont_f3_light;
571 571 ring_node_cwf3_light.coarseTime = 0x00;
572 572 ring_node_cwf3_light.fineTime = 0x00;
573 573 ring_node_cwf3_light.next = NULL;
574 574 ring_node_cwf3_light.previous = NULL;
575 575 ring_node_cwf3_light.sid = SID_NORM_CWF_F3;
576 576 ring_node_cwf3_light.status = 0x00;
577 577
578 578 BOOT_PRINTF("in CWF3 ***\n")
579 579
580 580 while(1){
581 581 // wait for an RTEMS_EVENT
582 582 rtems_event_receive( RTEMS_EVENT_0,
583 583 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
584 584 if ( (lfrCurrentMode == LFR_MODE_NORMAL)
585 585 || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode==LFR_MODE_SBM2) )
586 586 {
587 587 ring_node_to_send_cwf = getRingNodeToSendCWF( 3 );
588 588 if ( (parameter_dump_packet.sy_lfr_n_cwf_long_f3 & 0x01) == 0x01)
589 589 {
590 590 PRINTF("send CWF_LONG_F3\n")
591 591 ring_node_to_send_cwf_f3->sid = SID_NORM_CWF_LONG_F3;
592 592 status = rtems_message_queue_send( queue_id, &ring_node_to_send_cwf, sizeof( ring_node* ) );
593 593 }
594 594 else
595 595 {
596 596 PRINTF("send CWF_F3 (light)\n")
597 597 send_waveform_CWF3_light( ring_node_to_send_cwf, &ring_node_cwf3_light, queue_id );
598 598 }
599 599
600 600 }
601 601 else
602 602 {
603 603 PRINTF1("in CWF3 *** lfrCurrentMode is %d, no data will be sent\n", lfrCurrentMode)
604 604 }
605 605 }
606 606 }
607 607
608 608 rtems_task cwf2_task(rtems_task_argument argument) // ONLY USED IN BURST AND SBM2
609 609 {
610 610 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f2.
611 611 *
612 612 * @param unused is the starting argument of the RTEMS task
613 613 *
614 614 * The following data packet is sent by this function:
615 615 * - TM_LFR_SCIENCE_BURST_CWF_F2
616 616 * - TM_LFR_SCIENCE_SBM2_CWF_F2
617 617 *
618 618 */
619 619
620 620 rtems_event_set event_out;
621 621 rtems_id queue_id;
622 622 rtems_status_code status;
623 623 ring_node *ring_node_to_send;
624 624 unsigned long long int acquisitionTimeF0_asLong;
625 625
626 626 acquisitionTimeF0_asLong = 0x00;
627 627
628 628 status = get_message_queue_id_send( &queue_id );
629 629 if (status != RTEMS_SUCCESSFUL)
630 630 {
631 631 PRINTF1("in CWF2 *** ERR get_message_queue_id_send %d\n", status)
632 632 }
633 633
634 634 BOOT_PRINTF("in CWF2 ***\n")
635 635
636 636 while(1){
637 637 // wait for an RTEMS_EVENT
638 638 rtems_event_receive( RTEMS_EVENT_MODE_BURST | RTEMS_EVENT_MODE_SBM2,
639 639 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
640 640 ring_node_to_send = getRingNodeToSendCWF( 2 );
641 641 if (event_out == RTEMS_EVENT_MODE_BURST)
642 642 {
643 643 status = rtems_message_queue_send( queue_id, &ring_node_to_send, sizeof( ring_node* ) );
644 644 }
645 645 if (event_out == RTEMS_EVENT_MODE_SBM2)
646 646 {
647 647 status = rtems_message_queue_send( queue_id, &ring_node_to_send, sizeof( ring_node* ) );
648 648 // launch snapshot extraction if needed
649 649 if (extractSWF == true)
650 650 {
651 651 ring_node_to_send_swf_f2 = ring_node_to_send_cwf_f2;
652 652 // extract the snapshot
653 653 build_snapshot_from_ring( ring_node_to_send_swf_f2, 2, acquisitionTimeF0_asLong );
654 654 // send the snapshot when built
655 655 status = rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_SBM2 );
656 656 extractSWF = false;
657 657 }
658 658 if (swf_f0_ready && swf_f1_ready)
659 659 {
660 660 extractSWF = true;
661 661 // record the acquition time of the fΓ  snapshot to use to build the snapshot at f2
662 662 acquisitionTimeF0_asLong = get_acquisition_time( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
663 663 swf_f0_ready = false;
664 664 swf_f1_ready = false;
665 665 }
666 666 }
667 667 }
668 668 }
669 669
670 670 rtems_task cwf1_task(rtems_task_argument argument) // ONLY USED IN SBM1
671 671 {
672 672 /** This RTEMS task is dedicated to the transmission of continuous waveforms at f1.
673 673 *
674 674 * @param unused is the starting argument of the RTEMS task
675 675 *
676 676 * The following data packet is sent by this function:
677 677 * - TM_LFR_SCIENCE_SBM1_CWF_F1
678 678 *
679 679 */
680 680
681 681 rtems_event_set event_out;
682 682 rtems_id queue_id;
683 683 rtems_status_code status;
684 684
685 685 ring_node *ring_node_to_send_cwf;
686 686
687 687 status = get_message_queue_id_send( &queue_id );
688 688 if (status != RTEMS_SUCCESSFUL)
689 689 {
690 690 PRINTF1("in CWF1 *** ERR get_message_queue_id_send %d\n", status)
691 691 }
692 692
693 693 BOOT_PRINTF("in CWF1 ***\n")
694 694
695 695 while(1){
696 696 // wait for an RTEMS_EVENT
697 697 rtems_event_receive( RTEMS_EVENT_MODE_SBM1,
698 698 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
699 699 ring_node_to_send_cwf = getRingNodeToSendCWF( 1 );
700 700 ring_node_to_send_cwf_f1->sid = SID_SBM1_CWF_F1;
701 701 status = rtems_message_queue_send( queue_id, &ring_node_to_send_cwf, sizeof( ring_node* ) );
702 702 if (status != 0)
703 703 {
704 704 PRINTF("cwf sending failed\n")
705 705 }
706 706 // launch snapshot extraction if needed
707 707 if (extractSWF == true)
708 708 {
709 709 ring_node_to_send_swf_f1 = ring_node_to_send_cwf;
710 710 // launch the snapshot extraction
711 711 status = rtems_event_send( Task_id[TASKID_SWBD], RTEMS_EVENT_MODE_SBM1 );
712 712 extractSWF = false;
713 713 }
714 714 if (swf_f0_ready == true)
715 715 {
716 716 extractSWF = true;
717 717 swf_f0_ready = false; // this step shall be executed only one time
718 718 }
719 719 if ((swf_f1_ready == true) && (swf_f2_ready == true)) // swf_f1 is ready after the extraction
720 720 {
721 721 status = rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_SBM1 );
722 722 swf_f1_ready = false;
723 723 swf_f2_ready = false;
724 724 }
725 725 }
726 726 }
727 727
728 728 rtems_task swbd_task(rtems_task_argument argument)
729 729 {
730 730 /** This RTEMS task is dedicated to the building of snapshots from different continuous waveforms buffers.
731 731 *
732 732 * @param unused is the starting argument of the RTEMS task
733 733 *
734 734 */
735 735
736 736 rtems_event_set event_out;
737 737 unsigned long long int acquisitionTimeF0_asLong;
738 738
739 739 acquisitionTimeF0_asLong = 0x00;
740 740
741 741 BOOT_PRINTF("in SWBD ***\n")
742 742
743 743 while(1){
744 744 // wait for an RTEMS_EVENT
745 745 rtems_event_receive( RTEMS_EVENT_MODE_SBM1 | RTEMS_EVENT_MODE_SBM2,
746 746 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out);
747 747 if (event_out == RTEMS_EVENT_MODE_SBM1)
748 748 {
749 749 acquisitionTimeF0_asLong = get_acquisition_time( (unsigned char *) &ring_node_to_send_swf_f0->coarseTime );
750 750 build_snapshot_from_ring( ring_node_to_send_swf_f1, 1, acquisitionTimeF0_asLong );
751 751 swf_f1_ready = true; // the snapshot has been extracted and is ready to be sent
752 752 }
753 753 else
754 754 {
755 755 PRINTF1("in SWBD *** unexpected rtems event received %x\n", (int) event_out)
756 756 }
757 757 }
758 758 }
759 759
760 760 //******************
761 761 // general functions
762 762
763 763 void WFP_init_rings( void )
764 764 {
765 765 // F0 RING
766 766 init_ring( waveform_ring_f0, NB_RING_NODES_F0, wf_buffer_f0, WFRM_BUFFER );
767 767 // F1 RING
768 768 init_ring( waveform_ring_f1, NB_RING_NODES_F1, wf_buffer_f1, WFRM_BUFFER );
769 769 // F2 RING
770 770 init_ring( waveform_ring_f2, NB_RING_NODES_F2, wf_buffer_f2, WFRM_BUFFER );
771 771 // F3 RING
772 772 init_ring( waveform_ring_f3, NB_RING_NODES_F3, wf_buffer_f3, WFRM_BUFFER );
773 773
774 774 ring_node_wf_snap_extracted.buffer_address = (int) wf_snap_extracted;
775 775
776 776 DEBUG_PRINTF1("waveform_ring_f0 @%x\n", (unsigned int) waveform_ring_f0)
777 777 DEBUG_PRINTF1("waveform_ring_f1 @%x\n", (unsigned int) waveform_ring_f1)
778 778 DEBUG_PRINTF1("waveform_ring_f2 @%x\n", (unsigned int) waveform_ring_f2)
779 779 DEBUG_PRINTF1("waveform_ring_f3 @%x\n", (unsigned int) waveform_ring_f3)
780 780 DEBUG_PRINTF1("wf_buffer_f0 @%x\n", (unsigned int) wf_buffer_f0)
781 781 DEBUG_PRINTF1("wf_buffer_f1 @%x\n", (unsigned int) wf_buffer_f1)
782 782 DEBUG_PRINTF1("wf_buffer_f2 @%x\n", (unsigned int) wf_buffer_f2)
783 783 DEBUG_PRINTF1("wf_buffer_f3 @%x\n", (unsigned int) wf_buffer_f3)
784 784
785 785 }
786 786
787 787 void WFP_reset_current_ring_nodes( void )
788 788 {
789 789 current_ring_node_f0 = waveform_ring_f0[0].next;
790 790 current_ring_node_f1 = waveform_ring_f1[0].next;
791 791 current_ring_node_f2 = waveform_ring_f2[0].next;
792 792 current_ring_node_f3 = waveform_ring_f3[0].next;
793 793
794 794 ring_node_to_send_swf_f0 = waveform_ring_f0;
795 795 ring_node_to_send_swf_f1 = waveform_ring_f1;
796 796 ring_node_to_send_swf_f2 = waveform_ring_f2;
797 797
798 798 ring_node_to_send_cwf_f1 = waveform_ring_f1;
799 799 ring_node_to_send_cwf_f2 = waveform_ring_f2;
800 800 ring_node_to_send_cwf_f3 = waveform_ring_f3;
801 801 }
802 802
803 803 int send_waveform_CWF3_light( ring_node *ring_node_to_send, ring_node *ring_node_cwf3_light, rtems_id queue_id )
804 804 {
805 805 /** This function sends CWF_F3 CCSDS packets without the b1, b2 and b3 data.
806 806 *
807 807 * @param waveform points to the buffer containing the data that will be send.
808 808 * @param headerCWF points to a table of headers that have been prepared for the data transmission.
809 809 * @param queue_id is the id of the rtems queue to which spw_ioctl_pkt_send structures will be send. The structures
810 810 * contain information to setup the transmission of the data packets.
811 811 *
812 812 * By default, CWF_F3 packet are send without the b1, b2 and b3 data. This function rebuilds a data buffer
813 813 * from the incoming data and sends it in 7 packets, 6 containing 340 blocks and 1 one containing 8 blocks.
814 814 *
815 815 */
816 816
817 817 unsigned int i;
818 818 int ret;
819 819 rtems_status_code status;
820 820
821 821 char *sample;
822 822 int *dataPtr;
823 823
824 824 ret = LFR_DEFAULT;
825 825
826 826 dataPtr = (int*) ring_node_to_send->buffer_address;
827 827
828 828 ring_node_cwf3_light->coarseTime = ring_node_to_send->coarseTime;
829 829 ring_node_cwf3_light->fineTime = ring_node_to_send->fineTime;
830 830
831 831 //**********************
832 832 // BUILD CWF3_light DATA
833 833 for ( i=0; i< NB_SAMPLES_PER_SNAPSHOT; i++)
834 834 {
835 835 sample = (char*) &dataPtr[ (i * NB_WORDS_SWF_BLK) ];
836 836 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) ] = sample[ 0 ];
837 837 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 1 ] = sample[ 1 ];
838 838 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 2 ] = sample[ 2 ];
839 839 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 3 ] = sample[ 3 ];
840 840 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 4 ] = sample[ 4 ];
841 841 wf_cont_f3_light[ (i * NB_BYTES_CWF3_LIGHT_BLK) + 5 ] = sample[ 5 ];
842 842 }
843 843
844 844 // SEND PACKET
845 845 status = rtems_message_queue_send( queue_id, &ring_node_cwf3_light, sizeof( ring_node* ) );
846 846 if (status != RTEMS_SUCCESSFUL) {
847 847 ret = LFR_DEFAULT;
848 848 }
849 849
850 850 return ret;
851 851 }
852 852
853 853 void compute_acquisition_time( unsigned int coarseTime, unsigned int fineTime,
854 854 unsigned int sid, unsigned char pa_lfr_pkt_nr, unsigned char * acquisitionTime )
855 855 {
856 856 unsigned long long int acquisitionTimeAsLong;
857 857 unsigned char localAcquisitionTime[6];
858 858 double deltaT;
859 859
860 860 deltaT = 0.;
861 861
862 862 localAcquisitionTime[0] = (unsigned char) ( coarseTime >> 24 );
863 863 localAcquisitionTime[1] = (unsigned char) ( coarseTime >> 16 );
864 864 localAcquisitionTime[2] = (unsigned char) ( coarseTime >> 8 );
865 865 localAcquisitionTime[3] = (unsigned char) ( coarseTime );
866 866 localAcquisitionTime[4] = (unsigned char) ( fineTime >> 8 );
867 867 localAcquisitionTime[5] = (unsigned char) ( fineTime );
868 868
869 869 acquisitionTimeAsLong = ( (unsigned long long int) localAcquisitionTime[0] << 40 )
870 870 + ( (unsigned long long int) localAcquisitionTime[1] << 32 )
871 871 + ( (unsigned long long int) localAcquisitionTime[2] << 24 )
872 872 + ( (unsigned long long int) localAcquisitionTime[3] << 16 )
873 873 + ( (unsigned long long int) localAcquisitionTime[4] << 8 )
874 874 + ( (unsigned long long int) localAcquisitionTime[5] );
875 875
876 876 switch( sid )
877 877 {
878 878 case SID_NORM_SWF_F0:
879 879 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 24576. ;
880 880 break;
881 881
882 882 case SID_NORM_SWF_F1:
883 883 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 4096. ;
884 884 break;
885 885
886 886 case SID_NORM_SWF_F2:
887 887 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_304 * 65536. / 256. ;
888 888 break;
889 889
890 890 case SID_SBM1_CWF_F1:
891 891 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 4096. ;
892 892 break;
893 893
894 894 case SID_SBM2_CWF_F2:
895 895 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 256. ;
896 896 break;
897 897
898 898 case SID_BURST_CWF_F2:
899 899 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 256. ;
900 900 break;
901 901
902 902 case SID_NORM_CWF_F3:
903 903 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF_SHORT_F3 * 65536. / 16. ;
904 904 break;
905 905
906 906 case SID_NORM_CWF_LONG_F3:
907 907 deltaT = ( (double ) (pa_lfr_pkt_nr) ) * BLK_NR_CWF * 65536. / 16. ;
908 908 break;
909 909
910 910 default:
911 911 PRINTF1("in compute_acquisition_time *** ERR unexpected sid %d\n", sid)
912 912 deltaT = 0.;
913 913 break;
914 914 }
915 915
916 916 acquisitionTimeAsLong = acquisitionTimeAsLong + (unsigned long long int) deltaT;
917 917 //
918 918 acquisitionTime[0] = (unsigned char) (acquisitionTimeAsLong >> 40);
919 919 acquisitionTime[1] = (unsigned char) (acquisitionTimeAsLong >> 32);
920 920 acquisitionTime[2] = (unsigned char) (acquisitionTimeAsLong >> 24);
921 921 acquisitionTime[3] = (unsigned char) (acquisitionTimeAsLong >> 16);
922 922 acquisitionTime[4] = (unsigned char) (acquisitionTimeAsLong >> 8 );
923 923 acquisitionTime[5] = (unsigned char) (acquisitionTimeAsLong );
924 924
925 925 }
926 926
927 927 void build_snapshot_from_ring( ring_node *ring_node_to_send, unsigned char frequencyChannel, unsigned long long int acquisitionTimeF0_asLong )
928 928 {
929 929 unsigned int i;
930 930 unsigned long long int centerTime_asLong;
931 931 unsigned long long int acquisitionTime_asLong;
932 932 unsigned long long int bufferAcquisitionTime_asLong;
933 933 unsigned char *ptr1;
934 934 unsigned char *ptr2;
935 935 unsigned char *timeCharPtr;
936 936 unsigned char nb_ring_nodes;
937 937 unsigned long long int frequency_asLong;
938 938 unsigned long long int nbTicksPerSample_asLong;
939 939 unsigned long long int nbSamplesPart1_asLong;
940 940 unsigned long long int sampleOffset_asLong;
941 941
942 942 unsigned int deltaT_F0;
943 943 unsigned int deltaT_F1;
944 944 unsigned long long int deltaT_F2;
945 945
946 946 deltaT_F0 = 2731; // (2048. / 24576. / 2.) * 65536. = 2730.667;
947 947 deltaT_F1 = 16384; // (2048. / 4096. / 2.) * 65536. = 16384;
948 948 deltaT_F2 = 262144; // (2048. / 256. / 2.) * 65536. = 262144;
949 949 sampleOffset_asLong = 0x00;
950 950
951 951 // (1) get the f0 acquisition time => the value is passed in argument
952 952
953 953 // (2) compute the central reference time
954 954 centerTime_asLong = acquisitionTimeF0_asLong + deltaT_F0;
955 955
956 956 // (3) compute the acquisition time of the current snapshot
957 957 switch(frequencyChannel)
958 958 {
959 959 case 1: // 1 is for F1 = 4096 Hz
960 960 acquisitionTime_asLong = centerTime_asLong - deltaT_F1;
961 961 nb_ring_nodes = NB_RING_NODES_F1;
962 962 frequency_asLong = 4096;
963 963 nbTicksPerSample_asLong = 16; // 65536 / 4096;
964 964 break;
965 965 case 2: // 2 is for F2 = 256 Hz
966 966 acquisitionTime_asLong = centerTime_asLong - deltaT_F2;
967 967 nb_ring_nodes = NB_RING_NODES_F2;
968 968 frequency_asLong = 256;
969 969 nbTicksPerSample_asLong = 256; // 65536 / 256;
970 970 break;
971 971 default:
972 972 acquisitionTime_asLong = centerTime_asLong;
973 973 frequency_asLong = 256;
974 974 nbTicksPerSample_asLong = 256;
975 975 break;
976 976 }
977 977
978 978 //****************************************************************************
979 979 // (4) search the ring_node with the acquisition time <= acquisitionTime_asLong
980 980 for (i=0; i<nb_ring_nodes; i++)
981 981 {
982 982 PRINTF1("%d ... ", i)
983 983 bufferAcquisitionTime_asLong = get_acquisition_time( (unsigned char *) &ring_node_to_send->coarseTime );
984 984 if (bufferAcquisitionTime_asLong <= acquisitionTime_asLong)
985 985 {
986 986 PRINTF1("buffer found with acquisition time = %llx\n", bufferAcquisitionTime_asLong)
987 987 break;
988 988 }
989 989 ring_node_to_send = ring_node_to_send->previous;
990 990 }
991 991
992 992 // (5) compute the number of samples to take in the current buffer
993 993 sampleOffset_asLong = ((acquisitionTime_asLong - bufferAcquisitionTime_asLong) * frequency_asLong ) >> 16;
994 994 nbSamplesPart1_asLong = NB_SAMPLES_PER_SNAPSHOT - sampleOffset_asLong;
995 995 PRINTF2("sampleOffset_asLong = %lld, nbSamplesPart1_asLong = %lld\n", sampleOffset_asLong, nbSamplesPart1_asLong)
996 996
997 997 // (6) compute the final acquisition time
998 998 acquisitionTime_asLong = bufferAcquisitionTime_asLong +
999 999 sampleOffset_asLong * nbTicksPerSample_asLong;
1000 1000
1001 1001 // (7) copy the acquisition time at the beginning of the extrated snapshot
1002 1002 ptr1 = (unsigned char*) &acquisitionTime_asLong;
1003 1003 // fine time
1004 1004 ptr2 = (unsigned char*) &ring_node_wf_snap_extracted.fineTime;
1005 1005 ptr2[2] = ptr1[ 4 + 2 ];
1006 1006 ptr2[3] = ptr1[ 5 + 2 ];
1007 1007 // coarse time
1008 1008 ptr2 = (unsigned char*) &ring_node_wf_snap_extracted.coarseTime;
1009 1009 ptr2[0] = ptr1[ 0 + 2 ];
1010 1010 ptr2[1] = ptr1[ 1 + 2 ];
1011 1011 ptr2[2] = ptr1[ 2 + 2 ];
1012 1012 ptr2[3] = ptr1[ 3 + 2 ];
1013 1013
1014 1014 // re set the synchronization bit
1015 1015 timeCharPtr = (unsigned char*) &ring_node_to_send->coarseTime;
1016 1016 ptr2[0] = ptr2[0] | (timeCharPtr[0] & 0x80); // [1000 0000]
1017 1017
1018 1018 if ( (nbSamplesPart1_asLong >= NB_SAMPLES_PER_SNAPSHOT) | (nbSamplesPart1_asLong < 0) )
1019 1019 {
1020 1020 nbSamplesPart1_asLong = 0;
1021 1021 }
1022 1022 // copy the part 1 of the snapshot in the extracted buffer
1023 1023 for ( i = 0; i < (nbSamplesPart1_asLong * NB_WORDS_SWF_BLK); i++ )
1024 1024 {
1025 1025 wf_snap_extracted[i] =
1026 1026 ((int*) ring_node_to_send->buffer_address)[ i + (sampleOffset_asLong * NB_WORDS_SWF_BLK) ];
1027 1027 }
1028 1028 // copy the part 2 of the snapshot in the extracted buffer
1029 1029 ring_node_to_send = ring_node_to_send->next;
1030 1030 for ( i = (nbSamplesPart1_asLong * NB_WORDS_SWF_BLK); i < (NB_SAMPLES_PER_SNAPSHOT * NB_WORDS_SWF_BLK); i++ )
1031 1031 {
1032 1032 wf_snap_extracted[i] =
1033 1033 ((int*) ring_node_to_send->buffer_address)[ (i-(nbSamplesPart1_asLong * NB_WORDS_SWF_BLK)) ];
1034 1034 }
1035 1035 }
1036 1036
1037 1037 void snapshot_resynchronization( unsigned char *timePtr )
1038 1038 {
1039 1039 unsigned long long int acquisitionTime;
1040 1040 unsigned long long int centerTime;
1041 1041 unsigned long long int previousTick;
1042 1042 unsigned long long int nextTick;
1043 1043 unsigned long long int deltaPreviousTick;
1044 1044 unsigned long long int deltaNextTick;
1045 1045 unsigned int deltaTickInF2;
1046 1046 double deltaPrevious;
1047 1047 double deltaNext;
1048 1048
1049 1049 acquisitionTime = get_acquisition_time( timePtr );
1050 1050
1051 1051 // compute center time
1052 1052 centerTime = acquisitionTime + 2731; // (2048. / 24576. / 2.) * 65536. = 2730.667;
1053 1053 previousTick = centerTime - (centerTime & 0xffff);
1054 1054 nextTick = previousTick + 65536;
1055 1055
1056 1056 deltaPreviousTick = centerTime - previousTick;
1057 1057 deltaNextTick = nextTick - centerTime;
1058 1058
1059 1059 deltaPrevious = ((double) deltaPreviousTick) / 65536. * 1000.;
1060 1060 deltaNext = ((double) deltaNextTick) / 65536. * 1000.;
1061 1061
1062 1062 PRINTF2("delta previous = %f ms, delta next = %f ms\n", deltaPrevious, deltaNext)
1063 1063 PRINTF2("delta previous = %llu, delta next = %llu\n", deltaPreviousTick, deltaNextTick)
1064 1064
1065 1065 // which tick is the closest
1066 1066 if (deltaPreviousTick > deltaNextTick)
1067 1067 {
1068 1068 deltaTickInF2 = floor( (deltaNext * 256. / 1000.) ); // the division by 2 is important here
1069 1069 waveform_picker_regs->delta_snapshot = waveform_picker_regs->delta_snapshot + deltaTickInF2;
1070 1070 PRINTF1("correction of = + %u\n", deltaTickInF2)
1071 1071 }
1072 1072 else
1073 1073 {
1074 1074 deltaTickInF2 = floor( (deltaPrevious * 256. / 1000.) ); // the division by 2 is important here
1075 1075 waveform_picker_regs->delta_snapshot = waveform_picker_regs->delta_snapshot - deltaTickInF2;
1076 1076 PRINTF1("correction of = - %u\n", deltaTickInF2)
1077 1077 }
1078 1078 }
1079 1079
1080 1080 //**************
1081 1081 // wfp registers
1082 1082 void reset_wfp_burst_enable( void )
1083 1083 {
1084 1084 /** This function resets the waveform picker burst_enable register.
1085 1085 *
1086 1086 * The burst bits [f2 f1 f0] and the enable bits [f3 f2 f1 f0] are set to 0.
1087 1087 *
1088 1088 */
1089 1089
1090 1090 // [1000 000] burst f2, f1, f0 enable f3, f2, f1, f0
1091 1091 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable & 0x80;
1092 1092 }
1093 1093
1094 1094 void reset_wfp_status( void )
1095 1095 {
1096 1096 /** This function resets the waveform picker status register.
1097 1097 *
1098 1098 * All status bits are set to 0 [new_err full_err full].
1099 1099 *
1100 1100 */
1101 1101
1102 1102 waveform_picker_regs->status = 0xffff;
1103 1103 }
1104 1104
1105 1105 void reset_wfp_buffer_addresses( void )
1106 1106 {
1107 1107 // F0
1108 1108 waveform_picker_regs->addr_data_f0_0 = current_ring_node_f0->previous->buffer_address; // 0x08
1109 1109 waveform_picker_regs->addr_data_f0_1 = current_ring_node_f0->buffer_address; // 0x0c
1110 1110 // F1
1111 1111 waveform_picker_regs->addr_data_f1_0 = current_ring_node_f1->previous->buffer_address; // 0x10
1112 1112 waveform_picker_regs->addr_data_f1_1 = current_ring_node_f1->buffer_address; // 0x14
1113 1113 // F2
1114 1114 waveform_picker_regs->addr_data_f2_0 = current_ring_node_f2->previous->buffer_address; // 0x18
1115 1115 waveform_picker_regs->addr_data_f2_1 = current_ring_node_f2->buffer_address; // 0x1c
1116 1116 // F3
1117 1117 waveform_picker_regs->addr_data_f3_0 = current_ring_node_f3->previous->buffer_address; // 0x20
1118 1118 waveform_picker_regs->addr_data_f3_1 = current_ring_node_f3->buffer_address; // 0x24
1119 1119 }
1120 1120
1121 1121 void reset_waveform_picker_regs( void )
1122 1122 {
1123 1123 /** This function resets the waveform picker module registers.
1124 1124 *
1125 1125 * The registers affected by this function are located at the following offset addresses:
1126 1126 * - 0x00 data_shaping
1127 1127 * - 0x04 run_burst_enable
1128 1128 * - 0x08 addr_data_f0
1129 1129 * - 0x0C addr_data_f1
1130 1130 * - 0x10 addr_data_f2
1131 1131 * - 0x14 addr_data_f3
1132 1132 * - 0x18 status
1133 1133 * - 0x1C delta_snapshot
1134 1134 * - 0x20 delta_f0
1135 1135 * - 0x24 delta_f0_2
1136 1136 * - 0x28 delta_f1
1137 1137 * - 0x2c delta_f2
1138 1138 * - 0x30 nb_data_by_buffer
1139 1139 * - 0x34 nb_snapshot_param
1140 1140 * - 0x38 start_date
1141 1141 * - 0x3c nb_word_in_buffer
1142 1142 *
1143 1143 */
1144 1144
1145 1145 set_wfp_data_shaping(); // 0x00 *** R1 R0 SP1 SP0 BW
1146 1146
1147 1147 reset_wfp_burst_enable(); // 0x04 *** [run *** burst f2, f1, f0 *** enable f3, f2, f1, f0 ]
1148 1148
1149 1149 reset_wfp_buffer_addresses();
1150 1150
1151 1151 reset_wfp_status(); // 0x18
1152 1152
1153 1153 set_wfp_delta_snapshot(); // 0x1c *** 300 s => 0x12bff
1154 1154
1155 1155 set_wfp_delta_f0_f0_2(); // 0x20, 0x24
1156 1156
1157 1157 set_wfp_delta_f1(); // 0x28
1158 1158
1159 1159 set_wfp_delta_f2(); // 0x2c
1160 1160
1161 1161 DEBUG_PRINTF1("delta_snapshot %x\n", waveform_picker_regs->delta_snapshot)
1162 1162 DEBUG_PRINTF1("delta_f0 %x\n", waveform_picker_regs->delta_f0)
1163 1163 DEBUG_PRINTF1("delta_f0_2 %x\n", waveform_picker_regs->delta_f0_2)
1164 1164 DEBUG_PRINTF1("delta_f1 %x\n", waveform_picker_regs->delta_f1)
1165 1165 DEBUG_PRINTF1("delta_f2 %x\n", waveform_picker_regs->delta_f2)
1166 1166 // 2688 = 8 * 336
1167 1167 waveform_picker_regs->nb_data_by_buffer = 0xa7f; // 0x30 *** 2688 - 1 => nb samples -1
1168 1168 waveform_picker_regs->snapshot_param = 0xa80; // 0x34 *** 2688 => nb samples
1169 1169 waveform_picker_regs->start_date = 0x7fffffff; // 0x38
1170 1170 //
1171 1171 // coarse time and fine time registers are not initialized, they are volatile
1172 1172 //
1173 1173 waveform_picker_regs->buffer_length = 0x1f8;// buffer length in burst = 3 * 2688 / 16 = 504 = 0x1f8
1174 1174 }
1175 1175
1176 1176 void set_wfp_data_shaping( void )
1177 1177 {
1178 1178 /** This function sets the data_shaping register of the waveform picker module.
1179 1179 *
1180 1180 * The value is read from one field of the parameter_dump_packet structure:\n
1181 1181 * bw_sp0_sp1_r0_r1
1182 1182 *
1183 1183 */
1184 1184
1185 1185 unsigned char data_shaping;
1186 1186
1187 1187 // get the parameters for the data shaping [BW SP0 SP1 R0 R1] in sy_lfr_common1 and configure the register
1188 1188 // waveform picker : [R1 R0 SP1 SP0 BW]
1189 1189
1190 1190 data_shaping = parameter_dump_packet.sy_lfr_common_parameters;
1191 1191
1192 1192 waveform_picker_regs->data_shaping =
1193 1193 ( (data_shaping & 0x20) >> 5 ) // BW
1194 1194 + ( (data_shaping & 0x10) >> 3 ) // SP0
1195 1195 + ( (data_shaping & 0x08) >> 1 ) // SP1
1196 1196 + ( (data_shaping & 0x04) << 1 ) // R0
1197 1197 + ( (data_shaping & 0x02) << 3 ) // R1
1198 1198 + ( (data_shaping & 0x01) << 5 ); // R2
1199 1199 }
1200 1200
1201 1201 void set_wfp_burst_enable_register( unsigned char mode )
1202 1202 {
1203 1203 /** This function sets the waveform picker burst_enable register depending on the mode.
1204 1204 *
1205 1205 * @param mode is the LFR mode to launch.
1206 1206 *
1207 1207 * The burst bits shall be before the enable bits.
1208 1208 *
1209 1209 */
1210 1210
1211 1211 // [0000 0000] burst f2, f1, f0 enable f3 f2 f1 f0
1212 1212 // the burst bits shall be set first, before the enable bits
1213 1213 switch(mode) {
1214 1214 case(LFR_MODE_NORMAL):
1215 waveform_picker_regs->run_burst_enable = 0x00; // [0000 0000] no burst enable
1216 waveform_picker_regs->run_burst_enable = 0x0f; // [0000 1111] enable f3 f2 f1 f0
1215 waveform_picker_regs->run_burst_enable = 0x60; // [0110 0000] enable f2 AND f1 burst
1216 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x0c; // [1111] enable f3 f2 f1 f0
1217 1217 break;
1218 1218 case(LFR_MODE_BURST):
1219 1219 waveform_picker_regs->run_burst_enable = 0x40; // [0100 0000] f2 burst enabled
1220 // waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x04; // [0100] enable f2
1221 1220 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x0c; // [1100] enable f3 AND f2
1222 1221 break;
1223 1222 case(LFR_MODE_SBM1):
1224 1223 waveform_picker_regs->run_burst_enable = 0x20; // [0010 0000] f1 burst enabled
1225 1224 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x0f; // [1111] enable f3 f2 f1 f0
1226 1225 break;
1227 1226 case(LFR_MODE_SBM2):
1228 1227 waveform_picker_regs->run_burst_enable = 0x40; // [0100 0000] f2 burst enabled
1229 1228 waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x0f; // [1111] enable f3 f2 f1 f0
1230 1229 break;
1231 1230 default:
1232 1231 waveform_picker_regs->run_burst_enable = 0x00; // [0000 0000] no burst enabled, no waveform enabled
1233 1232 break;
1234 1233 }
1235 1234 }
1236 1235
1237 1236 void set_wfp_delta_snapshot( void )
1238 1237 {
1239 1238 /** This function sets the delta_snapshot register of the waveform picker module.
1240 1239 *
1241 1240 * The value is read from two (unsigned char) of the parameter_dump_packet structure:
1242 1241 * - sy_lfr_n_swf_p[0]
1243 1242 * - sy_lfr_n_swf_p[1]
1244 1243 *
1245 1244 */
1246 1245
1247 1246 unsigned int delta_snapshot;
1248 1247 unsigned int delta_snapshot_in_T2;
1249 1248
1250 1249 delta_snapshot = parameter_dump_packet.sy_lfr_n_swf_p[0]*256
1251 1250 + parameter_dump_packet.sy_lfr_n_swf_p[1];
1252 1251
1253 1252 delta_snapshot_in_T2 = delta_snapshot * 256;
1254 1253 waveform_picker_regs->delta_snapshot = delta_snapshot_in_T2 - 1; // max 4 bytes
1255 1254 }
1256 1255
1257 1256 void set_wfp_delta_f0_f0_2( void )
1258 1257 {
1259 1258 unsigned int delta_snapshot;
1260 1259 unsigned int nb_samples_per_snapshot;
1261 1260 float delta_f0_in_float;
1262 1261
1263 1262 delta_snapshot = waveform_picker_regs->delta_snapshot;
1264 1263 nb_samples_per_snapshot = parameter_dump_packet.sy_lfr_n_swf_l[0] * 256 + parameter_dump_packet.sy_lfr_n_swf_l[1];
1265 1264 delta_f0_in_float =nb_samples_per_snapshot / 2. * ( 1. / 256. - 1. / 24576.) * 256.;
1266 1265
1267 1266 waveform_picker_regs->delta_f0 = delta_snapshot - floor( delta_f0_in_float );
1268 1267 waveform_picker_regs->delta_f0_2 = 0x30; // 48 = 11 0000, max 7 bits
1269 1268 }
1270 1269
1271 1270 void set_wfp_delta_f1( void )
1272 1271 {
1273 1272 unsigned int delta_snapshot;
1274 1273 unsigned int nb_samples_per_snapshot;
1275 1274 float delta_f1_in_float;
1276 1275
1277 1276 delta_snapshot = waveform_picker_regs->delta_snapshot;
1278 1277 nb_samples_per_snapshot = parameter_dump_packet.sy_lfr_n_swf_l[0] * 256 + parameter_dump_packet.sy_lfr_n_swf_l[1];
1279 1278 delta_f1_in_float = nb_samples_per_snapshot / 2. * ( 1. / 256. - 1. / 4096.) * 256.;
1280 1279
1281 1280 waveform_picker_regs->delta_f1 = delta_snapshot - floor( delta_f1_in_float );
1282 1281 }
1283 1282
1284 1283 void set_wfp_delta_f2()
1285 1284 {
1286 1285 unsigned int delta_snapshot;
1287 1286 unsigned int nb_samples_per_snapshot;
1288 1287
1289 1288 delta_snapshot = waveform_picker_regs->delta_snapshot;
1290 1289 nb_samples_per_snapshot = parameter_dump_packet.sy_lfr_n_swf_l[0] * 256 + parameter_dump_packet.sy_lfr_n_swf_l[1];
1291 1290
1292 1291 waveform_picker_regs->delta_f2 = delta_snapshot - nb_samples_per_snapshot / 2;
1293 1292 }
1294 1293
1295 1294 //*****************
1296 1295 // local parameters
1297 1296
1298 1297 void increment_seq_counter_source_id( unsigned char *packet_sequence_control, unsigned int sid )
1299 1298 {
1300 1299 /** This function increments the parameter "sequence_cnt" depending on the sid passed in argument.
1301 1300 *
1302 1301 * @param packet_sequence_control is a pointer toward the parameter sequence_cnt to update.
1303 1302 * @param sid is the source identifier of the packet being updated.
1304 1303 *
1305 1304 * REQ-LFR-SRS-5240 / SSS-CP-FS-590
1306 1305 * The sequence counters shall wrap around from 2^14 to zero.
1307 1306 * The sequence counter shall start at zero at startup.
1308 1307 *
1309 1308 * REQ-LFR-SRS-5239 / SSS-CP-FS-580
1310 1309 * All TM_LFR_SCIENCE_ packets are sent to ground, i.e. destination id = 0
1311 1310 *
1312 1311 */
1313 1312
1314 1313 unsigned short *sequence_cnt;
1315 1314 unsigned short segmentation_grouping_flag;
1316 1315 unsigned short new_packet_sequence_control;
1317 1316 rtems_mode initial_mode_set;
1318 1317 rtems_mode current_mode_set;
1319 1318 rtems_status_code status;
1320 1319
1321 1320 //******************************************
1322 1321 // CHANGE THE MODE OF THE CALLING RTEMS TASK
1323 1322 status = rtems_task_mode( RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &initial_mode_set );
1324 1323
1325 1324 if ( (sid == SID_NORM_SWF_F0) || (sid == SID_NORM_SWF_F1) || (sid == SID_NORM_SWF_F2)
1326 1325 || (sid == SID_NORM_CWF_F3) || (sid == SID_NORM_CWF_LONG_F3)
1327 1326 || (sid == SID_BURST_CWF_F2)
1328 1327 || (sid == SID_NORM_ASM_F0) || (sid == SID_NORM_ASM_F1) || (sid == SID_NORM_ASM_F2)
1329 1328 || (sid == SID_NORM_BP1_F0) || (sid == SID_NORM_BP1_F1) || (sid == SID_NORM_BP1_F2)
1330 1329 || (sid == SID_NORM_BP2_F0) || (sid == SID_NORM_BP2_F1) || (sid == SID_NORM_BP2_F2)
1331 1330 || (sid == SID_BURST_BP1_F0) || (sid == SID_BURST_BP2_F0)
1332 1331 || (sid == SID_BURST_BP1_F1) || (sid == SID_BURST_BP2_F1) )
1333 1332 {
1334 1333 sequence_cnt = (unsigned short *) &sequenceCounters_SCIENCE_NORMAL_BURST;
1335 1334 }
1336 1335 else if ( (sid ==SID_SBM1_CWF_F1) || (sid ==SID_SBM2_CWF_F2)
1337 1336 || (sid == SID_SBM1_BP1_F0) || (sid == SID_SBM1_BP2_F0)
1338 1337 || (sid == SID_SBM2_BP1_F0) || (sid == SID_SBM2_BP2_F0)
1339 1338 || (sid == SID_SBM2_BP1_F1) || (sid == SID_SBM2_BP2_F1) )
1340 1339 {
1341 1340 sequence_cnt = (unsigned short *) &sequenceCounters_SCIENCE_SBM1_SBM2;
1342 1341 }
1343 1342 else
1344 1343 {
1345 1344 sequence_cnt = (unsigned short *) NULL;
1346 1345 PRINTF1("in increment_seq_counter_source_id *** ERR apid_destid %d not known\n", sid)
1347 1346 }
1348 1347
1349 1348 if (sequence_cnt != NULL)
1350 1349 {
1351 1350 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << 8;
1352 1351 *sequence_cnt = (*sequence_cnt) & 0x3fff;
1353 1352
1354 1353 new_packet_sequence_control = segmentation_grouping_flag | (*sequence_cnt) ;
1355 1354
1356 1355 packet_sequence_control[0] = (unsigned char) (new_packet_sequence_control >> 8);
1357 1356 packet_sequence_control[1] = (unsigned char) (new_packet_sequence_control );
1358 1357
1359 1358 // increment the sequence counter
1360 1359 if ( *sequence_cnt < SEQ_CNT_MAX)
1361 1360 {
1362 1361 *sequence_cnt = *sequence_cnt + 1;
1363 1362 }
1364 1363 else
1365 1364 {
1366 1365 *sequence_cnt = 0;
1367 1366 }
1368 1367 }
1369 1368
1370 1369 //*************************************
1371 1370 // RESTORE THE MODE OF THE CALLING TASK
1372 1371 status = rtems_task_mode( initial_mode_set, RTEMS_PREEMPT_MASK, &current_mode_set );
1373 1372 }
General Comments 0
You need to be logged in to leave comments. Login now