##// END OF EJS Templates
EDAC information fetching functions added.
paul -
r251:b70f1b89bd70 R3a
parent child
Show More
@@ -1,116 +1,124
1 1 TEMPLATE = app
2 2 # CONFIG += console v8 sim
3 # CONFIG options = verbose *** boot_messages *** debug_messages *** cpu_usage_report *** stack_report *** vhdl_dev *** debug_tch
4 # lpp_dpu_destid
3 # CONFIG options =
4 # verbose
5 # boot_messages
6 # debug_messages
7 # cpu_usage_report
8 # stack_report
9 # vhdl_dev
10 # debug_tch
11 # lpp_dpu_destid REMOVE BEFORE DELIVERY TO LESIA
12 # debug_watchdog
5 13 CONFIG += console verbose lpp_dpu_destid
6 14 CONFIG -= qt
7 15
8 16 include(./sparc.pri)
9 17
10 18 # flight software version
11 19 SWVERSION=-1-0
12 20 DEFINES += SW_VERSION_N1=3 # major
13 21 DEFINES += SW_VERSION_N2=0 # minor
14 22 DEFINES += SW_VERSION_N3=0 # patch
15 DEFINES += SW_VERSION_N4=13 # internal
23 DEFINES += SW_VERSION_N4=14 # internal
16 24
17 25 # <GCOV>
18 26 #QMAKE_CFLAGS_RELEASE += -fprofile-arcs -ftest-coverage
19 27 #LIBS += -lgcov /opt/GCOV/01A/lib/overload.o -lc
20 28 # </GCOV>
21 29
22 30 # <CHANGE BEFORE FLIGHT>
23 31 contains( CONFIG, lpp_dpu_destid ) {
24 32 DEFINES += LPP_DPU_DESTID
25 33 }
26 34 # </CHANGE BEFORE FLIGHT>
27 35
28 36 contains( CONFIG, debug_tch ) {
29 37 DEFINES += DEBUG_TCH
30 38 }
31 39 DEFINES += MSB_FIRST_TCH
32 40
33 41 contains( CONFIG, vhdl_dev ) {
34 42 DEFINES += VHDL_DEV
35 43 }
36 44
37 45 contains( CONFIG, verbose ) {
38 46 DEFINES += PRINT_MESSAGES_ON_CONSOLE
39 47 }
40 48
41 49 contains( CONFIG, debug_messages ) {
42 50 DEFINES += DEBUG_MESSAGES
43 51 }
44 52
45 53 contains( CONFIG, cpu_usage_report ) {
46 54 DEFINES += PRINT_TASK_STATISTICS
47 55 }
48 56
49 57 contains( CONFIG, stack_report ) {
50 58 DEFINES += PRINT_STACK_REPORT
51 59 }
52 60
53 61 contains( CONFIG, boot_messages ) {
54 62 DEFINES += BOOT_MESSAGES
55 63 }
56 64
57 65 contains( CONFIG, debug_watchdog ) {
58 66 DEFINES += DEBUG_WATCHDOG
59 67 }
60 68
61 69 #doxygen.target = doxygen
62 70 #doxygen.commands = doxygen ../doc/Doxyfile
63 71 #QMAKE_EXTRA_TARGETS += doxygen
64 72
65 73 TARGET = fsw
66 74
67 75 INCLUDEPATH += \
68 76 $${PWD}/../src \
69 77 $${PWD}/../header \
70 78 $${PWD}/../header/lfr_common_headers \
71 79 $${PWD}/../header/processing \
72 80 $${PWD}/../LFR_basic-parameters
73 81
74 82 SOURCES += \
75 83 ../src/wf_handler.c \
76 84 ../src/tc_handler.c \
77 85 ../src/fsw_misc.c \
78 86 ../src/fsw_init.c \
79 87 ../src/fsw_globals.c \
80 88 ../src/fsw_spacewire.c \
81 89 ../src/tc_load_dump_parameters.c \
82 90 ../src/tm_lfr_tc_exe.c \
83 91 ../src/tc_acceptance.c \
84 92 ../src/processing/fsw_processing.c \
85 93 ../src/processing/avf0_prc0.c \
86 94 ../src/processing/avf1_prc1.c \
87 95 ../src/processing/avf2_prc2.c \
88 96 ../src/lfr_cpu_usage_report.c \
89 97 ../LFR_basic-parameters/basic_parameters.c
90 98
91 99 HEADERS += \
92 100 ../header/wf_handler.h \
93 101 ../header/tc_handler.h \
94 102 ../header/grlib_regs.h \
95 103 ../header/fsw_misc.h \
96 104 ../header/fsw_init.h \
97 105 ../header/fsw_spacewire.h \
98 106 ../header/tc_load_dump_parameters.h \
99 107 ../header/tm_lfr_tc_exe.h \
100 108 ../header/tc_acceptance.h \
101 109 ../header/processing/fsw_processing.h \
102 110 ../header/processing/avf0_prc0.h \
103 111 ../header/processing/avf1_prc1.h \
104 112 ../header/processing/avf2_prc2.h \
105 113 ../header/fsw_params_wf_handler.h \
106 114 ../header/lfr_cpu_usage_report.h \
107 115 ../header/lfr_common_headers/ccsds_types.h \
108 116 ../header/lfr_common_headers/fsw_params.h \
109 117 ../header/lfr_common_headers/fsw_params_nb_bytes.h \
110 118 ../header/lfr_common_headers/fsw_params_processing.h \
111 119 ../header/lfr_common_headers/TC_types.h \
112 120 ../header/lfr_common_headers/tm_byte_positions.h \
113 121 ../LFR_basic-parameters/basic_parameters.h \
114 122 ../LFR_basic-parameters/basic_parameters_params.h \
115 123 ../header/GscMemoryLPP.hpp
116 124
@@ -1,69 +1,192
1 1 #ifndef GSCMEMORY_HPP_
2 2 #define GSCMEMORY_HPP_
3 3
4 4 #ifndef LEON3
5 5 #define LEON3
6 6 #endif
7 7
8 static unsigned int getCacheControlRegister(){
9 #ifdef LEON3
10 unsigned int cacheControlRegister = 0;
11 __asm__ __volatile__("lda [%%g0] 2, %0" : "=r"(cacheControlRegister) : );
12 return cacheControlRegister;
13 #endif
14 }
8 #define REGS_ADDR_PLUGANDPLAY 0xFFFFF000
9 #define ASR16_REG_ADDRESS 0x90400040 // Ancillary State Register 16 = Register protection control register (FT only)
10
11 #define DEVICEID_LEON3 0x003
12 #define DEVICEID_LEON3FT 0x053
13 #define VENDORID_GAISLER 0x01
15 14
16 static void setCacheControlRegister(unsigned int cacheControlRegister)
15 // CCR
16 #define POS_ITE 12
17 #define COUNTER_FIELD_ITE 0x00003000 // 0000 0000 0000 0000 0011 0000 0000 0000
18 #define COUNTER_MASK_ITE 0xffffcfff // 1111 1111 1111 1111 1100 1111 1111 1111
19 #define POS_IDE 10
20 #define COUNTER_FIELD_IDE 0x00000c00 // 0000 0000 0000 0000 0000 1100 0000 0000
21 #define COUNTER_MASK_IDE 0xfffff3ff // 1111 1111 1111 1111 1111 0011 1111 1111
22 //
23 #define POS_DTE 8
24 #define COUNTER_FIELD_DTE 0x00000300 // 0000 0000 0000 0000 0000 0011 0000 0000
25 #define COUNTER_MASK_DTE 0xfffffcff // 1111 1111 1111 1111 1111 1100 1111 1111
26 #define POS_DDE 6
27 #define COUNTER_FIELD_DDE 0x000000c0 // 0000 0000 0000 0000 0000 0000 1100 0000
28 #define COUNTER_MASK_DDE 0xffffff3f // 1111 1111 1111 1111 1111 1111 0011 1111
29
30 // ASR16
31 #define POS_FPRF 27
32 #define COUNTER_FIELD_FPRF 0x38000000 // 0011 1000 0000 0000 0000 0000 0000 0000
33 #define COUNTER_MASK_FPRF 0xc7ffffff // 1100 0111 1111 1111 1111 1111 1111 1111
34 #define POS_IURF 11
35 #define COUNTER_FIELD_IURF 0x00003800 // 0000 0000 0000 0000 0011 1000 0000 0000
36 #define COUNTER_MASK_IURF 0xffffc7ff // 1111 1111 1111 1111 1100 0111 1111 1111
37
38 volatile unsigned int *asr16Ptr = (volatile unsigned int *) ASR16_REG_ADDRESS;
39
40 static inline void flushCache()
17 41 {
18 #ifdef LEON3
19 __asm__ __volatile__("sta %0, [%%g0] 2" : : "r"(cacheControlRegister));
20 #endif
21 }
22
23
24 42 /**
25 43 * Flush the data cache and the instruction cache.
26 44 *
27 * @return
45 * @param void
46 *
47 * @return void
28 48 */
29 static inline void flushCache() {
49
30 50 asm("flush");
31 51 }
32 52
33 static void resetCacheControlRegister() {
34 #ifdef LEON3
53 //***************************
54 // CCR Cache control register
55
56 static unsigned int CCR_getValue()
57 {
58 unsigned int cacheControlRegister = 0;
59 __asm__ __volatile__("lda [%%g0] 2, %0" : "=r"(cacheControlRegister) : );
60 return cacheControlRegister;
61 }
62
63 static void CCR_setValue(unsigned int cacheControlRegister)
64 {
65 __asm__ __volatile__("sta %0, [%%g0] 2" : : "r"(cacheControlRegister));
66 }
67
68 static void CCR_resetCacheControlRegister()
69 {
35 70 unsigned int cacheControlRegister;
36 71 cacheControlRegister = 0x00;
37 setCacheControlRegister(cacheControlRegister);
38 #endif
72 CCR_setValue(cacheControlRegister);
73 }
74
75 static void CCR_enableInstructionCache()
76 {
77 // [1:0] Instruction Cache state (ICS)
78 // Indicates the current data cache state according to the following: X0 = disabled, 01 = frozen, 11 = enabled.
79 unsigned int cacheControlRegister;
80 cacheControlRegister = CCR_getValue();
81 cacheControlRegister = (cacheControlRegister | 0x3);
82 CCR_setValue(cacheControlRegister);
39 83 }
40 84
41 static void enableInstructionCache() {
42 #ifdef LEON3
85 static void CCR_enableDataCache()
86 {
87 // [3:2] Data Cache state (DCS)
88 // Indicates the current data cache state according to the following: X0 = disabled, 01 = frozen, 11 = enabled.
89 unsigned int cacheControlRegister;
90 cacheControlRegister = CCR_getValue();
91 cacheControlRegister = (cacheControlRegister | 0xc);
92 CCR_setValue(cacheControlRegister);
93 }
94
95 static void CCR_faultTolerantScheme()
96 {
97 // [20:19] FT scheme (FT) - β€œ00” = no FT, β€œ01” = 4-bit checking implemented
43 98 unsigned int cacheControlRegister;
44 cacheControlRegister = getCacheControlRegister();
45 cacheControlRegister = (cacheControlRegister | 0x3);
46 setCacheControlRegister(cacheControlRegister);
47 #endif
99 unsigned int *plugAndPlayRegister;
100 unsigned int vendorId;
101 unsigned int deviceId;
102
103 plugAndPlayRegister = (unsigned int*) REGS_ADDR_PLUGANDPLAY;
104 vendorId = ( (*plugAndPlayRegister) & 0xff000000 ) >> 24;
105 deviceId = ( (*plugAndPlayRegister) & 0x00fff000 ) >> 12;
106
107 if( (vendorId == VENDORID_GAISLER) & (deviceId ==DEVICEID_LEON3FT) )
108 {
109 PRINTF("in faultTolerantScheme *** Leon3FT detected, configure the CCR FT bits");
110 cacheControlRegister = CCR_getValue();
111 cacheControlRegister = (cacheControlRegister | 0xc);
112 CCR_setValue(cacheControlRegister);
113 }
114 else
115 {
116 PRINTF("in faultTolerantScheme *** not a Leon3FT, no need to configure the CCR FT bits\n");
117 PRINTF2(" *** vendorID = 0x%x, deviceId = 0x%x\n", vendorId, deviceId);
118 }
48 119 }
49 120
50 static void enableDataCache() {
51 #ifdef LEON3
121 static void CCR_enableInstructionBurstFetch()
122 {
123 // [16] Instruction burst fetch (IB). This bit enables burst fill during instruction fetch.
52 124 unsigned int cacheControlRegister;
53 cacheControlRegister = getCacheControlRegister();
54 cacheControlRegister = (cacheControlRegister | 0xc);
55 setCacheControlRegister(cacheControlRegister);
56 #endif
125 cacheControlRegister = CCR_getValue();
126 // set the bit IB to 1
127 cacheControlRegister = (cacheControlRegister | 0x10000);
128 CCR_setValue(cacheControlRegister);
57 129 }
58 130
59 static void enableInstructionBurstFetch() {
60 #ifdef LEON3
131 static void CCR_getInstructionAndDataErrorCounters( unsigned int* instructionErrorCounter, unsigned int* dataErrorCounter )
132 {
133 // [13:12] Instruction Tag Errors (ITE) - Number of detected parity errors in the instruction tag cache.
134 // Only available if fault-tolerance is enabled (FT field in this register is non-zero).
135 // [11:10] Instruction Data Errors (IDE) - Number of detected parity errors in the instruction data cache.
136 // Only available if fault-tolerance is enabled (FT field in this register is non-zero).
137
61 138 unsigned int cacheControlRegister;
62 cacheControlRegister = getCacheControlRegister();
63 // set the bit IB to 1
64 cacheControlRegister = (cacheControlRegister | 0x10000);
65 setCacheControlRegister(cacheControlRegister);
66 #endif
139 unsigned int iTE;
140 unsigned int iDE;
141 unsigned int dTE;
142 unsigned int dDE;
143
144 cacheControlRegister = CCR_getValue();
145 iTE = (cacheControlRegister & COUNTER_FIELD_ITE) >> POS_ITE;
146 iDE = (cacheControlRegister & COUNTER_FIELD_IDE) >> POS_IDE;
147 dTE = (cacheControlRegister & COUNTER_FIELD_DTE) >> POS_DTE;
148 dDE = (cacheControlRegister & COUNTER_FIELD_DDE) >> POS_DDE;
149
150 *instructionErrorCounter = iTE + iDE;
151 *dataErrorCounter = dTE + dDE;
152
153 // reset counters
154 cacheControlRegister = cacheControlRegister
155 & COUNTER_FIELD_ITE
156 & COUNTER_FIELD_IDE
157 & COUNTER_FIELD_DTE
158 & COUNTER_FIELD_DDE;
159
160 CCR_setValue(cacheControlRegister);
161 }
162
163 //*******************************************
164 // ASR16 Register protection control register
165
166 static unsigned int ASR16_get_FPRF_IURF_ErrorCounters( unsigned int* fprfErrorCounter, unsigned int* iurfErrorCounter)
167 {
168 /** This function is used to retrieve the integer unit register file error counter and the floating point unit
169 * register file error counter
170 *
171 * @return void
172 *
173 * [29:27] FP RF error counter - Number of detected parity errors in the FP register file.
174 * [13:11] IU RF error counter - Number of detected parity errors in the IU register file.
175 *
176 */
177
178 unsigned int asr16;
179
180 asr16 = *asr16Ptr;
181 *fprfErrorCounter = ( asr16 & COUNTER_FIELD_FPRF ) >> POS_FPRF;
182 *iurfErrorCounter = ( asr16 & COUNTER_FIELD_IURF ) >> POS_IURF;
183
184 // reset the counter to 0
185 asr16 = asr16Ptr
186 & COUNTER_MASK_FPRF
187 & COUNTER_FIELD_IURF;
188
189 *asr16Ptr = asr16;
67 190 }
68 191
69 192 #endif /* GSCMEMORY_HPP_ */
@@ -1,891 +1,910
1 1 /** This is the RTEMS initialization module.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 * This module contains two very different information:
7 7 * - specific instructions to configure the compilation of the RTEMS executive
8 8 * - functions related to the fligth softwre initialization, especially the INIT RTEMS task
9 9 *
10 10 */
11 11
12 12 //*************************
13 13 // GPL reminder to be added
14 14 //*************************
15 15
16 16 #include <rtems.h>
17 17
18 18 /* configuration information */
19 19
20 20 #define CONFIGURE_INIT
21 21
22 22 #include <bsp.h> /* for device driver prototypes */
23 23
24 24 /* configuration information */
25 25
26 26 #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
27 27 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
28 28
29 29 #define CONFIGURE_MAXIMUM_TASKS 20
30 30 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
31 31 #define CONFIGURE_EXTRA_TASK_STACKS (3 * RTEMS_MINIMUM_STACK_SIZE)
32 32 #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
33 33 #define CONFIGURE_INIT_TASK_PRIORITY 1 // instead of 100
34 34 #define CONFIGURE_INIT_TASK_MODE (RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT)
35 35 #define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT)
36 36 #define CONFIGURE_MAXIMUM_DRIVERS 16
37 37 #define CONFIGURE_MAXIMUM_PERIODS 5
38 38 #define CONFIGURE_MAXIMUM_TIMERS 5 // [spiq] [wtdg] [spacewire_reset_link]
39 39 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 5
40 40 #ifdef PRINT_STACK_REPORT
41 41 #define CONFIGURE_STACK_CHECKER_ENABLED
42 42 #endif
43 43
44 44 #include <rtems/confdefs.h>
45 45
46 46 /* If --drvmgr was enabled during the configuration of the RTEMS kernel */
47 47 #ifdef RTEMS_DRVMGR_STARTUP
48 48 #ifdef LEON3
49 49 /* Add Timer and UART Driver */
50 50 #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
51 51 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GPTIMER
52 52 #endif
53 53 #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
54 54 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_APBUART
55 55 #endif
56 56 #endif
57 57 #define CONFIGURE_DRIVER_AMBAPP_GAISLER_GRSPW /* GRSPW Driver */
58 58 #include <drvmgr/drvmgr_confdefs.h>
59 59 #endif
60 60
61 61 #include "fsw_init.h"
62 62 #include "fsw_config.c"
63 63 #include "GscMemoryLPP.hpp"
64 64
65 65 void initCache()
66 66 {
67 // ASI 2 contains a few control registers that have not been assigned as ancillary state registers.
68 // These should only be read and written using 32-bit LDA/STA instructions.
69 // All cache registers are accessed through load/store operations to the alternate address space (LDA/STA), using ASI = 2.
70 // The table below shows the register addresses:
71 // 0x00 Cache control register
72 // 0x04 Reserved
73 // 0x08 Instruction cache configuration register
74 // 0x0C Data cache configuration register
75
76 // Cache Control Register Leon3 / Leon3FT
77 // 31..30 29 28 27..24 23 22 21 20..19 18 17 16
78 // RFT PS TB DS FD FI FT ST IB
79 // 15 14 13..12 11..10 9..8 7..6 5 4 3..2 1..0
80 // IP DP ITE IDE DTE DDE DF IF DCS ICS
81
67 82 unsigned int cacheControlRegister;
68 83
69 cacheControlRegister = getCacheControlRegister();
70 PRINTF1("(0) cacheControlRegister = %x\n", cacheControlRegister)
84 cacheControlRegister = CCR_getValue();
85 PRINTF1("(0) cacheControlRegister = %x\n", cacheControlRegister);
71 86
72 resetCacheControlRegister();
87 CCR_resetCacheControlRegister();
73 88
74 enableInstructionCache();
75 enableDataCache();
76 enableInstructionBurstFetch();
89 CCR_enableInstructionCache(); // ICS bits
90 CCR_enableDataCache(); // DCS bits
91 CCR_enableInstructionBurstFetch(); // IB bit
77 92
78 cacheControlRegister = getCacheControlRegister();
79 PRINTF1("(1) cacheControlRegister = %x\n", cacheControlRegister)
93 cacheControlRegister = CCR_getValue();
94 PRINTF1("(1) cacheControlRegister = %x\n", cacheControlRegister);
95
96 CCR_faultTolerantScheme();
97
98 // FT activation
80 99 }
81 100
82 101 rtems_task Init( rtems_task_argument ignored )
83 102 {
84 103 /** This is the RTEMS INIT taks, it is the first task launched by the system.
85 104 *
86 105 * @param unused is the starting argument of the RTEMS task
87 106 *
88 107 * The INIT task create and run all other RTEMS tasks.
89 108 *
90 109 */
91 110
92 111 //***********
93 112 // INIT CACHE
94 113
95 114 unsigned char *vhdlVersion;
96 115
97 116 reset_lfr();
98 117
99 118 reset_local_time();
100 119
101 120 rtems_cpu_usage_reset();
102 121
103 122 rtems_status_code status;
104 123 rtems_status_code status_spw;
105 124 rtems_isr_entry old_isr_handler;
106 125
107 126 // UART settings
108 127 send_console_outputs_on_apbuart_port();
109 128 set_apbuart_scaler_reload_register(REGS_ADDR_APBUART, APBUART_SCALER_RELOAD_VALUE);
110 129 enable_apbuart_transmitter();
111 130
112 131 DEBUG_PRINTF("\n\n\n\n\nIn INIT *** Now the console is on port COM1\n")
113 132
114 133
115 134 PRINTF("\n\n\n\n\n")
116 135
117 136 initCache();
118 137
119 138 PRINTF("*************************\n")
120 139 PRINTF("** LFR Flight Software **\n")
121 140 PRINTF1("** %d.", SW_VERSION_N1)
122 141 PRINTF1("%d." , SW_VERSION_N2)
123 142 PRINTF1("%d." , SW_VERSION_N3)
124 143 PRINTF1("%d **\n", SW_VERSION_N4)
125 144
126 145 vhdlVersion = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
127 146 PRINTF("** VHDL **\n")
128 147 PRINTF1("** %d.", vhdlVersion[1])
129 148 PRINTF1("%d." , vhdlVersion[2])
130 149 PRINTF1("%d **\n", vhdlVersion[3])
131 150 PRINTF("*************************\n")
132 151 PRINTF("\n\n")
133 152
134 153 init_parameter_dump();
135 154 init_kcoefficients_dump();
136 155 init_local_mode_parameters();
137 156 init_housekeeping_parameters();
138 157 init_k_coefficients_prc0();
139 158 init_k_coefficients_prc1();
140 159 init_k_coefficients_prc2();
141 160 pa_bia_status_info = 0x00;
142 161 update_last_valid_transition_date( DEFAULT_LAST_VALID_TRANSITION_DATE );
143 162
144 163 // waveform picker initialization
145 164 WFP_init_rings(); LEON_Clear_interrupt( IRQ_SPARC_GPTIMER_WATCHDOG ); // initialize the waveform rings
146 165 WFP_reset_current_ring_nodes();
147 166 reset_waveform_picker_regs();
148 167
149 168 // spectral matrices initialization
150 169 SM_init_rings(); // initialize spectral matrices rings
151 170 SM_reset_current_ring_nodes();
152 171 reset_spectral_matrix_regs();
153 172
154 173 // configure calibration
155 174 configureCalibration( false ); // true means interleaved mode, false is for normal mode
156 175
157 176 updateLFRCurrentMode();
158 177
159 178 BOOT_PRINTF1("in INIT *** lfrCurrentMode is %d\n", lfrCurrentMode)
160 179
161 180 create_names(); // create all names
162 181
163 182 status = create_timecode_timer(); // create the timer used by timecode_irq_handler
164 183 if (status != RTEMS_SUCCESSFUL)
165 184 {
166 185 PRINTF1("in INIT *** ERR in create_timer_timecode, code %d", status)
167 186 }
168 187
169 188 status = create_message_queues(); // create message queues
170 189 if (status != RTEMS_SUCCESSFUL)
171 190 {
172 191 PRINTF1("in INIT *** ERR in create_message_queues, code %d", status)
173 192 }
174 193
175 194 status = create_all_tasks(); // create all tasks
176 195 if (status != RTEMS_SUCCESSFUL)
177 196 {
178 197 PRINTF1("in INIT *** ERR in create_all_tasks, code %d\n", status)
179 198 }
180 199
181 200 // **************************
182 201 // <SPACEWIRE INITIALIZATION>
183 202 grspw_timecode_callback = &timecode_irq_handler;
184 203
185 204 status_spw = spacewire_open_link(); // (1) open the link
186 205 if ( status_spw != RTEMS_SUCCESSFUL )
187 206 {
188 207 PRINTF1("in INIT *** ERR spacewire_open_link code %d\n", status_spw )
189 208 }
190 209
191 210 if ( status_spw == RTEMS_SUCCESSFUL ) // (2) configure the link
192 211 {
193 212 status_spw = spacewire_configure_link( fdSPW );
194 213 if ( status_spw != RTEMS_SUCCESSFUL )
195 214 {
196 215 PRINTF1("in INIT *** ERR spacewire_configure_link code %d\n", status_spw )
197 216 }
198 217 }
199 218
200 219 if ( status_spw == RTEMS_SUCCESSFUL) // (3) start the link
201 220 {
202 221 status_spw = spacewire_start_link( fdSPW );
203 222 if ( status_spw != RTEMS_SUCCESSFUL )
204 223 {
205 224 PRINTF1("in INIT *** ERR spacewire_start_link code %d\n", status_spw )
206 225 }
207 226 }
208 227 // </SPACEWIRE INITIALIZATION>
209 228 // ***************************
210 229
211 230 status = start_all_tasks(); // start all tasks
212 231 if (status != RTEMS_SUCCESSFUL)
213 232 {
214 233 PRINTF1("in INIT *** ERR in start_all_tasks, code %d", status)
215 234 }
216 235
217 236 // start RECV and SEND *AFTER* SpaceWire Initialization, due to the timeout of the start call during the initialization
218 237 status = start_recv_send_tasks();
219 238 if ( status != RTEMS_SUCCESSFUL )
220 239 {
221 240 PRINTF1("in INIT *** ERR start_recv_send_tasks code %d\n", status )
222 241 }
223 242
224 243 // suspend science tasks, they will be restarted later depending on the mode
225 244 status = suspend_science_tasks(); // suspend science tasks (not done in stop_current_mode if current mode = STANDBY)
226 245 if (status != RTEMS_SUCCESSFUL)
227 246 {
228 247 PRINTF1("in INIT *** in suspend_science_tasks *** ERR code: %d\n", status)
229 248 }
230 249
231 250 // configure IRQ handling for the waveform picker unit
232 251 status = rtems_interrupt_catch( waveforms_isr,
233 252 IRQ_SPARC_WAVEFORM_PICKER,
234 253 &old_isr_handler) ;
235 254 // configure IRQ handling for the spectral matrices unit
236 255 status = rtems_interrupt_catch( spectral_matrices_isr,
237 256 IRQ_SPARC_SPECTRAL_MATRIX,
238 257 &old_isr_handler) ;
239 258
240 259 // if the spacewire link is not up then send an event to the SPIQ task for link recovery
241 260 if ( status_spw != RTEMS_SUCCESSFUL )
242 261 {
243 262 status = rtems_event_send( Task_id[TASKID_SPIQ], SPW_LINKERR_EVENT );
244 263 if ( status != RTEMS_SUCCESSFUL ) {
245 264 PRINTF1("in INIT *** ERR rtems_event_send to SPIQ code %d\n", status )
246 265 }
247 266 }
248 267
249 268 BOOT_PRINTF("delete INIT\n")
250 269
251 270 set_hk_lfr_sc_potential_flag( true );
252 271
253 272 status = rtems_task_delete(RTEMS_SELF);
254 273
255 274 }
256 275
257 276 void init_local_mode_parameters( void )
258 277 {
259 278 /** This function initialize the param_local global variable with default values.
260 279 *
261 280 */
262 281
263 282 unsigned int i;
264 283
265 284 // LOCAL PARAMETERS
266 285
267 286 BOOT_PRINTF1("local_sbm1_nb_cwf_max %d \n", param_local.local_sbm1_nb_cwf_max)
268 287 BOOT_PRINTF1("local_sbm2_nb_cwf_max %d \n", param_local.local_sbm2_nb_cwf_max)
269 288 BOOT_PRINTF1("nb_interrupt_f0_MAX = %d\n", param_local.local_nb_interrupt_f0_MAX)
270 289
271 290 // init sequence counters
272 291
273 292 for(i = 0; i<SEQ_CNT_NB_DEST_ID; i++)
274 293 {
275 294 sequenceCounters_TC_EXE[i] = 0x00;
276 295 sequenceCounters_TM_DUMP[i] = 0x00;
277 296 }
278 297 sequenceCounters_SCIENCE_NORMAL_BURST = 0x00;
279 298 sequenceCounters_SCIENCE_SBM1_SBM2 = 0x00;
280 299 sequenceCounterHK = TM_PACKET_SEQ_CTRL_STANDALONE << 8;
281 300 }
282 301
283 302 void reset_local_time( void )
284 303 {
285 304 time_management_regs->ctrl = time_management_regs->ctrl | 0x02; // [0010] software reset, coarse time = 0x80000000
286 305 }
287 306
288 307 void create_names( void ) // create all names for tasks and queues
289 308 {
290 309 /** This function creates all RTEMS names used in the software for tasks and queues.
291 310 *
292 311 * @return RTEMS directive status codes:
293 312 * - RTEMS_SUCCESSFUL - successful completion
294 313 *
295 314 */
296 315
297 316 // task names
298 317 Task_name[TASKID_RECV] = rtems_build_name( 'R', 'E', 'C', 'V' );
299 318 Task_name[TASKID_ACTN] = rtems_build_name( 'A', 'C', 'T', 'N' );
300 319 Task_name[TASKID_SPIQ] = rtems_build_name( 'S', 'P', 'I', 'Q' );
301 320 Task_name[TASKID_LOAD] = rtems_build_name( 'L', 'O', 'A', 'D' );
302 321 Task_name[TASKID_AVF0] = rtems_build_name( 'A', 'V', 'F', '0' );
303 322 Task_name[TASKID_SWBD] = rtems_build_name( 'S', 'W', 'B', 'D' );
304 323 Task_name[TASKID_WFRM] = rtems_build_name( 'W', 'F', 'R', 'M' );
305 324 Task_name[TASKID_DUMB] = rtems_build_name( 'D', 'U', 'M', 'B' );
306 325 Task_name[TASKID_HOUS] = rtems_build_name( 'H', 'O', 'U', 'S' );
307 326 Task_name[TASKID_PRC0] = rtems_build_name( 'P', 'R', 'C', '0' );
308 327 Task_name[TASKID_CWF3] = rtems_build_name( 'C', 'W', 'F', '3' );
309 328 Task_name[TASKID_CWF2] = rtems_build_name( 'C', 'W', 'F', '2' );
310 329 Task_name[TASKID_CWF1] = rtems_build_name( 'C', 'W', 'F', '1' );
311 330 Task_name[TASKID_SEND] = rtems_build_name( 'S', 'E', 'N', 'D' );
312 331 Task_name[TASKID_WTDG] = rtems_build_name( 'W', 'T', 'D', 'G' );
313 332 Task_name[TASKID_AVF1] = rtems_build_name( 'A', 'V', 'F', '1' );
314 333 Task_name[TASKID_PRC1] = rtems_build_name( 'P', 'R', 'C', '1' );
315 334 Task_name[TASKID_AVF2] = rtems_build_name( 'A', 'V', 'F', '2' );
316 335 Task_name[TASKID_PRC2] = rtems_build_name( 'P', 'R', 'C', '2' );
317 336
318 337 // rate monotonic period names
319 338 name_hk_rate_monotonic = rtems_build_name( 'H', 'O', 'U', 'S' );
320 339
321 340 misc_name[QUEUE_RECV] = rtems_build_name( 'Q', '_', 'R', 'V' );
322 341 misc_name[QUEUE_SEND] = rtems_build_name( 'Q', '_', 'S', 'D' );
323 342 misc_name[QUEUE_PRC0] = rtems_build_name( 'Q', '_', 'P', '0' );
324 343 misc_name[QUEUE_PRC1] = rtems_build_name( 'Q', '_', 'P', '1' );
325 344 misc_name[QUEUE_PRC2] = rtems_build_name( 'Q', '_', 'P', '2' );
326 345
327 346 timecode_timer_name = rtems_build_name( 'S', 'P', 'T', 'C' );
328 347 }
329 348
330 349 int create_all_tasks( void ) // create all tasks which run in the software
331 350 {
332 351 /** This function creates all RTEMS tasks used in the software.
333 352 *
334 353 * @return RTEMS directive status codes:
335 354 * - RTEMS_SUCCESSFUL - task created successfully
336 355 * - RTEMS_INVALID_ADDRESS - id is NULL
337 356 * - RTEMS_INVALID_NAME - invalid task name
338 357 * - RTEMS_INVALID_PRIORITY - invalid task priority
339 358 * - RTEMS_MP_NOT_CONFIGURED - multiprocessing not configured
340 359 * - RTEMS_TOO_MANY - too many tasks created
341 360 * - RTEMS_UNSATISFIED - not enough memory for stack/FP context
342 361 * - RTEMS_TOO_MANY - too many global objects
343 362 *
344 363 */
345 364
346 365 rtems_status_code status;
347 366
348 367 //**********
349 368 // SPACEWIRE
350 369 // RECV
351 370 status = rtems_task_create(
352 371 Task_name[TASKID_RECV], TASK_PRIORITY_RECV, RTEMS_MINIMUM_STACK_SIZE,
353 372 RTEMS_DEFAULT_MODES,
354 373 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_RECV]
355 374 );
356 375 if (status == RTEMS_SUCCESSFUL) // SEND
357 376 {
358 377 status = rtems_task_create(
359 378 Task_name[TASKID_SEND], TASK_PRIORITY_SEND, RTEMS_MINIMUM_STACK_SIZE * 2,
360 379 RTEMS_DEFAULT_MODES,
361 380 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SEND]
362 381 );
363 382 }
364 383 if (status == RTEMS_SUCCESSFUL) // WTDG
365 384 {
366 385 status = rtems_task_create(
367 386 Task_name[TASKID_WTDG], TASK_PRIORITY_WTDG, RTEMS_MINIMUM_STACK_SIZE,
368 387 RTEMS_DEFAULT_MODES,
369 388 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_WTDG]
370 389 );
371 390 }
372 391 if (status == RTEMS_SUCCESSFUL) // ACTN
373 392 {
374 393 status = rtems_task_create(
375 394 Task_name[TASKID_ACTN], TASK_PRIORITY_ACTN, RTEMS_MINIMUM_STACK_SIZE,
376 395 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
377 396 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_ACTN]
378 397 );
379 398 }
380 399 if (status == RTEMS_SUCCESSFUL) // SPIQ
381 400 {
382 401 status = rtems_task_create(
383 402 Task_name[TASKID_SPIQ], TASK_PRIORITY_SPIQ, RTEMS_MINIMUM_STACK_SIZE,
384 403 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
385 404 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SPIQ]
386 405 );
387 406 }
388 407
389 408 //******************
390 409 // SPECTRAL MATRICES
391 410 if (status == RTEMS_SUCCESSFUL) // AVF0
392 411 {
393 412 status = rtems_task_create(
394 413 Task_name[TASKID_AVF0], TASK_PRIORITY_AVF0, RTEMS_MINIMUM_STACK_SIZE,
395 414 RTEMS_DEFAULT_MODES,
396 415 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF0]
397 416 );
398 417 }
399 418 if (status == RTEMS_SUCCESSFUL) // PRC0
400 419 {
401 420 status = rtems_task_create(
402 421 Task_name[TASKID_PRC0], TASK_PRIORITY_PRC0, RTEMS_MINIMUM_STACK_SIZE * 2,
403 422 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
404 423 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC0]
405 424 );
406 425 }
407 426 if (status == RTEMS_SUCCESSFUL) // AVF1
408 427 {
409 428 status = rtems_task_create(
410 429 Task_name[TASKID_AVF1], TASK_PRIORITY_AVF1, RTEMS_MINIMUM_STACK_SIZE,
411 430 RTEMS_DEFAULT_MODES,
412 431 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF1]
413 432 );
414 433 }
415 434 if (status == RTEMS_SUCCESSFUL) // PRC1
416 435 {
417 436 status = rtems_task_create(
418 437 Task_name[TASKID_PRC1], TASK_PRIORITY_PRC1, RTEMS_MINIMUM_STACK_SIZE * 2,
419 438 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
420 439 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC1]
421 440 );
422 441 }
423 442 if (status == RTEMS_SUCCESSFUL) // AVF2
424 443 {
425 444 status = rtems_task_create(
426 445 Task_name[TASKID_AVF2], TASK_PRIORITY_AVF2, RTEMS_MINIMUM_STACK_SIZE,
427 446 RTEMS_DEFAULT_MODES,
428 447 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_AVF2]
429 448 );
430 449 }
431 450 if (status == RTEMS_SUCCESSFUL) // PRC2
432 451 {
433 452 status = rtems_task_create(
434 453 Task_name[TASKID_PRC2], TASK_PRIORITY_PRC2, RTEMS_MINIMUM_STACK_SIZE * 2,
435 454 RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT,
436 455 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_PRC2]
437 456 );
438 457 }
439 458
440 459 //****************
441 460 // WAVEFORM PICKER
442 461 if (status == RTEMS_SUCCESSFUL) // WFRM
443 462 {
444 463 status = rtems_task_create(
445 464 Task_name[TASKID_WFRM], TASK_PRIORITY_WFRM, RTEMS_MINIMUM_STACK_SIZE,
446 465 RTEMS_DEFAULT_MODES,
447 466 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_WFRM]
448 467 );
449 468 }
450 469 if (status == RTEMS_SUCCESSFUL) // CWF3
451 470 {
452 471 status = rtems_task_create(
453 472 Task_name[TASKID_CWF3], TASK_PRIORITY_CWF3, RTEMS_MINIMUM_STACK_SIZE,
454 473 RTEMS_DEFAULT_MODES,
455 474 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF3]
456 475 );
457 476 }
458 477 if (status == RTEMS_SUCCESSFUL) // CWF2
459 478 {
460 479 status = rtems_task_create(
461 480 Task_name[TASKID_CWF2], TASK_PRIORITY_CWF2, RTEMS_MINIMUM_STACK_SIZE,
462 481 RTEMS_DEFAULT_MODES,
463 482 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF2]
464 483 );
465 484 }
466 485 if (status == RTEMS_SUCCESSFUL) // CWF1
467 486 {
468 487 status = rtems_task_create(
469 488 Task_name[TASKID_CWF1], TASK_PRIORITY_CWF1, RTEMS_MINIMUM_STACK_SIZE,
470 489 RTEMS_DEFAULT_MODES,
471 490 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_CWF1]
472 491 );
473 492 }
474 493 if (status == RTEMS_SUCCESSFUL) // SWBD
475 494 {
476 495 status = rtems_task_create(
477 496 Task_name[TASKID_SWBD], TASK_PRIORITY_SWBD, RTEMS_MINIMUM_STACK_SIZE,
478 497 RTEMS_DEFAULT_MODES,
479 498 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_SWBD]
480 499 );
481 500 }
482 501
483 502 //*****
484 503 // MISC
485 504 if (status == RTEMS_SUCCESSFUL) // LOAD
486 505 {
487 506 status = rtems_task_create(
488 507 Task_name[TASKID_LOAD], TASK_PRIORITY_LOAD, RTEMS_MINIMUM_STACK_SIZE,
489 508 RTEMS_DEFAULT_MODES,
490 509 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_LOAD]
491 510 );
492 511 }
493 512 if (status == RTEMS_SUCCESSFUL) // DUMB
494 513 {
495 514 status = rtems_task_create(
496 515 Task_name[TASKID_DUMB], TASK_PRIORITY_DUMB, RTEMS_MINIMUM_STACK_SIZE,
497 516 RTEMS_DEFAULT_MODES,
498 517 RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_DUMB]
499 518 );
500 519 }
501 520 if (status == RTEMS_SUCCESSFUL) // HOUS
502 521 {
503 522 status = rtems_task_create(
504 523 Task_name[TASKID_HOUS], TASK_PRIORITY_HOUS, RTEMS_MINIMUM_STACK_SIZE,
505 524 RTEMS_DEFAULT_MODES,
506 525 RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &Task_id[TASKID_HOUS]
507 526 );
508 527 }
509 528
510 529 return status;
511 530 }
512 531
513 532 int start_recv_send_tasks( void )
514 533 {
515 534 rtems_status_code status;
516 535
517 536 status = rtems_task_start( Task_id[TASKID_RECV], recv_task, 1 );
518 537 if (status!=RTEMS_SUCCESSFUL) {
519 538 BOOT_PRINTF("in INIT *** Error starting TASK_RECV\n")
520 539 }
521 540
522 541 if (status == RTEMS_SUCCESSFUL) // SEND
523 542 {
524 543 status = rtems_task_start( Task_id[TASKID_SEND], send_task, 1 );
525 544 if (status!=RTEMS_SUCCESSFUL) {
526 545 BOOT_PRINTF("in INIT *** Error starting TASK_SEND\n")
527 546 }
528 547 }
529 548
530 549 return status;
531 550 }
532 551
533 552 int start_all_tasks( void ) // start all tasks except SEND RECV and HOUS
534 553 {
535 554 /** This function starts all RTEMS tasks used in the software.
536 555 *
537 556 * @return RTEMS directive status codes:
538 557 * - RTEMS_SUCCESSFUL - ask started successfully
539 558 * - RTEMS_INVALID_ADDRESS - invalid task entry point
540 559 * - RTEMS_INVALID_ID - invalid task id
541 560 * - RTEMS_INCORRECT_STATE - task not in the dormant state
542 561 * - RTEMS_ILLEGAL_ON_REMOTE_OBJECT - cannot start remote task
543 562 *
544 563 */
545 564 // starts all the tasks fot eh flight software
546 565
547 566 rtems_status_code status;
548 567
549 568 //**********
550 569 // SPACEWIRE
551 570 status = rtems_task_start( Task_id[TASKID_SPIQ], spiq_task, 1 );
552 571 if (status!=RTEMS_SUCCESSFUL) {
553 572 BOOT_PRINTF("in INIT *** Error starting TASK_SPIQ\n")
554 573 }
555 574
556 575 if (status == RTEMS_SUCCESSFUL) // WTDG
557 576 {
558 577 status = rtems_task_start( Task_id[TASKID_WTDG], wtdg_task, 1 );
559 578 if (status!=RTEMS_SUCCESSFUL) {
560 579 BOOT_PRINTF("in INIT *** Error starting TASK_WTDG\n")
561 580 }
562 581 }
563 582
564 583 if (status == RTEMS_SUCCESSFUL) // ACTN
565 584 {
566 585 status = rtems_task_start( Task_id[TASKID_ACTN], actn_task, 1 );
567 586 if (status!=RTEMS_SUCCESSFUL) {
568 587 BOOT_PRINTF("in INIT *** Error starting TASK_ACTN\n")
569 588 }
570 589 }
571 590
572 591 //******************
573 592 // SPECTRAL MATRICES
574 593 if (status == RTEMS_SUCCESSFUL) // AVF0
575 594 {
576 595 status = rtems_task_start( Task_id[TASKID_AVF0], avf0_task, LFR_MODE_STANDBY );
577 596 if (status!=RTEMS_SUCCESSFUL) {
578 597 BOOT_PRINTF("in INIT *** Error starting TASK_AVF0\n")
579 598 }
580 599 }
581 600 if (status == RTEMS_SUCCESSFUL) // PRC0
582 601 {
583 602 status = rtems_task_start( Task_id[TASKID_PRC0], prc0_task, LFR_MODE_STANDBY );
584 603 if (status!=RTEMS_SUCCESSFUL) {
585 604 BOOT_PRINTF("in INIT *** Error starting TASK_PRC0\n")
586 605 }
587 606 }
588 607 if (status == RTEMS_SUCCESSFUL) // AVF1
589 608 {
590 609 status = rtems_task_start( Task_id[TASKID_AVF1], avf1_task, LFR_MODE_STANDBY );
591 610 if (status!=RTEMS_SUCCESSFUL) {
592 611 BOOT_PRINTF("in INIT *** Error starting TASK_AVF1\n")
593 612 }
594 613 }
595 614 if (status == RTEMS_SUCCESSFUL) // PRC1
596 615 {
597 616 status = rtems_task_start( Task_id[TASKID_PRC1], prc1_task, LFR_MODE_STANDBY );
598 617 if (status!=RTEMS_SUCCESSFUL) {
599 618 BOOT_PRINTF("in INIT *** Error starting TASK_PRC1\n")
600 619 }
601 620 }
602 621 if (status == RTEMS_SUCCESSFUL) // AVF2
603 622 {
604 623 status = rtems_task_start( Task_id[TASKID_AVF2], avf2_task, 1 );
605 624 if (status!=RTEMS_SUCCESSFUL) {
606 625 BOOT_PRINTF("in INIT *** Error starting TASK_AVF2\n")
607 626 }
608 627 }
609 628 if (status == RTEMS_SUCCESSFUL) // PRC2
610 629 {
611 630 status = rtems_task_start( Task_id[TASKID_PRC2], prc2_task, 1 );
612 631 if (status!=RTEMS_SUCCESSFUL) {
613 632 BOOT_PRINTF("in INIT *** Error starting TASK_PRC2\n")
614 633 }
615 634 }
616 635
617 636 //****************
618 637 // WAVEFORM PICKER
619 638 if (status == RTEMS_SUCCESSFUL) // WFRM
620 639 {
621 640 status = rtems_task_start( Task_id[TASKID_WFRM], wfrm_task, 1 );
622 641 if (status!=RTEMS_SUCCESSFUL) {
623 642 BOOT_PRINTF("in INIT *** Error starting TASK_WFRM\n")
624 643 }
625 644 }
626 645 if (status == RTEMS_SUCCESSFUL) // CWF3
627 646 {
628 647 status = rtems_task_start( Task_id[TASKID_CWF3], cwf3_task, 1 );
629 648 if (status!=RTEMS_SUCCESSFUL) {
630 649 BOOT_PRINTF("in INIT *** Error starting TASK_CWF3\n")
631 650 }
632 651 }
633 652 if (status == RTEMS_SUCCESSFUL) // CWF2
634 653 {
635 654 status = rtems_task_start( Task_id[TASKID_CWF2], cwf2_task, 1 );
636 655 if (status!=RTEMS_SUCCESSFUL) {
637 656 BOOT_PRINTF("in INIT *** Error starting TASK_CWF2\n")
638 657 }
639 658 }
640 659 if (status == RTEMS_SUCCESSFUL) // CWF1
641 660 {
642 661 status = rtems_task_start( Task_id[TASKID_CWF1], cwf1_task, 1 );
643 662 if (status!=RTEMS_SUCCESSFUL) {
644 663 BOOT_PRINTF("in INIT *** Error starting TASK_CWF1\n")
645 664 }
646 665 }
647 666 if (status == RTEMS_SUCCESSFUL) // SWBD
648 667 {
649 668 status = rtems_task_start( Task_id[TASKID_SWBD], swbd_task, 1 );
650 669 if (status!=RTEMS_SUCCESSFUL) {
651 670 BOOT_PRINTF("in INIT *** Error starting TASK_SWBD\n")
652 671 }
653 672 }
654 673
655 674 //*****
656 675 // MISC
657 676 if (status == RTEMS_SUCCESSFUL) // HOUS
658 677 {
659 678 status = rtems_task_start( Task_id[TASKID_HOUS], hous_task, 1 );
660 679 if (status!=RTEMS_SUCCESSFUL) {
661 680 BOOT_PRINTF("in INIT *** Error starting TASK_HOUS\n")
662 681 }
663 682 }
664 683 if (status == RTEMS_SUCCESSFUL) // DUMB
665 684 {
666 685 status = rtems_task_start( Task_id[TASKID_DUMB], dumb_task, 1 );
667 686 if (status!=RTEMS_SUCCESSFUL) {
668 687 BOOT_PRINTF("in INIT *** Error starting TASK_DUMB\n")
669 688 }
670 689 }
671 690 if (status == RTEMS_SUCCESSFUL) // LOAD
672 691 {
673 692 status = rtems_task_start( Task_id[TASKID_LOAD], load_task, 1 );
674 693 if (status!=RTEMS_SUCCESSFUL) {
675 694 BOOT_PRINTF("in INIT *** Error starting TASK_LOAD\n")
676 695 }
677 696 }
678 697
679 698 return status;
680 699 }
681 700
682 701 rtems_status_code create_message_queues( void ) // create the two message queues used in the software
683 702 {
684 703 rtems_status_code status_recv;
685 704 rtems_status_code status_send;
686 705 rtems_status_code status_q_p0;
687 706 rtems_status_code status_q_p1;
688 707 rtems_status_code status_q_p2;
689 708 rtems_status_code ret;
690 709 rtems_id queue_id;
691 710
692 711 //****************************************
693 712 // create the queue for handling valid TCs
694 713 status_recv = rtems_message_queue_create( misc_name[QUEUE_RECV],
695 714 MSG_QUEUE_COUNT_RECV, CCSDS_TC_PKT_MAX_SIZE,
696 715 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
697 716 if ( status_recv != RTEMS_SUCCESSFUL ) {
698 717 PRINTF1("in create_message_queues *** ERR creating QUEU queue, %d\n", status_recv)
699 718 }
700 719
701 720 //************************************************
702 721 // create the queue for handling TM packet sending
703 722 status_send = rtems_message_queue_create( misc_name[QUEUE_SEND],
704 723 MSG_QUEUE_COUNT_SEND, MSG_QUEUE_SIZE_SEND,
705 724 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
706 725 if ( status_send != RTEMS_SUCCESSFUL ) {
707 726 PRINTF1("in create_message_queues *** ERR creating PKTS queue, %d\n", status_send)
708 727 }
709 728
710 729 //*****************************************************************************
711 730 // create the queue for handling averaged spectral matrices for processing @ f0
712 731 status_q_p0 = rtems_message_queue_create( misc_name[QUEUE_PRC0],
713 732 MSG_QUEUE_COUNT_PRC0, MSG_QUEUE_SIZE_PRC0,
714 733 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
715 734 if ( status_q_p0 != RTEMS_SUCCESSFUL ) {
716 735 PRINTF1("in create_message_queues *** ERR creating Q_P0 queue, %d\n", status_q_p0)
717 736 }
718 737
719 738 //*****************************************************************************
720 739 // create the queue for handling averaged spectral matrices for processing @ f1
721 740 status_q_p1 = rtems_message_queue_create( misc_name[QUEUE_PRC1],
722 741 MSG_QUEUE_COUNT_PRC1, MSG_QUEUE_SIZE_PRC1,
723 742 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
724 743 if ( status_q_p1 != RTEMS_SUCCESSFUL ) {
725 744 PRINTF1("in create_message_queues *** ERR creating Q_P1 queue, %d\n", status_q_p1)
726 745 }
727 746
728 747 //*****************************************************************************
729 748 // create the queue for handling averaged spectral matrices for processing @ f2
730 749 status_q_p2 = rtems_message_queue_create( misc_name[QUEUE_PRC2],
731 750 MSG_QUEUE_COUNT_PRC2, MSG_QUEUE_SIZE_PRC2,
732 751 RTEMS_FIFO | RTEMS_LOCAL, &queue_id );
733 752 if ( status_q_p2 != RTEMS_SUCCESSFUL ) {
734 753 PRINTF1("in create_message_queues *** ERR creating Q_P2 queue, %d\n", status_q_p2)
735 754 }
736 755
737 756 if ( status_recv != RTEMS_SUCCESSFUL )
738 757 {
739 758 ret = status_recv;
740 759 }
741 760 else if( status_send != RTEMS_SUCCESSFUL )
742 761 {
743 762 ret = status_send;
744 763 }
745 764 else if( status_q_p0 != RTEMS_SUCCESSFUL )
746 765 {
747 766 ret = status_q_p0;
748 767 }
749 768 else if( status_q_p1 != RTEMS_SUCCESSFUL )
750 769 {
751 770 ret = status_q_p1;
752 771 }
753 772 else
754 773 {
755 774 ret = status_q_p2;
756 775 }
757 776
758 777 return ret;
759 778 }
760 779
761 780 rtems_status_code create_timecode_timer( void )
762 781 {
763 782 rtems_status_code status;
764 783
765 784 status = rtems_timer_create( timecode_timer_name, &timecode_timer_id );
766 785
767 786 if ( status != RTEMS_SUCCESSFUL )
768 787 {
769 788 PRINTF1("in create_timer_timecode *** ERR creating SPTC timer, %d\n", status)
770 789 }
771 790 else
772 791 {
773 792 PRINTF("in create_timer_timecode *** OK creating SPTC timer\n")
774 793 }
775 794
776 795 return status;
777 796 }
778 797
779 798 rtems_status_code get_message_queue_id_send( rtems_id *queue_id )
780 799 {
781 800 rtems_status_code status;
782 801 rtems_name queue_name;
783 802
784 803 queue_name = rtems_build_name( 'Q', '_', 'S', 'D' );
785 804
786 805 status = rtems_message_queue_ident( queue_name, 0, queue_id );
787 806
788 807 return status;
789 808 }
790 809
791 810 rtems_status_code get_message_queue_id_recv( rtems_id *queue_id )
792 811 {
793 812 rtems_status_code status;
794 813 rtems_name queue_name;
795 814
796 815 queue_name = rtems_build_name( 'Q', '_', 'R', 'V' );
797 816
798 817 status = rtems_message_queue_ident( queue_name, 0, queue_id );
799 818
800 819 return status;
801 820 }
802 821
803 822 rtems_status_code get_message_queue_id_prc0( rtems_id *queue_id )
804 823 {
805 824 rtems_status_code status;
806 825 rtems_name queue_name;
807 826
808 827 queue_name = rtems_build_name( 'Q', '_', 'P', '0' );
809 828
810 829 status = rtems_message_queue_ident( queue_name, 0, queue_id );
811 830
812 831 return status;
813 832 }
814 833
815 834 rtems_status_code get_message_queue_id_prc1( rtems_id *queue_id )
816 835 {
817 836 rtems_status_code status;
818 837 rtems_name queue_name;
819 838
820 839 queue_name = rtems_build_name( 'Q', '_', 'P', '1' );
821 840
822 841 status = rtems_message_queue_ident( queue_name, 0, queue_id );
823 842
824 843 return status;
825 844 }
826 845
827 846 rtems_status_code get_message_queue_id_prc2( rtems_id *queue_id )
828 847 {
829 848 rtems_status_code status;
830 849 rtems_name queue_name;
831 850
832 851 queue_name = rtems_build_name( 'Q', '_', 'P', '2' );
833 852
834 853 status = rtems_message_queue_ident( queue_name, 0, queue_id );
835 854
836 855 return status;
837 856 }
838 857
839 858 void update_queue_max_count( rtems_id queue_id, unsigned char*fifo_size_max )
840 859 {
841 860 u_int32_t count;
842 861 rtems_status_code status;
843 862
844 863 status = rtems_message_queue_get_number_pending( queue_id, &count );
845 864
846 865 count = count + 1;
847 866
848 867 if (status != RTEMS_SUCCESSFUL)
849 868 {
850 869 PRINTF1("in update_queue_max_count *** ERR = %d\n", status)
851 870 }
852 871 else
853 872 {
854 873 if (count > *fifo_size_max)
855 874 {
856 875 *fifo_size_max = count;
857 876 }
858 877 }
859 878 }
860 879
861 880 void init_ring(ring_node ring[], unsigned char nbNodes, volatile int buffer[], unsigned int bufferSize )
862 881 {
863 882 unsigned char i;
864 883
865 884 //***************
866 885 // BUFFER ADDRESS
867 886 for(i=0; i<nbNodes; i++)
868 887 {
869 888 ring[i].coarseTime = 0xffffffff;
870 889 ring[i].fineTime = 0xffffffff;
871 890 ring[i].sid = 0x00;
872 891 ring[i].status = 0x00;
873 892 ring[i].buffer_address = (int) &buffer[ i * bufferSize ];
874 893 }
875 894
876 895 //*****
877 896 // NEXT
878 897 ring[ nbNodes - 1 ].next = (ring_node*) &ring[ 0 ];
879 898 for(i=0; i<nbNodes-1; i++)
880 899 {
881 900 ring[i].next = (ring_node*) &ring[ i + 1 ];
882 901 }
883 902
884 903 //*********
885 904 // PREVIOUS
886 905 ring[ 0 ].previous = (ring_node*) &ring[ nbNodes - 1 ];
887 906 for(i=1; i<nbNodes; i++)
888 907 {
889 908 ring[i].previous = (ring_node*) &ring[ i - 1 ];
890 909 }
891 910 }
@@ -1,742 +1,745
1 1 /** General usage functions and RTEMS tasks.
2 2 *
3 3 * @file
4 4 * @author P. LEROY
5 5 *
6 6 */
7 7
8 8 #include "fsw_misc.h"
9 9
10 10 void timer_configure(unsigned char timer, unsigned int clock_divider,
11 11 unsigned char interrupt_level, rtems_isr (*timer_isr)() )
12 12 {
13 13 /** This function configures a GPTIMER timer instantiated in the VHDL design.
14 14 *
15 15 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
16 16 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
17 17 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
18 18 * @param interrupt_level is the interrupt level that the timer drives.
19 19 * @param timer_isr is the interrupt subroutine that will be attached to the IRQ driven by the timer.
20 20 *
21 21 * Interrupt levels are described in the SPARC documentation sparcv8.pdf p.76
22 22 *
23 23 */
24 24
25 25 rtems_status_code status;
26 26 rtems_isr_entry old_isr_handler;
27 27
28 28 gptimer_regs->timer[timer].ctrl = 0x00; // reset the control register
29 29
30 30 status = rtems_interrupt_catch( timer_isr, interrupt_level, &old_isr_handler) ; // see sparcv8.pdf p.76 for interrupt levels
31 31 if (status!=RTEMS_SUCCESSFUL)
32 32 {
33 33 PRINTF("in configure_timer *** ERR rtems_interrupt_catch\n")
34 34 }
35 35
36 36 timer_set_clock_divider( timer, clock_divider);
37 37 }
38 38
39 39 void timer_start(unsigned char timer)
40 40 {
41 41 /** This function starts a GPTIMER timer.
42 42 *
43 43 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
44 44 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
45 45 *
46 46 */
47 47
48 48 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
49 49 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000004; // LD load value from the reload register
50 50 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000001; // EN enable the timer
51 51 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000002; // RS restart
52 52 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000008; // IE interrupt enable
53 53 }
54 54
55 55 void timer_stop(unsigned char timer)
56 56 {
57 57 /** This function stops a GPTIMER timer.
58 58 *
59 59 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
60 60 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
61 61 *
62 62 */
63 63
64 64 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xfffffffe; // EN enable the timer
65 65 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl & 0xffffffef; // IE interrupt enable
66 66 gptimer_regs->timer[timer].ctrl = gptimer_regs->timer[timer].ctrl | 0x00000010; // clear pending IRQ if any
67 67 }
68 68
69 69 void timer_set_clock_divider(unsigned char timer, unsigned int clock_divider)
70 70 {
71 71 /** This function sets the clock divider of a GPTIMER timer.
72 72 *
73 73 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
74 74 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
75 75 * @param clock_divider is the divider of the 1 MHz clock that will be configured.
76 76 *
77 77 */
78 78
79 79 gptimer_regs->timer[timer].reload = clock_divider; // base clock frequency is 1 MHz
80 80 }
81 81
82 82 // WATCHDOG
83 83
84 84 rtems_isr watchdog_isr( rtems_vector_number vector )
85 85 {
86 86 rtems_status_code status_code;
87 87
88 88 status_code = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_12 );
89 89 }
90 90
91 91 void watchdog_configure(void)
92 92 {
93 93 /** This function configure the watchdog.
94 94 *
95 95 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
96 96 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
97 97 *
98 98 * The watchdog is a timer provided by the GPTIMER IP core of the GRLIB.
99 99 *
100 100 */
101 101
102 102 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt during configuration
103 103
104 104 timer_configure( TIMER_WATCHDOG, CLKDIV_WATCHDOG, IRQ_SPARC_GPTIMER_WATCHDOG, watchdog_isr );
105 105
106 106 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
107 107 }
108 108
109 109 void watchdog_stop(void)
110 110 {
111 111 LEON_Mask_interrupt( IRQ_GPTIMER_WATCHDOG ); // mask gptimer/watchdog interrupt line
112 112 timer_stop( TIMER_WATCHDOG );
113 113 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG ); // clear gptimer/watchdog interrupt
114 114 }
115 115
116 116 void watchdog_reload(void)
117 117 {
118 118 /** This function reloads the watchdog timer counter with the timer reload value.
119 119 *
120 * @param void
121 *
122 * @return void
120 123 *
121 124 */
122 125
123 126 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000004; // LD load value from the reload register
124 127 }
125 128
126 129 void watchdog_start(void)
127 130 {
128 131 /** This function starts the watchdog timer.
129 132 *
130 133 * @param gptimer_regs points to the APB registers of the GPTIMER IP core.
131 134 * @param timer is the number of the timer in the IP core (several timers can be instantiated).
132 135 *
133 136 */
134 137
135 138 LEON_Clear_interrupt( IRQ_GPTIMER_WATCHDOG );
136 139
137 140 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000010; // clear pending IRQ if any
138 141 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000004; // LD load value from the reload register
139 142 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000001; // EN enable the timer
140 143 gptimer_regs->timer[TIMER_WATCHDOG].ctrl = gptimer_regs->timer[TIMER_WATCHDOG].ctrl | 0x00000008; // IE interrupt enable
141 144
142 145 LEON_Unmask_interrupt( IRQ_GPTIMER_WATCHDOG );
143 146
144 147 }
145 148
146 149 int send_console_outputs_on_apbuart_port( void ) // Send the console outputs on the apbuart port
147 150 {
148 151 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
149 152
150 153 apbuart_regs->ctrl = APBUART_CTRL_REG_MASK_TE;
151 154
152 155 return 0;
153 156 }
154 157
155 158 int enable_apbuart_transmitter( void ) // set the bit 1, TE Transmitter Enable to 1 in the APBUART control register
156 159 {
157 160 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) REGS_ADDR_APBUART;
158 161
159 162 apbuart_regs->ctrl = apbuart_regs->ctrl | APBUART_CTRL_REG_MASK_TE;
160 163
161 164 return 0;
162 165 }
163 166
164 167 void set_apbuart_scaler_reload_register(unsigned int regs, unsigned int value)
165 168 {
166 169 /** This function sets the scaler reload register of the apbuart module
167 170 *
168 171 * @param regs is the address of the apbuart registers in memory
169 172 * @param value is the value that will be stored in the scaler register
170 173 *
171 174 * The value shall be set by the software to get data on the serial interface.
172 175 *
173 176 */
174 177
175 178 struct apbuart_regs_str *apbuart_regs = (struct apbuart_regs_str *) regs;
176 179
177 180 apbuart_regs->scaler = value;
178 181 BOOT_PRINTF1("OK *** apbuart port scaler reload register set to 0x%x\n", value)
179 182 }
180 183
181 184 //************
182 185 // RTEMS TASKS
183 186
184 187 rtems_task load_task(rtems_task_argument argument)
185 188 {
186 189 BOOT_PRINTF("in LOAD *** \n")
187 190
188 191 rtems_status_code status;
189 192 unsigned int i;
190 193 unsigned int j;
191 194 rtems_name name_watchdog_rate_monotonic; // name of the watchdog rate monotonic
192 195 rtems_id watchdog_period_id; // id of the watchdog rate monotonic period
193 196
194 197 name_watchdog_rate_monotonic = rtems_build_name( 'L', 'O', 'A', 'D' );
195 198
196 199 status = rtems_rate_monotonic_create( name_watchdog_rate_monotonic, &watchdog_period_id );
197 200 if( status != RTEMS_SUCCESSFUL ) {
198 201 PRINTF1( "in LOAD *** rtems_rate_monotonic_create failed with status of %d\n", status )
199 202 }
200 203
201 204 i = 0;
202 205 j = 0;
203 206
204 207 watchdog_configure();
205 208
206 209 watchdog_start();
207 210
208 211 while(1){
209 212 status = rtems_rate_monotonic_period( watchdog_period_id, WATCHDOG_PERIOD );
210 213 watchdog_reload();
211 214 i = i + 1;
212 215 if ( i == 10 )
213 216 {
214 217 i = 0;
215 218 j = j + 1;
216 219 PRINTF1("%d\n", j)
217 220 }
218 221 #ifdef DEBUG_WATCHDOG
219 222 if (j == 3 )
220 223 {
221 224 status = rtems_task_delete(RTEMS_SELF);
222 225 }
223 226 #endif
224 227 }
225 228 }
226 229
227 230 rtems_task hous_task(rtems_task_argument argument)
228 231 {
229 232 rtems_status_code status;
230 233 rtems_status_code spare_status;
231 234 rtems_id queue_id;
232 235 rtems_rate_monotonic_period_status period_status;
233 236
234 237 status = get_message_queue_id_send( &queue_id );
235 238 if (status != RTEMS_SUCCESSFUL)
236 239 {
237 240 PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status)
238 241 }
239 242
240 243 BOOT_PRINTF("in HOUS ***\n")
241 244
242 245 if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) {
243 246 status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id );
244 247 if( status != RTEMS_SUCCESSFUL ) {
245 248 PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status )
246 249 }
247 250 }
248 251
249 252 status = rtems_rate_monotonic_cancel(HK_id);
250 253 if( status != RTEMS_SUCCESSFUL ) {
251 254 PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status )
252 255 }
253 256 else {
254 257 DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n")
255 258 }
256 259
257 260 // startup phase
258 261 status = rtems_rate_monotonic_period( HK_id, SY_LFR_TIME_SYN_TIMEOUT_in_ticks );
259 262 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
260 263 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
261 264 while(period_status.state != RATE_MONOTONIC_EXPIRED ) // after SY_LFR_TIME_SYN_TIMEOUT ms, starts HK anyway
262 265 {
263 266 if ((time_management_regs->coarse_time & 0x80000000) == 0x00000000) // check time synchronization
264 267 {
265 268 break; // break if LFR is synchronized
266 269 }
267 270 else
268 271 {
269 272 status = rtems_rate_monotonic_get_status( HK_id, &period_status );
270 273 // sched_yield();
271 274 status = rtems_task_wake_after( 10 ); // wait SY_LFR_DPU_CONNECT_TIMEOUT 100 ms = 10 * 10 ms
272 275 }
273 276 }
274 277 status = rtems_rate_monotonic_cancel(HK_id);
275 278 DEBUG_PRINTF1("startup HK, HK_id status = %d\n", period_status.state)
276 279
277 280 set_hk_lfr_reset_cause( POWER_ON );
278 281
279 282 while(1){ // launch the rate monotonic task
280 283 status = rtems_rate_monotonic_period( HK_id, HK_PERIOD );
281 284 if ( status != RTEMS_SUCCESSFUL ) {
282 285 PRINTF1( "in HOUS *** ERR period: %d\n", status);
283 286 spare_status = rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_6 );
284 287 }
285 288 else {
286 289 housekeeping_packet.packetSequenceControl[0] = (unsigned char) (sequenceCounterHK >> 8);
287 290 housekeeping_packet.packetSequenceControl[1] = (unsigned char) (sequenceCounterHK );
288 291 increment_seq_counter( &sequenceCounterHK );
289 292
290 293 housekeeping_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
291 294 housekeeping_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
292 295 housekeeping_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
293 296 housekeeping_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
294 297 housekeeping_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
295 298 housekeeping_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
296 299
297 300 spacewire_update_statistics();
298 301
299 302 hk_lfr_le_me_he_update();
300 303
301 304 set_hk_lfr_time_not_synchro();
302 305
303 306 housekeeping_packet.hk_lfr_q_sd_fifo_size_max = hk_lfr_q_sd_fifo_size_max;
304 307 housekeeping_packet.hk_lfr_q_rv_fifo_size_max = hk_lfr_q_rv_fifo_size_max;
305 308 housekeeping_packet.hk_lfr_q_p0_fifo_size_max = hk_lfr_q_p0_fifo_size_max;
306 309 housekeeping_packet.hk_lfr_q_p1_fifo_size_max = hk_lfr_q_p1_fifo_size_max;
307 310 housekeeping_packet.hk_lfr_q_p2_fifo_size_max = hk_lfr_q_p2_fifo_size_max;
308 311
309 312 housekeeping_packet.sy_lfr_common_parameters_spare = parameter_dump_packet.sy_lfr_common_parameters_spare;
310 313 housekeeping_packet.sy_lfr_common_parameters = parameter_dump_packet.sy_lfr_common_parameters;
311 314 get_temperatures( housekeeping_packet.hk_lfr_temp_scm );
312 315 get_v_e1_e2_f3( housekeeping_packet.hk_lfr_sc_v_f3 );
313 316 get_cpu_load( (unsigned char *) &housekeeping_packet.hk_lfr_cpu_load );
314 317
315 318 // SEND PACKET
316 319 status = rtems_message_queue_send( queue_id, &housekeeping_packet,
317 320 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
318 321 if (status != RTEMS_SUCCESSFUL) {
319 322 PRINTF1("in HOUS *** ERR send: %d\n", status)
320 323 }
321 324 }
322 325 }
323 326
324 327 PRINTF("in HOUS *** deleting task\n")
325 328
326 329 status = rtems_task_delete( RTEMS_SELF ); // should not return
327 330
328 331 return;
329 332 }
330 333
331 334 rtems_task dumb_task( rtems_task_argument unused )
332 335 {
333 336 /** This RTEMS taks is used to print messages without affecting the general behaviour of the software.
334 337 *
335 338 * @param unused is the starting argument of the RTEMS task
336 339 *
337 340 * The DUMB taks waits for RTEMS events and print messages depending on the incoming events.
338 341 *
339 342 */
340 343
341 344 unsigned int i;
342 345 unsigned int intEventOut;
343 346 unsigned int coarse_time = 0;
344 347 unsigned int fine_time = 0;
345 348 rtems_event_set event_out;
346 349
347 350 char *DumbMessages[14] = {"in DUMB *** default", // RTEMS_EVENT_0
348 351 "in DUMB *** timecode_irq_handler", // RTEMS_EVENT_1
349 352 "in DUMB *** f3 buffer changed", // RTEMS_EVENT_2
350 353 "in DUMB *** in SMIQ *** Error sending event to AVF0", // RTEMS_EVENT_3
351 354 "in DUMB *** spectral_matrices_isr *** Error sending event to SMIQ", // RTEMS_EVENT_4
352 355 "in DUMB *** waveforms_simulator_isr", // RTEMS_EVENT_5
353 356 "VHDL SM *** two buffers f0 ready", // RTEMS_EVENT_6
354 357 "ready for dump", // RTEMS_EVENT_7
355 358 "VHDL ERR *** spectral matrix", // RTEMS_EVENT_8
356 359 "tick", // RTEMS_EVENT_9
357 360 "VHDL ERR *** waveform picker", // RTEMS_EVENT_10
358 361 "VHDL ERR *** unexpected ready matrix values", // RTEMS_EVENT_11
359 362 "WATCHDOG timer", // RTEMS_EVENT_12
360 363 "TIMECODE timer" // RTEMS_EVENT_13
361 364 };
362 365
363 366 BOOT_PRINTF("in DUMB *** \n")
364 367
365 368 while(1){
366 369 rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3
367 370 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7
368 371 | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12 | RTEMS_EVENT_13,
369 372 RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT
370 373 intEventOut = (unsigned int) event_out;
371 374 for ( i=0; i<32; i++)
372 375 {
373 376 if ( ((intEventOut >> i) & 0x0001) != 0)
374 377 {
375 378 coarse_time = time_management_regs->coarse_time;
376 379 fine_time = time_management_regs->fine_time;
377 380 if (i==12)
378 381 {
379 382 PRINTF1("%s\n", DumbMessages[12])
380 383 }
381 384 if (i==13)
382 385 {
383 386 PRINTF1("%s\n", DumbMessages[13])
384 387 }
385 388 }
386 389 }
387 390 }
388 391 }
389 392
390 393 //*****************************
391 394 // init housekeeping parameters
392 395
393 396 void init_housekeeping_parameters( void )
394 397 {
395 398 /** This function initialize the housekeeping_packet global variable with default values.
396 399 *
397 400 */
398 401
399 402 unsigned int i = 0;
400 403 unsigned char *parameters;
401 404 unsigned char sizeOfHK;
402 405
403 406 sizeOfHK = sizeof( Packet_TM_LFR_HK_t );
404 407
405 408 parameters = (unsigned char*) &housekeeping_packet;
406 409
407 410 for(i = 0; i< sizeOfHK; i++)
408 411 {
409 412 parameters[i] = 0x00;
410 413 }
411 414
412 415 housekeeping_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
413 416 housekeeping_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
414 417 housekeeping_packet.reserved = DEFAULT_RESERVED;
415 418 housekeeping_packet.userApplication = CCSDS_USER_APP;
416 419 housekeeping_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
417 420 housekeeping_packet.packetID[1] = (unsigned char) (APID_TM_HK);
418 421 housekeeping_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
419 422 housekeeping_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
420 423 housekeeping_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
421 424 housekeeping_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
422 425 housekeeping_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
423 426 housekeeping_packet.serviceType = TM_TYPE_HK;
424 427 housekeeping_packet.serviceSubType = TM_SUBTYPE_HK;
425 428 housekeeping_packet.destinationID = TM_DESTINATION_ID_GROUND;
426 429 housekeeping_packet.sid = SID_HK;
427 430
428 431 // init status word
429 432 housekeeping_packet.lfr_status_word[0] = DEFAULT_STATUS_WORD_BYTE0;
430 433 housekeeping_packet.lfr_status_word[1] = DEFAULT_STATUS_WORD_BYTE1;
431 434 // init software version
432 435 housekeeping_packet.lfr_sw_version[0] = SW_VERSION_N1;
433 436 housekeeping_packet.lfr_sw_version[1] = SW_VERSION_N2;
434 437 housekeeping_packet.lfr_sw_version[2] = SW_VERSION_N3;
435 438 housekeeping_packet.lfr_sw_version[3] = SW_VERSION_N4;
436 439 // init fpga version
437 440 parameters = (unsigned char *) (REGS_ADDR_VHDL_VERSION);
438 441 housekeeping_packet.lfr_fpga_version[0] = parameters[1]; // n1
439 442 housekeeping_packet.lfr_fpga_version[1] = parameters[2]; // n2
440 443 housekeeping_packet.lfr_fpga_version[2] = parameters[3]; // n3
441 444
442 445 housekeeping_packet.hk_lfr_q_sd_fifo_size = MSG_QUEUE_COUNT_SEND;
443 446 housekeeping_packet.hk_lfr_q_rv_fifo_size = MSG_QUEUE_COUNT_RECV;
444 447 housekeeping_packet.hk_lfr_q_p0_fifo_size = MSG_QUEUE_COUNT_PRC0;
445 448 housekeeping_packet.hk_lfr_q_p1_fifo_size = MSG_QUEUE_COUNT_PRC1;
446 449 housekeeping_packet.hk_lfr_q_p2_fifo_size = MSG_QUEUE_COUNT_PRC2;
447 450 }
448 451
449 452 void increment_seq_counter( unsigned short *packetSequenceControl )
450 453 {
451 454 /** This function increment the sequence counter passes in argument.
452 455 *
453 456 * The increment does not affect the grouping flag. In case of an overflow, the counter is reset to 0.
454 457 *
455 458 */
456 459
457 460 unsigned short segmentation_grouping_flag;
458 461 unsigned short sequence_cnt;
459 462
460 463 segmentation_grouping_flag = TM_PACKET_SEQ_CTRL_STANDALONE << 8; // keep bits 7 downto 6
461 464 sequence_cnt = (*packetSequenceControl) & 0x3fff; // [0011 1111 1111 1111]
462 465
463 466 if ( sequence_cnt < SEQ_CNT_MAX)
464 467 {
465 468 sequence_cnt = sequence_cnt + 1;
466 469 }
467 470 else
468 471 {
469 472 sequence_cnt = 0;
470 473 }
471 474
472 475 *packetSequenceControl = segmentation_grouping_flag | sequence_cnt ;
473 476 }
474 477
475 478 void getTime( unsigned char *time)
476 479 {
477 480 /** This function write the current local time in the time buffer passed in argument.
478 481 *
479 482 */
480 483
481 484 time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
482 485 time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
483 486 time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
484 487 time[3] = (unsigned char) (time_management_regs->coarse_time);
485 488 time[4] = (unsigned char) (time_management_regs->fine_time>>8);
486 489 time[5] = (unsigned char) (time_management_regs->fine_time);
487 490 }
488 491
489 492 unsigned long long int getTimeAsUnsignedLongLongInt( )
490 493 {
491 494 /** This function write the current local time in the time buffer passed in argument.
492 495 *
493 496 */
494 497 unsigned long long int time;
495 498
496 499 time = ( (unsigned long long int) (time_management_regs->coarse_time & 0x7fffffff) << 16 )
497 500 + time_management_regs->fine_time;
498 501
499 502 return time;
500 503 }
501 504
502 505 void send_dumb_hk( void )
503 506 {
504 507 Packet_TM_LFR_HK_t dummy_hk_packet;
505 508 unsigned char *parameters;
506 509 unsigned int i;
507 510 rtems_id queue_id;
508 511
509 512 dummy_hk_packet.targetLogicalAddress = CCSDS_DESTINATION_ID;
510 513 dummy_hk_packet.protocolIdentifier = CCSDS_PROTOCOLE_ID;
511 514 dummy_hk_packet.reserved = DEFAULT_RESERVED;
512 515 dummy_hk_packet.userApplication = CCSDS_USER_APP;
513 516 dummy_hk_packet.packetID[0] = (unsigned char) (APID_TM_HK >> 8);
514 517 dummy_hk_packet.packetID[1] = (unsigned char) (APID_TM_HK);
515 518 dummy_hk_packet.packetSequenceControl[0] = TM_PACKET_SEQ_CTRL_STANDALONE;
516 519 dummy_hk_packet.packetSequenceControl[1] = TM_PACKET_SEQ_CNT_DEFAULT;
517 520 dummy_hk_packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_HK >> 8);
518 521 dummy_hk_packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_HK );
519 522 dummy_hk_packet.spare1_pusVersion_spare2 = DEFAULT_SPARE1_PUSVERSION_SPARE2;
520 523 dummy_hk_packet.serviceType = TM_TYPE_HK;
521 524 dummy_hk_packet.serviceSubType = TM_SUBTYPE_HK;
522 525 dummy_hk_packet.destinationID = TM_DESTINATION_ID_GROUND;
523 526 dummy_hk_packet.time[0] = (unsigned char) (time_management_regs->coarse_time>>24);
524 527 dummy_hk_packet.time[1] = (unsigned char) (time_management_regs->coarse_time>>16);
525 528 dummy_hk_packet.time[2] = (unsigned char) (time_management_regs->coarse_time>>8);
526 529 dummy_hk_packet.time[3] = (unsigned char) (time_management_regs->coarse_time);
527 530 dummy_hk_packet.time[4] = (unsigned char) (time_management_regs->fine_time>>8);
528 531 dummy_hk_packet.time[5] = (unsigned char) (time_management_regs->fine_time);
529 532 dummy_hk_packet.sid = SID_HK;
530 533
531 534 // init status word
532 535 dummy_hk_packet.lfr_status_word[0] = 0xff;
533 536 dummy_hk_packet.lfr_status_word[1] = 0xff;
534 537 // init software version
535 538 dummy_hk_packet.lfr_sw_version[0] = SW_VERSION_N1;
536 539 dummy_hk_packet.lfr_sw_version[1] = SW_VERSION_N2;
537 540 dummy_hk_packet.lfr_sw_version[2] = SW_VERSION_N3;
538 541 dummy_hk_packet.lfr_sw_version[3] = SW_VERSION_N4;
539 542 // init fpga version
540 543 parameters = (unsigned char *) (REGS_ADDR_WAVEFORM_PICKER + 0xb0);
541 544 dummy_hk_packet.lfr_fpga_version[0] = parameters[1]; // n1
542 545 dummy_hk_packet.lfr_fpga_version[1] = parameters[2]; // n2
543 546 dummy_hk_packet.lfr_fpga_version[2] = parameters[3]; // n3
544 547
545 548 parameters = (unsigned char *) &dummy_hk_packet.hk_lfr_cpu_load;
546 549
547 550 for (i=0; i<100; i++)
548 551 {
549 552 parameters[i] = 0xff;
550 553 }
551 554
552 555 get_message_queue_id_send( &queue_id );
553 556
554 557 rtems_message_queue_send( queue_id, &dummy_hk_packet,
555 558 PACKET_LENGTH_HK + CCSDS_TC_TM_PACKET_OFFSET + CCSDS_PROTOCOLE_EXTRA_BYTES);
556 559 }
557 560
558 561 void get_temperatures( unsigned char *temperatures )
559 562 {
560 563 unsigned char* temp_scm_ptr;
561 564 unsigned char* temp_pcb_ptr;
562 565 unsigned char* temp_fpga_ptr;
563 566
564 567 // SEL1 SEL0
565 568 // 0 0 => PCB
566 569 // 0 1 => FPGA
567 570 // 1 0 => SCM
568 571
569 572 temp_scm_ptr = (unsigned char *) &time_management_regs->temp_scm;
570 573 temp_pcb_ptr = (unsigned char *) &time_management_regs->temp_pcb;
571 574 temp_fpga_ptr = (unsigned char *) &time_management_regs->temp_fpga;
572 575
573 576 temperatures[0] = temp_scm_ptr[2];
574 577 temperatures[1] = temp_scm_ptr[3];
575 578 temperatures[2] = temp_pcb_ptr[2];
576 579 temperatures[3] = temp_pcb_ptr[3];
577 580 temperatures[4] = temp_fpga_ptr[2];
578 581 temperatures[5] = temp_fpga_ptr[3];
579 582 }
580 583
581 584 void get_v_e1_e2_f3( unsigned char *spacecraft_potential )
582 585 {
583 586 unsigned char* v_ptr;
584 587 unsigned char* e1_ptr;
585 588 unsigned char* e2_ptr;
586 589
587 590 v_ptr = (unsigned char *) &waveform_picker_regs->v;
588 591 e1_ptr = (unsigned char *) &waveform_picker_regs->e1;
589 592 e2_ptr = (unsigned char *) &waveform_picker_regs->e2;
590 593
591 594 spacecraft_potential[0] = v_ptr[2];
592 595 spacecraft_potential[1] = v_ptr[3];
593 596 spacecraft_potential[2] = e1_ptr[2];
594 597 spacecraft_potential[3] = e1_ptr[3];
595 598 spacecraft_potential[4] = e2_ptr[2];
596 599 spacecraft_potential[5] = e2_ptr[3];
597 600 }
598 601
599 602 void get_cpu_load( unsigned char *resource_statistics )
600 603 {
601 604 unsigned char cpu_load;
602 605
603 606 cpu_load = lfr_rtems_cpu_usage_report();
604 607
605 608 // HK_LFR_CPU_LOAD
606 609 resource_statistics[0] = cpu_load;
607 610
608 611 // HK_LFR_CPU_LOAD_MAX
609 612 if (cpu_load > resource_statistics[1])
610 613 {
611 614 resource_statistics[1] = cpu_load;
612 615 }
613 616
614 617 // CPU_LOAD_AVE
615 618 resource_statistics[2] = 0;
616 619
617 620 #ifndef PRINT_TASK_STATISTICS
618 621 rtems_cpu_usage_reset();
619 622 #endif
620 623
621 624 }
622 625
623 626 void set_hk_lfr_sc_potential_flag( bool state )
624 627 {
625 628 if (state == true)
626 629 {
627 630 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x40; // [0100 0000]
628 631 }
629 632 else
630 633 {
631 634 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xbf; // [1011 1111]
632 635 }
633 636 }
634 637
635 638 void set_hk_lfr_mag_fields_flag( bool state )
636 639 {
637 640 if (state == true)
638 641 {
639 642 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x20; // [0010 0000]
640 643 }
641 644 else
642 645 {
643 646 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xd7; // [1101 1111]
644 647 }
645 648 }
646 649
647 650 void set_hk_lfr_calib_enable( bool state )
648 651 {
649 652 if (state == true)
650 653 {
651 654 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] | 0x08; // [0000 1000]
652 655 }
653 656 else
654 657 {
655 658 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1] & 0xf7; // [1111 0111]
656 659 }
657 660 }
658 661
659 662 void set_hk_lfr_reset_cause( enum lfr_reset_cause_t lfr_reset_cause )
660 663 {
661 664 housekeeping_packet.lfr_status_word[1] = housekeeping_packet.lfr_status_word[1]
662 665 | (lfr_reset_cause & 0x07 ); // [0000 0111]
663 666 }
664 667
665 668 void hk_lfr_le_me_he_update()
666 669 {
667 670 unsigned int hk_lfr_le_cnt;
668 671 unsigned int hk_lfr_me_cnt;
669 672 unsigned int hk_lfr_he_cnt;
670 673
671 674 hk_lfr_le_cnt = 0;
672 675 hk_lfr_me_cnt = 0;
673 676 hk_lfr_he_cnt = 0;
674 677
675 678 //update the low severity error counter
676 679 hk_lfr_le_cnt =
677 680 housekeeping_packet.hk_lfr_dpu_spw_parity
678 681 + housekeeping_packet.hk_lfr_dpu_spw_disconnect
679 682 + housekeeping_packet.hk_lfr_dpu_spw_escape
680 683 + housekeeping_packet.hk_lfr_dpu_spw_credit
681 684 + housekeeping_packet.hk_lfr_dpu_spw_write_sync
682 685 + housekeeping_packet.hk_lfr_dpu_spw_rx_ahb
683 686 + housekeeping_packet.hk_lfr_dpu_spw_tx_ahb
684 687 + housekeeping_packet.hk_lfr_timecode_erroneous
685 688 + housekeeping_packet.hk_lfr_timecode_missing
686 689 + housekeeping_packet.hk_lfr_timecode_invalid
687 690 + housekeeping_packet.hk_lfr_time_timecode_it
688 691 + housekeeping_packet.hk_lfr_time_not_synchro
689 692 + housekeeping_packet.hk_lfr_time_timecode_ctr;
690 693
691 694 //update the medium severity error counter
692 695 hk_lfr_me_cnt =
693 696 housekeeping_packet.hk_lfr_dpu_spw_early_eop
694 697 + housekeeping_packet.hk_lfr_dpu_spw_invalid_addr
695 698 + housekeeping_packet.hk_lfr_dpu_spw_eep
696 699 + housekeeping_packet.hk_lfr_dpu_spw_rx_too_big;
697 700
698 701 //update the high severity error counter
699 702 hk_lfr_he_cnt = 0;
700 703
701 704 // update housekeeping packet counters, convert unsigned int numbers in 2 bytes numbers
702 705 // LE
703 706 housekeeping_packet.hk_lfr_le_cnt[0] = (unsigned char) ((hk_lfr_le_cnt & 0xff00) >> 8);
704 707 housekeeping_packet.hk_lfr_le_cnt[1] = (unsigned char) (hk_lfr_le_cnt & 0x00ff);
705 708 // ME
706 709 housekeeping_packet.hk_lfr_me_cnt[0] = (unsigned char) ((hk_lfr_me_cnt & 0xff00) >> 8);
707 710 housekeeping_packet.hk_lfr_me_cnt[1] = (unsigned char) (hk_lfr_me_cnt & 0x00ff);
708 711 // HE
709 712 housekeeping_packet.hk_lfr_he_cnt[0] = (unsigned char) ((hk_lfr_he_cnt & 0xff00) >> 8);
710 713 housekeeping_packet.hk_lfr_he_cnt[1] = (unsigned char) (hk_lfr_he_cnt & 0x00ff);
711 714
712 715 }
713 716
714 717 void set_hk_lfr_time_not_synchro()
715 718 {
716 719 static unsigned char synchroLost = 0;
717 720 int synchronizationBit;
718 721
719 722 // get the synchronization bit
720 723 synchronizationBit = (time_management_regs->coarse_time & 0x80000000) >> 31; // 1000 0000 0000 0000
721 724
722 725 switch (synchronizationBit)
723 726 {
724 727 case 0:
725 728 if (synchroLost == 1)
726 729 {
727 730 synchroLost = 0;
728 731 }
729 732 break;
730 733 case 1:
731 734 if (synchroLost == 0 )
732 735 {
733 736 synchroLost = 1;
734 737 increase_unsigned_char_counter(&housekeeping_packet.hk_lfr_time_not_synchro);
735 738 }
736 739 break;
737 740 default:
738 741 PRINTF1("in hk_lfr_time_not_synchro *** unexpected value for synchronizationBit = %d\n", synchronizationBit);
739 742 break;
740 743 }
741 744
742 745 }
General Comments 0
You need to be logged in to leave comments. Login now