##// END OF EJS Templates
934 HK_LFR_SC_RW1_F1_FLAG not updated when RW1_F1 is set
paul -
r347:5e14d03e51fa R3++ draft
parent child
Show More
@@ -1,59 +1,57
1 1 #ifndef FSW_INIT_H_INCLUDED
2 2 #define FSW_INIT_H_INCLUDED
3 3
4 4 #include <rtems.h>
5 5 #include <leon.h>
6 6
7 7 #include "fsw_params.h"
8 8 #include "fsw_misc.h"
9 9 #include "fsw_processing.h"
10 10
11 11 #include "tc_handler.h"
12 12 #include "wf_handler.h"
13 13 #include "fsw_spacewire.h"
14 14
15 15 #include "avf0_prc0.h"
16 16 #include "avf1_prc1.h"
17 17 #include "avf2_prc2.h"
18 18
19 19 extern rtems_name Task_name[]; /* array of task names */
20 20 extern rtems_id Task_id[]; /* array of task ids */
21 21 extern rtems_name timecode_timer_name;
22 22 extern rtems_id timecode_timer_id;
23 23 extern unsigned char pa_bia_status_info;
24 extern unsigned char cp_rpw_sc_rw1_rw2_f_flags;
25 extern unsigned char cp_rpw_sc_rw3_rw4_f_flags;
26 24
27 25 extern filterPar_t filterPar;
28 26 extern rw_f_t rw_f;
29 27
30 28 // RTEMS TASKS
31 29 rtems_task Init( rtems_task_argument argument);
32 30
33 31 // OTHER functions
34 32 void create_names( void );
35 33 int create_all_tasks( void );
36 34 int start_all_tasks( void );
37 35 //
38 36 rtems_status_code create_message_queues( void );
39 37 rtems_status_code create_timecode_timer( void );
40 38 rtems_status_code get_message_queue_id_send( rtems_id *queue_id );
41 39 rtems_status_code get_message_queue_id_recv( rtems_id *queue_id );
42 40 rtems_status_code get_message_queue_id_prc0( rtems_id *queue_id );
43 41 rtems_status_code get_message_queue_id_prc1( rtems_id *queue_id );
44 42 rtems_status_code get_message_queue_id_prc2( rtems_id *queue_id );
45 43 void update_queue_max_count( rtems_id queue_id, unsigned char*fifo_size_max );
46 44 void init_ring(ring_node ring[], unsigned char nbNodes, volatile int buffer[], unsigned int bufferSize );
47 45 //
48 46 int start_recv_send_tasks( void );
49 47 //
50 48 void init_local_mode_parameters( void );
51 49 void reset_local_time( void );
52 50
53 51 extern void rtems_cpu_usage_report( void );
54 52 extern void rtems_cpu_usage_reset( void );
55 53 extern void rtems_stack_checker_report_usage( void );
56 54
57 55 extern int sched_yield( void );
58 56
59 57 #endif // FSW_INIT_H_INCLUDED
@@ -1,100 +1,98
1 1 /** Global variables of the LFR flight software.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * Among global variables, there are:
7 7 * - RTEMS names and id.
8 8 * - APB configuration registers.
9 9 * - waveforms global buffers, used by the waveform picker hardware module to store data.
10 10 * - spectral matrices buffesr, used by the hardware module to store data.
11 11 * - variable related to LFR modes parameters.
12 12 * - the global HK packet buffer.
13 13 * - the global dump parameter buffer.
14 14 *
15 15 */
16 16
17 17 #include <rtems.h>
18 18 #include <grspw.h>
19 19
20 20 #include "ccsds_types.h"
21 21 #include "grlib_regs.h"
22 22 #include "fsw_params.h"
23 23 #include "fsw_params_wf_handler.h"
24 24
25 25 #define NB_OF_TASKS 20
26 26 #define NB_OF_MISC_NAMES 5
27 27
28 28 // RTEMS GLOBAL VARIABLES
29 29 rtems_name misc_name[NB_OF_MISC_NAMES] = {0};
30 30 rtems_name Task_name[NB_OF_TASKS] = {0}; /* array of task names */
31 31 rtems_id Task_id[NB_OF_TASKS] = {0}; /* array of task ids */
32 32 rtems_name timecode_timer_name = 0;
33 33 rtems_id timecode_timer_id = RTEMS_ID_NONE;
34 34 rtems_name name_hk_rate_monotonic = 0; // name of the HK rate monotonic
35 35 rtems_id HK_id = RTEMS_ID_NONE;// id of the HK rate monotonic period
36 36 rtems_name name_avgv_rate_monotonic = 0; // name of the AVGV rate monotonic
37 37 rtems_id AVGV_id = RTEMS_ID_NONE;// id of the AVGV rate monotonic period
38 38 int fdSPW = 0;
39 39 int fdUART = 0;
40 40 unsigned char lfrCurrentMode = 0;
41 41 unsigned char pa_bia_status_info = 0;
42 42 unsigned char thisIsAnASMRestart = 0;
43 43 unsigned char oneTcLfrUpdateTimeReceived = 0;
44 44
45 45 // WAVEFORMS GLOBAL VARIABLES // 2048 * 3 * 4 + 2 * 4 = 24576 + 8 bytes = 24584
46 46 // 97 * 256 = 24832 => delta = 248 bytes = 62 words
47 47 // WAVEFORMS GLOBAL VARIABLES // 2688 * 3 * 4 + 2 * 4 = 32256 + 8 bytes = 32264
48 48 // 127 * 256 = 32512 => delta = 248 bytes = 62 words
49 49 // F0 F1 F2 F3
50 50 volatile int wf_buffer_f0[ NB_RING_NODES_F0 * WFRM_BUFFER ] __attribute__((aligned(0x100))) = {0};
51 51 volatile int wf_buffer_f1[ NB_RING_NODES_F1 * WFRM_BUFFER ] __attribute__((aligned(0x100))) = {0};
52 52 volatile int wf_buffer_f2[ NB_RING_NODES_F2 * WFRM_BUFFER ] __attribute__((aligned(0x100))) = {0};
53 53 volatile int wf_buffer_f3[ NB_RING_NODES_F3 * WFRM_BUFFER ] __attribute__((aligned(0x100))) = {0};
54 54
55 55 //***********************************
56 56 // SPECTRAL MATRICES GLOBAL VARIABLES
57 57
58 58 // alignment constraints for the spectral matrices buffers => the first data after the time (8 bytes) shall be aligned on 0x00
59 59 volatile int sm_f0[ NB_RING_NODES_SM_F0 * TOTAL_SIZE_SM ] __attribute__((aligned(0x100))) = {0};
60 60 volatile int sm_f1[ NB_RING_NODES_SM_F1 * TOTAL_SIZE_SM ] __attribute__((aligned(0x100))) = {0};
61 61 volatile int sm_f2[ NB_RING_NODES_SM_F2 * TOTAL_SIZE_SM ] __attribute__((aligned(0x100))) = {0};
62 62
63 63 // APB CONFIGURATION REGISTERS
64 64 time_management_regs_t *time_management_regs = (time_management_regs_t*) REGS_ADDR_TIME_MANAGEMENT;
65 65 gptimer_regs_t *gptimer_regs = (gptimer_regs_t *) REGS_ADDR_GPTIMER;
66 66 waveform_picker_regs_0_1_18_t *waveform_picker_regs = (waveform_picker_regs_0_1_18_t*) REGS_ADDR_WAVEFORM_PICKER;
67 67 spectral_matrix_regs_t *spectral_matrix_regs = (spectral_matrix_regs_t*) REGS_ADDR_SPECTRAL_MATRIX;
68 68
69 69 // MODE PARAMETERS
70 70 Packet_TM_LFR_PARAMETER_DUMP_t parameter_dump_packet = {0};
71 71 struct param_local_str param_local = {0};
72 72 unsigned int lastValidEnterModeTime = {0};
73 73
74 74 // HK PACKETS
75 75 Packet_TM_LFR_HK_t housekeeping_packet = {0};
76 unsigned char cp_rpw_sc_rw1_rw2_f_flags = 0;
77 unsigned char cp_rpw_sc_rw3_rw4_f_flags = 0;
78 76 // message queues occupancy
79 77 unsigned char hk_lfr_q_sd_fifo_size_max = 0;
80 78 unsigned char hk_lfr_q_rv_fifo_size_max = 0;
81 79 unsigned char hk_lfr_q_p0_fifo_size_max = 0;
82 80 unsigned char hk_lfr_q_p1_fifo_size_max = 0;
83 81 unsigned char hk_lfr_q_p2_fifo_size_max = 0;
84 82 // sequence counters are incremented by APID (PID + CAT) and destination ID
85 83 unsigned short sequenceCounters_SCIENCE_NORMAL_BURST = 0;
86 84 unsigned short sequenceCounters_SCIENCE_SBM1_SBM2 = 0;
87 85 unsigned short sequenceCounters_TC_EXE[SEQ_CNT_NB_DEST_ID] = {0};
88 86 unsigned short sequenceCounters_TM_DUMP[SEQ_CNT_NB_DEST_ID] = {0};
89 87 unsigned short sequenceCounterHK = {0};
90 88 spw_stats grspw_stats = {0};
91 89
92 90 // TC_LFR_UPDATE_INFO
93 91 rw_f_t rw_f;
94 92
95 93 // TC_LFR_LOAD_FILTER_PAR
96 94 filterPar_t filterPar = {0};
97 95
98 96 fbins_masks_t fbins_masks = {0};
99 97 unsigned int acquisitionDurations[NB_ACQUISITION_DURATION]
100 98 = {ACQUISITION_DURATION_F0, ACQUISITION_DURATION_F1, ACQUISITION_DURATION_F2};
@@ -1,975 +1,972
1 1 /** This is the RTEMS initialization module.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * This module contains two very different information:
7 7 * - specific instructions to configure the compilation of the RTEMS executive
8 8 * - functions related to the fligth softwre initialization, especially the INIT RTEMS task
9 9 *
10 10 */
11 11
12 12 //*************************
13 13 // GPL reminder to be added
14 14 //*************************
15 15
16 16 #include <rtems.h>
17 17
18 18 /* configuration information */
19 19
20 20 #define CONFIGURE_INIT
21 21
22 22 #include <bsp.h> /* for device driver prototypes */
23 23
24 24 /* configuration information */
25 25
26 26 #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
27 27 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
28 28
29 29 #define CONFIGURE_MAXIMUM_TASKS 21 // number of tasks concurrently active including INIT
30 30 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
31 31 #define CONFIGURE_EXTRA_TASK_STACKS (3 * RTEMS_MINIMUM_STACK_SIZE)
32 32 #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
33 33 #define CONFIGURE_INIT_TASK_PRIORITY 1 // instead of 100
34 34 #define CONFIGURE_INIT_TASK_MODE (RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT)
35 35 #define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT)
36 36 #define CONFIGURE_MAXIMUM_DRIVERS 16
37 37 #define CONFIGURE_MAXIMUM_PERIODS 5 // [hous] [load] [avgv]
38 38 #define CONFIGURE_MAXIMUM_TIMERS 5 // [spiq] [link] [spacewire_reset_link]
39 39 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 5
40 40 #ifdef PRINT_STACK_REPORT
41 41 #define CONFIGURE_STACK_CHECKER_ENABLED
42 42 #endif
43 43
44 44 #include <rtems/confdefs.h>
45 45
46 46 /* If --drvmgr was enabled during the configuration of the RTEMS kernel */
47 47 #ifdef RTEMS_DRVMGR_STARTUP
48 48 #ifdef LEON3
49 49 /* Add Timer and UART Driver */
50 50
51 51 #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
52 52 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GPTIMER
53 53 #endif
54 54
55 55 #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
56 56 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_APBUART
57 57 #endif
58 58
59 59 #endif
60 60 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GRSPW /* GRSPW Driver */
61 61
62 62 #include <drvmgr/drvmgr_confdefs.h>
63 63 #endif
64 64
65 65 #include "fsw_init.h"
66 66 #include "fsw_config.c"
67 67 #include "GscMemoryLPP.hpp"
68 68
69 69 void initCache()
70 70 {
71 71 // ASI 2 contains a few control registers that have not been assigned as ancillary state registers.
72 72 // These should only be read and written using 32-bit LDA/STA instructions.
73 73 // All cache registers are accessed through load/store operations to the alternate address space (LDA/STA), using ASI = 2.
74 74 // The table below shows the register addresses:
75 75 // 0x00 Cache control register
76 76 // 0x04 Reserved
77 77 // 0x08 Instruction cache configuration register
78 78 // 0x0C Data cache configuration register
79 79
80 80 // Cache Control Register Leon3 / Leon3FT
81 81 // 31..30 29 28 27..24 23 22 21 20..19 18 17 16
82 82 // RFT PS TB DS FD FI FT ST IB
83 83 // 15 14 13..12 11..10 9..8 7..6 5 4 3..2 1..0
84 84 // IP DP ITE IDE DTE DDE DF IF DCS ICS
85 85
86 86 unsigned int cacheControlRegister;
87 87
88 88 CCR_resetCacheControlRegister();
89 89 ASR16_resetRegisterProtectionControlRegister();
90 90
91 91 cacheControlRegister = CCR_getValue();
92 92 PRINTF1("(0) CCR - Cache Control Register = %x\n", cacheControlRegister);
93 93 PRINTF1("(0) ASR16 = %x\n", *asr16Ptr);
94 94
95 95 CCR_enableInstructionCache(); // ICS bits
96 96 CCR_enableDataCache(); // DCS bits
97 97 CCR_enableInstructionBurstFetch(); // IB bit
98 98
99 99 faultTolerantScheme();
100 100
101 101 cacheControlRegister = CCR_getValue();
102 102 PRINTF1("(1) CCR - Cache Control Register = %x\n", cacheControlRegister);
103 103 PRINTF1("(1) ASR16 Register protection control register = %x\n", *asr16Ptr);
104 104
105 105 PRINTF("\n");
106 106 }
107 107
108 108 rtems_task Init( rtems_task_argument ignored )
109 109 {
110 110 /** This is the RTEMS INIT taks, it is the first task launched by the system.
111 111 *
112 112 * @param unused is the starting argument of the RTEMS task
113 113 *
114 114 * The INIT task create and run all other RTEMS tasks.
115 115 *
116 116 */
117 117
118 118 //***********
119 119 // INIT CACHE
120 120
121 121 unsigned char *vhdlVersion;
122 122
123 123 reset_lfr();
124 124
125 125 reset_local_time();
126 126
127 127 rtems_cpu_usage_reset();
128 128
129 129 rtems_status_code status;
130 130 rtems_status_code status_spw;
131 131 rtems_isr_entry old_isr_handler;
132 132
133 133 old_isr_handler = NULL;
134 134
135 135 // UART settings
136 136 enable_apbuart_transmitter();
137 137 set_apbuart_scaler_reload_register(REGS_ADDR_APBUART, APBUART_SCALER_RELOAD_VALUE);
138 138
139 139 DEBUG_PRINTF("\n\n\n\n\nIn INIT *** Now the console is on port COM1\n")
140 140
141 141
142 142 PRINTF("\n\n\n\n\n")
143 143
144 144 initCache();
145 145
146 146 PRINTF("*************************\n")
147 147 PRINTF("** LFR Flight Software **\n")
148 148
149 149 PRINTF1("** %d-", SW_VERSION_N1)
150 150 PRINTF1("%d-" , SW_VERSION_N2)
151 151 PRINTF1("%d-" , SW_VERSION_N3)
152 152 PRINTF1("%d **\n", SW_VERSION_N4)
153 153
154 154 vhdlVersion = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
155 155 PRINTF("** VHDL **\n")
156 156 PRINTF1("** %d-", vhdlVersion[1])
157 157 PRINTF1("%d-" , vhdlVersion[2])
158 158 PRINTF1("%d **\n", vhdlVersion[3])
159 159 PRINTF("*************************\n")
160 160 PRINTF("\n\n")
161 161
162 162 init_parameter_dump();
163 163 init_kcoefficients_dump();
164 164 init_local_mode_parameters();
165 165 init_housekeeping_parameters();
166 166 init_k_coefficients_prc0();
167 167 init_k_coefficients_prc1();
168 168 init_k_coefficients_prc2();
169 169 pa_bia_status_info = INIT_CHAR;
170 170
171 171 // initialize all reaction wheels frequencies to NaN
172 172 rw_f.cp_rpw_sc_rw1_f1 = NAN;
173 173 rw_f.cp_rpw_sc_rw1_f2 = NAN;
174 174 rw_f.cp_rpw_sc_rw1_f3 = NAN;
175 175 rw_f.cp_rpw_sc_rw1_f4 = NAN;
176 176 rw_f.cp_rpw_sc_rw2_f1 = NAN;
177 177 rw_f.cp_rpw_sc_rw2_f2 = NAN;
178 178 rw_f.cp_rpw_sc_rw2_f3 = NAN;
179 179 rw_f.cp_rpw_sc_rw2_f4 = NAN;
180 180 rw_f.cp_rpw_sc_rw3_f1 = NAN;
181 181 rw_f.cp_rpw_sc_rw3_f2 = NAN;
182 182 rw_f.cp_rpw_sc_rw3_f3 = NAN;
183 183 rw_f.cp_rpw_sc_rw3_f4 = NAN;
184 184 rw_f.cp_rpw_sc_rw4_f1 = NAN;
185 185 rw_f.cp_rpw_sc_rw4_f2 = NAN;
186 186 rw_f.cp_rpw_sc_rw4_f3 = NAN;
187 187 rw_f.cp_rpw_sc_rw4_f4 = NAN;
188 188
189 cp_rpw_sc_rw1_rw2_f_flags = INIT_CHAR;
190 cp_rpw_sc_rw3_rw4_f_flags = INIT_CHAR;
191
192 189 // initialize filtering parameters
193 190 filterPar.spare_sy_lfr_pas_filter_enabled = DEFAULT_SY_LFR_PAS_FILTER_ENABLED;
194 191 filterPar.sy_lfr_pas_filter_modulus = DEFAULT_SY_LFR_PAS_FILTER_MODULUS;
195 192 filterPar.sy_lfr_pas_filter_tbad = DEFAULT_SY_LFR_PAS_FILTER_TBAD;
196 193 filterPar.sy_lfr_pas_filter_offset = DEFAULT_SY_LFR_PAS_FILTER_OFFSET;
197 194 filterPar.sy_lfr_pas_filter_shift = DEFAULT_SY_LFR_PAS_FILTER_SHIFT;
198 195 filterPar.sy_lfr_sc_rw_delta_f = DEFAULT_SY_LFR_SC_RW_DELTA_F;
199 196 update_last_valid_transition_date( DEFAULT_LAST_VALID_TRANSITION_DATE );
200 197
201 198 // waveform picker initialization
202 199 WFP_init_rings();
203 200 LEON_Clear_interrupt( IRQ_SPARC_GPTIMER_WATCHDOG ); // initialize the waveform rings
204 201 WFP_reset_current_ring_nodes();
205 202 reset_waveform_picker_regs();
206 203
207 204 // spectral matrices initialization
208 205 SM_init_rings(); // initialize spectral matrices rings
209 206 SM_reset_current_ring_nodes();
210 207 reset_spectral_matrix_regs();
211 208
212 209 // configure calibration
213 210 configureCalibration( false ); // true means interleaved mode, false is for normal mode
214 211
215 212 updateLFRCurrentMode( LFR_MODE_STANDBY );
216 213
217 214 BOOT_PRINTF1("in INIT *** lfrCurrentMode is %d\n", lfrCurrentMode)
218 215
219 216 create_names(); // create all names
220 217
221 218 status = create_timecode_timer(); // create the timer used by timecode_irq_handler
222 219 if (status != RTEMS_SUCCESSFUL)
223 220 {
224 221 PRINTF1("in INIT *** ERR in create_timer_timecode, code %d", status)
225 222 }
226 223
227 224 status = create_message_queues(); // create message queues
228 225 if (status != RTEMS_SUCCESSFUL)
229 226 {
230 227 PRINTF1("in INIT *** ERR in create_message_queues, code %d", status)
231 228 }
232 229
233 230 status = create_all_tasks(); // create all tasks
234 231 if (status != RTEMS_SUCCESSFUL)
235 232 {
236 233 PRINTF1("in INIT *** ERR in create_all_tasks, code %d\n", status)
237 234 }
238 235
239 236 // **************************
240 237 // <SPACEWIRE INITIALIZATION>
241 238 status_spw = spacewire_open_link(); // (1) open the link
242 239 if ( status_spw != RTEMS_SUCCESSFUL )
243 240 {
244 241 PRINTF1("in INIT *** ERR spacewire_open_link code %d\n", status_spw )
245 242 }
246 243
247 244 if ( status_spw == RTEMS_SUCCESSFUL ) // (2) configure the link
248 245 {
249 246 status_spw = spacewire_configure_link( fdSPW );
250 247 if ( status_spw != RTEMS_SUCCESSFUL )
251 248 {
252 249 PRINTF1("in INIT *** ERR spacewire_configure_link code %d\n", status_spw )
253 250 }
254 251 }
255 252
256 253 if ( status_spw == RTEMS_SUCCESSFUL) // (3) start the link
257 254 {
258 255 status_spw = spacewire_start_link( fdSPW );
259 256 if ( status_spw != RTEMS_SUCCESSFUL )
260 257 {
261 258 PRINTF1("in INIT *** ERR spacewire_start_link code %d\n", status_spw )
262 259 }
263 260 }
264 261 // </SPACEWIRE INITIALIZATION>
265 262 // ***************************
266 263
267 264 status = start_all_tasks(); // start all tasks
268 265 if (status != RTEMS_SUCCESSFUL)
269 266 {
270 267 PRINTF1("in INIT *** ERR in start_all_tasks, code %d", status)
271 268 }
272 269
273 270 // start RECV and SEND *AFTER* SpaceWire Initialization, due to the timeout of the start call during the initialization
274 271 status = start_recv_send_tasks();
275 272 if ( status != RTEMS_SUCCESSFUL )
276 273 {
277 274 PRINTF1("in INIT *** ERR start_recv_send_tasks code %d\n", status )
278 275 }
279 276
280 277 // suspend science tasks, they will be restarted later depending on the mode
281 278 status = suspend_science_tasks(); // suspend science tasks (not done in stop_current_mode if current mode = STANDBY)
282 279 if (status != RTEMS_SUCCESSFUL)
283 280 {
284 281 PRINTF1("in INIT *** in suspend_science_tasks *** ERR code: %d\n", status)
285 282 }
286 283
287 284 // configure IRQ handling for the waveform picker unit
288 285 status = rtems_interrupt_catch( waveforms_isr,
289 286 IRQ_SPARC_WAVEFORM_PICKER,
290 287 &old_isr_handler) ;
291 288 // configure IRQ handling for the spectral matrices unit
292 289 status = rtems_interrupt_catch( spectral_matrices_isr,
293 290 IRQ_SPARC_SPECTRAL_MATRIX,
294 291 &old_isr_handler) ;
295 292
296 293 // if the spacewire link is not up then send an event to the SPIQ task for link recovery
297 294 if ( status_spw != RTEMS_SUCCESSFUL )
298 295 {
299 296 status = rtems_event_send( Task_id[TASKID_SPIQ], SPW_LINKERR_EVENT );
300 297 if ( status != RTEMS_SUCCESSFUL ) {
301 298 PRINTF1("in INIT *** ERR rtems_event_send to SPIQ code %d\n", status )
302 299 }
303 300 }
304 301
305 302 BOOT_PRINTF("delete INIT\n")
306 303
307 304 set_hk_lfr_sc_potential_flag( true );
308 305
309 306 // start the timer to detect a missing spacewire timecode
310 307 // the timeout is larger because the spw IP needs to receive several valid timecodes before generating a tickout
311 308 // if a tickout is generated, the timer is restarted
312 309 status = rtems_timer_fire_after( timecode_timer_id, TIMECODE_TIMER_TIMEOUT_INIT, timecode_timer_routine, NULL );
313 310
314 311 grspw_timecode_callback = &timecode_irq_handler;
315 312
316 313 status = rtems_task_delete(RTEMS_SELF);
317 314
318 315 }
319 316
320 317 void init_local_mode_parameters( void )
321 318 {
322 319 /** This function initialize the param_local global variable with default values.
323 320 *
324 321 */
325 322
326 323 unsigned int i;
327 324
328 325 // LOCAL PARAMETERS
329 326
330 327 BOOT_PRINTF1("local_sbm1_nb_cwf_max %d \n", param_local.local_sbm1_nb_cwf_max)
331 328 BOOT_PRINTF1("local_sbm2_nb_cwf_max %d \n", param_local.local_sbm2_nb_cwf_max)
332 329
333 330 // init sequence counters
334 331
335 332 for(i = 0; i<SEQ_CNT_NB_DEST_ID; i++)
336 333 {
337 334 sequenceCounters_TC_EXE[i] = INIT_CHAR;
338 335 sequenceCounters_TM_DUMP[i] = INIT_CHAR;
339 336 }
340 337 sequenceCounters_SCIENCE_NORMAL_BURST = INIT_CHAR;
341 338 sequenceCounters_SCIENCE_SBM1_SBM2 = INIT_CHAR;
342 339 sequenceCounterHK = TM_PACKET_SEQ_CTRL_STANDALONE << TM_PACKET_SEQ_SHIFT;
343 340 }
344 341
345 342 void reset_local_time( void )
346 343 {
347 344 time_management_regs->ctrl = time_management_regs->ctrl | VAL_SOFTWARE_RESET; // [0010] software reset, coarse time = 0x80000000
348 345 }
349 346
350 347 void create_names( void ) // create all names for tasks and queues
351 348 {
352 349 /** This function creates all RTEMS names used in the software for tasks and queues.
353 350 *
354 351 * @return RTEMS directive status codes:
355 352 * - RTEMS_SUCCESSFUL - successful completion
356 353 *
357 354 */
358 355
359 356 // task names
360 357 Task_name[TASKID_AVGV] = rtems_build_name( 'A', 'V', 'G', 'V' );
361 358 Task_name[TASKID_RECV] = rtems_build_name( 'R', 'E', 'C', 'V' );
362 359 Task_name[TASKID_ACTN] = rtems_build_name( 'A', 'C', 'T', 'N' );
363 360 Task_name[TASKID_SPIQ] = rtems_build_name( 'S', 'P', 'I', 'Q' );
364 361 Task_name[TASKID_LOAD] = rtems_build_name( 'L', 'O', 'A', 'D' );
365 362 Task_name[TASKID_AVF0] = rtems_build_name( 'A', 'V', 'F', '0' );
366 363 Task_name[TASKID_SWBD] = rtems_build_name( 'S', 'W', 'B', 'D' );
367 364 Task_name[TASKID_WFRM] = rtems_build_name( 'W', 'F', 'R', 'M' );
368 365 Task_name[TASKID_DUMB] = rtems_build_name( 'D', 'U', 'M', 'B' );
369 366 Task_name[TASKID_HOUS] = rtems_build_name( 'H', 'O', 'U', 'S' );
370 367 Task_name[TASKID_PRC0] = rtems_build_name( 'P', 'R', 'C', '0' );
371 368 Task_name[TASKID_CWF3] = rtems_build_name( 'C', 'W', 'F', '3' );
372 369 Task_name[TASKID_CWF2] = rtems_build_name( 'C', 'W', 'F', '2' );
373 370 Task_name[TASKID_CWF1] = rtems_build_name( 'C', 'W', 'F', '1' );
374 371 Task_name[TASKID_SEND] = rtems_build_name( 'S', 'E', 'N', 'D' );
375 372 Task_name[TASKID_LINK] = rtems_build_name( 'L', 'I', 'N', 'K' );
376 373 Task_name[TASKID_AVF1] = rtems_build_name( 'A', 'V', 'F', '1' );
377 374 Task_name[TASKID_PRC1] = rtems_build_name( 'P', 'R', 'C', '1' );
378 375 Task_name[TASKID_AVF2] = rtems_build_name( 'A', 'V', 'F', '2' );
379 376 Task_name[TASKID_PRC2] = rtems_build_name( 'P', 'R', 'C', '2' );
380 377
381 378 // rate monotonic period names
382 379 name_hk_rate_monotonic = rtems_build_name( 'H', 'O', 'U', 'S' );
383 380 name_avgv_rate_monotonic = rtems_build_name( 'A', 'V', 'G', 'V' );
384 381
385 382 misc_name[QUEUE_RECV] = rtems_build_name( 'Q', '_', 'R', 'V' );
386 383 misc_name[QUEUE_SEND] = rtems_build_name( 'Q', '_', 'S', 'D' );
387 384 misc_name[QUEUE_PRC0] = rtems_build_name( 'Q', '_', 'P', '0' );
388 385 misc_name[QUEUE_PRC1] = rtems_build_name( 'Q', '_', 'P', '1' );
389 386 misc_name[QUEUE_PRC2] = rtems_build_name( 'Q', '_', 'P', '2' );
390 387
391 388 timecode_timer_name = rtems_build_name( 'S', 'P', 'T', 'C' );
392 389 }
393 390
394 391 int create_all_tasks( void ) // create all tasks which run in the software
395 392 {
396 393 /** This function creates all RTEMS tasks used in the software.
397 394 *
398 395 * @return RTEMS directive status codes:
399 396 * - RTEMS_SUCCESSFUL - task created successfully
400 397 * - RTEMS_INVALID_ADDRESS - id is NULL
401 398 * - RTEMS_INVALID_NAME - invalid task name
402 399 * - RTEMS_INVALID_PRIORITY - invalid task priority
403 400 * - RTEMS_MP_NOT_CONFIGURED - multiprocessing not configured
404 401 * - RTEMS_TOO_MANY - too many tasks created
405 402 * - RTEMS_UNSATISFIED - not enough memory for stack/FP context
406 403 * - RTEMS_TOO_MANY - too many global objects
407 404 *
408 405 */
409 406
410 407 rtems_status_code status;
411 408
412 409 //**********
413 410 // SPACEWIRE
414 411 // RECV
415 412 status = rtems_task_create(
416 413 Task_name[TASKID_RECV], TASK_PRIORITY_RECV, RTEMS_MINIMUM_STACK_SIZE,
417 414 RTEMS_DEFAULT_MODES,
418 415 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_RECV]
419 416 );
420 417 if (status == RTEMS_SUCCESSFUL) // SEND
421 418 {
422 419 status = rtems_task_create(
423 420 Task_name[TASKID_SEND], TASK_PRIORITY_SEND, RTEMS_MINIMUM_STACK_SIZE * STACK_SIZE_MULT,
424 421 RTEMS_DEFAULT_MODES,
425 422 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SEND]
426 423 );
427 424 }
428 425 if (status == RTEMS_SUCCESSFUL) // LINK
429 426 {
430 427 status = rtems_task_create(
431 428 Task_name[TASKID_LINK], TASK_PRIORITY_LINK, RTEMS_MINIMUM_STACK_SIZE,
432 429 RTEMS_DEFAULT_MODES,
433 430 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_LINK]
434 431 );
435 432 }
436 433 if (status == RTEMS_SUCCESSFUL) // ACTN
437 434 {
438 435 status = rtems_task_create(
439 436 Task_name[TASKID_ACTN], TASK_PRIORITY_ACTN, RTEMS_MINIMUM_STACK_SIZE,
440 437 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
441 438 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_ACTN]
442 439 );
443 440 }
444 441 if (status == RTEMS_SUCCESSFUL) // SPIQ
445 442 {
446 443 status = rtems_task_create(
447 444 Task_name[TASKID_SPIQ], TASK_PRIORITY_SPIQ, RTEMS_MINIMUM_STACK_SIZE,
448 445 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
449 446 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SPIQ]
450 447 );
451 448 }
452 449
453 450 //******************
454 451 // SPECTRAL MATRICES
455 452 if (status == RTEMS_SUCCESSFUL) // AVF0
456 453 {
457 454 status = rtems_task_create(
458 455 Task_name[TASKID_AVF0], TASK_PRIORITY_AVF0, RTEMS_MINIMUM_STACK_SIZE,
459 456 RTEMS_DEFAULT_MODES,
460 457 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF0]
461 458 );
462 459 }
463 460 if (status == RTEMS_SUCCESSFUL) // PRC0
464 461 {
465 462 status = rtems_task_create(
466 463 Task_name[TASKID_PRC0], TASK_PRIORITY_PRC0, RTEMS_MINIMUM_STACK_SIZE * STACK_SIZE_MULT,
467 464 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
468 465 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC0]
469 466 );
470 467 }
471 468 if (status == RTEMS_SUCCESSFUL) // AVF1
472 469 {
473 470 status = rtems_task_create(
474 471 Task_name[TASKID_AVF1], TASK_PRIORITY_AVF1, RTEMS_MINIMUM_STACK_SIZE,
475 472 RTEMS_DEFAULT_MODES,
476 473 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF1]
477 474 );
478 475 }
479 476 if (status == RTEMS_SUCCESSFUL) // PRC1
480 477 {
481 478 status = rtems_task_create(
482 479 Task_name[TASKID_PRC1], TASK_PRIORITY_PRC1, RTEMS_MINIMUM_STACK_SIZE * STACK_SIZE_MULT,
483 480 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
484 481 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC1]
485 482 );
486 483 }
487 484 if (status == RTEMS_SUCCESSFUL) // AVF2
488 485 {
489 486 status = rtems_task_create(
490 487 Task_name[TASKID_AVF2], TASK_PRIORITY_AVF2, RTEMS_MINIMUM_STACK_SIZE,
491 488 RTEMS_DEFAULT_MODES,
492 489 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF2]
493 490 );
494 491 }
495 492 if (status == RTEMS_SUCCESSFUL) // PRC2
496 493 {
497 494 status = rtems_task_create(
498 495 Task_name[TASKID_PRC2], TASK_PRIORITY_PRC2, RTEMS_MINIMUM_STACK_SIZE * STACK_SIZE_MULT,
499 496 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
500 497 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC2]
501 498 );
502 499 }
503 500
504 501 //****************
505 502 // WAVEFORM PICKER
506 503 if (status == RTEMS_SUCCESSFUL) // WFRM
507 504 {
508 505 status = rtems_task_create(
509 506 Task_name[TASKID_WFRM], TASK_PRIORITY_WFRM, RTEMS_MINIMUM_STACK_SIZE,
510 507 RTEMS_DEFAULT_MODES,
511 508 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_WFRM]
512 509 );
513 510 }
514 511 if (status == RTEMS_SUCCESSFUL) // CWF3
515 512 {
516 513 status = rtems_task_create(
517 514 Task_name[TASKID_CWF3], TASK_PRIORITY_CWF3, RTEMS_MINIMUM_STACK_SIZE,
518 515 RTEMS_DEFAULT_MODES,
519 516 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF3]
520 517 );
521 518 }
522 519 if (status == RTEMS_SUCCESSFUL) // CWF2
523 520 {
524 521 status = rtems_task_create(
525 522 Task_name[TASKID_CWF2], TASK_PRIORITY_CWF2, RTEMS_MINIMUM_STACK_SIZE,
526 523 RTEMS_DEFAULT_MODES,
527 524 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF2]
528 525 );
529 526 }
530 527 if (status == RTEMS_SUCCESSFUL) // CWF1
531 528 {
532 529 status = rtems_task_create(
533 530 Task_name[TASKID_CWF1], TASK_PRIORITY_CWF1, RTEMS_MINIMUM_STACK_SIZE,
534 531 RTEMS_DEFAULT_MODES,
535 532 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF1]
536 533 );
537 534 }
538 535 if (status == RTEMS_SUCCESSFUL) // SWBD
539 536 {
540 537 status = rtems_task_create(
541 538 Task_name[TASKID_SWBD], TASK_PRIORITY_SWBD, RTEMS_MINIMUM_STACK_SIZE,
542 539 RTEMS_DEFAULT_MODES,
543 540 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SWBD]
544 541 );
545 542 }
546 543
547 544 //*****
548 545 // MISC
549 546 if (status == RTEMS_SUCCESSFUL) // LOAD
550 547 {
551 548 status = rtems_task_create(
552 549 Task_name[TASKID_LOAD], TASK_PRIORITY_LOAD, RTEMS_MINIMUM_STACK_SIZE,
553 550 RTEMS_DEFAULT_MODES,
554 551 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_LOAD]
555 552 );
556 553 }
557 554 if (status == RTEMS_SUCCESSFUL) // DUMB
558 555 {
559 556 status = rtems_task_create(
560 557 Task_name[TASKID_DUMB], TASK_PRIORITY_DUMB, RTEMS_MINIMUM_STACK_SIZE,
561 558 RTEMS_DEFAULT_MODES,
562 559 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_DUMB]
563 560 );
564 561 }
565 562 if (status == RTEMS_SUCCESSFUL) // HOUS
566 563 {
567 564 status = rtems_task_create(
568 565 Task_name[TASKID_HOUS], TASK_PRIORITY_HOUS, RTEMS_MINIMUM_STACK_SIZE,
569 566 RTEMS_DEFAULT_MODES,
570 567 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_HOUS]
571 568 );
572 569 }
573 570 if (status == RTEMS_SUCCESSFUL) // AVGV
574 571 {
575 572 status = rtems_task_create(
576 573 Task_name[TASKID_AVGV], TASK_PRIORITY_AVGV, RTEMS_MINIMUM_STACK_SIZE,
577 574 RTEMS_DEFAULT_MODES,
578 575 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVGV]
579 576 );
580 577 }
581 578
582 579 return status;
583 580 }
584 581
585 582 int start_recv_send_tasks( void )
586 583 {
587 584 rtems_status_code status;
588 585
589 586 status = rtems_task_start( Task_id[TASKID_RECV], recv_task, 1 );
590 587 if (status!=RTEMS_SUCCESSFUL) {
591 588 BOOT_PRINTF("in INIT *** Error starting TASK_RECV\n")
592 589 }
593 590
594 591 if (status == RTEMS_SUCCESSFUL) // SEND
595 592 {
596 593 status = rtems_task_start( Task_id[TASKID_SEND], send_task, 1 );
597 594 if (status!=RTEMS_SUCCESSFUL) {
598 595 BOOT_PRINTF("in INIT *** Error starting TASK_SEND\n")
599 596 }
600 597 }
601 598
602 599 return status;
603 600 }
604 601
605 602 int start_all_tasks( void ) // start all tasks except SEND RECV and HOUS
606 603 {
607 604 /** This function starts all RTEMS tasks used in the software.
608 605 *
609 606 * @return RTEMS directive status codes:
610 607 * - RTEMS_SUCCESSFUL - ask started successfully
611 608 * - RTEMS_INVALID_ADDRESS - invalid task entry point
612 609 * - RTEMS_INVALID_ID - invalid task id
613 610 * - RTEMS_INCORRECT_STATE - task not in the dormant state
614 611 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot start remote task
615 612 *
616 613 */
617 614 // starts all the tasks fot eh flight software
618 615
619 616 rtems_status_code status;
620 617
621 618 //**********
622 619 // SPACEWIRE
623 620 status = rtems_task_start( Task_id[TASKID_SPIQ], spiq_task, 1 );
624 621 if (status!=RTEMS_SUCCESSFUL) {
625 622 BOOT_PRINTF("in INIT *** Error starting TASK_SPIQ\n")
626 623 }
627 624
628 625 if (status == RTEMS_SUCCESSFUL) // LINK
629 626 {
630 627 status = rtems_task_start( Task_id[TASKID_LINK], link_task, 1 );
631 628 if (status!=RTEMS_SUCCESSFUL) {
632 629 BOOT_PRINTF("in INIT *** Error starting TASK_LINK\n")
633 630 }
634 631 }
635 632
636 633 if (status == RTEMS_SUCCESSFUL) // ACTN
637 634 {
638 635 status = rtems_task_start( Task_id[TASKID_ACTN], actn_task, 1 );
639 636 if (status!=RTEMS_SUCCESSFUL) {
640 637 BOOT_PRINTF("in INIT *** Error starting TASK_ACTN\n")
641 638 }
642 639 }
643 640
644 641 //******************
645 642 // SPECTRAL MATRICES
646 643 if (status == RTEMS_SUCCESSFUL) // AVF0
647 644 {
648 645 status = rtems_task_start( Task_id[TASKID_AVF0], avf0_task, LFR_MODE_STANDBY );
649 646 if (status!=RTEMS_SUCCESSFUL) {
650 647 BOOT_PRINTF("in INIT *** Error starting TASK_AVF0\n")
651 648 }
652 649 }
653 650 if (status == RTEMS_SUCCESSFUL) // PRC0
654 651 {
655 652 status = rtems_task_start( Task_id[TASKID_PRC0], prc0_task, LFR_MODE_STANDBY );
656 653 if (status!=RTEMS_SUCCESSFUL) {
657 654 BOOT_PRINTF("in INIT *** Error starting TASK_PRC0\n")
658 655 }
659 656 }
660 657 if (status == RTEMS_SUCCESSFUL) // AVF1
661 658 {
662 659 status = rtems_task_start( Task_id[TASKID_AVF1], avf1_task, LFR_MODE_STANDBY );
663 660 if (status!=RTEMS_SUCCESSFUL) {
664 661 BOOT_PRINTF("in INIT *** Error starting TASK_AVF1\n")
665 662 }
666 663 }
667 664 if (status == RTEMS_SUCCESSFUL) // PRC1
668 665 {
669 666 status = rtems_task_start( Task_id[TASKID_PRC1], prc1_task, LFR_MODE_STANDBY );
670 667 if (status!=RTEMS_SUCCESSFUL) {
671 668 BOOT_PRINTF("in INIT *** Error starting TASK_PRC1\n")
672 669 }
673 670 }
674 671 if (status == RTEMS_SUCCESSFUL) // AVF2
675 672 {
676 673 status = rtems_task_start( Task_id[TASKID_AVF2], avf2_task, 1 );
677 674 if (status!=RTEMS_SUCCESSFUL) {
678 675 BOOT_PRINTF("in INIT *** Error starting TASK_AVF2\n")
679 676 }
680 677 }
681 678 if (status == RTEMS_SUCCESSFUL) // PRC2
682 679 {
683 680 status = rtems_task_start( Task_id[TASKID_PRC2], prc2_task, 1 );
684 681 if (status!=RTEMS_SUCCESSFUL) {
685 682 BOOT_PRINTF("in INIT *** Error starting TASK_PRC2\n")
686 683 }
687 684 }
688 685
689 686 //****************
690 687 // WAVEFORM PICKER
691 688 if (status == RTEMS_SUCCESSFUL) // WFRM
692 689 {
693 690 status = rtems_task_start( Task_id[TASKID_WFRM], wfrm_task, 1 );
694 691 if (status!=RTEMS_SUCCESSFUL) {
695 692 BOOT_PRINTF("in INIT *** Error starting TASK_WFRM\n")
696 693 }
697 694 }
698 695 if (status == RTEMS_SUCCESSFUL) // CWF3
699 696 {
700 697 status = rtems_task_start( Task_id[TASKID_CWF3], cwf3_task, 1 );
701 698 if (status!=RTEMS_SUCCESSFUL) {
702 699 BOOT_PRINTF("in INIT *** Error starting TASK_CWF3\n")
703 700 }
704 701 }
705 702 if (status == RTEMS_SUCCESSFUL) // CWF2
706 703 {
707 704 status = rtems_task_start( Task_id[TASKID_CWF2], cwf2_task, 1 );
708 705 if (status!=RTEMS_SUCCESSFUL) {
709 706 BOOT_PRINTF("in INIT *** Error starting TASK_CWF2\n")
710 707 }
711 708 }
712 709 if (status == RTEMS_SUCCESSFUL) // CWF1
713 710 {
714 711 status = rtems_task_start( Task_id[TASKID_CWF1], cwf1_task, 1 );
715 712 if (status!=RTEMS_SUCCESSFUL) {
716 713 BOOT_PRINTF("in INIT *** Error starting TASK_CWF1\n")
717 714 }
718 715 }
719 716 if (status == RTEMS_SUCCESSFUL) // SWBD
720 717 {
721 718 status = rtems_task_start( Task_id[TASKID_SWBD], swbd_task, 1 );
722 719 if (status!=RTEMS_SUCCESSFUL) {
723 720 BOOT_PRINTF("in INIT *** Error starting TASK_SWBD\n")
724 721 }
725 722 }
726 723
727 724 //*****
728 725 // MISC
729 726 if (status == RTEMS_SUCCESSFUL) // HOUS
730 727 {
731 728 status = rtems_task_start( Task_id[TASKID_HOUS], hous_task, 1 );
732 729 if (status!=RTEMS_SUCCESSFUL) {
733 730 BOOT_PRINTF("in INIT *** Error starting TASK_HOUS\n")
734 731 }
735 732 }
736 733 if (status == RTEMS_SUCCESSFUL) // AVGV
737 734 {
738 735 status = rtems_task_start( Task_id[TASKID_AVGV], avgv_task, 1 );
739 736 if (status!=RTEMS_SUCCESSFUL) {
740 737 BOOT_PRINTF("in INIT *** Error starting TASK_AVGV\n")
741 738 }
742 739 }
743 740 if (status == RTEMS_SUCCESSFUL) // DUMB
744 741 {
745 742 status = rtems_task_start( Task_id[TASKID_DUMB], dumb_task, 1 );
746 743 if (status!=RTEMS_SUCCESSFUL) {
747 744 BOOT_PRINTF("in INIT *** Error starting TASK_DUMB\n")
748 745 }
749 746 }
750 747 if (status == RTEMS_SUCCESSFUL) // LOAD
751 748 {
752 749 status = rtems_task_start( Task_id[TASKID_LOAD], load_task, 1 );
753 750 if (status!=RTEMS_SUCCESSFUL) {
754 751 BOOT_PRINTF("in INIT *** Error starting TASK_LOAD\n")
755 752 }
756 753 }
757 754
758 755 return status;
759 756 }
760 757
761 758 rtems_status_code create_message_queues( void ) // create the two message queues used in the software
762 759 {
763 760 rtems_status_code status_recv;
764 761 rtems_status_code status_send;
765 762 rtems_status_code status_q_p0;
766 763 rtems_status_code status_q_p1;
767 764 rtems_status_code status_q_p2;
768 765 rtems_status_code ret;
769 766 rtems_id queue_id;
770 767
771 768 ret = RTEMS_SUCCESSFUL;
772 769 queue_id = RTEMS_ID_NONE;
773 770
774 771 //****************************************
775 772 // create the queue for handling valid TCs
776 773 status_recv = rtems_message_queue_create( misc_name[QUEUE_RECV],
777 774 MSG_QUEUE_COUNT_RECV, CCSDS_TC_PKT_MAX_SIZE,
778 775 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
779 776 if ( status_recv != RTEMS_SUCCESSFUL ) {
780 777 PRINTF1("in create_message_queues *** ERR creating QUEU queue, %d\n", status_recv)
781 778 }
782 779
783 780 //************************************************
784 781 // create the queue for handling TM packet sending
785 782 status_send = rtems_message_queue_create( misc_name[QUEUE_SEND],
786 783 MSG_QUEUE_COUNT_SEND, MSG_QUEUE_SIZE_SEND,
787 784 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
788 785 if ( status_send != RTEMS_SUCCESSFUL ) {
789 786 PRINTF1("in create_message_queues *** ERR creating PKTS queue, %d\n", status_send)
790 787 }
791 788
792 789 //*****************************************************************************
793 790 // create the queue for handling averaged spectral matrices for processing @ f0
794 791 status_q_p0 = rtems_message_queue_create( misc_name[QUEUE_PRC0],
795 792 MSG_QUEUE_COUNT_PRC0, MSG_QUEUE_SIZE_PRC0,
796 793 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
797 794 if ( status_q_p0 != RTEMS_SUCCESSFUL ) {
798 795 PRINTF1("in create_message_queues *** ERR creating Q_P0 queue, %d\n", status_q_p0)
799 796 }
800 797
801 798 //*****************************************************************************
802 799 // create the queue for handling averaged spectral matrices for processing @ f1
803 800 status_q_p1 = rtems_message_queue_create( misc_name[QUEUE_PRC1],
804 801 MSG_QUEUE_COUNT_PRC1, MSG_QUEUE_SIZE_PRC1,
805 802 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
806 803 if ( status_q_p1 != RTEMS_SUCCESSFUL ) {
807 804 PRINTF1("in create_message_queues *** ERR creating Q_P1 queue, %d\n", status_q_p1)
808 805 }
809 806
810 807 //*****************************************************************************
811 808 // create the queue for handling averaged spectral matrices for processing @ f2
812 809 status_q_p2 = rtems_message_queue_create( misc_name[QUEUE_PRC2],
813 810 MSG_QUEUE_COUNT_PRC2, MSG_QUEUE_SIZE_PRC2,
814 811 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
815 812 if ( status_q_p2 != RTEMS_SUCCESSFUL ) {
816 813 PRINTF1("in create_message_queues *** ERR creating Q_P2 queue, %d\n", status_q_p2)
817 814 }
818 815
819 816 if ( status_recv != RTEMS_SUCCESSFUL )
820 817 {
821 818 ret = status_recv;
822 819 }
823 820 else if( status_send != RTEMS_SUCCESSFUL )
824 821 {
825 822 ret = status_send;
826 823 }
827 824 else if( status_q_p0 != RTEMS_SUCCESSFUL )
828 825 {
829 826 ret = status_q_p0;
830 827 }
831 828 else if( status_q_p1 != RTEMS_SUCCESSFUL )
832 829 {
833 830 ret = status_q_p1;
834 831 }
835 832 else
836 833 {
837 834 ret = status_q_p2;
838 835 }
839 836
840 837 return ret;
841 838 }
842 839
843 840 rtems_status_code create_timecode_timer( void )
844 841 {
845 842 rtems_status_code status;
846 843
847 844 status = rtems_timer_create( timecode_timer_name, &timecode_timer_id );
848 845
849 846 if ( status != RTEMS_SUCCESSFUL )
850 847 {
851 848 PRINTF1("in create_timer_timecode *** ERR creating SPTC timer, %d\n", status)
852 849 }
853 850 else
854 851 {
855 852 PRINTF("in create_timer_timecode *** OK creating SPTC timer\n")
856 853 }
857 854
858 855 return status;
859 856 }
860 857
861 858 rtems_status_code get_message_queue_id_send( rtems_id *queue_id )
862 859 {
863 860 rtems_status_code status;
864 861 rtems_name queue_name;
865 862
866 863 queue_name = rtems_build_name( 'Q', '_', 'S', 'D' );
867 864
868 865 status = rtems_message_queue_ident( queue_name, 0, queue_id );
869 866
870 867 return status;
871 868 }
872 869
873 870 rtems_status_code get_message_queue_id_recv( rtems_id *queue_id )
874 871 {
875 872 rtems_status_code status;
876 873 rtems_name queue_name;
877 874
878 875 queue_name = rtems_build_name( 'Q', '_', 'R', 'V' );
879 876
880 877 status = rtems_message_queue_ident( queue_name, 0, queue_id );
881 878
882 879 return status;
883 880 }
884 881
885 882 rtems_status_code get_message_queue_id_prc0( rtems_id *queue_id )
886 883 {
887 884 rtems_status_code status;
888 885 rtems_name queue_name;
889 886
890 887 queue_name = rtems_build_name( 'Q', '_', 'P', '0' );
891 888
892 889 status = rtems_message_queue_ident( queue_name, 0, queue_id );
893 890
894 891 return status;
895 892 }
896 893
897 894 rtems_status_code get_message_queue_id_prc1( rtems_id *queue_id )
898 895 {
899 896 rtems_status_code status;
900 897 rtems_name queue_name;
901 898
902 899 queue_name = rtems_build_name( 'Q', '_', 'P', '1' );
903 900
904 901 status = rtems_message_queue_ident( queue_name, 0, queue_id );
905 902
906 903 return status;
907 904 }
908 905
909 906 rtems_status_code get_message_queue_id_prc2( rtems_id *queue_id )
910 907 {
911 908 rtems_status_code status;
912 909 rtems_name queue_name;
913 910
914 911 queue_name = rtems_build_name( 'Q', '_', 'P', '2' );
915 912
916 913 status = rtems_message_queue_ident( queue_name, 0, queue_id );
917 914
918 915 return status;
919 916 }
920 917
921 918 void update_queue_max_count( rtems_id queue_id, unsigned char*fifo_size_max )
922 919 {
923 920 u_int32_t count;
924 921 rtems_status_code status;
925 922
926 923 count = 0;
927 924
928 925 status = rtems_message_queue_get_number_pending( queue_id, &count );
929 926
930 927 count = count + 1;
931 928
932 929 if (status != RTEMS_SUCCESSFUL)
933 930 {
934 931 PRINTF1("in update_queue_max_count *** ERR = %d\n", status)
935 932 }
936 933 else
937 934 {
938 935 if (count > *fifo_size_max)
939 936 {
940 937 *fifo_size_max = count;
941 938 }
942 939 }
943 940 }
944 941
945 942 void init_ring(ring_node ring[], unsigned char nbNodes, volatile int buffer[], unsigned int bufferSize )
946 943 {
947 944 unsigned char i;
948 945
949 946 //***************
950 947 // BUFFER ADDRESS
951 948 for(i=0; i<nbNodes; i++)
952 949 {
953 950 ring[i].coarseTime = INT32_ALL_F;
954 951 ring[i].fineTime = INT32_ALL_F;
955 952 ring[i].sid = INIT_CHAR;
956 953 ring[i].status = INIT_CHAR;
957 954 ring[i].buffer_address = (int) &buffer[ i * bufferSize ];
958 955 }
959 956
960 957 //*****
961 958 // NEXT
962 959 ring[ nbNodes - 1 ].next = (ring_node*) &ring[ 0 ];
963 960 for(i=0; i<nbNodes-1; i++)
964 961 {
965 962 ring[i].next = (ring_node*) &ring[ i + 1 ];
966 963 }
967 964
968 965 //*********
969 966 // PREVIOUS
970 967 ring[ 0 ].previous = (ring_node*) &ring[ nbNodes - 1 ];
971 968 for(i=1; i<nbNodes; i++)
972 969 {
973 970 ring[i].previous = (ring_node*) &ring[ i - 1 ];
974 971 }
975 972 }
@@ -1,1004 +1,1001
1 1 /** General usage functions and RTEMS tasks.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 */
7 7
8 8 #include "fsw_misc.h"
9 9
10 10 int16_t hk_lfr_sc_v_f3_as_int16 = 0;
11 11 int16_t hk_lfr_sc_e1_f3_as_int16 = 0;
12 12 int16_t hk_lfr_sc_e2_f3_as_int16 = 0;
13 13
14 14 void timer_configure(unsigned char timer, unsigned int clock_divider,
15 15 unsigned char interrupt_level, rtems_isr (*timer_isr)() )
16 16 {
17 17 /** This function configures a GPTIMER timer instantiated in the VHDL design.
18 18 *
19 19 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
20 20 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
21 21 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
22 22 * @param interrupt_level is the interrupt level that the timer drives.
23 23 * @param timer_isr is the interrupt subroutine that will be attached to the IRQ driven by the timer.
24 24 *
25 25 * Interrupt levels are described in the SPARC documentation sparcv8.pdf p.76
26 26 *
27 27 */
28 28
29 29 rtems_status_code status;
30 30 rtems_isr_entry old_isr_handler;
31 31
32 32 old_isr_handler = NULL;
33 33
34 34 gptimer_regs->timer[timer].ctrl = INIT_CHAR; // reset the control register
35 35
36 36 status = rtems_interrupt_catch( timer_isr, interrupt_level, &old_isr_handler) ; // see sparcv8.pdf p.76 for interrupt levels
37 37 if (status!=RTEMS_SUCCESSFUL)
38 38 {
39 39 PRINTF("in configure_timer *** ERR rtems_interrupt_catch\n")
40 40 }
41 41
42 42 timer_set_clock_divider( timer, clock_divider);
43 43 }
44 44
45 45 void timer_start(unsigned char timer)
46 46 {
47 47 /** This function starts a GPTIMER timer.
48 48 *
49 49 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
50 50 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
51 51 *
52 52 */
53 53
54 54 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_CLEAR_IRQ;
55 55 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_LD;
56 56 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_EN;
57 57 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_RS;
58 58 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_IE;
59 59 }
60 60
61 61 void timer_stop(unsigned char timer)
62 62 {
63 63 /** This function stops a GPTIMER timer.
64 64 *
65 65 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
66 66 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
67 67 *
68 68 */
69 69
70 70 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & GPTIMER_EN_MASK;
71 71 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & GPTIMER_IE_MASK;
72 72 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | GPTIMER_CLEAR_IRQ;
73 73 }
74 74
75 75 void timer_set_clock_divider(unsigned char timer, unsigned int clock_divider)
76 76 {
77 77 /** This function sets the clock divider of a GPTIMER timer.
78 78 *
79 79 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
80 80 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
81 81 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
82 82 *
83 83 */
84 84
85 85 gptimer_regs->timer[timer].reload = clock_divider; // base clock frequency is 1 MHz
86 86 }
87 87
88 88 // WATCHDOG
89 89
90 90 rtems_isr watchdog_isr( rtems_vector_number vector )
91 91 {
92 92 rtems_status_code status_code;
93 93
94 94 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_12 );
95 95
96 96 PRINTF("watchdog_isr *** this is the end, exit(0)\n");
97 97
98 98 exit(0);
99 99 }
100 100
101 101 void watchdog_configure(void)
102 102 {
103 103 /** This function configure the watchdog.
104 104 *
105 105 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
106 106 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
107 107 *
108 108 * The watchdog is a timer provided by the GPTIMER IP core of the GRLIB.
109 109 *
110 110 */
111 111
112 112 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt during configuration
113 113
114 114 timer_configure( TIMER_WATCHDOG, CLKDIV_WATCHDOG, IRQ_SPARC_GPTIMER_WATCHDOG, watchdog_isr );
115 115
116 116 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
117 117 }
118 118
119 119 void watchdog_stop(void)
120 120 {
121 121 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt line
122 122 timer_stop( TIMER_WATCHDOG );
123 123 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
124 124 }
125 125
126 126 void watchdog_reload(void)
127 127 {
128 128 /** This function reloads the watchdog timer counter with the timer reload value.
129 129 *
130 130 * @param void
131 131 *
132 132 * @return void
133 133 *
134 134 */
135 135
136 136 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_LD;
137 137 }
138 138
139 139 void watchdog_start(void)
140 140 {
141 141 /** This function starts the watchdog timer.
142 142 *
143 143 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
144 144 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
145 145 *
146 146 */
147 147
148 148 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG );
149 149
150 150 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_CLEAR_IRQ;
151 151 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_LD;
152 152 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_EN;
153 153 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | GPTIMER_IE;
154 154
155 155 LEON_Unmask_interrupt( IRQ_GPTIMER_WATCHDOG );
156 156
157 157 }
158 158
159 159 int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register
160 160 {
161 161 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
162 162
163 163 apbuart_regs->ctrl = APBUART_CTRL_REG_MASK_TE;
164 164
165 165 return 0;
166 166 }
167 167
168 168 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value)
169 169 {
170 170 /** This function sets the scaler reload register of the apbuart module
171 171 *
172 172 * @param regs is the address of the apbuart registers in memory
173 173 * @param value is the value that will be stored in the scaler register
174 174 *
175 175 * The value shall be set by the software to get data on the serial interface.
176 176 *
177 177 */
178 178
179 179 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs;
180 180
181 181 apbuart_regs->scaler = value;
182 182
183 183 BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value)
184 184 }
185 185
186 186 //************
187 187 // RTEMS TASKS
188 188
189 189 rtems_task load_task(rtems_task_argument argument)
190 190 {
191 191 BOOT_PRINTF("in LOAD *** \n")
192 192
193 193 rtems_status_code status;
194 194 unsigned int i;
195 195 unsigned int j;
196 196 rtems_name name_watchdog_rate_monotonic; // name of the watchdog rate monotonic
197 197 rtems_id watchdog_period_id; // id of the watchdog rate monotonic period
198 198
199 199 watchdog_period_id = RTEMS_ID_NONE;
200 200
201 201 name_watchdog_rate_monotonic = rtems_build_name( 'L', 'O', 'A', 'D' );
202 202
203 203 status = rtems_rate_monotonic_create( name_watchdog_rate_monotonic, &watchdog_period_id );
204 204 if( status != RTEMS_SUCCESSFUL ) {
205 205 PRINTF1( "in LOAD *** rtems_rate_monotonic_create failed with status of %d\n", status )
206 206 }
207 207
208 208 i = 0;
209 209 j = 0;
210 210
211 211 watchdog_configure();
212 212
213 213 watchdog_start();
214 214
215 215 set_sy_lfr_watchdog_enabled( true );
216 216
217 217 while(1){
218 218 status = rtems_rate_monotonic_period( watchdog_period_id, WATCHDOG_PERIOD );
219 219 watchdog_reload();
220 220 i = i + 1;
221 221 if ( i == WATCHDOG_LOOP_PRINTF )
222 222 {
223 223 i = 0;
224 224 j = j + 1;
225 225 PRINTF1("%d\n", j)
226 226 }
227 227 #ifdef DEBUG_WATCHDOG
228 228 if (j == WATCHDOG_LOOP_DEBUG )
229 229 {
230 230 status = rtems_task_delete(RTEMS_SELF);
231 231 }
232 232 #endif
233 233 }
234 234 }
235 235
236 236 rtems_task hous_task(rtems_task_argument argument)
237 237 {
238 238 rtems_status_code status;
239 239 rtems_status_code spare_status;
240 240 rtems_id queue_id;
241 241 rtems_rate_monotonic_period_status period_status;
242 242 bool isSynchronized;
243 243
244 244 queue_id = RTEMS_ID_NONE;
245 245 memset(&period_status, 0, sizeof(rtems_rate_monotonic_period_status));
246 246 isSynchronized = false;
247 247
248 248 status = get_message_queue_id_send( &queue_id );
249 249 if (status != RTEMS_SUCCESSFUL)
250 250 {
251 251 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
252 252 }
253 253
254 254 BOOT_PRINTF("in HOUS ***\n");
255 255
256 256 if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
257 257 status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id );
258 258 if( status != RTEMS_SUCCESSFUL ) {
259 259 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status );
260 260 }
261 261 }
262 262
263 263 status = rtems_rate_monotonic_cancel(HK_id);
264 264 if( status != RTEMS_SUCCESSFUL ) {
265 265 PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status );
266 266 }
267 267 else {
268 268 DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n");
269 269 }
270 270
271 271 // startup phase
272 272 status = rtems_rate_monotonic_period( HK_id, SY_LFR_TIME_SYN_TIMEOUT_in_ticks );
273 273 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
274 274 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
275 275 while( (period_status.state != RATE_MONOTONIC_EXPIRED)
276 276 && (isSynchronized == false) ) // after SY_LFR_TIME_SYN_TIMEOUT ms, starts HK anyway
277 277 {
278 278 if ((time_management_regs->coarse_time & VAL_LFR_SYNCHRONIZED) == INT32_ALL_0) // check time synchronization
279 279 {
280 280 isSynchronized = true;
281 281 }
282 282 else
283 283 {
284 284 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
285 285
286 286 status = rtems_task_wake_after( HK_SYNC_WAIT ); // wait HK_SYNCH_WAIT 100 ms = 10 * 10 ms
287 287 }
288 288 }
289 289 status = rtems_rate_monotonic_cancel(HK_id);
290 290 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
291 291
292 292 set_hk_lfr_reset_cause( POWER_ON );
293 293
294 294 while(1){ // launch the rate monotonic task
295 295 status = rtems_rate_monotonic_period( HK_id, HK_PERIOD );
296 296 if ( status != RTEMS_SUCCESSFUL ) {
297 297 PRINTF1( "in HOUS *** ERR period: %d\n", status);
298 298 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 );
299 299 }
300 300 else {
301 301 housekeeping_packet.packetSequenceControl[BYTE_0] = (unsigned char) (sequenceCounterHK >> SHIFT_1_BYTE);
302 302 housekeeping_packet.packetSequenceControl[BYTE_1] = (unsigned char) (sequenceCounterHK );
303 303 increment_seq_counter( &sequenceCounterHK );
304 304
305 305 housekeeping_packet.time[BYTE_0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
306 306 housekeeping_packet.time[BYTE_1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
307 307 housekeeping_packet.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
308 308 housekeeping_packet.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
309 309 housekeeping_packet.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
310 310 housekeeping_packet.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
311 311
312 312 spacewire_update_hk_lfr_link_state( &housekeeping_packet.lfr_status_word[0] );
313 313
314 314 spacewire_read_statistics();
315 315
316 316 update_hk_with_grspw_stats();
317 317
318 318 set_hk_lfr_time_not_synchro();
319 319
320 320 housekeeping_packet.hk_lfr_q_sd_fifo_size_max = hk_lfr_q_sd_fifo_size_max;
321 321 housekeeping_packet.hk_lfr_q_rv_fifo_size_max = hk_lfr_q_rv_fifo_size_max;
322 322 housekeeping_packet.hk_lfr_q_p0_fifo_size_max = hk_lfr_q_p0_fifo_size_max;
323 323 housekeeping_packet.hk_lfr_q_p1_fifo_size_max = hk_lfr_q_p1_fifo_size_max;
324 324 housekeeping_packet.hk_lfr_q_p2_fifo_size_max = hk_lfr_q_p2_fifo_size_max;
325 325
326 326 housekeeping_packet.sy_lfr_common_parameters_spare = parameter_dump_packet.sy_lfr_common_parameters_spare;
327 327 housekeeping_packet.sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
328 328 get_temperatures( housekeeping_packet.hk_lfr_temp_scm );
329 329 get_v_e1_e2_f3( housekeeping_packet.hk_lfr_sc_v_f3 );
330 330 get_cpu_load( (unsigned char *) &housekeeping_packet.hk_lfr_cpu_load );
331 331
332 332 hk_lfr_le_me_he_update();
333 333
334 housekeeping_packet.hk_lfr_sc_rw1_rw2_f_flags = cp_rpw_sc_rw1_rw2_f_flags;
335 housekeeping_packet.hk_lfr_sc_rw3_rw4_f_flags = cp_rpw_sc_rw3_rw4_f_flags;
336
337 334 // SEND PACKET
338 335 status = rtems_message_queue_send( queue_id, &housekeeping_packet,
339 336 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
340 337 if (status != RTEMS_SUCCESSFUL) {
341 338 PRINTF1("in HOUS *** ERR send: %d\n", status)
342 339 }
343 340 }
344 341 }
345 342
346 343 PRINTF("in HOUS *** deleting task\n")
347 344
348 345 status = rtems_task_delete( RTEMS_SELF ); // should not return
349 346
350 347 return;
351 348 }
352 349
353 350 rtems_task avgv_task(rtems_task_argument argument)
354 351 {
355 352 #define MOVING_AVERAGE 16
356 353 rtems_status_code status;
357 354 static unsigned int v[MOVING_AVERAGE] = {0};
358 355 static unsigned int e1[MOVING_AVERAGE] = {0};
359 356 static unsigned int e2[MOVING_AVERAGE] = {0};
360 357 float average_v;
361 358 float average_e1;
362 359 float average_e2;
363 360 float newValue_v;
364 361 float newValue_e1;
365 362 float newValue_e2;
366 363 unsigned char k;
367 364 unsigned char indexOfOldValue;
368 365
369 366 BOOT_PRINTF("in AVGV ***\n");
370 367
371 368 if (rtems_rate_monotonic_ident( name_avgv_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
372 369 status = rtems_rate_monotonic_create( name_avgv_rate_monotonic, &AVGV_id );
373 370 if( status != RTEMS_SUCCESSFUL ) {
374 371 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status );
375 372 }
376 373 }
377 374
378 375 status = rtems_rate_monotonic_cancel(AVGV_id);
379 376 if( status != RTEMS_SUCCESSFUL ) {
380 377 PRINTF1( "ERR *** in AVGV *** rtems_rate_monotonic_cancel(AVGV_id) ***code: %d\n", status );
381 378 }
382 379 else {
383 380 DEBUG_PRINTF("OK *** in AVGV *** rtems_rate_monotonic_cancel(AVGV_id)\n");
384 381 }
385 382
386 383 // initialize values
387 384 indexOfOldValue = MOVING_AVERAGE - 1;
388 385 average_v = INIT_FLOAT;
389 386 average_e1 = INIT_FLOAT;
390 387 average_e2 = INIT_FLOAT;
391 388 newValue_v = INIT_FLOAT;
392 389 newValue_e1 = INIT_FLOAT;
393 390 newValue_e2 = INIT_FLOAT;
394 391
395 392 k = INIT_CHAR;
396 393
397 394 while(1)
398 395 { // launch the rate monotonic task
399 396 status = rtems_rate_monotonic_period( AVGV_id, AVGV_PERIOD );
400 397 if ( status != RTEMS_SUCCESSFUL )
401 398 {
402 399 PRINTF1( "in AVGV *** ERR period: %d\n", status);
403 400 }
404 401 else
405 402 {
406 403 // get new values
407 404 newValue_v = waveform_picker_regs->v;
408 405 newValue_e1 = waveform_picker_regs->e1;
409 406 newValue_e2 = waveform_picker_regs->e2;
410 407
411 408 // compute the moving average
412 409 average_v = average_v + newValue_v - v[k];
413 410 average_e1 = average_e1 + newValue_e1 - e1[k];
414 411 average_e2 = average_e2 + newValue_e2 - e2[k];
415 412
416 413 // store new values in buffers
417 414 v[k] = newValue_v;
418 415 e1[k] = newValue_e1;
419 416 e2[k] = newValue_e2;
420 417 }
421 418 if (k == (MOVING_AVERAGE-1))
422 419 {
423 420 k = 0;
424 421 }
425 422 else
426 423 {
427 424 k++;
428 425 }
429 426 //update int16 values
430 427 hk_lfr_sc_v_f3_as_int16 = (int16_t) (average_v / ((float) MOVING_AVERAGE) );
431 428 hk_lfr_sc_e1_f3_as_int16 = (int16_t) (average_e1 / ((float) MOVING_AVERAGE) );
432 429 hk_lfr_sc_e2_f3_as_int16 = (int16_t) (average_e2 / ((float) MOVING_AVERAGE) );
433 430 }
434 431
435 432 PRINTF("in AVGV *** deleting task\n");
436 433
437 434 status = rtems_task_delete( RTEMS_SELF ); // should not return
438 435
439 436 return;
440 437 }
441 438
442 439 rtems_task dumb_task( rtems_task_argument unused )
443 440 {
444 441 /** This RTEMS taks is used to print messages without affecting the general behaviour of the software.
445 442 *
446 443 * @param unused is the starting argument of the RTEMS task
447 444 *
448 445 * The DUMB taks waits for RTEMS events and print messages depending on the incoming events.
449 446 *
450 447 */
451 448
452 449 unsigned int i;
453 450 unsigned int intEventOut;
454 451 unsigned int coarse_time = 0;
455 452 unsigned int fine_time = 0;
456 453 rtems_event_set event_out;
457 454
458 455 event_out = EVENT_SETS_NONE_PENDING;
459 456
460 457 BOOT_PRINTF("in DUMB *** \n")
461 458
462 459 while(1){
463 460 rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3
464 461 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7
465 462 | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12 | RTEMS_EVENT_13
466 463 | RTEMS_EVENT_14,
467 464 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT
468 465 intEventOut = (unsigned int) event_out;
469 466 for ( i=0; i<NB_RTEMS_EVENTS; i++)
470 467 {
471 468 if ( ((intEventOut >> i) & 1) != 0)
472 469 {
473 470 coarse_time = time_management_regs->coarse_time;
474 471 fine_time = time_management_regs->fine_time;
475 472 if (i==EVENT_12)
476 473 {
477 474 PRINTF1("%s\n", DUMB_MESSAGE_12)
478 475 }
479 476 if (i==EVENT_13)
480 477 {
481 478 PRINTF1("%s\n", DUMB_MESSAGE_13)
482 479 }
483 480 if (i==EVENT_14)
484 481 {
485 482 PRINTF1("%s\n", DUMB_MESSAGE_1)
486 483 }
487 484 }
488 485 }
489 486 }
490 487 }
491 488
492 489 //*****************************
493 490 // init housekeeping parameters
494 491
495 492 void init_housekeeping_parameters( void )
496 493 {
497 494 /** This function initialize the housekeeping_packet global variable with default values.
498 495 *
499 496 */
500 497
501 498 unsigned int i = 0;
502 499 unsigned char *parameters;
503 500 unsigned char sizeOfHK;
504 501
505 502 sizeOfHK = sizeof( Packet_TM_LFR_HK_t );
506 503
507 504 parameters = (unsigned char*) &housekeeping_packet;
508 505
509 506 for(i = 0; i< sizeOfHK; i++)
510 507 {
511 508 parameters[i] = INIT_CHAR;
512 509 }
513 510
514 511 housekeeping_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
515 512 housekeeping_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
516 513 housekeeping_packet.reserved = DEFAULT_RESERVED;
517 514 housekeeping_packet.userApplication = CCSDS_USER_APP;
518 515 housekeeping_packet.packetID[0] = (unsigned char) (APID_TM_HK >> SHIFT_1_BYTE);
519 516 housekeeping_packet.packetID[1] = (unsigned char) (APID_TM_HK);
520 517 housekeeping_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
521 518 housekeeping_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
522 519 housekeeping_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> SHIFT_1_BYTE);
523 520 housekeeping_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
524 521 housekeeping_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
525 522 housekeeping_packet.serviceType = TM_TYPE_HK;
526 523 housekeeping_packet.serviceSubType = TM_SUBTYPE_HK;
527 524 housekeeping_packet.destinationID = TM_DESTINATION_ID_GROUND;
528 525 housekeeping_packet.sid = SID_HK;
529 526
530 527 // init status word
531 528 housekeeping_packet.lfr_status_word[0] = DEFAULT_STATUS_WORD_BYTE0;
532 529 housekeeping_packet.lfr_status_word[1] = DEFAULT_STATUS_WORD_BYTE1;
533 530 // init software version
534 531 housekeeping_packet.lfr_sw_version[0] = SW_VERSION_N1;
535 532 housekeeping_packet.lfr_sw_version[1] = SW_VERSION_N2;
536 533 housekeeping_packet.lfr_sw_version[BYTE_2] = SW_VERSION_N3;
537 534 housekeeping_packet.lfr_sw_version[BYTE_3] = SW_VERSION_N4;
538 535 // init fpga version
539 536 parameters = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
540 537 housekeeping_packet.lfr_fpga_version[BYTE_0] = parameters[BYTE_1]; // n1
541 538 housekeeping_packet.lfr_fpga_version[BYTE_1] = parameters[BYTE_2]; // n2
542 539 housekeeping_packet.lfr_fpga_version[BYTE_2] = parameters[BYTE_3]; // n3
543 540
544 541 housekeeping_packet.hk_lfr_q_sd_fifo_size = MSG_QUEUE_COUNT_SEND;
545 542 housekeeping_packet.hk_lfr_q_rv_fifo_size = MSG_QUEUE_COUNT_RECV;
546 543 housekeeping_packet.hk_lfr_q_p0_fifo_size = MSG_QUEUE_COUNT_PRC0;
547 544 housekeeping_packet.hk_lfr_q_p1_fifo_size = MSG_QUEUE_COUNT_PRC1;
548 545 housekeeping_packet.hk_lfr_q_p2_fifo_size = MSG_QUEUE_COUNT_PRC2;
549 546 }
550 547
551 548 void increment_seq_counter( unsigned short *packetSequenceControl )
552 549 {
553 550 /** This function increment the sequence counter passes in argument.
554 551 *
555 552 * The increment does not affect the grouping flag. In case of an overflow, the counter is reset to 0.
556 553 *
557 554 */
558 555
559 556 unsigned short segmentation_grouping_flag;
560 557 unsigned short sequence_cnt;
561 558
562 559 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << SHIFT_1_BYTE; // keep bits 7 downto 6
563 560 sequence_cnt = (*packetSequenceControl) & SEQ_CNT_MASK; // [0011 1111 1111 1111]
564 561
565 562 if ( sequence_cnt < SEQ_CNT_MAX)
566 563 {
567 564 sequence_cnt = sequence_cnt + 1;
568 565 }
569 566 else
570 567 {
571 568 sequence_cnt = 0;
572 569 }
573 570
574 571 *packetSequenceControl = segmentation_grouping_flag | sequence_cnt ;
575 572 }
576 573
577 574 void getTime( unsigned char *time)
578 575 {
579 576 /** This function write the current local time in the time buffer passed in argument.
580 577 *
581 578 */
582 579
583 580 time[0] = (unsigned char) (time_management_regs->coarse_time>>SHIFT_3_BYTES);
584 581 time[1] = (unsigned char) (time_management_regs->coarse_time>>SHIFT_2_BYTES);
585 582 time[2] = (unsigned char) (time_management_regs->coarse_time>>SHIFT_1_BYTE);
586 583 time[3] = (unsigned char) (time_management_regs->coarse_time);
587 584 time[4] = (unsigned char) (time_management_regs->fine_time>>SHIFT_1_BYTE);
588 585 time[5] = (unsigned char) (time_management_regs->fine_time);
589 586 }
590 587
591 588 unsigned long long int getTimeAsUnsignedLongLongInt( )
592 589 {
593 590 /** This function write the current local time in the time buffer passed in argument.
594 591 *
595 592 */
596 593 unsigned long long int time;
597 594
598 595 time = ( (unsigned long long int) (time_management_regs->coarse_time & COARSE_TIME_MASK) << SHIFT_2_BYTES )
599 596 + time_management_regs->fine_time;
600 597
601 598 return time;
602 599 }
603 600
604 601 void send_dumb_hk( void )
605 602 {
606 603 Packet_TM_LFR_HK_t dummy_hk_packet;
607 604 unsigned char *parameters;
608 605 unsigned int i;
609 606 rtems_id queue_id;
610 607
611 608 queue_id = RTEMS_ID_NONE;
612 609
613 610 dummy_hk_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
614 611 dummy_hk_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
615 612 dummy_hk_packet.reserved = DEFAULT_RESERVED;
616 613 dummy_hk_packet.userApplication = CCSDS_USER_APP;
617 614 dummy_hk_packet.packetID[0] = (unsigned char) (APID_TM_HK >> SHIFT_1_BYTE);
618 615 dummy_hk_packet.packetID[1] = (unsigned char) (APID_TM_HK);
619 616 dummy_hk_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
620 617 dummy_hk_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
621 618 dummy_hk_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> SHIFT_1_BYTE);
622 619 dummy_hk_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
623 620 dummy_hk_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
624 621 dummy_hk_packet.serviceType = TM_TYPE_HK;
625 622 dummy_hk_packet.serviceSubType = TM_SUBTYPE_HK;
626 623 dummy_hk_packet.destinationID = TM_DESTINATION_ID_GROUND;
627 624 dummy_hk_packet.time[0] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_3_BYTES);
628 625 dummy_hk_packet.time[1] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_2_BYTES);
629 626 dummy_hk_packet.time[BYTE_2] = (unsigned char) (time_management_regs->coarse_time >> SHIFT_1_BYTE);
630 627 dummy_hk_packet.time[BYTE_3] = (unsigned char) (time_management_regs->coarse_time);
631 628 dummy_hk_packet.time[BYTE_4] = (unsigned char) (time_management_regs->fine_time >> SHIFT_1_BYTE);
632 629 dummy_hk_packet.time[BYTE_5] = (unsigned char) (time_management_regs->fine_time);
633 630 dummy_hk_packet.sid = SID_HK;
634 631
635 632 // init status word
636 633 dummy_hk_packet.lfr_status_word[0] = INT8_ALL_F;
637 634 dummy_hk_packet.lfr_status_word[1] = INT8_ALL_F;
638 635 // init software version
639 636 dummy_hk_packet.lfr_sw_version[0] = SW_VERSION_N1;
640 637 dummy_hk_packet.lfr_sw_version[1] = SW_VERSION_N2;
641 638 dummy_hk_packet.lfr_sw_version[BYTE_2] = SW_VERSION_N3;
642 639 dummy_hk_packet.lfr_sw_version[BYTE_3] = SW_VERSION_N4;
643 640 // init fpga version
644 641 parameters = (unsigned char *) (REGS_ADDR_WAVEFORM_PICKER + APB_OFFSET_VHDL_REV);
645 642 dummy_hk_packet.lfr_fpga_version[BYTE_0] = parameters[BYTE_1]; // n1
646 643 dummy_hk_packet.lfr_fpga_version[BYTE_1] = parameters[BYTE_2]; // n2
647 644 dummy_hk_packet.lfr_fpga_version[BYTE_2] = parameters[BYTE_3]; // n3
648 645
649 646 parameters = (unsigned char *) &dummy_hk_packet.hk_lfr_cpu_load;
650 647
651 648 for (i=0; i<(BYTE_POS_HK_REACTION_WHEELS_FREQUENCY - BYTE_POS_HK_LFR_CPU_LOAD); i++)
652 649 {
653 650 parameters[i] = INT8_ALL_F;
654 651 }
655 652
656 653 get_message_queue_id_send( &queue_id );
657 654
658 655 rtems_message_queue_send( queue_id, &dummy_hk_packet,
659 656 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
660 657 }
661 658
662 659 void get_temperatures( unsigned char *temperatures )
663 660 {
664 661 unsigned char* temp_scm_ptr;
665 662 unsigned char* temp_pcb_ptr;
666 663 unsigned char* temp_fpga_ptr;
667 664
668 665 // SEL1 SEL0
669 666 // 0 0 => PCB
670 667 // 0 1 => FPGA
671 668 // 1 0 => SCM
672 669
673 670 temp_scm_ptr = (unsigned char *) &time_management_regs->temp_scm;
674 671 temp_pcb_ptr = (unsigned char *) &time_management_regs->temp_pcb;
675 672 temp_fpga_ptr = (unsigned char *) &time_management_regs->temp_fpga;
676 673
677 674 temperatures[ BYTE_0 ] = temp_scm_ptr[ BYTE_2 ];
678 675 temperatures[ BYTE_1 ] = temp_scm_ptr[ BYTE_3 ];
679 676 temperatures[ BYTE_2 ] = temp_pcb_ptr[ BYTE_2 ];
680 677 temperatures[ BYTE_3 ] = temp_pcb_ptr[ BYTE_3 ];
681 678 temperatures[ BYTE_4 ] = temp_fpga_ptr[ BYTE_2 ];
682 679 temperatures[ BYTE_5 ] = temp_fpga_ptr[ BYTE_3 ];
683 680 }
684 681
685 682 void get_v_e1_e2_f3( unsigned char *spacecraft_potential )
686 683 {
687 684 unsigned char* v_ptr;
688 685 unsigned char* e1_ptr;
689 686 unsigned char* e2_ptr;
690 687
691 688 v_ptr = (unsigned char *) &hk_lfr_sc_v_f3_as_int16;
692 689 e1_ptr = (unsigned char *) &hk_lfr_sc_e1_f3_as_int16;
693 690 e2_ptr = (unsigned char *) &hk_lfr_sc_e2_f3_as_int16;
694 691
695 692 spacecraft_potential[BYTE_0] = v_ptr[0];
696 693 spacecraft_potential[BYTE_1] = v_ptr[1];
697 694 spacecraft_potential[BYTE_2] = e1_ptr[0];
698 695 spacecraft_potential[BYTE_3] = e1_ptr[1];
699 696 spacecraft_potential[BYTE_4] = e2_ptr[0];
700 697 spacecraft_potential[BYTE_5] = e2_ptr[1];
701 698 }
702 699
703 700 void get_cpu_load( unsigned char *resource_statistics )
704 701 {
705 702 unsigned char cpu_load;
706 703
707 704 cpu_load = lfr_rtems_cpu_usage_report();
708 705
709 706 // HK_LFR_CPU_LOAD
710 707 resource_statistics[0] = cpu_load;
711 708
712 709 // HK_LFR_CPU_LOAD_MAX
713 710 if (cpu_load > resource_statistics[1])
714 711 {
715 712 resource_statistics[1] = cpu_load;
716 713 }
717 714
718 715 // CPU_LOAD_AVE
719 716 resource_statistics[BYTE_2] = 0;
720 717
721 718 #ifndef PRINT_TASK_STATISTICS
722 719 rtems_cpu_usage_reset();
723 720 #endif
724 721
725 722 }
726 723
727 724 void set_hk_lfr_sc_potential_flag( bool state )
728 725 {
729 726 if (state == true)
730 727 {
731 728 housekeeping_packet.lfr_status_word[1] =
732 729 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_SC_POTENTIAL_FLAG_BIT; // [0100 0000]
733 730 }
734 731 else
735 732 {
736 733 housekeeping_packet.lfr_status_word[1] =
737 734 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_SC_POTENTIAL_FLAG_MASK; // [1011 1111]
738 735 }
739 736 }
740 737
741 738 void set_sy_lfr_pas_filter_enabled( bool state )
742 739 {
743 740 if (state == true)
744 741 {
745 742 housekeeping_packet.lfr_status_word[1] =
746 743 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_PAS_FILTER_ENABLED_BIT; // [0010 0000]
747 744 }
748 745 else
749 746 {
750 747 housekeeping_packet.lfr_status_word[1] =
751 748 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_PAS_FILTER_ENABLED_MASK; // [1101 1111]
752 749 }
753 750 }
754 751
755 752 void set_sy_lfr_watchdog_enabled( bool state )
756 753 {
757 754 if (state == true)
758 755 {
759 756 housekeeping_packet.lfr_status_word[1] =
760 757 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_WATCHDOG_BIT; // [0001 0000]
761 758 }
762 759 else
763 760 {
764 761 housekeeping_packet.lfr_status_word[1] =
765 762 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_WATCHDOG_MASK; // [1110 1111]
766 763 }
767 764 }
768 765
769 766 void set_hk_lfr_calib_enable( bool state )
770 767 {
771 768 if (state == true)
772 769 {
773 770 housekeeping_packet.lfr_status_word[1] =
774 771 housekeeping_packet.lfr_status_word[1] | STATUS_WORD_CALIB_BIT; // [0000 1000]
775 772 }
776 773 else
777 774 {
778 775 housekeeping_packet.lfr_status_word[1] =
779 776 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_CALIB_MASK; // [1111 0111]
780 777 }
781 778 }
782 779
783 780 void set_hk_lfr_reset_cause( enum lfr_reset_cause_t lfr_reset_cause )
784 781 {
785 782 housekeeping_packet.lfr_status_word[1] =
786 783 housekeeping_packet.lfr_status_word[1] & STATUS_WORD_RESET_CAUSE_MASK; // [1111 1000]
787 784
788 785 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1]
789 786 | (lfr_reset_cause & STATUS_WORD_RESET_CAUSE_BITS ); // [0000 0111]
790 787
791 788 }
792 789
793 790 void increment_hk_counter( unsigned char newValue, unsigned char oldValue, unsigned int *counter )
794 791 {
795 792 int delta;
796 793
797 794 delta = 0;
798 795
799 796 if (newValue >= oldValue)
800 797 {
801 798 delta = newValue - oldValue;
802 799 }
803 800 else
804 801 {
805 802 delta = (CONST_256 - oldValue) + newValue;
806 803 }
807 804
808 805 *counter = *counter + delta;
809 806 }
810 807
811 808 void hk_lfr_le_update( void )
812 809 {
813 810 static hk_lfr_le_t old_hk_lfr_le = {0};
814 811 hk_lfr_le_t new_hk_lfr_le;
815 812 unsigned int counter;
816 813
817 814 counter = (((unsigned int) housekeeping_packet.hk_lfr_le_cnt[0]) * CONST_256) + housekeeping_packet.hk_lfr_le_cnt[1];
818 815
819 816 // DPU
820 817 new_hk_lfr_le.dpu_spw_parity = housekeeping_packet.hk_lfr_dpu_spw_parity;
821 818 new_hk_lfr_le.dpu_spw_disconnect= housekeeping_packet.hk_lfr_dpu_spw_disconnect;
822 819 new_hk_lfr_le.dpu_spw_escape = housekeeping_packet.hk_lfr_dpu_spw_escape;
823 820 new_hk_lfr_le.dpu_spw_credit = housekeeping_packet.hk_lfr_dpu_spw_credit;
824 821 new_hk_lfr_le.dpu_spw_write_sync= housekeeping_packet.hk_lfr_dpu_spw_write_sync;
825 822 // TIMECODE
826 823 new_hk_lfr_le.timecode_erroneous= housekeeping_packet.hk_lfr_timecode_erroneous;
827 824 new_hk_lfr_le.timecode_missing = housekeeping_packet.hk_lfr_timecode_missing;
828 825 new_hk_lfr_le.timecode_invalid = housekeeping_packet.hk_lfr_timecode_invalid;
829 826 // TIME
830 827 new_hk_lfr_le.time_timecode_it = housekeeping_packet.hk_lfr_time_timecode_it;
831 828 new_hk_lfr_le.time_not_synchro = housekeeping_packet.hk_lfr_time_not_synchro;
832 829 new_hk_lfr_le.time_timecode_ctr = housekeeping_packet.hk_lfr_time_timecode_ctr;
833 830 //AHB
834 831 new_hk_lfr_le.ahb_correctable = housekeeping_packet.hk_lfr_ahb_correctable;
835 832 // housekeeping_packet.hk_lfr_dpu_spw_rx_ahb => not handled by the grspw driver
836 833 // housekeeping_packet.hk_lfr_dpu_spw_tx_ahb => not handled by the grspw driver
837 834
838 835 // update the le counter
839 836 // DPU
840 837 increment_hk_counter( new_hk_lfr_le.dpu_spw_parity, old_hk_lfr_le.dpu_spw_parity, &counter );
841 838 increment_hk_counter( new_hk_lfr_le.dpu_spw_disconnect,old_hk_lfr_le.dpu_spw_disconnect, &counter );
842 839 increment_hk_counter( new_hk_lfr_le.dpu_spw_escape, old_hk_lfr_le.dpu_spw_escape, &counter );
843 840 increment_hk_counter( new_hk_lfr_le.dpu_spw_credit, old_hk_lfr_le.dpu_spw_credit, &counter );
844 841 increment_hk_counter( new_hk_lfr_le.dpu_spw_write_sync,old_hk_lfr_le.dpu_spw_write_sync, &counter );
845 842 // TIMECODE
846 843 increment_hk_counter( new_hk_lfr_le.timecode_erroneous,old_hk_lfr_le.timecode_erroneous, &counter );
847 844 increment_hk_counter( new_hk_lfr_le.timecode_missing, old_hk_lfr_le.timecode_missing, &counter );
848 845 increment_hk_counter( new_hk_lfr_le.timecode_invalid, old_hk_lfr_le.timecode_invalid, &counter );
849 846 // TIME
850 847 increment_hk_counter( new_hk_lfr_le.time_timecode_it, old_hk_lfr_le.time_timecode_it, &counter );
851 848 increment_hk_counter( new_hk_lfr_le.time_not_synchro, old_hk_lfr_le.time_not_synchro, &counter );
852 849 increment_hk_counter( new_hk_lfr_le.time_timecode_ctr, old_hk_lfr_le.time_timecode_ctr, &counter );
853 850 // AHB
854 851 increment_hk_counter( new_hk_lfr_le.ahb_correctable, old_hk_lfr_le.ahb_correctable, &counter );
855 852
856 853 // DPU
857 854 old_hk_lfr_le.dpu_spw_parity = new_hk_lfr_le.dpu_spw_parity;
858 855 old_hk_lfr_le.dpu_spw_disconnect= new_hk_lfr_le.dpu_spw_disconnect;
859 856 old_hk_lfr_le.dpu_spw_escape = new_hk_lfr_le.dpu_spw_escape;
860 857 old_hk_lfr_le.dpu_spw_credit = new_hk_lfr_le.dpu_spw_credit;
861 858 old_hk_lfr_le.dpu_spw_write_sync= new_hk_lfr_le.dpu_spw_write_sync;
862 859 // TIMECODE
863 860 old_hk_lfr_le.timecode_erroneous= new_hk_lfr_le.timecode_erroneous;
864 861 old_hk_lfr_le.timecode_missing = new_hk_lfr_le.timecode_missing;
865 862 old_hk_lfr_le.timecode_invalid = new_hk_lfr_le.timecode_invalid;
866 863 // TIME
867 864 old_hk_lfr_le.time_timecode_it = new_hk_lfr_le.time_timecode_it;
868 865 old_hk_lfr_le.time_not_synchro = new_hk_lfr_le.time_not_synchro;
869 866 old_hk_lfr_le.time_timecode_ctr = new_hk_lfr_le.time_timecode_ctr;
870 867 //AHB
871 868 old_hk_lfr_le.ahb_correctable = new_hk_lfr_le.ahb_correctable;
872 869 // housekeeping_packet.hk_lfr_dpu_spw_rx_ahb => not handled by the grspw driver
873 870 // housekeeping_packet.hk_lfr_dpu_spw_tx_ahb => not handled by the grspw driver
874 871
875 872 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
876 873 // LE
877 874 housekeeping_packet.hk_lfr_le_cnt[0] = (unsigned char) ((counter & BYTE0_MASK) >> SHIFT_1_BYTE);
878 875 housekeeping_packet.hk_lfr_le_cnt[1] = (unsigned char) (counter & BYTE1_MASK);
879 876 }
880 877
881 878 void hk_lfr_me_update( void )
882 879 {
883 880 static hk_lfr_me_t old_hk_lfr_me = {0};
884 881 hk_lfr_me_t new_hk_lfr_me;
885 882 unsigned int counter;
886 883
887 884 counter = (((unsigned int) housekeeping_packet.hk_lfr_me_cnt[0]) * CONST_256) + housekeeping_packet.hk_lfr_me_cnt[1];
888 885
889 886 // get the current values
890 887 new_hk_lfr_me.dpu_spw_early_eop = housekeeping_packet.hk_lfr_dpu_spw_early_eop;
891 888 new_hk_lfr_me.dpu_spw_invalid_addr = housekeeping_packet.hk_lfr_dpu_spw_invalid_addr;
892 889 new_hk_lfr_me.dpu_spw_eep = housekeeping_packet.hk_lfr_dpu_spw_eep;
893 890 new_hk_lfr_me.dpu_spw_rx_too_big = housekeeping_packet.hk_lfr_dpu_spw_rx_too_big;
894 891
895 892 // update the me counter
896 893 increment_hk_counter( new_hk_lfr_me.dpu_spw_early_eop, old_hk_lfr_me.dpu_spw_early_eop, &counter );
897 894 increment_hk_counter( new_hk_lfr_me.dpu_spw_invalid_addr, old_hk_lfr_me.dpu_spw_invalid_addr, &counter );
898 895 increment_hk_counter( new_hk_lfr_me.dpu_spw_eep, old_hk_lfr_me.dpu_spw_eep, &counter );
899 896 increment_hk_counter( new_hk_lfr_me.dpu_spw_rx_too_big, old_hk_lfr_me.dpu_spw_rx_too_big, &counter );
900 897
901 898 // store the counters for the next time
902 899 old_hk_lfr_me.dpu_spw_early_eop = new_hk_lfr_me.dpu_spw_early_eop;
903 900 old_hk_lfr_me.dpu_spw_invalid_addr = new_hk_lfr_me.dpu_spw_invalid_addr;
904 901 old_hk_lfr_me.dpu_spw_eep = new_hk_lfr_me.dpu_spw_eep;
905 902 old_hk_lfr_me.dpu_spw_rx_too_big = new_hk_lfr_me.dpu_spw_rx_too_big;
906 903
907 904 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
908 905 // ME
909 906 housekeeping_packet.hk_lfr_me_cnt[0] = (unsigned char) ((counter & BYTE0_MASK) >> SHIFT_1_BYTE);
910 907 housekeeping_packet.hk_lfr_me_cnt[1] = (unsigned char) (counter & BYTE1_MASK);
911 908 }
912 909
913 910 void hk_lfr_le_me_he_update()
914 911 {
915 912
916 913 unsigned int hk_lfr_he_cnt;
917 914
918 915 hk_lfr_he_cnt = (((unsigned int) housekeeping_packet.hk_lfr_he_cnt[0]) * 256) + housekeeping_packet.hk_lfr_he_cnt[1];
919 916
920 917 //update the low severity error counter
921 918 hk_lfr_le_update( );
922 919
923 920 //update the medium severity error counter
924 921 hk_lfr_me_update();
925 922
926 923 //update the high severity error counter
927 924 hk_lfr_he_cnt = 0;
928 925
929 926 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
930 927 // HE
931 928 housekeeping_packet.hk_lfr_he_cnt[0] = (unsigned char) ((hk_lfr_he_cnt & BYTE0_MASK) >> SHIFT_1_BYTE);
932 929 housekeeping_packet.hk_lfr_he_cnt[1] = (unsigned char) (hk_lfr_he_cnt & BYTE1_MASK);
933 930
934 931 }
935 932
936 933 void set_hk_lfr_time_not_synchro()
937 934 {
938 935 static unsigned char synchroLost = 1;
939 936 int synchronizationBit;
940 937
941 938 // get the synchronization bit
942 939 synchronizationBit =
943 940 (time_management_regs->coarse_time & VAL_LFR_SYNCHRONIZED) >> BIT_SYNCHRONIZATION; // 1000 0000 0000 0000
944 941
945 942 switch (synchronizationBit)
946 943 {
947 944 case 0:
948 945 if (synchroLost == 1)
949 946 {
950 947 synchroLost = 0;
951 948 }
952 949 break;
953 950 case 1:
954 951 if (synchroLost == 0 )
955 952 {
956 953 synchroLost = 1;
957 954 increase_unsigned_char_counter(&housekeeping_packet.hk_lfr_time_not_synchro);
958 955 update_hk_lfr_last_er_fields( RID_LE_LFR_TIME, CODE_NOT_SYNCHRO );
959 956 }
960 957 break;
961 958 default:
962 959 PRINTF1("in hk_lfr_time_not_synchro *** unexpected value for synchronizationBit = %d\n", synchronizationBit);
963 960 break;
964 961 }
965 962
966 963 }
967 964
968 965 void set_hk_lfr_ahb_correctable() // CRITICITY L
969 966 {
970 967 /** This function builds the error counter hk_lfr_ahb_correctable using the statistics provided
971 968 * by the Cache Control Register (ASI 2, offset 0) and in the Register Protection Control Register (ASR16) on the
972 969 * detected errors in the cache, in the integer unit and in the floating point unit.
973 970 *
974 971 * @param void
975 972 *
976 973 * @return void
977 974 *
978 975 * All errors are summed to set the value of the hk_lfr_ahb_correctable counter.
979 976 *
980 977 */
981 978
982 979 unsigned int ahb_correctable;
983 980 unsigned int instructionErrorCounter;
984 981 unsigned int dataErrorCounter;
985 982 unsigned int fprfErrorCounter;
986 983 unsigned int iurfErrorCounter;
987 984
988 985 instructionErrorCounter = 0;
989 986 dataErrorCounter = 0;
990 987 fprfErrorCounter = 0;
991 988 iurfErrorCounter = 0;
992 989
993 990 CCR_getInstructionAndDataErrorCounters( &instructionErrorCounter, &dataErrorCounter);
994 991 ASR16_get_FPRF_IURF_ErrorCounters( &fprfErrorCounter, &iurfErrorCounter);
995 992
996 993 ahb_correctable = instructionErrorCounter
997 994 + dataErrorCounter
998 995 + fprfErrorCounter
999 996 + iurfErrorCounter
1000 997 + housekeeping_packet.hk_lfr_ahb_correctable;
1001 998
1002 999 housekeeping_packet.hk_lfr_ahb_correctable = (unsigned char) (ahb_correctable & INT8_ALL_F); // [1111 1111]
1003 1000
1004 1001 }
General Comments 0
You need to be logged in to leave comments. Login now