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